Skip to content

feat(resume): move the corpus query into step 4 β€” it fired 1/14 where it was - #1332

Merged
ZacxDev merged 4 commits into
mainfrom
feat/resume-index-step
Sep 6, 2026
Merged

feat(resume): move the corpus query into step 4 β€” it fired 1/14 where it was#1332
ZacxDev merged 4 commits into
mainfrom
feat/resume-index-step

Conversation

@ZacxDev

@ZacxDev ZacxDev commented Sep 6, 2026

Copy link
Copy Markdown
Member

Rank 1 of handoff-handoff-search-index. The measurement that motivated it merged as #1329.

What changed

The handoff section index had exactly one consumer: a conditional buried in step 3's prose ("before working any open item…"). It is now the second command of step 4, keyed on the handoff's topic rather than an open item β€” every resume has a topic, and keying on an item is the conditional being removed.

Why β€” measured, not argued

Over the 34 h after #1295 merged, 1 of 14 /resume runs across both hosts invoked it, and that one was reading origin/main off the staleness alarm rather than firing the step. Yield: 0.

The non-firing was not correct restraint β€” all six workbench non-firing runs ran claim-work, five made edits, and five of six resumed a doc with an ## Open investigations section.

Discriminator β€” placement, not the tool: step 3's sibling check (git log --since; same trigger, same block, an ordinary command) fired 0/6, while step 4 (cairn recall; numbered, unconditional, fenced) fired 5/6.

Not a new numbered step, deliberately

~15 prose cross-references across skills and scripts pin "step 4" (cairn) and "step 6" (claim-work), none machine-checked. A renumber would falsify all of them.

The guard is structural, not spelled

A grep for "unconditional" passes on a body that says the word and still gates the command. The new test asserts which numbered step the command physically sits in. Watched to fail two ways: red at origin/main (count arm), and an isolated mutant β€” query moved back into step 3, wording untouched β€” fires the step-identity arm with its own message.

Residual, stated in both the skill and the test

The 5/6 was measured with one command in that step. Co-locating a second is a prediction, not a measurement. Re-measure with check 1 of the handoff's "How to verify".

Gate

Both tiers on the merged tree at base f0b9c474:

  • nix build .#checks.x86_64-linux.pytests β€” collected=21837 passed=21834 failed=0 (floor 18610)
  • nix build .#checks.x86_64-linux.nodetests β€” suites=5 tests=1449 pass=1449 fail=0 (floor 1367)

Run one at a time. Base re-confirmed unmoved after the run.

πŸ€– Generated with Claude Code

https://claude.ai/code/session_01G7eZPAdX7nAeamShBnYNg2

ZacxDev added a commit that referenced this pull request Sep 6, 2026
…claims

Round 1 of /audit-pr on #1332 returned six 🟑, no πŸ”΄. Every one is fixed here.

F1 (guard narrower than its name) β€” the test claimed to prove the command is
UNCONDITIONAL and asserted only a shared step DIGIT. The audit built four
isolated mutants; three survived a fully green suite. Renamed to what it
checks, and widened: it now compares the FENCE, which kills M4 (a second list
item re-labelled `4.`, gated, in its own block) with its own message. M2 and
M3 β€” a gating sentence above the fence, a conditional comment inside it β€”
STILL SURVIVE and are now named in the docstring as uncovered. They are
prose-shaped; no structural check here sees them, and saying so is better than
a keyword guard that would read as coverage.

F2 (byte claim wrong by ~10x) β€” "a few hundred bytes" replaced with the
measured figures: 3,941 B and 3,999 B for two real --limit 3 queries, 1,251 B
for a no-match, which is the floor because the banner prints either way.
Re-measured independently before changing it.

F3 (the conditional came back) β€” the step-3 replacement sentence re-created an
open-item-keyed instruction inside the block this PR measured at 0/6, told the
reader to "re-run" something not yet run, was invisible from step 4, and
dropped the tool's PURPOSE. Step 3 is now a pointer with no action; the
item-level re-run and the "Ruled out: bullets stop you re-running a probe
someone already ran" rationale both moved into step 4.

F4 (asymmetric scope, unstated) β€” `cairn recall --repo` is repo-scoped while
the query searches all four repos, two of them client repos, and routinely
returns client sections above devrc ones. The step now says so and tells the
reader to check each hit's repo before reusing it. Not narrowed to --repo:
cross-repo reach is the point.

F5 (report step named one surface) β€” step 5 said `from index`; handoff_search
prints `from handoff docs`. Verified both banners by running them. Step 5 now
carries each surface's own label.

F6 (dangling referent) β€” "that doc's How to verify" had no antecedent and the
nearest one was the wrong document. Named explicitly.

F7 (denominators did not reconcile) β€” 8 - 1 = 7, not 6. The missing run is the
measuring session itself, excluded as the instrument; that was true and never
stated. Now stated in the skill, the test docstring and the handoff doc, with
an as-of timestamp, since the corpus grows and a later re-run reports larger
numbers rather than contradicting these.

Also fixed the nit: a docstring said the recall posture sits "four steps
earlier", which was wrong before this PR (cairn was one step LATER) and wrong
after it (co-located).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G7eZPAdX7nAeamShBnYNg2
Claude-Session-Id: 1de26f50-0e47-4964-b6ff-b87bea89b1fb
@ZacxDev
ZacxDev force-pushed the feat/resume-index-step branch from 87989ef to e8a273c Compare September 6, 2026 06:46
@ZacxDev

ZacxDev commented Sep 6, 2026

