fix(tooling): qualify the cutover ratchet's ordinary-English alternative - #461
Merged
Conversation
…ive (BACKLOG #1261) The pattern's bare definite-article alternative is an ordinary English noun phrase. It matched any sentence containing it, with no regard for whether the sentence concerned repository topology at all -- and nothing in the regex looks at the surrounding words. IT HAS FIRED ON INNOCENT PROSE AT LEAST THREE TIMES AND WAS FIXED BY EDITING THE PROSE EVERY TIME. The most recent, e6d25d1, reworded two sentences to "counterpart" and left the pattern untouched; `git diff e6d25d1 origin/main` over this file is empty, so the next author writing the same ordinary sentence reproduced the same red on a documentation-only branch. Two earlier firings are recorded in this file's own comments and were answered the same way. A defect fixed three times at the instance level is a class nobody had priced. WHAT CHANGED: the four unambiguous topology phrases still count bare, because they cannot mean anything else. The bare form now counts only when a topology qualifier shares its line. MEASURED BEFORE CHANGING, 52 hits over 1619 tracked files, of which 20 matched ONLY via the bare form. Reading all 20 splits them three ways: 5 are figurative English with no repository in view, 9 carry an unambiguous topology term and still count, and 6 are historical narration the retrospective filter never covered. The last group drops, and dropping it is correct -- this gate's subject is a PRESENT-TENSE claim that this repo is a copy, which "what it did on the mirror" does not make. THE QUALIFIER LIST IS SHORT ON PURPOSE. `remote` and `branch` are deliberately absent: with either of them in, two of the five false positives survive -- a line about a remote-tracking ref and one about a case that broke every open branch. Every term in the set means repository topology and nothing else. A longer list makes the false-positive rate worse, which is the trap the previous three fixes fell into. Ratchet re-baselined 52 -> 41 in the same change, with its measurement, per this file's own rule that the number may fall and never rise. The slack was ZERO before this, which is what turned a nuisance into a tripwire: the next innocent sentence red `main` immediately, and the sanctioned remedies were to reword it or delete an unrelated genuine hit to buy room. BOTH DIRECTIONS ARE PINNED, and each was made to fail on purpose: - revert the classifier to the bare pattern -> the ordinary-English arm reds - delete the bare form instead of qualifying it -> the real-claim arm reds, naming the line Restored after each; the file hashed byte-identical both times. A one-directional test would have passed against retiring the check entirely. The fixtures are the real lines quoted from the tree, not invented to fit the regex. This module is excluded from its own scan, which is the only reason the gate can be documented in the repository it polices -- an early draft of the ledger item raised the counted population by three just by describing it. Verification, with its scope: pytest tests/test_cutover_slug_rot.py, 5 passed; ruff check and ruff format --check on the changed file, clean. This lane's own .venv (ruff 0.15.22, the pin). Not run here: the full suite, which is a separate pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Cherry-picked by the lander from claude/builder-2bee12, whose authoring session is archived. Authorship preserved. TAKEN ALONE, and the exclusions are deliberate. The dispatcher seat holds the owner's delegation on that branch's shape and excluded the other four; I verified the two that are checkable: f34eb88 ALREADY LANDING as PR #457's single commit -- patch-id 778090c3ab9f5d34 on BOTH, so taking it here would DOUBLE-LAND it. Verified by patch-id, not diffstat. ff426e5 its own archived author left a DO NOT LAND with a substantive reason: the counter it adds would read 0 forever on a default deployment. Excluded on my own judgement -- a control resting on a false premise reads as coverage and is worse than none. d37589b the item's own stated precondition is unmet. 6734748 pending an unanswered owner design question. Now backed on origin at snapshot/builder-2bee12-20260820 so it cannot be lost while that is settled. main currently carries the bare pattern at ZERO slack on the topology ratchet, so this is also the commit that stops an innocent doc edit redding main.
wshallwshall
enabled auto-merge (squash)
August 20, 2026 13:58
wshallwshall
added a commit
that referenced
this pull request
Aug 20, 2026
…rning runs an index test) (#465) * backlog: close #1261 -- the cutover ratchet fix is on main by content parse_items 313 items / 231 open / 82 closed, from 232/81. Expected closure delta: 0 items, -1 open, +1 closed. backlog_status_check reports 549 across both files, each declaring exactly one status. Closed on the release condition this project uses -- the fix TEXT on main -- and verified that way rather than on a merged badge. The tests/test_cutover_slug_rot.py blob is 13a711b on origin/main, on PR #461's head and on 9d781ed: all three identical. Recorded in the banner because it will be reached for again: the cumulative patch-id test does NOT match here, branch 43f5a21a against squash 148226e6, and that proves nothing. A cherry-pick onto a different base plus an update-branch breaks the equality without the work being absent. On a squash-merging repo a patch-id MATCH proves landed and a NO-MATCH proves nothing. Blob identity settled it in one command. The banner's closed-alphabet character was LIFTED PROGRAMMATICALLY from an already-closed item rather than typed, and asserted a member of _CLOSED before use. Typing a status glyph by hand is how a wrong one enters the file, and the alphabet is machine-parsed. Held until the fix landed rather than closing on the PR, because main carried the bare pattern at zero slack until then and a premature close leaves main one innocent documentation edit from red. * backlog: file #1298 -- the archive dialog's discard warning is an index test, not a loss test The session-archive dialog lists the worktree's dirty set and says the files "will be permanently discarded". For a ?? entry that is a statement about THIS worktree's index, not about the content: a worktree whose HEAD predates a commit sees every file that landed since as untracked, because they are absent from its index while being tracked on main. Measured on a live instance. It warned that tests/test_notifiable_admin.py and docs/adr/0167-*.md would be permanently discarded. Both are tracked on origin/main -- the test was added at 4c28bad (PR #428), which merged that same session -- and every local copy was byte-identical to main's blob in all six worktrees holding them. Archiving would have discarded nothing. Reproduced on this seat's own tree, which is what establishes the mechanism rather than the coincidence: at dd655da, two behind origin/main, git status showed the identical ?? pair; fast-forwarding to 1df0c07 converted both to tracked with no edit and no conflict. The files never changed, the base did. The failure is systematic and its timing is adversarial -- the warning is loudest exactly when the fleet lands fastest, and wrong in those cases. Both responses are damaging: believing it refuses a safe archive, and learning to dismiss it trains the response that defeats a real one. Scope is stated in the item so it is not mis-built: the dialog is the Claude Code harness and is not this repository's code. In scope here is a WORKTREES.md subsection plus a scripts/coord/ helper that answers the recoverability question for a whole dirty set and prints what it examined, refusing to call anything it cannot read safe. Also records #1297 as a permanent hole in the erratum. It was allocated from the PRIMARY checkout because the allocating shell's cwd was the primary, so the ledger gate correctly refused that commit and the item was re-filed at #1298. alloc.ps1 records the claim against whatever tree it runs in. Verified with the repo's own gate: each item declares exactly one status.
wshallwshall
added a commit
that referenced
this pull request
Aug 20, 2026
… own banner named (#466) * backlog: retire #1259's inverted do-not-build banner, and record #1292's fifth sighting against its own argument Two body amendments to landed items. No item filed, no item closed, no banner status changed: parse_items reads 313 items / 232 open / 81 closed before and after, the expected 0/0/0 delta for an amendment. #1259 -- the 2026-08-15 banner had INVERTED. It read "DO NOT BUILD -- ALREADY BUILT AND UNLANDED ON PR #394" and named #394 landing as its own expiry condition. #394 landed, so the banner then said do-not-build over work that was only half done. That is the dangerous direction: it removes an item from the queue so nobody looks again. The first scope option shipped -- parse_items refuses a source carrying conflict markers, defined :94, called :132, reached before any parsing. The second did not, and the item's own failure sentence stayed true: no pre-commit hook called parse_items, so a conflicted ledger could still be committed with every gate passing. Also folded in a measurement the item did not carry, and it is the difference between a defect and a non-defect here: the SHAPE of the conflict decides whether anything catches it. A conflict that ADDS HEADINGS is caught incidentally, by the ownership guard, because both sides' numbers read as unallocated -- which renders as "already covered". A real ledger conflict is two sides editing PROSE, adds no heading, and the ownership guard has nothing to fire on. Measured with a prose-only conflict at dd655da, file restored byte-identical: every gate passes, overall rc 0, the conflicted ledger commits, while backlog_status_check.py on the same file exits 1. #1292 -- a fifth sighting on main's own tip, recorded because it WEAKENS the argument the fourth entry made rather than confirming it. The ack series is now 13, 14, 24 against a fixed sent=36. The fourth entry's case was that the shortfall reproduces to within one ack, which is what made "systematic" persuasive; 24 is a spread, not a reproduction. The verdict is NOT flipped to starvation -- two clustered points and one outlier is not a distribution. What changed is that neither reading now has an argument from reproducibility, so the store-side discriminator is the only thing that settles it. The same entry records that this sighting is NOT what was redding main. That run's failing assertion is tests/test_connscale_smoke.py:128, the FD probe. no_loss passed, and it is computed as agg_sent minus engine_read so acked is not in it at all. The sent/acked figures are real and incidental -- pytest prints the record's full repr on any assertion failure, and three sessions attributed the red to this item because the numbers pattern-matched it. When a sighting names an item, quote the line with the caret, never the values in the dump. Amendments to items already on origin/main add no heading, so the ledger gate's ownership check is never consulted; docs-only, so the claim gate's code-touching scope does not apply. Every added line verified cp1252-encodable. * backlog: write four provenance lines generically, so the widened slug guard can land MUST LAND WITH BACKLOG #1083's WIDENED GUARD, NOT BEFORE OR AFTER IT. With that guard on main and these four lines as they stood, the forbidden-content pre-commit hook refuses ANY commit touching docs/BACKLOG.md or docs/archive/backlog/BACKLOG-CLOSED.md -- the two most-edited files in the repo. Measured by the builder that widened it: the fixed scanner exits 1 on them. Allowlisting is not an alternative; the guard's own failure text forbids it. Four lines, five tokens (one line carries two). Line set taken from the guard's OWN output rather than from a pattern of mine: a shape regex I wrote reported five and the guard reports four, and reconciling that showed the two counts agreed on the population and differed on the counting rule -- the guard reports one hit per LINE, my regex counted TOKENS. Identical line sets. Redacting off my own pattern would have been a second, silently different definition of the predicate the guard defines. Each line is a Source or provenance note naming which session found something. The slug carried no meaning the sentence needed, so each is now generic and the distinction that mattered is preserved -- the two-session line still reads as one session and a second session, in their original roles. The alloc-record line keeps its point (the record captured the wrong worktree) with a placeholder. Written generically rather than allowlisted, per the standing rule: when the gate refuses a branch or worktree slug in a committed file, that is correct behaviour. Ordering was checked before writing, not assumed. A redaction commit republishes the token in its own diff, so this is only safe because the tokens were already public on origin/main -- verified present there first. The shape was classified WITHOUT echoing it: three-part hyphenated, 18-21 characters, an auto-generated session slug rather than a customer or site token. Had it classified as customer or site, the correct move was to hold the disclosure rather than commit. Verification. parse_items 313 items / 232 open / 81 closed before and after, the expected 0/0/0 delta for a prose amendment; backlog_status_check.py reports 549 across both files, 313 and 236. Residual slug-shapes in both ledger files: ZERO -- and that zero is stated only because the positive control FIRES. The first control I ran returned zero itself, which would have made the result indistinguishable from a broken pattern; re-run against a file known to carry slugs it returns 16. No item filed, no item closed, no banner changed. * backlog: record #1083 as built-and-awaiting-merge, in a form that cannot invert Body amendment to a landed item. parse_items 313 items / 232 open / 81 closed before and after; #1083 stays OPEN, which is correct -- the fix is on PR #462 and not on main. WHY THIS IS WORDED AT THE CODE AND NOT AT THE PR. A banner that says "do not build, it is on PR #N" INVERTS the moment #N lands: it then reads do-not-build over finished or half-finished work, and nothing in the document can tell. That is not hypothetical. #1259 carried exactly that banner, its named PR landed, and the banner then steered lanes away from an item whose second half was genuinely undone -- I retired that banner earlier today in 4656694. So this one names the check instead: read _WORKTREE_SLUG in scripts/security/scan_forbidden.py on origin/main and see whether the prefix is still mandatory. A pointer to a symbol re-answers itself on every read; a pointer to a merge state answers correctly once and then lies. Also recorded, because whoever works this item inherits both: The ordering constraint. With the widened guard on main and the four pre-existing ledger instances unredacted, the forbidden-content hook refuses any commit touching docs/BACKLOG.md or BACKLOG-CLOSED.md. Established on the combined tree by the guard itself, in a 2x2 with an asymmetric control -- widened guard exits 1 on the unredacted ledger and 0 on the redacted one, current guard exits 0 on both. The exit 1 is the load-bearing cell: without it the green would be indistinguishable from a guard that cannot see the class. The second-order effect. Once the widened guard exists in a working tree, any agent that RUNS it sees live ledger hits and helpfully edits the ledger, which a builder may not author. Three occurrences on 2026-08-20, three different agents, the last two under an explicit prohibition naming both files. The prohibition is nought for three; checking git status --porcelain for what is actually staged is three for three. Residual slug-shapes in the ledger after this edit: zero, from a pattern whose positive control fires at 20. * backlog: close #1261 -- the cutover ratchet fix is on main by content parse_items 313 items / 231 open / 82 closed, from 232/81. Expected closure delta: 0 items, -1 open, +1 closed. backlog_status_check reports 549 across both files, each declaring exactly one status. Closed on the release condition this project uses -- the fix TEXT on main -- and verified that way rather than on a merged badge. The tests/test_cutover_slug_rot.py blob is 13a711b on origin/main, on PR #461's head and on 9d781ed: all three identical. Recorded in the banner because it will be reached for again: the cumulative patch-id test does NOT match here, branch 43f5a21a against squash 148226e6, and that proves nothing. A cherry-pick onto a different base plus an update-branch breaks the equality without the work being absent. On a squash-merging repo a patch-id MATCH proves landed and a NO-MATCH proves nothing. Blob identity settled it in one command. The banner's closed-alphabet character was LIFTED PROGRAMMATICALLY from an already-closed item rather than typed, and asserted a member of _CLOSED before use. Typing a status glyph by hand is how a wrong one enters the file, and the alphabet is machine-parsed. Held until the fix landed rather than closing on the PR, because main carried the bare pattern at zero slack until then and a premature close leaves main one innocent documentation edit from red. * backlog: #1003's trigger will not fire -- record the no-lab ruling and stop four items reading as imminent Owner ruled 2026-08-20, asked directly: there is no multi-VM lab. parse_items 314 items / 231 open / 83 closed before and after -- the expected 0/0/0 amendment delta. #1003 stays open, correctly: the ruling closed a question, it did not discharge the item. THE DEFECT THIS FIXES IS A SENTENCE, NOT A STATUS. #1003's body says the four residuals are "parked on a blocker that is about to stop existing". That blocker is not about to stop existing. It is indefinite. Every planning pass that read that line priced #99, #98, #320 and #351 as nearly-available capacity, and they are blocked on HARDWARE rather than on a decision -- which no amount of triage, scoring or re-reading can move. #98 is a partial exception in exactly one limb, and the amendment says so rather than flattening it: its trigger reads "a deployment that wants EPA, OR the first domain-joined lab box". The first disjunct survives the ruling. The lab half is dead; the deployment half is not. Also carried into the item, because it will be reached for when a rig eventually exists and not before: a green rig result must NOT be recorded as retiring the db_lookup workaround. AOAG-DEPLOYMENT.md section 4.5's planned-outage mandate stands until the RECONNECT ITSELF is proven. "The setting exists" is not the same claim as "the reconnect works", and a rig standing up demonstrates only the first. Amendment to an item already on origin/main, so it adds no heading and the ledger gate's ownership check is never consulted. Docs-only, so the claim gate's code-touching scope does not apply. Every added line verified cp1252-encodable. * backlog: close #1233 -- delete_user purges search_presets on all three backends, verified per limb parse_items 314 items / 230 open / 84 closed, from 231/83. Expected closure delta: 0 items, -1 open, +1 closed. backlog_status_check OK, 550 across both files. VERIFIED PER LIMB RATHER THAN ON ONE, deliberately. Twice today I called a multi-limb item done after checking a single limb and was wrong both times, so this one was checked as: code on each of the three backends, then coverage for each of the three, then whether that coverage actually asserts the purge. store/store.py, store/postgres.py, store/sqlserver.py -- one keyed search_presets purge each, alongside five DELETEs each. tests/test_postgres_store.py and tests/test_sqlserver_store.py cover two backends directly. The SQLite/default path is covered through tests/test_search_presets_api.py, which a filename-shaped search would have missed -- the same wrong-mechanism null that produced a false zero elsewhere today. THE TEST WAS READ, NOT COUNTED, and it is non-vacuous by construction: it asserts a PRECONDITION that the preset exists before deletion, then asserts the purge on both the id and the freed username. It further carries two independent controls, re-inserting the captured row afterwards, because with the row purged #1225's key assertions would pass TRIVIALLY and stop being evidence about the key at all. That is the anti-vacuity property this project keeps having to rediscover, and it was already there. It also retracts in place: the assertion it replaced said delete_user does NOT purge preset rows, which was true when written and is the defect this item fixes. The old line is recorded rather than quietly deleted. Closed on the release condition this project uses -- the fix TEXT on main -- not on a merged badge. The holder's claim can be released; that condition is met. The closed-alphabet character was lifted programmatically from an already-closed item and asserted a member of _CLOSED before use, never typed. * backlog: close #1083 -- the bare-slug arm, its tests and the ledger redaction all landed together parse_items 314 items / 229 open / 85 closed, from 230/84. Expected closure delta: 0 items, -1 open, +1 closed. backlog_status_check OK, 550 across both files. VERIFIED ON ALL THREE LIMBS AT origin/main 7f68ea4, not on the merged badge and not on one limb: 1. THE FIX -- scan_forbidden.py carries two arms now, _WORKTREE_SLUG_PATH for the prefixed form and _WORKTREE_SLUG_BARE for the bare one. The claude/ or worktrees/ prefix is no longer mandatory. 2. THE TESTS -- tests/test_scan_tokens_source.py, 54 tests, referencing the bare arm. 3. THE LEDGER REDACTION -- zero slug-shapes remain in docs/BACKLOG.md or docs/archive/backlog/BACKLOG-CLOSED.md, against a control that fires at 22 on a file known to carry them. LIMB 3 IS NOT INCIDENTAL AND THE ITEM COULD NOT HAVE LANDED WITHOUT IT. With the widened guard on main and those lines unredacted, the forbidden-content hook refuses EVERY commit touching either ledger file -- the two most-edited files in the repo. The three landed as one change, and merge safety was established on the combined tree by the guard itself in a 2x2 with an asymmetric control: widened guard exits 1 on the unredacted ledger and 0 on the redacted one, current guard exits 0 on both. The exit-1 cell is what made the green mean anything; without it the answer would have been indistinguishable from a guard that cannot see the class. THE PRIOR BANNER DID THE JOB IT WAS BUILT FOR, and that is worth recording because the alternative was tried on another item today and failed. It named a CHECK -- read _WORKTREE_SLUG on origin/main and see whether the prefix is still mandatory -- rather than a PR state. When #462 merged, that check returned FIXED, so the paragraph read as SPENT. A banner saying "do not build, it is on PR #N" INVERTS the moment #N lands; #1259 carried exactly that and had to be retired this morning. A pointer to a symbol re-answers itself on every read. Closed on the release condition this project uses -- the fix TEXT on main. The closed-alphabet character was lifted programmatically from an already-closed item and asserted a member of _CLOSED before use, never typed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Routed by the lander from
claude/builder-2bee12, whose authoring session has been archived. Authorship preserved on the commit.Why this one, alone
maincurrently carries the bare pattern at zero slack on the topology ratchet, so this is the commit that stops an innocent documentation edit from reddingmain.It splits the bare form out from the four unambiguous topology phrases, gates it on a topology qualifier, rewires both ratchet assertions, adds the both-directions test the item demands, and re-baselines the ceiling in the same change. Two mutants each red the new test, so it is not one-polarity.
The four exclusions, and why each
The dispatcher seat holds the owner's delegation on this branch's shape. I verified the two that are mechanically checkable rather than accepting the list:
f34eb881f34eb881 (commit) patch-id=778090c3ab9f5d34andf94eb73f (commit) patch-id=778090c3ab9f5d34-- the same change. Taking it here double-lands it. Verified by patch-id, not by diffstat: two different diffs can share a stat.ff426e58require_rcsi_for_pooled, which defaultsTrue. Excluded on my own judgement: a control resting on a false premise reads as coverage and is worse than no control.d37589b467347480snapshot/builder-2bee12-20260820, so settling that question is no longer a race against a prune.Ledger banner is OWED, and is explicitly NOT mine to write
The item number is written bare on purpose. The dispatcher seat has asked to author this banner once the merge lands, and has a specific reason: the entry must not be closed before the merge is on
main, because until thenmainstill carries the bare pattern at zero slack and a premature close leaves it one doc edit from red.I will tell them when this is on
main.