I've drafted the December 2025 commentary in `output/mbr-narrative.md`. All the figures come from the reporting script's output (`output/mbr.json`), and its checks passed: the P&L lines add up to operating income and the months add up to the year to date.

**Month:** revenue beat budget slightly but profit missed. Revenue was $827K against a $824K budget. Operating income was $8K against $13K, a ($5K) miss. Gross margin was 26.1% against 26.8%, (0.7) pts. Operating expenses came in on budget.

**Year to date:** December's small beat doesn't change the full-year picture. Revenue was $11.2M against $11.6M, a ($362K) shortfall. Operating income was $388K against $583K, a ($195K) miss. Gross margin was 25.9% against 26.8%.

**Biggest line variances:**
- **Month:**
  - Cost of goods sold was ($6K) over budget.
  - Other operating costs were ($6K) over budget.
  - Technology came in $4K under budget, which offset most of the other operating overrun.
- **Year to date:**
  - Revenue was ($362K) short.
  - Cost of goods sold was $196K under budget, but not enough to hold gross margin.
  - Salaries and wages were ($38K) over budget. This one isn't in the draft, because the format allows four driver bullets.

**KPIs that slipped:** four of the eight were off target in December.

| KPI | Actual | Target | Months off target |
| --- | ---: | ---: | ---: |
| Days sales outstanding | 51.2 days | 45.0 | 3 |
| On-time delivery | 93.3% | 95.0% | 3 |
| Active customers | 40 | 42 | 2 |
| Inventory turns | 5.33 | 6.50 | 1 |

The data shows the amounts but not the reasons behind them, so the draft doesn't give causes. If the review will ask why cost of goods sold ran over budget in December or why revenue fell short for the year, you'll need customer- and product-level detail to answer.