Copy link
Copy Markdown
Member Author

Audit round 1 β€” six 🟑, no πŸ”΄, all fixed in e8a273c8

Both sandbox tiers green on the rebased tree (base e8143452): pytests 21868/21865/0 failed (floor 18610); nodetests 1449/1449/0 (floor 1367).

1. F1 β€” test renamed off the UNCONDITIONAL claim it did not check, and widened from a shared step DIGIT to a shared FENCE; mutant M4 (second list item re-labelled `4.`, gated, own fence) now dies with its own message. M2 and M3 are claimed STILL UNCOVERED and named as such in the docstring, not fixed.
2. F2 β€” "a few hundred bytes" replaced with re-measured figures: 3941 B and 3999 B for two real --limit 3 queries, 1251 B no-match floor.
3. F3 β€” step 3 reduced to a pointer carrying no action; the item-level re-run instruction and the "Ruled out: bullets" purpose statement both moved into step 4.
4. F4 β€” step 4 now states that handoff_search is corpus-wide over four repos (two of them client repos) while cairn recall is repo-scoped, and tells the reader to check each hit repo before reuse. Scope deliberately NOT narrowed to --repo.
5. F5 β€” step 5 now carries both surfaces and their distinct banner labels (`from index` vs `from handoff docs`), both verified by running the tools.
6. F6 β€” "that doc's How to verify" replaced with the named path claudedocs/handoff-handoff-search-index.md, with an explicit "not the handoff you read in step 3".
7. F7 β€” denominator accounting stated (8 = 1 fired + 6 analysed + 1 measuring session excluded as the instrument), with an as-of timestamp, in the skill, the test docstring and the handoff doc.
8. Nit β€” docstring claiming the recall posture sits "four steps earlier" corrected; it was wrong both before and after the move.

Round 1 produced findings that needed fixing, so a delta round follows.

ZacxDev added a commit that referenced this pull request Sep 6, 2026
…claims

Round 1 of /audit-pr on #1332 returned six 🟑, no πŸ”΄. Every one is fixed here.

F1 (guard narrower than its name) β€” the test claimed to prove the command is
UNCONDITIONAL and asserted only a shared step DIGIT. The audit built four
isolated mutants; three survived a fully green suite. Renamed to what it
checks, and widened: it now compares the FENCE, which kills M4 (a second list
item re-labelled `4.`, gated, in its own block) with its own message. M2 and
M3 β€” a gating sentence above the fence, a conditional comment inside it β€”
STILL SURVIVE and are now named in the docstring as uncovered. They are
prose-shaped; no structural check here sees them, and saying so is better than
a keyword guard that would read as coverage.

F2 (byte claim wrong by ~10x) β€” "a few hundred bytes" replaced with the
measured figures: 3,941 B and 3,999 B for two real --limit 3 queries, 1,251 B
for a no-match, which is the floor because the banner prints either way.
Re-measured independently before changing it.

F3 (the conditional came back) β€” the step-3 replacement sentence re-created an
open-item-keyed instruction inside the block this PR measured at 0/6, told the
reader to "re-run" something not yet run, was invisible from step 4, and
dropped the tool's PURPOSE. Step 3 is now a pointer with no action; the
item-level re-run and the "Ruled out: bullets stop you re-running a probe
someone already ran" rationale both moved into step 4.

F4 (asymmetric scope, unstated) β€” `cairn recall --repo` is repo-scoped while
the query searches all four repos, two of them client repos, and routinely
returns client sections above devrc ones. The step now says so and tells the
reader to check each hit's repo before reusing it. Not narrowed to --repo:
cross-repo reach is the point.

F5 (report step named one surface) β€” step 5 said `from index`; handoff_search
prints `from handoff docs`. Verified both banners by running them. Step 5 now
carries each surface's own label.

F6 (dangling referent) β€” "that doc's How to verify" had no antecedent and the
nearest one was the wrong document. Named explicitly.

F7 (denominators did not reconcile) β€” 8 - 1 = 7, not 6. The missing run is the
measuring session itself, excluded as the instrument; that was true and never
stated. Now stated in the skill, the test docstring and the handoff doc, with
an as-of timestamp, since the corpus grows and a later re-run reports larger
numbers rather than contradicting these.

Also fixed the nit: a docstring said the recall posture sits "four steps
earlier", which was wrong before this PR (cairn was one step LATER) and wrong
after it (co-located).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G7eZPAdX7nAeamShBnYNg2
Claude-Session-Id: 1de26f50-0e47-4964-b6ff-b87bea89b1fb
@ZacxDev
ZacxDev force-pushed the feat/resume-index-step branch from e8a273c to 00e803a Compare September 6, 2026 07:43
@ZacxDev

ZacxDev commented Sep 6, 2026

Copy link
Copy Markdown
Member Author

Audit round 2 β€” all 8 round-1 claims verified fixed; 2 🟑 + 1 🟒 found and fixed in 00e803a2

Round 2 re-ran the mutation matrix at both guard revisions and re-derived the adoption count live rather than accepting the self-reports. Both sandbox tiers green on the rebased tree (base 10d437c9): pytests 21871/21868/0 failed (floor 18610); nodetests 1449/1449/0 (floor 1367).

