Repository navigation
v0.86 lane wave and release prep: every artifact's outcome, the instruments they shipped, and the notes - #1537
Merged
Merged
Conversation
This was referenced Oct 14, 2026
Closed
…ed, and the records that carry them CONSOLIDATED from six lane branches because the merge arithmetic made sequential merging unaffordable, and the consolidation was VERIFIED BY SIMULATION rather than reasoned. WHY. A dependabot auto-merge (#1534) moved main at 07:39Z and every one of the six lane PRs went behind=1 after roughly an hour and three quarters of queue progress each. The merge gate's CHECK2 is branch CURRENCY, not baseRefOid - `merge_gate.py:branch_currency()` requires `rev-list --count head..base` to be zero, and the ritual's own header records that the baseRefOid form once passed on a stale branch. Since merging ANY lane PR moves main, the lanes were forced sequential: six rebases, six full CI cycles. Three more dependabot PRs carry auto-merge ENABLED and will move main again. WHAT WAS CHECKED BEFORE CHOOSING. The whole wave was applied to a detached worktree off origin/main, the one conflict resolved, committed under this subject, and gated there at no CI cost: status_evidence rc=0, 0 failures, no WARN claim_check 75/75 verdict_prose rc=0 window guard 1 delivery-shaped commit in the window, 1 attributed The window guard does NOT trip: WINDOW_RECOGNIZER_FLOOR_COMMITS is 6 and it reds only at six or more window commits with ZERO delivery-shaped subjects. FALCON3 already supplies one. The "lane wave" subject shape is precedented here (v0.82 used it). THE ONE CONFLICT, read with context on BOTH sides before resolving: the spellscan and should-records branches each append a self-test step at the same anchor. Both belong; both are kept, in sequence. Verified after: zero conflict markers, ci.yml parses, both steps present. AND ONE CORRECTION THE SIMULATION SURFACED. The merged tree authorised closing #1515, whose own title names the SELFTEST2 subject - a self-test that stays green with the capability it tests removed. SELFTEST2 is PARTIAL with exactly that function still uncovered, so SPELLSCAN must not authorise its closure. It now carries `issue-scope: outlives`. After the fix: three issues authorised, all three ALREADY CLOSED so the authorisation is a no-op, and ten held open explicitly - where the previous release held none. The six superseded PRs are closed with a pointer to this one. Their content is here in full; nothing was dropped, and the artifact records are byte-identical apart from the PR number they name and the SPELLSCAN scope line. Refs #1318 Refs #1436 Refs #1145 Refs #1259 Refs #1183 Refs #1439 Refs #1136 Refs #1454 Refs #1453 Refs #1458 Refs #1476 Refs #1432 Refs #1460 Refs #1428 Refs #1516 Refs #1451 Refs #1515 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
… FALCON3's alone Seventeen records named the PR of the lane branch they were written on. All of that content now lands in one PR, so R15's demand - that `landed:` name the DELIVERING PR alongside its issue - points at the consolidated one. FALCON3 is deliberately EXCLUDED and asserted so: it already landed in its own merged PR, and rewriting it would replace a true reference with a false one. The script verifies FALCON3 still carries its real PR and that none of the rewritten numbers appears in it, before writing any file. Every anchor was verified before any write - exactly one PR reference per record - and the sweep reports zero stale references afterwards. Refs #1136 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
The consolidation carried a reversal of a merged dependabot commit, and no gate would ever have caught it. WHAT HAPPENED. Each lane patch was computed as `git diff origin/main..branch` with origin/main already at the install-action bump (#1534), while the lane branches were cut from BEFORE it. So every patch contained the bump's REVERSAL, and `git apply --3way` applied it. The consolidated branch carried `taiki-e/install-action@v2.87.22` in BOTH ci.yml and fuzz-smoke.yml while main carried v2.87.27. WHY NOTHING CAUGHT IT, which is the part worth recording. A rebase dry run onto the moved main reported rc=0 with NO conflict, and on that tree status_evidence, claim_check and verdict_prose were all green. Git saw an explicit edit rather than a conflict, and no gate inspects action versions. A clean rebase and a green battery were both true about a tree that had quietly undone someone else's merged work. AND A REBASE WOULD NOT HAVE FIXED IT. The reversal lives in this branch's own commit, so replaying it preserves it. That is what separates this from the Cargo.lock difference also visible against main: ZERO commits on this branch touch Cargo.lock, so that one is purely BEING BEHIND and the rebase resolves it. One is a defect, the other is arithmetic. FIXED by restoring the bumped version in both files, with every anchor verified before any write (exactly one stale occurrence and zero bumped, per file) and asserted after. fuzz-smoke.yml is now byte-identical to main; ci.yml differs only by this release's two new self-test steps, and no install-action line differs any more. Both workflows parse. A full sweep of every line this branch removes relative to main found no other reversal of merged work. Refs #1136 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
avrabe
force-pushed
the
v086-lane-wave
branch
from
October 14, 2026 10:19
2472e44 to
a8ff02a
Compare
…s the version scrubber withholds The cold review's round 2 derives its attack queue from the numbers round 1 introduced, using scripts/extract_r1_numbers.py. That script was in NO WORKFLOW. Its self-test existed, carried a vacuity guard and a leave-one-out derivation, and nothing ever ran it: defined but not enforced, which is not a gate. It is now a step in the Claim Check job, which is a required context, has no `if:` and no `needs:`, and runs on the `light` pool. The audit went both ways. REFUTED, recorded so it is not re-attempted. The worry was that the `sha` scrubber swallows an uncommaed seven-digit byte count. Measured over the six `v0.8*` records shipped before this one: every all-digit token it removes is an IDENTIFIER -- GitHub run ids, a comment id, and two genuine all-digit eight-character git shas. The obvious narrowing, requiring a hex letter, would have leaked those two real shas into the queue as quantities. The blind spot is real and has no observed instance. v0.85's round-2 repair of that scrubber stands, and no pattern changed here. CONFIRMED. The `version` scrubber necessarily eats a bare two-component decimal, because a ratio and a crate version share that shape exactly. One record carries 23 such removals and the newest 15, and reading them in context settles that the class is MIXED rather than noise: durations, percentages and a ratio on one side; crate and operating-system versions, a section number, and an IEEE literal quoted in prose about negative zero on the other. No pattern separates them, so widening the scrubber trades one error for the other. The case that forced the decision: v0.85 round 1 wrote "twelve", rounded up from a 364/31 ratio, and the tool whose whole job is to queue round 1's numbers for attack could not see the number the word came from. So the withheld decimals are neither dropped nor asserted -- they are PRINTED in their own labelled bucket for hand triage. A false positive costs round 2 one glance; a false negative means an unreviewed figure is never reviewed, which is the defect this file exists to prevent. Both halves of the new bucket are NEGATIVE-CONTROLLED, which is why they are worth gating: an inert bucket (pattern requiring three components) reds the positive half, and a bucket widened to eat `v`-prefixed versions reds the negative half. Baseline green, both mutants red. An EMPTY bucket is a legitimate observation here rather than a refusal, and that is measured too -- two of those six records carry no bare decimal at all. The self-test's own closing line enumerated the checks it ran and did not name the new pair; it does now. That is the same stale-self-description class the theme names, one layer in. Refs #1516 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
…sured as wrong in the opposite direction PINDEBT11 (#1428) ran a three-way control with ONLY THE NAME differing between runs, and it refuted a standing claim in CLAUDE.md. The claim said a suppression table under a non-matching name escapes the tripwire AND the ratchet ENTIRELY. Measured: rename a LISTED table out of the pattern count falls below its pin REDS add a NEW table under a non-matching name count unchanged at its pin GREEN add the SAME table under a matching name count rises above its pin REDS So the escape is ADDITION, not RENAMING -- the opposite of what the paragraph said. A rename is CAUGHT twice over: the explicit table list no longer resolves it, and the population count drops below its pinned value. THE CORRECTION WAS RECORDED AND NOT APPLIED. The artifact says the standing claim is wrong and the notes list it under measurements that corrected this programme's own records, but this release had touched CLAUDE.md zero times -- so the most consequential site went on asserting the refuted version, in the file injected into every future session. That is the "corrected at two sites with a third left asserting it" shape, with the third site being the one that propagates. Swept for other asserting sites with a positive control over 1066 tracked files: two hits, both inside PINDEBT11's own artifact, both QUOTING the claim in order to refute it. Those are left alone -- and they are why an "old string must reach zero" sweep would have been false by construction here. The v0.73 round-2 reading the paragraph cited is kept, reclassified: a byte-identical table under a non-matching name leaving the ledger green is the ADDITION case, and is inconsistent with a rename, which moves the pinned count. Both splice sides re-read after the edit. The passage is not pinned in claims.yaml (0 hits for four spellings of it; 16 CLAUDE.md pins, none on this text), and claim_check holds at 75/75 with status_evidence exit 0 after the change. Refs #1428 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
… on the shipped records
Auditing the tool I had just wired found three further defects in it. All three are
in the FALSE-NEGATIVE direction -- round 2 attacking a figure nobody claimed, or
never seeing one that was.
1. A COMMA WAS ABSORBED UNCONDITIONALLY. `\b\d[\d,]*\b` merged `92,11` into ONE
token: 22 distinct such tokens across the records shipped before this release,
from lists, tuples, and quoted diff coordinates. So the queue carried a figure
that was never claimed and lost the two that were. The same pattern left a
TRAILING COMMA on `184,`, so one quantity counted in two buckets. A comma is now
absorbed ONLY as a proper thousands separator.
2. QUOTED GIT DIFF HUNK HEADERS LEAKED. `@@ -92,11 +104,14 @@` yielded four
coordinates as numbers -- tool output, not claims, the same noise class as a
timestamp or a runner name. Six such headers in the newest of those records.
Scrubbed now, as the most specific form, first in the list.
3. THE EXTRACTION PATTERN WAS WRITTEN OUT TWICE -- once in the shipped `numbers()`
and once in the `numbers_with()` leave-one-out primitive. So the thing that
MEASURES which scrubbers are necessary could come to measure a different
extraction from the one that ships. There is now one `NUMBER` constant. This is
the second-source-of-truth defect this project's own context file exists to
count, inside the instrument added to find defects.
PAIRED CONTROLS, all fired, each reding only the assertion it names:
old regex restored -> extract-split reds with {'92,11': 1, '1,2': 1}
commas stripped entirely -> extract-keep reds with {'4','770','546'}
diff-hunk scrubber removed -> diff-hunk reds with all six coordinates
restored -> 0 failures
Both extraction directions are asserted because either alone permits the opposite
error: a thousands-separated byte count must stay WHOLE, and a comma that is not a
separator must SPLIT.
MEASURED AFTER: merged/trailing-comma tokens over those records fall 22 -> 0, and
the three legitimate thousands-separated figures are preserved.
AND THE CLOSING LINE WAS STALE AGAIN. The self-test's summary enumerates the checks
it ran, and my own edit added an assertion without adding it to that line -- the
same defect I had corrected in this very file one commit earlier. It now names the
extraction control too. A line that lists its own contents is this programme's most
frequently wrong sentence, and it was wrong about my correction of it.
Refs #1516
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
…ithheld bucket from the scrubber instead of mirroring it A review of this branch found two FALSE statements in what it had already pushed. Both were introduced by corrections, which is this programme's standing finding about its own review cycle. 1. RETRACTION. Commit 2c08920 said a renamed suppression table is "caught twice over" -- "the explicit table list no longer resolves it AND the population count falls below its pin" -- and wrote that into CLAUDE.md, the file injected into every future session. THE FIRST CONJUNCT IS INVENTED. RQ-86-PINDEBT11's own record says the rename is applied in the oracle AND in the ledger's name field, "so the explicit list still resolves and ONLY THE NAME differs", and that what reds is the population tripwire falling below its pinned count. ONE mechanism, not two. CLAUDE.md now says that, and this message is the retraction of the earlier one, which the squash body will carry above it. Note the shape: the commit that corrected a false claim introduced a new false claim about the same subject, in the same sentence, while citing the artifact that contradicts it. 2. THE WITHHELD-DECIMAL BUCKET WAS A HAND-WRITTEN MIRROR OF THE SCRUBBER, AND THE MIRROR WAS WRONG. Its trailing `(?![\d.])` rejected a decimal that ENDS A SENTENCE, so `rounded up from 11.74.` yielded NOTHING -- and that sentence is the exact case the bucket was built for, the ratio a previous round 1 rounded to produce a headline word. "Nothing is hidden" was therefore false when shipped. Worse, the positive sample ended without a period, so it was SHAPED AROUND THE BLIND SPOT: the control could not have caught this. The bucket is now ENUMERATED FROM THE `version` SCRUBBER'S OWN MATCHES, keeping the bare two-component ones -- so the label "withheld by the version scrubber" is true by construction and cannot drift from what the shipped path removes. That is this repository's own North Star rule: derive what you check against from the artifact you ship, never mirror it. POTENCY, paired: restoring the exact mirror this replaces now REDS the positive half with `got {'16.3': 1}` -- the test detects its own predecessor's defect. An inert bucket reds it with `{}`; a bucket widened to eat `v`-prefixed versions reds the negative half. Restored: 0 failures. And writing that docstring introduced a SyntaxWarning by putting a regex in a non-raw docstring -- itself a defect a previous release's corrections introduced. Fixed; the file now compiles clean under `-W error::SyntaxWarning`. The sweep I wrote to look for siblings reported 13 and was wrong: its pattern pairs a raw docstring's closing quotes with the next opening. The compiler is the oracle for this question and it says zero. 3. FIGURES RE-DERIVED FROM THE SHIPPED TOOL, not from throwaway scripts. * The withheld counts are OCCURRENCES: 23 over 17 distinct on one record, 15 over 13 on the newest. Both are now stated, because the two are different numbers and this programme has confused them before. Two of the six records carry no bare decimal at all. * The "22 distinct merged tokens" CONFLATED TWO DEFECTS. It is 15 merges plus 7 trailing commas, and the two halves are fixed by different changes: the diff-hunk scrubber accounts for 10 of the 15 merges, and the regex change for the remaining 12. The notes now say so. * "Every all-digit token is an identifier" was asserted after reading 5 of the 8 in context. All 8 are now read: GitHub run ids, TWO JOB IDS -- a category the claim did not list -- a comment id, and two genuine all-digit git shas. None is a quantity, so the refutation stands with its wording corrected. 4. A DANGLING ARTIFACT ID. The new CI step was named for `RQ-86-R1NUMBERS`, which is in no artifact file. That is the provenance class RQ-86-PROVENANCE2 measures, in a place no gate inspects. The step now cites only the issue. Closer keywords were scanned on the THREE REAL VECTORS this time -- commit messages, the PR body, and all three of a PR's comment populations -- rather than on changelog additions, which are file content and not a vector at all. Zero hits, with a control confirming the matcher catches a newline-separated closer and correctly ignores `Closing #N`. Refs #1428 Refs #1516 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
…the closure gate early DISPVOCAB3 declared `issue-scope: outlives` over #1458, and that issue was CLOSED on 2026-10-07 -- a week before this release opened. So a shipped record claimed to be holding open something already shut. FOUND BY RUNNING GATE5 EARLY rather than at the tag, where it is advisory and prints. Its message is precise about why nothing else could have caught it: the close happened OUTSIDE this release's window, "which the closed-set alone cannot see". No required CI context reads this field, so the defect would have survived to the tag and been printed into a log nobody re-reads. before: issue-closure: v0.86.0 -- 3 authorised, 10 held open, 0 closed, 1 failures rc=1 after: issue-closure: v0.86.0 -- 4 authorised, 9 held open, 0 closed, 0 failures rc=0 That red-to-green on exactly this one-line change is the gate's own paired control: it fired on the real defect and cleared on the real fix, with nothing planted. THE POPULATION, not just the hit. Every one of the 18 artifacts was audited against its issue's LIVE state rather than against the record's own claim, and this was the ONLY mismatch. Its three already-closed siblings -- CLOSESCOPE, NOTESPOP3 and TWOSOURCE3 -- all omit the field entirely, so removing it makes DISPVOCAB3 agree with them rather than inventing a fourth spelling. The lane's prose was checked for the same claim and carries none: it says DELIVERED, and the falsehood lived only in the field. I ALSO AUDITED WHAT I NEARLY MIS-REPORTED. Running GATE5 before any tag exists tracebacks, because `--since-tag` resolves through a REMOTE commit lookup. That is not a vacuous gate: `tag_release.sh` pushes the tag at line 163 and asks the gate at line 184, and its comment says the order is deliberate -- "before the tag exists there is nothing to compare a close-set against". The theme primed me to read a crash as a vacuous gate and the ordering refutes it. Recorded so the next reader does not repeat it. AND THE COUNTS THIS EDIT INVALIDATED. The PR body stated "three issues authorised ... and ten held open"; it now states four and nine, amended in the same change rather than left to go stale. A repository-wide sweep for the old figures returned ten other hits, every one a previous release's review record or an unrelated sentence, left untouched. FALCON3's `landed:` names PR #1525 rather than this one, and that is correct, not an oversight: #1525 is MERGED, its merge commit is on main's first-parent line, and it is the lane-shaped subject that keeps the window guard from reading this release's artifacts as silent. Refs #1458 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
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.
v0.86 lane wave: every artifact's outcome, the instruments they shipped, and the records that carry them
CONSOLIDATED from six lane branches because the merge arithmetic made sequential
merging unaffordable, and the consolidation was VERIFIED BY SIMULATION rather
than reasoned.
WHY. A dependabot auto-merge (#1534) moved main at 07:39Z and every one of the
six lane PRs went behind=1 after roughly an hour and three quarters of queue
progress each. The merge gate's CHECK2 is branch CURRENCY, not baseRefOid -
merge_gate.py:branch_currency()requiresrev-list --count head..baseto bezero, and the ritual's own header records that the baseRefOid form once passed on
a stale branch. Since merging ANY lane PR moves main, the lanes were forced
sequential: six rebases, six full CI cycles. Three more dependabot PRs carry
auto-merge ENABLED and will move main again.
WHAT WAS CHECKED BEFORE CHOOSING. The whole wave was applied to a detached
worktree off origin/main, the one conflict resolved, committed under this
subject, and gated there at no CI cost:
status_evidence rc=0, 0 failures, no WARN
claim_check 75/75
verdict_prose rc=0
window guard 1 delivery-shaped commit in the window, 1 attributed
The window guard does NOT trip: WINDOW_RECOGNIZER_FLOOR_COMMITS is 6 and it reds
only at six or more window commits with ZERO delivery-shaped subjects. FALCON3
already supplies one. The "lane wave" subject shape is precedented here (v0.82
used it).
THE ONE CONFLICT, read with context on BOTH sides before resolving: the spellscan
and should-records branches each append a self-test step at the same anchor.
Both belong; both are kept, in sequence. Verified after: zero conflict markers,
ci.yml parses, both steps present.
AND ONE CORRECTION THE SIMULATION SURFACED. The merged tree authorised closing
#1515, whose own title names the SELFTEST2 subject - a self-test that stays green
with the capability it tests removed. SELFTEST2 is PARTIAL with exactly that
function still uncovered, so SPELLSCAN must not authorise its closure. It now
carries
issue-scope: outlives.AND A SECOND CORRECTION, which the closure gate found when it was asked early
rather than at the tag: DISPVOCAB3 declared
issue-scope: outlivesover an issuethat was CLOSED a week before this release opened, so the record claimed to hold
open something already shut. The gate's message is precise about why a close-set
alone cannot see it - the close happened OUTSIDE this release's window. Its three
already-closed siblings all omit the field; it now does too. Every one of the 18
artifacts was then audited against its issue's LIVE state, and that was the only
mismatch. The gate went rc=1 -> rc=0 on exactly this change, which is its own
paired control.
After both fixes: FOUR issues authorised, all four ALREADY CLOSED so the
authorisation is a no-op, and NINE held open explicitly - where the previous
release held none.
The six superseded PRs are closed with a pointer to this one. Their content is
here in full; nothing was dropped, and the artifact records are byte-identical
apart from the PR number they name and the SPELLSCAN scope line.
Refs #1318
Refs #1436
Refs #1145
Refs #1259
Refs #1183
Refs #1439
Refs #1136
Refs #1454
Refs #1453
Refs #1458
Refs #1476
Refs #1432
Refs #1460
Refs #1428
Refs #1516
Refs #1451
Refs #1515
🤖 Generated with Claude Code
https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
Rebased onto the settled base, with the release prep folded in
The dependabot auto-merge wave moved
mainfour times during this PR's life (#1534, #1531, #1532, #1535), each time putting itbehind— the merge gate's CHECK2 is branch currency (rev-list --count head..basemust be zero), notbaseRefOid. Rather than burn a CI cycle per move, the branch waited for the wave to settle and was then rebased once, ontofa93c658, with only the held 0.x-minor bump (#1533) still open.The release prep is folded into the same cycle rather than following in its own PR: the workspace bump to 0.86.0 and the CHANGELOG section for
[0.86.0]. This saves a full CI cycle, and it matches how the cold review is pinned — the previous release's review declared its prep commit.Verified on the final tree before pushing
0.86.0## [0.86.0]ANCHOR_TAGv0.85.0— the anchor moves in the v0.87 planning PR, or A0 reds a release earlyinstall-actionin both workflowsThe do-not-touch set is asserted in both directions deliberately: a missing entry would mean a pin was skipped, and an extra one would mean a measurement was falsified. Two of its nine members are files whose
0.85.0is part of a sentence recording what was measured at that version — bumping those would have rewritten this release's own evidence.GATE1 on this tree reduces to a single failure: the missing
docs/reviews/v0.86-cold-review.md, which the two-round cold review supplies.