You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
check_calculator_roster_tether() (PR #562) asserts exactly one thing:
ifre.search(r"(?<![\w-])"+re.escape(identity) +r"(?![\w-])", prose):
continuefindings.append("...calculator roster drift: identity `X` is declared in code but has no entry...")
It searches docs/pipeline-fidelity-gate.md for the identity string. That is the whole check. It verifies the calculator is mentioned in a document — not that the mention is true, and not that the calculator produces anything.
Its own error message asks the author to state dormant or casts no votes. Nothing verifies that claim against reality.
Consequence, live today: the tether passes for local-name-frequency-v1, a calculator that has cast nothing in its entire existence — 0 rows in every vote table, 0 of 994 PilotRunLedger rows, never called by anything. It is documented, so it is clean. That is the exact failure mode the tether was built to catch, surviving inside the tether.
We made the mention mandatory and left the accuracy unchecked.
Why this matters — three channels, zero read as "fine" every time
channel
what happened
how long undetected
stage-d-illustration-v1
3 votes ever — its eligibility gate read ImageEvidence.layout_class believing it carried faced-ness, when that column holds a border colour (non-blank on 99.34% of rows)
since it was written
local-name-frequency-v1
never called, never run — 0 of 994 ledger rows
13 days, across two review passes
local-fallback-v1 chips
53,966 CardTagVote rows (border / frame-style / bleed-edge) destroyed by an identity-scoped purge that was meant to be channel-scoped
caught immediately, but only by luck
A dormant channel generates no divergence to explain, so a coverage-based audit reads it as clean by being invisible.
The design: one declaration, two checks
Rather than bolt a second, parallel check alongside the tether, extend the roster entry itself into a machine-readable contract.
Each entry in docs/pipeline-fidelity-gate.md declares which tables that calculator writes — a structured field, not prose. Then:
Check A (existing, code -> doc): every declared *_ANONYMOUS_ID has a roster entry. Unchanged.
Check B (new, doc -> reality): for every table an entry declares, that (identity, table) pair has rows in production. Zero is a failure, not a quiet outcome.
The (identity, table) distinction then lives in the roster, next to everything else about that calculator, rather than in a separate list that can disagree with it.
Why the pair, not the identity alone
This is the distinction the purge incident turned on. local-fallback-v1 writes CardTagVoteand (formerly) CardPrintingTag. Asserting on the identity alone would have seen "this identity has rows somewhere" and passed, while the chips were gone. Under the pair:
stage-d-slow-path-v1 declares CardScanLog only -> its 0 votes and 135,362 routing markers are correct by declaration, and no allowlist entry is needed to explain it.
local-fallback-v1 declares CardTagVote -> 0 rows would have failed the build.
Note the direction is new
The two existing tethers are code -> doc: derive a roster from source, check the doc mentions it. This adds a doc -> reality direction: the doc states a contract, and production is checked against it. Which tables a calculator writes cannot be reliably derived statically (writes go through shared helpers like purge_and_write_votes), so the declaration is human-authored — but it stops being unfalsifiable prose the moment something checks it.
Design constraints
Legitimately-zero cases need an explicit, per-entry-justified allowlist, exactly like CALCULATOR_ROSTER_ALLOWLIST — a retired calculator, or one not yet run. "Expected zero" must be a visible decision, never a silent gap. Note local-ocr-v1 is retiring and local-name-frequency-v1 may be, so both will need one.
Assert a floor, not a count. "Produced something" is durable; a hardcoded N rots — see docs/features/catalog-stats.md and catalog_stats.py, which both claimed "~11 distinct reasons" against ~30 in code until PR Adopt a *_SKIP_REASON declaration convention; tether the roster to a doc #567 removed the number entirely.
Where does it run? Check A is a lint and runs in CI. Check B needs a database, so it is a post-run report or an ops command, not a CI job. A 7-hour pass should probably report loudly rather than exit non-zero at the end; a pass finding a channel silent in its first batch could fail fast. Decide deliberately.
Immediate concrete use
After the first monolith run, the three destroyed chip channels — cast_border_attribute_vote, cast_frame_style_vote, cast_bleed_edge_vote in local_fallback.py — must be non-zero again. If they are not, the re-derivation did not happen and a recoverable loss became permanent. Right now nothing would tell us.
The gap, stated precisely
check_calculator_roster_tether()(PR #562) asserts exactly one thing:It searches
docs/pipeline-fidelity-gate.mdfor the identity string. That is the whole check. It verifies the calculator is mentioned in a document — not that the mention is true, and not that the calculator produces anything.Its own error message asks the author to state
dormantorcasts no votes. Nothing verifies that claim against reality.Consequence, live today: the tether passes for
local-name-frequency-v1, a calculator that has cast nothing in its entire existence — 0 rows in every vote table, 0 of 994PilotRunLedgerrows, never called by anything. It is documented, so it is clean. That is the exact failure mode the tether was built to catch, surviving inside the tether.We made the mention mandatory and left the accuracy unchecked.
Why this matters — three channels, zero read as "fine" every time
stage-d-illustration-v1ImageEvidence.layout_classbelieving it carried faced-ness, when that column holds a border colour (non-blank on 99.34% of rows)local-name-frequency-v1local-fallback-v1chipsCardTagVoterows (border / frame-style / bleed-edge) destroyed by an identity-scoped purge that was meant to be channel-scopedA dormant channel generates no divergence to explain, so a coverage-based audit reads it as clean by being invisible.
The design: one declaration, two checks
Rather than bolt a second, parallel check alongside the tether, extend the roster entry itself into a machine-readable contract.
Each entry in
docs/pipeline-fidelity-gate.mddeclares which tables that calculator writes — a structured field, not prose. Then:*_ANONYMOUS_IDhas a roster entry. Unchanged.(identity, table)pair has rows in production. Zero is a failure, not a quiet outcome.The
(identity, table)distinction then lives in the roster, next to everything else about that calculator, rather than in a separate list that can disagree with it.Why the pair, not the identity alone
This is the distinction the purge incident turned on.
local-fallback-v1writesCardTagVoteand (formerly)CardPrintingTag. Asserting on the identity alone would have seen "this identity has rows somewhere" and passed, while the chips were gone. Under the pair:stage-d-slow-path-v1declaresCardScanLogonly -> its 0 votes and 135,362 routing markers are correct by declaration, and no allowlist entry is needed to explain it.local-fallback-v1declaresCardTagVote-> 0 rows would have failed the build.Note the direction is new
The two existing tethers are code -> doc: derive a roster from source, check the doc mentions it. This adds a doc -> reality direction: the doc states a contract, and production is checked against it. Which tables a calculator writes cannot be reliably derived statically (writes go through shared helpers like
purge_and_write_votes), so the declaration is human-authored — but it stops being unfalsifiable prose the moment something checks it.Design constraints
CALCULATOR_ROSTER_ALLOWLIST— a retired calculator, or one not yet run. "Expected zero" must be a visible decision, never a silent gap. Notelocal-ocr-v1is retiring andlocal-name-frequency-v1may be, so both will need one.docs/features/catalog-stats.mdandcatalog_stats.py, which both claimed "~11 distinct reasons" against ~30 in code until PR Adopt a *_SKIP_REASON declaration convention; tether the roster to a doc #567 removed the number entirely.Immediate concrete use
After the first monolith run, the three destroyed chip channels —
cast_border_attribute_vote,cast_frame_style_vote,cast_bleed_edge_voteinlocal_fallback.py— must be non-zero again. If they are not, the re-derivation did not happen and a recoverable loss became permanent. Right now nothing would tell us.Related
CardScanLogretention janitor