1. 🟑 doc status β€” claudedocs/handoff-handoff-search-index.md said "No fix is built; awaits operator direction" and ranked next-step 1 still described THIS PR as pending. Both survivability mitigations (held claim, open PR in step 6 sweep) end at merge, so a post-merge /resume would have re-implemented a merged change. State now + rank 1 rewritten; rank 1 is now RE-MEASURE ADOPTION.
2. πŸ”΄-in-that-item β€” the same item asserted "SKILL.md is byte-capped, so promoting text means evicting text". FALSE; the caps cover browser/handoff/prune-skill/RULES.md, not resume. Corrected in place and LABELLED as a correction rather than silently deleted.
3. 🟑 M5 β€” a fifth mutant round 1 did not anticipate: command left in the fence but COMMENTED OUT. Every check here is a substring test, so a commented line satisfied the string pin, the step check AND the fence check over dead wiring. Now killed by requiring the fence line to be live. Docstring no longer presents the mutant list as closed.
4. 🟒 scope warning restated handoff_index.REPO_ENV_HANDLES membership instead of deriving it. Now pinned against the module. The pin covers the LABELS only; the "two of which are client repos" count is a human judgement and is stated as unpinnable.
5. Mutants re-run under PYTHONDONTWRITEBYTECODE=1 β€” control 8 passed; M5 killed with its own message; M6 (drop a handle from the warning) killed by the derived pin naming DATAPACKET. M2 and M3 STILL SURVIVE and remain named as uncovered.

Round 2 produced findings that needed fixing, so round 3 follows.

@ZacxDev
ZacxDev force-pushed the feat/resume-index-step branch from 00e803a to 1ce2818 Compare September 6, 2026 07:57
ZacxDev added a commit that referenced this pull request Sep 6, 2026
…claims

Round 1 of /audit-pr on #1332 returned six 🟑, no πŸ”΄. Every one is fixed here.

F1 (guard narrower than its name) β€” the test claimed to prove the command is
UNCONDITIONAL and asserted only a shared step DIGIT. The audit built four
isolated mutants; three survived a fully green suite. Renamed to what it
checks, and widened: it now compares the FENCE, which kills M4 (a second list
item re-labelled `4.`, gated, in its own block) with its own message. M2 and
M3 β€” a gating sentence above the fence, a conditional comment inside it β€”
STILL SURVIVE and are now named in the docstring as uncovered. They are
prose-shaped; no structural check here sees them, and saying so is better than
a keyword guard that would read as coverage.

F2 (byte claim wrong by ~10x) β€” "a few hundred bytes" replaced with the
measured figures: 3,941 B and 3,999 B for two real --limit 3 queries, 1,251 B
for a no-match, which is the floor because the banner prints either way.
Re-measured independently before changing it.

F3 (the conditional came back) β€” the step-3 replacement sentence re-created an
open-item-keyed instruction inside the block this PR measured at 0/6, told the
reader to "re-run" something not yet run, was invisible from step 4, and
dropped the tool's PURPOSE. Step 3 is now a pointer with no action; the
item-level re-run and the "Ruled out: bullets stop you re-running a probe
someone already ran" rationale both moved into step 4.

F4 (asymmetric scope, unstated) β€” `cairn recall --repo` is repo-scoped while
the query searches all four repos, two of them client repos, and routinely
returns client sections above devrc ones. The step now says so and tells the
reader to check each hit's repo before reusing it. Not narrowed to --repo:
cross-repo reach is the point.

F5 (report step named one surface) β€” step 5 said `from index`; handoff_search
prints `from handoff docs`. Verified both banners by running them. Step 5 now
carries each surface's own label.

F6 (dangling referent) β€” "that doc's How to verify" had no antecedent and the
nearest one was the wrong document. Named explicitly.

F7 (denominators did not reconcile) β€” 8 - 1 = 7, not 6. The missing run is the
measuring session itself, excluded as the instrument; that was true and never
stated. Now stated in the skill, the test docstring and the handoff doc, with
an as-of timestamp, since the corpus grows and a later re-run reports larger
numbers rather than contradicting these.

Also fixed the nit: a docstring said the recall posture sits "four steps
earlier", which was wrong before this PR (cairn was one step LATER) and wrong
after it (co-located).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G7eZPAdX7nAeamShBnYNg2
Claude-Session-Id: 1de26f50-0e47-4964-b6ff-b87bea89b1fb
ZacxDev added a commit that referenced this pull request Sep 6, 2026
🟑 THE DERIVED SCOPE PIN WAS DECORATION FOR ONE OF ITS FOUR ARMS. It searched
the whole wiring block, and EXPECTED_COMMAND contains
`~/workspace/devrc/scripts/lib/handoff_search.py`, so `"devrc" in block` was
guaranteed true on every green run. Round 2's sweep picked DATAPACKET β€” a
fixture that could only die β€” and read the kill as proof the pin worked. That
is exactly RULES.md's "prove it REACHABLE, not merely breakable" and "pick
fixtures distinct from any constant the assertion already names".

Narrowing to the warning PARAGRAPH was NOT sufficient, and measuring said so:
the paragraph itself says "a devrc-topic query" and "above the devrc ones", so
dropping `devrc` from the enumerated list still left 8 passed. Fixed by
matching BACKTICKED tokens β€” only the list is a code span. Now measured:
  control 8 passed Β· M6-devrc -> 1 failed, ['DEVRC'] Β· M7 (handle deleted from
  the list but mentioned in an unrelated sentence) -> 1 failed, ['CIVITAI'] Β·
  M5 and M1 still die with their own messages.
All four arms are now reachable; before this, two of four were not.

🟑 The `Claim:` line asserted a release that has not happened and dropped the
command that performs it β€” wider on one axis, narrower on the other. Restored
as STILL HELD with the explicit `claim-work --release`, and why an unreleased
claim blocks the next rank 1 under a different identity.

