The FY2025 budget-versus-actual commentary is written to `output/bva-note.md`, with the figures in `output/bva.json`. The script's reconciliation check passed.

**Headline:** Full-year revenue was $11,238K against a $11,600K budget, unfavourable by ($362K), or (3.1%). Operating income was $388K against $583K, unfavourable by ($195K), or (33.5%).

| Measure | Actual | Budget | Variance |
| --- | --- | --- | --- |
| Revenue | $11,238K | $11,600K | ($362K) |
| COGS | $8,324K | $8,491K | $167K |
| Gross profit | $2,914K | $3,109K | ($194K) |
| Gross margin | 25.9% | 26.8% | (0.9) pts |
| Operating expenses | $2,527K | $2,526K | ($1K) |
| Operating income | $388K | $583K | ($195K) |

**Drivers:**
- **Revenue miss:** It sits in three months: March ($123K), July ($132K) and August ($105K). Every other month was within ($6K) to $7K of budget.
- **Costs:** Cost of goods sold was favourable by $196K, which partly offset the revenue miss. Freight out was unfavourable by ($29K), and Salaries and wages by ($38K).
- **Reversed variance:** Professional fees peaked at ($31K) in March and ended the year at ($1K).

The data doesn't show why revenue missed in those three months. The note says so and asks the sales owners to explain them. It also asks the freight owners whether the overrun is rate or volume, which the data can't answer.

December on its own was close to budget: revenue was $827K, favourable by $3K, and operating income was $8K against $13K.

The data note cites `pnl_fy2025.csv`, 120 rows, sha256 `eaa52ac89e97`. Each amount is rounded on its own, so Gross profit and Operating income don't add exactly in the table. The note says this.