I've written the December 2025 business review narrative to `output/mbr-narrative.md`, with the script's figures in `output/mbr.json`. The script checks its own figures and they all agreed, so it finished cleanly.

**Main points:**
- **Month:** Revenue was $827K against a budget of $824K, $3K ahead. Operating income was $8K against $13K, ($5K) behind, because gross margin came in at 26.1% against 26.8%.
- **Year to date:** The year is still behind budget, so December's revenue beat doesn't change the picture. Revenue was $11.2M against $11.6M, ($362K) behind, and operating income was $388K against $583K, ($195K) behind.
- **Drivers:** In December, cost of goods sold was ($6K) over budget and other operating costs were ($6K) over. A $4K saving on technology offset part of the second. For the year, cost of goods sold was $196K under budget, but revenue was ($362K) short.
- **KPIs:** Four of eight are off target. Days sales outstanding (51.2 against 45.0) and on-time delivery (93.3% against 95.0%) have each missed for 3 months. Active customers (40 against 42) has missed for 2 months and inventory turns (5.33 against 6.50) for 1.

**Things to know:**
- The narrative has the six sections the template requires. All figures are copied exactly as the script printed them.
- The "Cost of goods sold" line in the drivers is $584K. The cost of goods sold total behind the month's gross profit is $611K. The total includes other cost-of-sales lines, so the two figures aren't a mismatch.
- The data doesn't show why costs or KPIs moved, so the narrative names no causes. Answering that would need data broken down by product and customer.