🟑 A THIRD site still said to build the fix: Open investigations -> Next probe
told the reader to "promote the query to its own numbered step". Rounds 1-2
fixed State now and rank 1 and left this one, so the doc contradicted itself at
the exact section /resume step 3 tells a session to read. Reworded to say the
promotion landed and only the re-run remains.

🟒 The correction paragraph's own number was wrong: "~1.9 KB" was one commit's
delta, not the PR's. Measured +3,688 B (41,852 -> 45,540, git cat-file -s at
base 10d437c and head 00e803a) and labelled as a correction of a correction.

🟒 Rank 1 now says to raise check 1's CUT to #1332's merge time before
re-running; left at #1295's, the 14 pre-fix runs stay in the denominator and a
fully successful fix reports ~10/24 and reads as a failure.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G7eZPAdX7nAeamShBnYNg2
Claude-Session-Id: 1de26f50-0e47-4964-b6ff-b87bea89b1fb
ZacxDev and others added 4 commits September 6, 2026 12:38
… it was

The handoff section index shipped with exactly one consumer, a conditional
buried in step 3's prose ("before working any open item..."). Over its first
34 h that consumer was invoked by 1 of 14 /resume runs across both hosts, and
the one that fired was reading origin/main because the SKILL block told it its
copy was stale β€” not because the step fired. Yield: 0.

The non-firing was NOT correct restraint. All six workbench non-firing runs
ran claim-work and five made edits, and five of six resumed a doc carrying an
## Open investigations section, so the trigger was met every time.

DISCRIMINATOR β€” placement, not the tool, its cost, or how loudly it is marked:
step 3's sibling check (git log --since; same trigger, same block, an ordinary
command) fired 0/6, while step 4 (cairn recall; numbered, unconditional,
fenced) fired 5/6. Two co-located conditionals at 0, one unconditional
numbered step next door at 5.

So the query becomes step 4's second command, keyed on the handoff's TOPIC
rather than an open item β€” every resume has a topic, and keying on an item is
the conditional this removes. It is NOT a new numbered step: ~15 prose
cross-references across skills and scripts pin "step 4" (cairn) and "step 6"
(claim-work), none machine-checked, and a renumber would falsify all of them.

The guard is STRUCTURAL, not spelled: a grep for "unconditional" passes on a
body that says the word and still gates the command. test_the_query_is_
UNCONDITIONAL__it_shares_a_numbered_step_with_cairn_recall asserts WHICH
numbered step the command physically sits in. Watched to fail two ways: red at
origin/main via the count arm, and an isolated mutant (query moved back into
step 3, wording untouched) fires the step-identity arm with its own message.

RESIDUAL, stated in the skill and the test: the 5/6 was measured with ONE
command in that step. Co-locating a second is a prediction, not a measurement
β€” re-measure with check 1 of the handoff's "How to verify".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G7eZPAdX7nAeamShBnYNg2
Claude-Session-Id: 1de26f50-0e47-4964-b6ff-b87bea89b1fb
…claims

Round 1 of /audit-pr on #1332 returned six 🟑, no πŸ”΄. Every one is fixed here.

F1 (guard narrower than its name) β€” the test claimed to prove the command is
UNCONDITIONAL and asserted only a shared step DIGIT. The audit built four
isolated mutants; three survived a fully green suite. Renamed to what it
checks, and widened: it now compares the FENCE, which kills M4 (a second list
item re-labelled `4.`, gated, in its own block) with its own message. M2 and
M3 β€” a gating sentence above the fence, a conditional comment inside it β€”
STILL SURVIVE and are now named in the docstring as uncovered. They are
prose-shaped; no structural check here sees them, and saying so is better than
a keyword guard that would read as coverage.

F2 (byte claim wrong by ~10x) β€” "a few hundred bytes" replaced with the
measured figures: 3,941 B and 3,999 B for two real --limit 3 queries, 1,251 B
for a no-match, which is the floor because the banner prints either way.
Re-measured independently before changing it.

F3 (the conditional came back) β€” the step-3 replacement sentence re-created an
open-item-keyed instruction inside the block this PR measured at 0/6, told the
reader to "re-run" something not yet run, was invisible from step 4, and
dropped the tool's PURPOSE. Step 3 is now a pointer with no action; the
item-level re-run and the "Ruled out: bullets stop you re-running a probe
someone already ran" rationale both moved into step 4.

F4 (asymmetric scope, unstated) β€” `cairn recall --repo` is repo-scoped while
the query searches all four repos, two of them client repos, and routinely
returns client sections above devrc ones. The step now says so and tells the
reader to check each hit's repo before reusing it. Not narrowed to --repo:
cross-repo reach is the point.

F5 (report step named one surface) β€” step 5 said `from index`; handoff_search
prints `from handoff docs`. Verified both banners by running them. Step 5 now
carries each surface's own label.

F6 (dangling referent) β€” "that doc's How to verify" had no antecedent and the
nearest one was the wrong document. Named explicitly.

F7 (denominators did not reconcile) β€” 8 - 1 = 7, not 6. The missing run is the
measuring session itself, excluded as the instrument; that was true and never
stated. Now stated in the skill, the test docstring and the handoff doc, with
an as-of timestamp, since the corpus grows and a later re-run reports larger
numbers rather than contradicting these.

