The Afternoon We Shipped Three Wrong Metrics
Bad numbers erode trust faster than no numbers
On June 1 we shipped three person-summary metrics that managers would have trusted in a staffing conversation. By 10:52 the same day, three commits corrected them: merges counted only PRs created in the window, open snapshots used the wrong catalog, and cycle time included still-open PRs. Bad numbers erode trust faster than no numbers. Here's the reconciliation identity we use now - and the three checks I'd run before putting any metrics in a staff meeting.
The morning CLI refactor and pipeline work mattered. The afternoon fixes mattered more.
Here's what this piece covers: the leadership cost of trusted fiction, the three wrong definitions, same-day corrections, the reconciliation identity, and three lead habits.
Part of Field Notes: agentic delivery.
1. The leadership problem
Managers staff from merged and open counts. If those columns are undefined - or defined wrong - you are not measuring engineering; you are laundering fiction through Excel.
Wrong: "We fixed some bugs in the afternoon."
Right: "Between 10:20 and 10:52 we corrected prs_merged, prs_open, and merge-cycle hours before anyone built a narrative on them."
The anti-pattern is metrics that lie - undefined columns, open PRs counted as cycle time, the wrong catalog for "open."
2. What the git history shows
Verified timestamps (EDT), same morning cluster as the productization:
| Time | Commit | Change |
|---|---|---|
| 10:20 | dd6c672 |
Per-person min/max/avg hours open → merge |
| 10:46 | 0f69edb |
Fix prs_open snapshot; exclude open PRs from merge cycle time |
| 10:52 | 923250f |
Fix prs_merged - all merges in window, not only PRs created in May |
3. The three bugs
prs_merged - counted merges only for PRs created in the window. Carry-over merges (opened earlier, merged in May) vanished. Staffing looked quieter than reality.
prs_open - snapshot at window end used the wrong catalog. Open queue overstated or understated depending on who had activity in-window.
Merge cycle hours - included still-open PRs. Averages inflated; "slow" looked systemic when the denominator was wrong.
Wrong definition before the fix (sketch):
# WRONG - merges only for PRs created in the window
def prs_merged_wrong(rows, start, end):
return sum(
1 for r in rows
if start <= r.created < end and start <= r.merged < end
)
# RIGHT - any merge whose merged_at falls in [start, end)
def prs_merged(rows, start, end):
return sum(1 for r in rows if r.merged and start <= r.merged < end)Phase 2 detail rows and Phase 3b catalogs are different sources for different columns - mixing them without a dictionary is how silent bugs ship. No automated tests that day; bugs found by manual reconciliation and later agent audit (article 11).
4. Named pattern: same-day metric correction
Same-day metric correction - ship, reconcile, fix before the narrative hardens.
The reconciliation identity
For window-opened PRs only, at window end:
authored ≈ merged + open + closed_unmerged
Verified example from the metrics review (monika-sbd, May 2026):
| Repo | authored | merged + open + closed_um | Match |
|---|---|---|---|
| global-services | 2 | 0 + 1 + 1 = 2 | Yes |
| global-user-services | 3 | 3 + 0 + 0 = 3 | Yes |
| polaris-turbo | 10 | 9 + 0 + 1 = 10 | Yes |
Confidence: git timestamps verified; reconciliation rows verified against May 2026 production caches in docs/metrics-review-findings.md. Do not apply the identity to totals that include carry-over prs_merged / prs_open without scoping to window-opened PRs (README as contract).
5. What I'd do as a lead
- Demand a one-page metrics dictionary before any dashboard ships. Column name ≠ definition.
- Reconcile one person manually each month. Spot-check is not optional - it is how
monika-sbdcaught fiction. - Never compare month-over-month until window semantics are frozen. Half-open windows and timezone belong in the contract first.
Further reading
- An 857-line honesty machine - origin probe
- Parallel fetch, raw cache, and run logs - same-day pipeline
- README as contract - freeze the window
- Field notes: agentic delivery
- github-analysis:
dd6c672·0f69edb·923250f· 2026-06-01