[read SKILL.md]
---
name: revenue-bridge
description: Computes a prior-year to current-year revenue bridge by customer (timing, loss, decline, upsell, new) and writes a one-page commentary note. Use when asked for a revenue bridge, a PY-to-CY revenue walk, a customer bridge, why revenue changed year over year, or which customers drove the change. Needs a customer CSV with prior-year and current-year revenue columns.
license: MIT
compatibility: Requires Python 3.9 or later (standard library only) and permission to run scripts. If scripts cannot run, the pack stops and says so; it never computes figures itself.
---

# Revenue bridge

Produces two files: the script's figures (`bridge.json`) and a commentary
note (`bridge-note.md`). Unless the user names other paths, write both to an
`output/` folder in the current working directory.

## Steps

1. Find the input CSV the user named. Open only its header row. It needs
   `customer_id`, `customer_name`, a prior-year and a current-year revenue
   column, and optionally `timing_amount`. If any are missing, ask.
2. Run the script, `scripts/bridge.py`. As in every
   file in this pack, paths are relative to the pack root, the top folder of
   the pack, which holds its main SKILL.md:

       python3 <pack root>/scripts/bridge.py \
           --input <the CSV> --output output/bridge.json

   If the revenue columns are not named `py_revenue`/`cy_revenue` or
   `fyNNNN_revenue`, add `--py-col <name> --cy-col <name>`.
3. If the script exits with an error, show the error and stop. Exit code 3
   means the bridge does not reconcile; never report its figures. Before
   exit 0 the script checks that PY + Timing + Loss + Decline + Upsell + New
   = CY to the cent.
4. Read `output/bridge.json`. Use only the strings under `display`.
5. Write `output/bridge-note.md` to the contract below.
6. Check the note before you finish. Every figure must be a display string,
   character for character, with parentheses exactly where `display` has
   them: a negative keeps them and a positive figure never gets them. Join a
   figure to a name with a verb: "Ember Analytics added $136K".

## Output contract

The note has exactly these four sections, in this order:

    ## Headline
    One sentence: current-year revenue, prior-year revenue, and the change
    with its percentage.

    ## Bridge
    A table with columns Step and Amount, and these rows in this order:
    <PY label>, Timing, Loss, Decline, Upsell, New, <CY label>.

    ## Drivers
    Two to four bullets. Each names one customer from `display.movers` and
    joins its amount to the name with a verb ("Ember Analytics added
    $136K"), or gives one movement total with its customer count.

    ## Data notes
    One line in this form, with the backticks, where <file>, <rows> and
    <sha12> are the strings in display.input:
    <file>, <rows> rows, sha256 `<sha12>`

- Copy every figure exactly as it appears in `display`, including parentheses.
- Display figures are rounded. Never add them up or derive new figures from them.
- Use the labels from `labels` (for example FY2024) for the first and last rows.
- You choose which customers and movements to name and in what order. Do not
  name a cause the data does not show.
- See `references/definitions.md` for what each movement means.

<!-- trace:SNT-D003B9 -->

[read _shared/executive-voice/SKILL.md]
---
name: executive-voice
description: House voice for every written deliverable. Read by pack skills when writing a note, memo, summary or commentary; not triggered on its own.
---

# Executive voice

- Lead with the answer. The first sentence states the result and its number.
- Sentences under 25 words. Plain verbs: grew, fell, offset, lost, added.
- Every claim about size carries its figure. No "significant", "strong",
  "robust" or "notable" without a number beside it.
- Negative amounts in parentheses, exactly as the script prints them.
  Parentheses mean negative and nothing else: no asides in parentheses, and
  never a positive figure, a count or an account number in them. Use commas
  for an aside.
- Name customers and movements; do not speculate about causes the data does
  not show. If a reader will ask why, say what data would answer it.
- No hedging ("it appears", "may suggest"), no filler ("it is worth noting").

<!-- trace:SNT-5B33A2 -->

[read _shared/source-trace/SKILL.md]
---
name: source-trace
description: Rules for tracing every figure in a deliverable to its source file and script output. Read by pack skills when a deliverable contains figures; not triggered on its own.
---

# Source trace

- Every figure in a deliverable comes from a script's output file, copied
  exactly. If you cannot point to the field it came from, delete it.
- Name the input file and its row count in the deliverable's data notes.
- Copy the input file's hash exactly as the script prints it. Write no other
  codes, IDs or numbers that the script output does not contain.
- If the script output and the source disagree, or a check fails, stop and
  report it. Do not reconcile figures by hand.

<!-- trace:SNT-F5EC35 -->

Wrote output/bridge.json and output/bridge-note.md.