Also fixed the nit: a docstring said the recall posture sits "four steps
earlier", which was wrong before this PR (cairn was one step LATER) and wrong
after it (co-located).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G7eZPAdX7nAeamShBnYNg2
Claude-Session-Id: 1de26f50-0e47-4964-b6ff-b87bea89b1fb
Round 2 verified all eight of round 1's claims actually fixed, and found two
🟑 plus one 🟒. All three fixed here.

🟑 the handoff doc's STATUS contradicted the PR shipping it. `State now` said
"No fix is built; awaits operator direction", and ranked next-step 1 still
described this very change as pending. Both mitigations that made it survivable
(the held claim, the open PR visible to step 6's sweep) end AT MERGE β€” so a
/resume on that doc would have read "no fix is built" and re-implemented a
merged change, which is precisely the re-derivation loop this PR exists to
break. Status and rank 1 rewritten: rank 1 is now RE-MEASURE ADOPTION, which is
the thing that is actually still open.

πŸ”΄ That item also carried a FALSE claim I wrote and the audit caught: "SKILL.md
is byte-capped, so promoting text means evicting text". It is not. The caps
cover browser, handoff, prune-skill and RULES.md; this PR's own test says so.
Corrected in place and labelled as a correction, not silently deleted.

🟑 M5 β€” a fifth mutant the round-1 residual list did not anticipate: the command
left in the fence but COMMENTED OUT. Every check in this module is a substring
test, and `# python3 ...handoff_search.py ...` contains the pinned string, so
the string pin, the step check and the fence check ALL went green over dead
wiring β€” this module's founding failure, reachable by one character. Now killed
by requiring the fence line to be live. The docstring no longer presents the
mutant list as closed: M5 was found after round 1 called the residual settled.

🟒 the scope warning restated `handoff_index.REPO_ENV_HANDLES` membership
instead of deriving it, in a module whose docstring says every claim is derived
from the tool. Now pinned against the module. Scope of that pin stated: it
checks the LABELS, not the "two of which are client repos" count, which is a
human judgement no module holds.

Mutants re-run under PYTHONDONTWRITEBYTECODE=1: control 8 passed; M5 killed by
the live-line assert with its own message; M6 (drop a handle from the warning)
killed by the derived pin, naming DATAPACKET. M2 and M3 still survive and are
still named as uncovered.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G7eZPAdX7nAeamShBnYNg2
Claude-Session-Id: 1de26f50-0e47-4964-b6ff-b87bea89b1fb
🟑 THE DERIVED SCOPE PIN WAS DECORATION FOR ONE OF ITS FOUR ARMS. It searched
the whole wiring block, and EXPECTED_COMMAND contains
`~/workspace/devrc/scripts/lib/handoff_search.py`, so `"devrc" in block` was
guaranteed true on every green run. Round 2's sweep picked DATAPACKET β€” a
fixture that could only die β€” and read the kill as proof the pin worked. That
is exactly RULES.md's "prove it REACHABLE, not merely breakable" and "pick
fixtures distinct from any constant the assertion already names".

Narrowing to the warning PARAGRAPH was NOT sufficient, and measuring said so:
the paragraph itself says "a devrc-topic query" and "above the devrc ones", so
dropping `devrc` from the enumerated list still left 8 passed. Fixed by
matching BACKTICKED tokens β€” only the list is a code span. Now measured:
  control 8 passed Β· M6-devrc -> 1 failed, ['DEVRC'] Β· M7 (handle deleted from
  the list but mentioned in an unrelated sentence) -> 1 failed, ['CIVITAI'] Β·
  M5 and M1 still die with their own messages.
All four arms are now reachable; before this, two of four were not.

🟑 The `Claim:` line asserted a release that has not happened and dropped the
command that performs it β€” wider on one axis, narrower on the other. Restored
as STILL HELD with the explicit `claim-work --release`, and why an unreleased
claim blocks the next rank 1 under a different identity.

🟑 A THIRD site still said to build the fix: Open investigations -> Next probe
told the reader to "promote the query to its own numbered step". Rounds 1-2
fixed State now and rank 1 and left this one, so the doc contradicted itself at
the exact section /resume step 3 tells a session to read. Reworded to say the
promotion landed and only the re-run remains.

🟒 The correction paragraph's own number was wrong: "~1.9 KB" was one commit's
delta, not the PR's. Measured +3,688 B (41,852 -> 45,540, git cat-file -s at
base 10d437c and head 00e803a) and labelled as a correction of a correction.

🟒 Rank 1 now says to raise check 1's CUT to #1332's merge time before
re-running; left at #1295's, the 14 pre-fix runs stay in the denominator and a
fully successful fix reports ~10/24 and reads as a failure.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G7eZPAdX7nAeamShBnYNg2
Claude-Session-Id: 1de26f50-0e47-4964-b6ff-b87bea89b1fb
@ZacxDev
ZacxDev force-pushed the feat/resume-index-step branch from 1ce2818 to 0d0f0b6 Compare September 6, 2026 17:38
@ZacxDev

ZacxDev commented Sep 6, 2026

Copy link
Copy Markdown
Member Author

Audit round 3 β€” three findings, all fixed in 0d0f0b6f. Ladder STOPS here, on the attribution gate.

Round 3 caught a real hole in the guard round 2 added β€” see claim 1; it is the sharpest finding of the whole ladder.

