Filed unassigned by the domain:spec seat (session session_01LpRNHxWZgSUgVnFT9mQQo4) from the #13041 dev run (PR #13081), where it was recorded as an honest residual — promoted to a card so it does not live in PR prose.
Dedup: one targeted semantic search over this repo returned 9 results (a non-empty return is itself the proof this session's search channel answers), and none of them is this defect — the nearest neighbours are #7377 (count columns disagreeing with the report) and #7257 (a governed type with no row), both about rows that exist rather than about a status the fold cannot see. REST was 403 on this seat, so the search was the channel; declared rather than assumed.
The gap
Nothing validates a liveness ledger entry's status string. classify() in check-liveness.mts accepts any truthy value and counts it:
cat.byStatus[status] = (cat.byStatus[status] || 0) + 1;
report.totals.byStatus[status] = (report.totals.byStatus[status] || 0) + 1;
foldStateCounts in readme-table.mts then reads exactly four names and nothing else:
live: b.live ?? 0,
experimental: b.experimental ?? 0,
dead: b.dead ?? 0,
planned: b.planned ?? 0,
So a ledger row written "status": "planed" is:
- classified — the forward pass is satisfied, no UNCLASSIFIED finding;
- counted by the walk, into a
byStatus bucket named after the typo;
- dropped by the fold — the artifact's four columns and its
classified total never see it;
- green —
check:liveness exits 0, state-counts.md reconciles byte-for-byte against a re-render of the same understated fold, and the README table agrees with it.
The published classified number is therefore smaller than the ledger by exactly the size of the typo'd population, and every reconciliation in the gate compares that number against itself. Same family as #13014: a reading that cannot come back wrong because the thing it reads is invisible to it.
What PR #13081 changed about the severity
That PR widened the evidence scan from live alone to live / planned / experimental, with dead explicitly excluded. It added a code-level exhaustiveness loop so a fifth status added to STATUS_COLUMNS must be declared scanned or unscanned or the gate throws. That closes the code half only. A typo in ledger data still falls outside both sets, so after that PR a typo'd status also has its evidence pointer unscanned — one more consequence riding on the same unvalidated string.
Not currently live: every ledger value today is one of the four (measured across all 31 ledgers during that run — live 819, planned 10, dead 80, experimental 5, no fifth value). This is a guard that is missing, not a break in progress.
Dispositions offered, none judged here
- Fail on an unrecognized status — the symmetric fix, matching how the gate already treats a malformed
verifiedAt (parsed to nothing, so it silently disables a check for that entry). Cheapest place is beside the existing partition check in check-liveness.mts; population is measurably zero today, so it starts green and only a new typo can red it — the same zero-census argument the orphan-proof and key-mention flips were switched on under.
- Make the fold total-preserving — have
foldStateCounts carry an "other" bucket, or assert its per-type sum equals cat.classified, so a status it cannot name shows up as an arithmetic mismatch rather than as absence.
- Both — 1 names the offending row, 2 makes the artifact structurally unable to understate. They are not exclusive.
Whether this is worth its own dispatch or should ride the next liveness-gate change is a triage call, not one this seat makes.
Refs: PR #13081 (where it was measured) · #13041 (the card that surfaced it) · #13014 (the class) · #7377 (the artifact) · #7257 (the table).
Filed unassigned by the
domain:specseat (sessionsession_01LpRNHxWZgSUgVnFT9mQQo4) from the #13041 dev run (PR #13081), where it was recorded as an honest residual — promoted to a card so it does not live in PR prose.Dedup: one targeted semantic search over this repo returned 9 results (a non-empty return is itself the proof this session's search channel answers), and none of them is this defect — the nearest neighbours are #7377 (count columns disagreeing with the report) and #7257 (a governed type with no row), both about rows that exist rather than about a status the fold cannot see. REST was 403 on this seat, so the search was the channel; declared rather than assumed.
The gap
Nothing validates a liveness ledger entry's
statusstring.classify()incheck-liveness.mtsaccepts any truthy value and counts it:foldStateCountsinreadme-table.mtsthen reads exactly four names and nothing else:So a ledger row written
"status": "planed"is:byStatusbucket named after the typo;classifiedtotal never see it;check:livenessexits 0,state-counts.mdreconciles byte-for-byte against a re-render of the same understated fold, and the README table agrees with it.The published
classifiednumber is therefore smaller than the ledger by exactly the size of the typo'd population, and every reconciliation in the gate compares that number against itself. Same family as #13014: a reading that cannot come back wrong because the thing it reads is invisible to it.What PR #13081 changed about the severity
That PR widened the evidence scan from
livealone tolive/planned/experimental, withdeadexplicitly excluded. It added a code-level exhaustiveness loop so a fifth status added toSTATUS_COLUMNSmust be declared scanned or unscanned or the gate throws. That closes the code half only. A typo in ledger data still falls outside both sets, so after that PR a typo'd status also has itsevidencepointer unscanned — one more consequence riding on the same unvalidated string.Not currently live: every ledger value today is one of the four (measured across all 31 ledgers during that run — live 819, planned 10, dead 80, experimental 5, no fifth value). This is a guard that is missing, not a break in progress.
Dispositions offered, none judged here
verifiedAt(parsed to nothing, so it silently disables a check for that entry). Cheapest place is beside the existing partition check incheck-liveness.mts; population is measurably zero today, so it starts green and only a new typo can red it — the same zero-census argument the orphan-proof and key-mention flips were switched on under.foldStateCountscarry an "other" bucket, or assert its per-type sum equalscat.classified, so a status it cannot name shows up as an arithmetic mismatch rather than as absence.Whether this is worth its own dispatch or should ride the next liveness-gate change is a triage call, not one this seat makes.
Refs: PR #13081 (where it was measured) · #13041 (the card that surfaced it) · #13014 (the class) · #7377 (the artifact) · #7257 (the table).