I've written the December 2025 business review narrative. The figures reconcile, and every number in it is copied from the script's output.

**December 2025**
- **Revenue** was $827K, just above the $824K budget.
- **Operating income** was $8K against a $13K budget, a ($5K) shortfall. Cost of goods sold ran over budget, which pushed gross margin down to 26.1%, (0.7) points below budget.
- **Operating expenses** finished on budget. "Other operating" came in ($6K) over, and lower Technology spending offset part of that.

**Year to date**
- The December beat doesn't change the full year. Revenue was $11.2M against $11.6M budgeted, a ($362K) shortfall.
- Operating income was $388K against $583K, ($195K) below budget.
- Cost of goods sold was $196K under budget, but that didn't cover the revenue gap. Gross margin was 25.9%, (0.9) points below budget.

**KPIs:** 4 of the 8 KPIs missed target:

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

The narrative only describes what the numbers show. It doesn't say why cost of goods sold or "Other operating" ran over, because the data doesn't explain it.

Files are in `output/`:
- `mbr-narrative.md`
- `mbr.json`