1. 🟑 the round-2 derived scope pin had a STRUCTURALLY UNREACHABLE arm. It searched the whole wiring block, and EXPECTED_COMMAND contains `~/workspace/devrc/...`, so "devrc" in block was guaranteed true on every green run; round 2 swept with DATAPACKET, a fixture that could only die, and read the kill as proof. Narrowing to the warning PARAGRAPH was measured INSUFFICIENT (the paragraph itself says "a devrc-topic query"). Fixed by matching BACKTICKED tokens. Now measured: control 8 passed; M6-devrc -> 1 failed naming [DEVRC]; M7 (handle dropped from the list but mentioned in an unrelated sentence, which passed before) -> 1 failed naming [CIVITAI]; M5 and M1 still die. All four arms reachable; two of four were not.
2. 🟑 the `Claim:` line asserted a release that had not happened and dropped the command that performs it. Restored as STILL HELD with the explicit `claim-work --release`, plus why an unreleased global claim blocks the next rank 1 under a different identity.
3. 🟑 a THIRD site still told the reader to build the fix β€” Open investigations -> Next probe. Rounds 1-2 fixed State now and rank 1 and missed this one, so the doc contradicted itself at the exact section /resume step 3 reads. Reworded.
4. 🟒 the correction paragraph`s own number was wrong: "~1.9 KB" was one commit`s delta. Measured +3,688 B (41,852 -> 45,540 via git cat-file -s) and labelled as a correction of a correction.
5. 🟒 rank 1 now says to raise check 1`s CUT to #1332`s merge time; left at #1295`s, the 14 pre-fix runs stay in the denominator and a successful fix reads as ~10/24, i.e. as a failure.

Why the ladder stops here β€” the attribution gate, measured

Payload for this PR is claude/skills/resume/SKILL.md. Measured with the prescribed command (git log --numstat --format= --remerge-diff <audited>..HEAD --not <base>, rc 0, non-empty range):

round fixes touched payload lines
round 2 test + handoff doc 0
round 3 test + handoff doc 0

Two consecutive rounds whose fixes changed zero payload lines β€” the skill body has been untouched since round 1. The ladder is auditing the guard and the notes it wrote, not the change. That is the documented stop condition, and it is a measurement, not a judgement call or a round cap.

Nothing is being left unfixed: all three round-3 findings are fixed above. The two known residuals (mutants M2 and M3 β€” a gating sentence above the fence, a conditional comment inside it) are not silently dropped: they are named as uncovered in the test docstring, which also states the mutant list is not closed.

Gate β€” merged tree, base f58d2df0, run one at a time

  • pytests β€” collected=21903 passed=21900 failed=0 (floor 18672)
  • nodetests β€” suites=5 tests=1449 pass=1449 fail=0 (floor 1367)

Base re-confirmed unmoved after the run. Re-gated because f58d2df0 changed scripts/run-tests.sh, which owns the per-target floor table β€” the floor moved 18610 -> 18672, so that re-run was substantive.

