[read SKILL.md]
---
name: variance-bridge
description: Builds revenue bridges, budget-vs-actual commentary, price-volume-mix analyses and forecast-accuracy reviews for finance reviews. Use when asked for a revenue bridge or PY-to-CY walk, why revenue changed, budget vs actual or variance commentary, price versus volume versus mix, or how accurate the forecasts were. Not for monthly reporting packs, account reconciliations or forward forecasts.
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.
metadata:
  pack-version: "1.0.0"
  pack-standard: "skills-pack/1.0"
---

# Variance and Bridge pack

This pack holds several skills. Pick the row that matches the request, read
every file listed for it, then follow the skill. Read the files before
answering; do not answer from memory.

All paths in this pack, in every file, are relative to this file's folder
(the pack root).

| Request | Read first | Then read |
| --- | --- | --- |
| Revenue bridge, PY-to-CY walk, customer movement, why revenue changed year over year | `skills/revenue-bridge/SKILL.md` | `_shared/source-trace/SKILL.md`, `_shared/executive-voice/SKILL.md` |
| Budget vs actual, BvA, actual versus plan, P&L variance commentary for a month or the year | `skills/budget-vs-actual/SKILL.md` | `_shared/source-trace/SKILL.md`, `_shared/executive-voice/SKILL.md` |
| Price-volume-mix, PVM, how much of the change was price versus volume, mix shift | `skills/price-volume-mix/SKILL.md` | `_shared/source-trace/SKILL.md`, `_shared/executive-voice/SKILL.md` |
| Forecast accuracy, how good were the reforecasts, forecast versus actual by version, MAPE, bias | `skills/forecast-accuracy/SKILL.md` | `_shared/source-trace/SKILL.md`, `_shared/executive-voice/SKILL.md` |
| Anything else (monthly review, close, cash, scenarios) | Not in this pack | Say so and stop |

## Rules for every skill in this pack

1. Numbers come from scripts. Never calculate, round or restate a figure yourself.
2. If a script fails or cannot run, report the error message and stop.
3. If the request is missing an input the skill needs, ask for it. Do not guess.

<!-- trace:SNT-1BB5E5 -->

[read skills/revenue-bridge/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.
---

# 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, `skills/revenue-bridge/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>/skills/revenue-bridge/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 `skills/revenue-bridge/references/definitions.md` for what each movement means.

<!-- trace:SNT-49BA52 -->

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