I've built the December 2025 KPI scorecard: 4 of 8 KPIs were on target, and 2 have been off target for three months or more. All three P&L checks match: revenue is $827K, gross margin is 26.1% and opex is 25.1% of revenue in both the scorecard and the P&L.

| KPI | Actual | Target | Variance | Status | Months off |
| :--- | ---: | ---: | ---: | :--- | ---: |
| Revenue | $827K | $824K | $3K | on target | 0 |
| Gross margin percent | 26.1% | 26.0% | 0.1 pts | 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) pts | off target | 3 |
| Order fill rate percent | 97.6% | 97.0% | 0.6 pts | 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 pts | on target | 0 |

**Exceptions (off target three months or more):**
- **Days sales outstanding (days customers take to pay):** 51.2 against a target of 45.0; off target 3 months. The note asks the credit owner which customers' overdue balances are holding collections back.
- **On-time delivery percent:** 93.3% against a target of 95.0%; off target 3 months. The note asks the operations owner which carriers, lanes or warehouses account for the late orders.

Active customers (2 months off) and inventory turns (1 month off) also missed target. They have not been off for three months yet, so they are not listed as exceptions.

**Rounding:** the opex variance is not exactly the gap between actual and target as shown, because each figure is rounded on its own. The data notes say so.

**Inputs:** `kpis_fy2025.csv`, 96 rows, and `pnl_fy2025.csv`, 120 rows. Their shortened sha256 hashes are in the data notes.

Files are in `output/`:
- `scorecard.json`
- `scorecard-note.md`