@ZacxDev
ZacxDev merged commit 8e9428e into main Sep 6, 2026
0 of 2 checks passed
@ZacxDev
ZacxDev deleted the feat/resume-index-step branch September 6, 2026 17:51
ZacxDev added a commit that referenced this pull request Sep 9, 2026
… just read (#1399)

* fix(handoff-search): stop spending the top hit on the doc the session just read

MEASURED over the 20 post-fix `/resume` runs that queried the corpus
(2026-09-08): 23 of 60 hit slots were the session's OWN handoff β€” the
document it had read minutes earlier in step 3 β€” and it was the #1 hit in
13 of 20 queries, taking all three slots twice.

That is arithmetic, not a ranker bug. Step 4 tells the caller to query the
handoff's TOPIC, and the best text match for a document's topic is that
document. The re-keying that made the step unconditional in #1332 is the
same thing that aimed it at itself.

It matters because YIELD was answered in the same pass and it is 1 of 20:
one session had a hit change what it did (it dropped the backlog it was
resuming for an unclaimed forcing:security item in another effort, five
hours later, off a hit it had carried in context). The other 19 got
nothing β€” and a third of what they were shown, they had already read.

  --exclude-slug SLUG|PATH   (repeatable)

Takes the doc path `resume-state.sh` printed on its `handoff:` line, or a
bare slug; a path is normalised through the indexer's own `slug_for`, never
a second hand-rolled strip. `/resume` step 4's fence now passes it.

It is a SCOPE filter, not a post-hoc drop of rows the query returned:
  * it goes through `_selected` / `_filter_predicates`, the single predicate
    both `stats` and `search` read, so the counter and the query cannot come
    to different views of what is in scope;
  * excluding everything is therefore `empty-scope` (rc 4) β€” "your filter
    emptied the corpus" β€” never `no-match` (rc 0), which would assert the
    corpus is silent about a topic it was never allowed to answer on;
  * it is NEVER silent: `excluded=` prints on the scope line of every status
    including the zeros, and `in_scope_*` appears beside `indexed_*`.

Also corrects "How to verify" check 3, which could not have worked as
written: the DB path needs `nix develop`, not just `KUBECONFIG` β€” a bare
python3 dies with `psycopg2 is required`.

Coverage: 13 new tests. An 8-mutant sweep (positive control included) was
run under PYTHONDONTWRITEBYTECODE=1 with each mutant verified PRESENT in
the file before scoring; all 8 died, each by its own named test. The two
that matter most are the silent ones β€” scoped stats blind to the exclusion
(turns "your filter emptied it" into "the corpus is silent") and the
exclude list bound before sections in the Postgres params, which psycopg2
binds positionally and so yields a valid query against the wrong columns.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SwwnnDzefhhE8cG9sqjafE
Claude-Session-Id: f0fffa8e-a2ab-464e-bd7c-dfe9bd8955f0

* docs(handoff): name the PR that carries the fix

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SwwnnDzefhhE8cG9sqjafE
Claude-Session-Id: f0fffa8e-a2ab-464e-bd7c-dfe9bd8955f0

* fix(handoff-search): round-1 audit β€” the flag was deletable to INERT with a green suite

Ten findings from the round-1 adversarial audit, all fixed. The one that
mattered: every layer was pinned in isolation β€” exclusion_slug, the row
filter, both backends' bound params, the renderer, `filtered` β€” and
NOTHING pinned that main() hands `exclude` to run_search. Deleting
`exclude=exclude` from the CLI call site left the flag completely inert
(excluded doc back as hit #1, no `excluded=` line, no scope pair) with
304/304 tests green. The pre-existing guard whose docstring says "πŸ”΄ THE
SEAM" proves only that argparse ACCEPTS the flag: it passes `--limit 0`,
which returns rc 2 before any store is built. RULES.md β€” "verified in
isolation is the new vacuous green"; "a count of DECLARATIONS is not a
count of INSTANCES"; a guard's description claiming coverage it does not
provide is worse than none, because it stops anyone looking.

Both call sites are now covered: the offline one behaviourally, the
postgres one β€” which no test here can execute β€” by an AST ledger that
fails if a call site is added without `exclude=` as well as if one is
removed.

Also fixed:
  * The no-match remedy told exclusion-only runs to "widen --repo /
    --section". I had fixed exactly this class in the empty-scope branch
    and written a comment citing it, while its neighbour kept the defect β€”
    and no-match is the branch that matters (against a 401-doc corpus one
    exclusion can essentially never empty the scope). Now ONE function,
    `active_filter_flags`, answers it for both.
  * exclusion_slug silently no-opped on an absolute path, on a
    `handoff-x` basename with no `.md`, and on a trailing space β€” each
    printing a confident `excluded=<garbage>` while filtering nothing.
    Normalisation is unconditional now. A filter that declines to filter
    renders identically to one that worked.
  * SKILL.md stated rc 0 for a case measured at rc 4, contradicting this
    module's own comment and its own test, in the paragraph an agent reads
    to decide whether a zero is an answer.
  * The fenced command was not valid shell (`bash -n` rc 2) β€” an unquoted
    placeholder carrying an apostrophe and backticks.
  * "drops in_scope_docs by one" was false in both directions.
  * test_the_CLI_dedupes_repeats_without_reordering asserted on its own
    inline expression and never invoked the CLI.
  * A bare `str` exclude iterates per character (a wrong scope, not a
    no-op); a None element makes postgres return zero while memory returns
    everything. Both refused loudly.
  * scripts/README.md did not know the flag exists.

Doc corrections, both mine: the "8-mutant sweep" was true but incomplete β€”
an independent 13-mutant sweep found 3 survivors it never covered; and the
adoption annotation claimed a session-id exclusion the published script
does not perform (20/22 was reached by subtracting by hand afterwards).

πŸ”΄ THE FIX ROUND RESET THE GATE, AND TWO OF ITS OWN FIXES SHIPPED
UNGUARDED. Re-sweeping the fixes rather than the findings: restoring the
silent-no-op exclusion_slug, and disabling the bare-str guard, both
SURVIVED a 306-test green suite. Ten tests added; the re-sweep now kills
all 8 mutants, each by its own named test, tree restored byte-identical.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SwwnnDzefhhE8cG9sqjafE
Claude-Session-Id: f0fffa8e-a2ab-464e-bd7c-dfe9bd8955f0

* fix(handoff-search): round-2 audit β€” I unified WHICH flags and left WHAT TO DO wrong

Six findings from the round-2 delta re-audit, all fixed. The instructive
one: round 1 consolidated which flags each remedy branch names, and left
the VERB open-coded β€” so the same two branches disagreed a second time,
one level in. `no-match` told an exclusion-only run to "widen
--exclude-slug", which is advice that guarantees the zero stays a zero:
widening an exclusion excludes MORE. Its sibling three lines up already
said "Widen or drop". Consolidation is a bug-finding instrument, and this
PR has now been caught by that rule twice.

  * `_exclusion_list` was called unconditionally on the memory backend and
    inside `if exclude:` on postgres, so `exclude=""` raised on one and was
    silently accepted by the other β€” a NEW cross-backend divergence, in the
    guard whose docstring says divergence is what it prevents. Coerced
    before the bool() on both. Pinned as a RELATIONSHIP over a shared table
    of shapes, not two per-backend tests: two tests that each pass alone is
    exactly how it survived.
  * The AST ledger pinned that `exclude=` is PRESENT, not that it carries
    the value. `exclude=()` at the postgres site survived 314 tests β€” a
    guard on a NAME, walkable by supplying a different value under it. It
    now pins the value is the normalised local.
  * "the whole suite green at 304 passed" named a scope nobody measured:
    304 is two files; the repo has ~21k tests. In the docstring of the
    guard against "verified in isolation".
  * Nothing asserted the FENCE parses. `bash -n` rc 0 was true of the line
    #1399 fixed and false of the block, because the untouched `cairn recall
    --repo <path>` line parses `<path>` as a redirect β€” and bash aborts the
    whole block, so a verbatim paste ran NEITHER command. Quoted, and
    pinned by a test over the whole fence with a positive control.
  * The "1,251 B no-match floor" was never a floor: the response echoes the
    query, so it is a function of query length (1,261 B at 15 chars, 1,289
    at 43, ~1,436 when excluding). Corrected to state the dependency rather
    than swap in another falsifiable number.

Two instrument failures during this round, both of which produced
confident results that were worthless:

πŸ”΄ The sweep script restored SKILL.md with `git checkout --`. Those edits
were UNCOMMITTED, so it reverted them to the last commit and silently
destroyed two of them. RULES.md says restore from `cp -a`, never `git
checkout --`; I wrote the violation into my own tooling. Recovered and
re-applied; the replacement uses `cp -a` and says why.

πŸ”΄ Two mutants scored SURVIVED off runs that never executed. The tell was
an empty summary β€” `SURVIVED ()`. zsh does not word-split unquoted
parameters, so two test paths in a variable became one impossible
filename; pytest errored and printed no verdict. The sweep now REQUIRES a
summary line before scoring and prints VOID otherwise, runs a baseline
control first, and uses a bash array. Re-run isolated (mutating the
production value only, never the guard beside it): both KILLED, each by
its own named test.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SwwnnDzefhhE8cG9sqjafE
Claude-Session-Id: f0fffa8e-a2ab-464e-bd7c-dfe9bd8955f0

* fix(handoff-search): round-3 audit β€” no behavioural defect; sweep the shape, not the site

Round 3 returned four 🟒 claim-corrections and NO behavioural defect. All
four fixed, and the third is the one worth recording.

  * The comment claiming "one rule, one place β€” the phrasing included" was
    false: round 2 consolidated WHICH flags each remedy branch names and
    left the VERB as two literals. Rather than correct the sentence, this
    makes it true β€” `widen_or_drop_clause` is the single literal both
    branches read, pinned by a test that breaks BOTH when it breaks.
  * The refusal for `exclude=""` ended `Pass ['']`, and `[""]` IS accepted:
    it filters nothing while printing a confident `excluded=` line. An
    error message naming the next defect as its own remedy β€” the silent
    no-op this PR spent three rounds closing, offered as the fix for its
    own trigger. The worked example is now suppressed for the empty string
    and kept for every other shape.
  * πŸ”΄ AN UNSCOPED TEST COUNT, FOR THE FOURTH TIME IN THIS PR. "the whole
    suite green at 304", "SURVIVED all 314 tests", "a 306-test green
    suite", "304 of 304 tests passed" β€” every one numerically TRUE and
    every one naming ~300 tests across two files against a repo of ~21,000.
    Three rounds each caught one site and fixed that site. It only went
    away when swept at all four. When a round fixes an instance of a shape,
    grep for the shape β€” which is the rule I was quoting while breaking it.
  * `_step4_fence` checks a STRIPPED reconstruction, not the pasted bytes.
    Both forms are rc 0 today so nothing is masked; the residual is now
    named in the docstring rather than left implicit (a heredoc added to
    that fence would make the two disagree).

Sweep: baseline green (321), D1 (shared clause back to bare "widen") and
D2 (refusal offers [''] again) both KILLED, each by its own named test,
tree restored byte-identical via cp -a.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SwwnnDzefhhE8cG9sqjafE
Claude-Session-Id: f0fffa8e-a2ab-464e-bd7c-dfe9bd8955f0

* fix(handoff-search): round-4 audit β€” my "consolidation" was dead-code-able with a green suite

Round 4 returned category (b): only claim-corrections, no behavioural
defect. All three fixed. The first is the round-1 seam lesson recurring
one class over.

  * πŸ”΄ THE CONSOLIDATION PIN WAS TEXT-AGREEMENT, NOT STRUCTURE. Round 4
    reverted both renderer branches to independent open-coded literals,
    leaving `widen_or_drop_clause` defined and ENTIRELY UNREFERENCED β€” and
    the suite passed 321/321. Every assertion I had written compared
    strings; none observed where the string came from, so the test whose
    NAME says "comes from ONE literal shared by both branches" could not
    see the branches stop sharing it. Now an AST ledger: both branches must
    CALL the helper, and the verb may not survive as a literal in render().
    Same instrument, and same lesson, as the run_search seam.
  * The unscoped-count sweep I claimed was complete missed a FIFTH site β€”
    four quoted counts, five textual occurrences β€” and the survivor was
    inside the very test the doc bullet held up as the exemplar. The bullet
    asserting the sweep was done was itself an instance of the shape it
    describes. Corrected, and it now says to grep AND COUNT.
  * The example-suppression was keyed on emptiness while its own comment
    named the hazard as "accepted and filters nothing". `exclude=" "` β€” one
    character different β€” was still told to pass `[' ']`. Re-keyed on
    `.strip()`, the predicate the sentence actually described.

NOT fixed, filed as rank 2 with a closing condition: `--exclude-slug "  "`
is still a silent no-op reachable from the CLI. The fix is an input
rejection at main() (rc 2), which is a behaviour change β€” it would reset
the gate and require another round, so it is recorded rather than absorbed.

Sweep, in a DETACHED cp -a copy with .git removed (round 3 flagged that
earlier sweeps mutated the shared checkout in place, where a concurrent
session could read a mutant): baseline green 322; E1 (helper unreferenced
β€” round 4's own survivor) and E2 (suppression back to emptiness) both
KILLED by their own named tests. E2's first attempt returned NO VERDICT
because the marker comment commented out a closing paren; the VOID guard
caught it instead of scoring a survivor, and the re-run parse-checks the
mutant before running it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SwwnnDzefhhE8cG9sqjafE
Claude-Session-Id: f0fffa8e-a2ab-464e-bd7c-dfe9bd8955f0

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant