The December 2025 KPI scorecard is done, and it ties to the P&L. Revenue, gross margin percent and opex percent each match `pnl_fy2025.csv`: $827K, 26.1% and 25.1%.

**Headline:** 4 of 8 KPIs were on target in December 2025, and 2 have been off target for three months or more.

| KPI | Actual | Target | Variance | Status | Months off |
| :-- | --: | --: | --: | :-- | --: |
| Revenue | $827K | $824K | $3K | on target | 0 |
| Gross margin percent | 26.1% | 26.0% | 0.1 | on target | 0 |
| Days sales outstanding | 51.2 | 45.0 | (6.2) | off target | 3 |
| On-time delivery percent | 93.3% | 95.0% | (1.7) | off target | 3 |
| Order fill rate percent | 97.6% | 97.0% | 0.6 | on target | 0 |
| Active customers | 40 | 42 | (2) | off target | 2 |
| Inventory turns | 5.33 | 6.50 | (1.17) | off target | 1 |
| Opex percent of revenue | 25.1% | 25.3% | 0.1 | on target | 0 |

**Exceptions** (off target three months or more):
- **Days sales outstanding:** 51.2 against a target of 45.0. The note asks the collections owner which customers' overdue balances caused the rise.
- **On-time delivery percent:** 93.3% against a target of 95.0%. The note asks the operations owner where the late orders come from and when delivery will recover.

Active customers and inventory turns are also off target. They have been off for fewer than three months, so they are not on the exceptions list.

**Opex variance:** the table shows 25.1% against 25.3% with a variance of 0.1, not 0.2. The script rounds the variance from the unrounded figures, so this is rounding, not an error. I left the figures as printed rather than adjusting them.

Files are in `output/`:
- `scorecard.json`: the script's figures
- `scorecard-note.md`: the four-section note, including data notes with each input's row count and hash