I've built the December 2025 KPI scorecard. The script's checks against the P&L passed: revenue ($827K), gross margin percent (26.1%) and opex percent of revenue (25.1%) all match.

**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 |

A positive variance means better than target; a variance in brackets means worse. For percent KPIs the variance is in percentage points.

**Exceptions (off target three months or more):**
- **Days sales outstanding:** 51.2 against a target of 45.0. Customers are taking longer to pay than the target allows.
- **On-time delivery percent:** 93.3% against a target of 95.0%. Fewer orders arrived by the promised date than planned.

Active customers has been off target for 2 months and inventory turns for 1 month, so neither counts as an exception yet.

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