scripts/native_result_ledger.py fails on pristine main:
Confirmed on an unmodified origin/main in a throwaway worktree (found during PR #10701's rebase; the check was re-run on pristine main specifically to rule the PR in or out as the cause — it is not the cause).
Why this went unnoticed
The ledger check's workflow is path-filtered to scripts/native_result_ledger.py and .tsv. It only runs when one of those two files changes. So a drift introduced by any other change — which is exactly how this drift arises, since the count tracks native result surfaces declared all over the tree — never triggers the check that would catch it. The gate then fires on the next PR that happens to touch the ledger, attributing a pre-existing drift of 5 to whoever is unlucky enough to edit it.
This is the fourth of the "ways a gate can be unable to fail" shapes in CLAUDE.md, with a twist: the gate is not merely unable to fail, it is set up to fail on the wrong PR. The binding-removal queue makes that concrete — every removal in it touches the ledger, so each one inherits this failure and has to prove it pre-existing before it can proceed. That is a fixed tax of one throwaway-worktree bisect per removal, which is what it cost here.
Suggested direction
Two separable pieces:
- Reconcile the 5. Work out whether
371 or 376 is correct — i.e. whether the recorded baseline went stale or the tree genuinely grew surfaces — and fix the side that is wrong. The two readings have opposite meanings: a stale baseline is bookkeeping, while five unrecorded native result surfaces is a real gap in what the ledger claims to cover.
- Make the trigger match the subject. A gate whose subject is "a count derived from the whole tree" cannot be path-filtered to the two files that record the count. Either run it on the same tier as the other whole-tree ratchets, or keep the filter and accept that the number is advisory — but not both, because the current arrangement produces a red gate on an innocent PR.
Filing separately rather than folding into a removal PR, since it is neither caused by nor fixable within any of them.
scripts/native_result_ledger.pyfails on pristinemain:Confirmed on an unmodified
origin/mainin a throwaway worktree (found during PR #10701's rebase; the check was re-run on pristine main specifically to rule the PR in or out as the cause — it is not the cause).Why this went unnoticed
The ledger check's workflow is path-filtered to
scripts/native_result_ledger.pyand.tsv. It only runs when one of those two files changes. So a drift introduced by any other change — which is exactly how this drift arises, since the count tracks native result surfaces declared all over the tree — never triggers the check that would catch it. The gate then fires on the next PR that happens to touch the ledger, attributing a pre-existing drift of 5 to whoever is unlucky enough to edit it.This is the fourth of the "ways a gate can be unable to fail" shapes in CLAUDE.md, with a twist: the gate is not merely unable to fail, it is set up to fail on the wrong PR. The binding-removal queue makes that concrete — every removal in it touches the ledger, so each one inherits this failure and has to prove it pre-existing before it can proceed. That is a fixed tax of one throwaway-worktree bisect per removal, which is what it cost here.
Suggested direction
Two separable pieces:
371or376is correct — i.e. whether the recorded baseline went stale or the tree genuinely grew surfaces — and fix the side that is wrong. The two readings have opposite meanings: a stale baseline is bookkeeping, while five unrecorded native result surfaces is a real gap in what the ledger claims to cover.Filing separately rather than folding into a removal PR, since it is neither caused by nor fixable within any of them.