Skip to content

fix(resume-state): resolve SESSION-HANDOFF.md, and stop DRIFT reporting a false green - #326

Merged
ZacxDev merged 13 commits into
mainfrom
fix/resume-state-session-handoff
Aug 4, 2026
Merged

fix(resume-state): resolve SESSION-HANDOFF.md, and stop DRIFT reporting a false green#326
ZacxDev merged 13 commits into
mainfrom
fix/resume-state-session-handoff

Conversation

@ZacxDev

@ZacxDev ZacxDev commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

The bug

resume-state.sh's resolve() globbed only claudedocs/handoff-*.md. The
civitai-manager repo names its handoff claudedocs/SESSION-HANDOFF.md.
Measured there against pristine origin/main:

GIT/PR
  civitai-manager  branch main  ↑0↓0  clean  last 8m: opencode
  handoff: (none found — git-only)
...
DRIFT
  (none detected — live state matches the handoff's claims)

The DRIFT line is the real damage: it is vacuous. It reconciled against
nothing and printed a reassuring result. A caller reads "no drift" as a fact
about the handoff when no handoff was ever loaded — a false green in the one
place /resume exists to be trustworthy.

Same repo, after this PR:

  handoff: SESSION-HANDOFF.md
  branch feat/breadcrumbs: exists (origin/feat/breadcrumbs)
  branch feat/comfy-model-cache: GONE (deleted or never local)
  branch fix/copy-reduction: exists (origin/fix/copy-reduction)
DRIFT
  - branch feat/comfy-model-cache referenced by handoff no longer exists (merged & pruned?)

Corrected. This block originally also showed a
branch docs/configuration.md ... no longer exists line and cited it as evidence
that the fix worked. That statement was falsedocs/configuration.md is a real
15,276-byte file in that repo, not a branch. Fixing that fabrication is 🔴-2
below. See
the correction comment
for the durable record.

What changed

1. A last-resort fallback glob in resolve().

[ -z "$HANDOFF" ] && HANDOFF=$(ls -t "$REPO"/claudedocs/*HANDOFF*.md 2>/dev/null | head -1)

Exact reach: basenames under claudedocs/ containing the literal,
uppercase substring HANDOFF and ending .md. That is
SESSION-HANDOFF.md, HANDOFF.md, HANDOFF-2026-08-04.md. It cannot reach
the design/audit docs that share these directories — *-DESIGN.md,
SECURITY-AUDIT-*.md, LAUNCH-*.md, *-RESEARCH.md — none of which contains
HANDOFF.

Behaviour preservation, per the brief's invariants:

  • It is tried last, so a repo with both shapes resolves exactly as today —
    handoff-*.md wins regardless of age. (Being tried last is the only thing
    protecting the lowercase family; an earlier comment also credited bash's
    case-sensitive globbing, which is inert here and has been removed.)
  • The ls -t | head -1 newest-first selection shape is unchanged in both families.
  • The explicit-path form (resume-state.sh path/to/doc.md) is untouched.
  • Verified against the real devrc repo (30+ claudedocs/handoff-*.md):
    resolve() returns a byte-identical answer at base and at HEAD for the
    no-arg case and for two topic slugs. Not just fixtures.

2. The topic slug gets no fallback of its own — decided, not overlooked.
An unmatched slug already falls through this chain, so resume-state.sh session
in a repo whose only handoff is SESSION-HANDOFF.md still finds it, for zero
extra code. The slug is only ever interpolated into the handoff-* glob, so it
can never reach a decoy. Both behaviours are tested.

3. DRIFT no longer lies when nothing was reconciled. Two cases:

  • no handoff resolved → (no handoff loaded — nothing to reconcile; this is NOT a clean bill of health)
  • a handoff loaded but a source never answered → (nothing detected, but a source did not answer — NOT a clean bill of health), with the ratio

4. The /resume skill carried the same blind spot in prose — step 1 told
the model to glob handoff-*.md and, failing that, to give up. The predicate
lived in two places and only one was fixed (RULES.md → "One rule, one
place"). Step 1 now names the same two-tier order; step 3 says to read the
handoff: line before DRIFT.

The three 🔴 findings from the adversarial audit

🔴-1 — the hermeticity tripwire was wired to nothing. run_resume() built
env (stub PATH, STUB_LOG, git-config isolation) then called
subprocess.run without env=, so the subject inherited os.environ.
test_no_network_tool_is_ever_invoked was asserting a structural zero.
Verified both directions with a gh call spliced into resolve(): green
before the fix, red after
. The positive control missed it because it execs
the stub directly with env=env — a path the subject never took.

🔴-2 — DRIFT fabricated branches from file paths. zach|feat|fix|docs|chore
are branch prefixes and ordinary directory names, and \b matches after a
slash, so a handoff that merely quoted a path minted a phantom branch
reported as "no longer exists (merged & pruned?)" — 2 of the 6 new DRIFT lines
across the two repos this fallback newly reaches. Three filters: the leading
boundary now excludes /; a trailing alphabetic file extension disqualifies a
token; and git cat-file -e HEAD:<tok> drops anything naming a real tracked
path. my-fix/x still matches and notafix/x still does not — / is the only
boundary change.

🔴-3 — the false green survived one layer up. With gh present and every
gh pr view failing, || continue swallowed it with no diagnostic and DRIFT
still claimed a clean reconciliation. The block now counts what answered and
reports the ratio. No cause is attributed — gh exits non-zero for a genuine
404 and an auth failure alike. A handoff referencing no PRs is deliberately
not downgraded, or the warning fires on every non-GitHub repo and becomes
noise.

Plus a bug the new tests caught in my own fix: a trailing [ … ] && printf as
the last statement of a branch made the whole script exit 1 whenever it
found drift with nothing unreconciled.

Tests — 55 hermetic cases, ~6 s

scripts/tests/test_resume_state_handoff_resolution.py drives the script end
to end against throwaway git repos and asserts the digest's handoff: line
names the exact file — never merely that the script exited 0, which is true
of the broken script too. Every absence-assertion has a positive control beside
it, because an absence is also what deleting the feature produces.

Written as pytest, not bash. scripts/run-tests.sh — the flake gate — takes
scripts/tests as a pytest target, so it collects test_*.py only. The two
.sh suites there are run by hand and by nothing else. The
stub-binaries-on-$PATH technique is still test_release_wrapper.sh's.

Red/green matrix

base 0294b82 HEAD
new suite 8 failed, 18 passed (1.23 s) 55 passed (~6 s)

Every base failure is a real AssertionError, not a collection or syntax
error, and the 18 that passed at base prove the harness was exercising the
script rather than erroring out.

Mutation battery — 20 mutations, all killed. Each verified to have landed
(git diff --stat), to leave bash -n passing (so it broke behaviour, not
parsing), and to fail with a real AssertionError in the expected test.
Covers: the fallback glob (delete / reorder / merge / broaden ×2 / drop .md /
drop head -1 / unscope from claudedocs/), slug anchoring, all three
branch-fabrication filters plus an over-broad "suppress everything" fix, and
six mutations across the unreconciled-source logic.

Four came back wrong on the first run — three were bugs in my own battery (a
literal \\b, a misfiled expectation, and one that left unbalanced quotes and
so was a parse error exercising no assertion) and one was a real gap:
test_a_quoted_file_path_is_not_reported_as_a_branch was over-determined,
because its fixture tracks the file so the cat-file probe rejected the token
and the extension filter was never load-bearing. Fixed by adding the
discriminating case rather than editing the measured fixture away.

Delta-audit round (F3/F2/F4) — 24 mutations, all killed

The delta audit found four residuals. Three are fixed here; the fourth is tracked
separately (below).

🟡 F3 was a REGRESSION this PR introduced and is the important one. Excluding
/ from the branch-token boundary killed the path fabrication and every
reference legitimately carrying a slash-bearing prefix — origin/fix/x,
upstream/feat/x, refs/heads/fix/x, and GitHub /tree/ and /compare/ URLs.
One live casualty across 211 real handoff docs:
origin/zach/engaged-models-client-store in datapacket-talos, the only form that
branch appears in, and it is genuinely gone — so the pre-PR DRIFT line was correct
and the regressed code was silently mute. Omission is the worse polarity in a
go/no-go tool
, because silence reads as "no drift" instead of announcing itself.

Fixed by stripping the ref-ish prefix before matching. Verified in both
directions on the real documents:

doc pre-PR base this PR, round 2 (regressed) HEAD
datapacket-talos handoff zach/engaged-models-client-store (nothing) zach/engaged-models-client-store
naida-ai HANDOFF.md 2 real + zach/workspace/scratch/naida-ai 2 real 2 real
civitai-manager SESSION-HANDOFF.md 3 real + docs/configuration.md 3 real 3 real

HEAD is base minus both fabrications plus the restored ref — the two fixes pull
in opposite directions and are pinned together in one test.

🟡 F2 — the partial-answer branch was unreachable (fixtures could only make gh
answer for all or none), so mutating it survived all 46 tests. The gh stub gained a
selective mode and the new test asserts its preconditions before its verdict.

🟡 F4claude/commands/resume.md now names both conditions that make an empty
DRIFT meaningless, including the ! gap lines, and says which single wording is an
actual all-clear.

Two 🟢s taken: the tracked-path probe now runs after the branch-existence checks (a
token that is both a live branch and a tracked path was being dropped — 0 such
collisions across 2893 real branches, so latent rather than live), and alerts_block's
trailing && is now a full if, the same class as the exit-1 bug fixed in main.

Follow-up tracked separately

#330 — three more "reconciled nothing" paths still print the clean line.
git_pr_block's not-a-git-repo early return, and an unreachable cluster in
workload_block / alerts_block, all reach (none detected — live state matches the handoff's claims) having checked nothing. UNRECONCILED is the right mechanism and
is simply not fed from those sites. Squarely within this PR's thesis and the largest
remaining gap — but pre-existing, not a regression from this PR, and this PR has
already grown twice. Two of the three are reproduced live in the issue; the third is
source-read only, since reaching it needs a live cluster.

Wider-suite check

pytest scripts/tests under an ad-hoc nix-shell (not the full toolchain, so
there is pre-existing environment noise): no failure at HEAD that is not also
at base
— 26 identical pre-existing failures, 1088 passed at HEAD.
test_opencode_engine.py is non-deterministic in this environment (the same
base commit
, run alone, gave 15, 2 and 4 failures on three consecutive runs),
established by measurement rather than assumption.

bash -n passes. shellcheck gains exactly one new finding, a third instance
of the pre-existing, accepted SC2012 (ls -t | head -1), which invariant 2
required me to keep. No new finding class. The pre-existing
scripts/tests/test_resume_state.sh still reports ALL PASS.

Out of scope — a second, unrelated bug worth its own PR

A separate defect in the branch loop of git_pr_block, which this PR does
not fix. When a handoff-referenced branch exists only on the remote, the code
sets tip="origin/$b" but then runs the merged-check against the bare $b,
which does not resolve; git branch --merged lists locals only. So a
remote-only branch is always reported exists, never merged into HEAD.
Measured: feat/breadcrumbs and fix/copy-reduction above are reported merely
"exists", while git merge-base --is-ancestor origin/<b> origin/main returns
rc=0 for both. Different function, different blast radius, needs its own test
coverage.

Also noted, not fixed

scripts/tests/test_resume_state.sh and test_release_wrapper.sh both derive
their own directory with HERE=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd).
With CDPATH exported (it is, on this host), bash's cd echoes the resolved
path
, so $HERE gains a newline and the source fails — every assertion then
reports command not found and the suite is meaningless. It only bites on a
relative invocation, which is exactly the documented run: line. Confirmed
pre-existing: pristine origin/main fails identically. The fix is CDPATH= cd ….

🤖 Generated with Claude Code

https://claude.ai/code/session_01SeGJdEJjtvyv5PY3HW9pEF

ZacxDev added 9 commits August 4, 2026 08:01
…alse green

resolve() globbed only claudedocs/handoff-*.md. civitai-manager names its
handoff claudedocs/SESSION-HANDOFF.md, so running the script there printed

    handoff: (none found — git-only)
    DRIFT
      (none detected — live state matches the handoff's claims)

The DRIFT line is the real damage: it reconciled against NOTHING and reported a
reassuring result, which a caller reads as a clean bill of health.

Two changes:

1. A LAST-RESORT fallback glob, claudedocs/*HANDOFF*.md, tried only when the
   existing lowercase glob finds nothing. Reach: basenames containing the
   literal uppercase substring HANDOFF and ending .md — SESSION-HANDOFF.md,
   HANDOFF.md, HANDOFF-<date>.md. The design/audit docs that share these
   directories (*-DESIGN.md, SECURITY-AUDIT-*.md, LAUNCH-*.md, *-RESEARCH.md)
   contain no HANDOFF and so can never resolve as one. Because it is tried
   last, a repo carrying both shapes resolves exactly as it does today.
   Verified against the real devrc repo (30+ handoff-*.md): resolve() returns
   a byte-identical answer for no-arg and for two topic slugs.

   The topic slug gets no fallback of its own, deliberately: an unmatched slug
   already falls through this chain, so `resume-state.sh session` in a repo
   whose only handoff is SESSION-HANDOFF.md still finds it, and there is
   nothing for a slug to disambiguate when the family holds one file.

2. DRIFT now distinguishes "reconciled, found nothing" from "never loaded a
   handoff". The git-only case says so instead of claiming a match.

Measured before/after in civitai-manager: the digest goes from a false green to
naming SESSION-HANDOFF.md and surfacing two real drift findings.
Drives resume-state.sh end to end against throwaway git repos and asserts the
digest's `handoff:` line names the EXACT file, never merely that the script
exited 0 — "exited 0" is true of the broken script too.

Covers: the SESSION-HANDOFF.md regression; HANDOFF.md; the uppercase family
beside NEWER decoy docs (so `ls -t` order cannot rescue an over-broad glob);
lowercase no-regression; precedence when both shapes are present, with
SESSION-HANDOFF.md written last so it is the newest file — merge the two globs
into one `ls -t` and this fails; newest-first selection in both families;
six real decoy docs asserted individually so a failure names the leak; the
explicit-path form; the slug form and its documented degradation; and the
DRIFT wording on both branches.

Hermetic and fast (26 cases, ~1.3s). Fixtures carry no origin remote and no
prod-kubeconfig, which keeps the PR/WORKLOAD/ALERTS blocks on their skip paths;
gh/kubectl/curl are additionally stubbed onto the front of $PATH as tripwires
that log and fail, and test_no_network_tool_is_ever_invoked asserts the log
stayed empty — so a change that reaches for the network fails here with the
command named instead of hanging on a real timeout.

test_harness_can_observe_a_named_handoff is the positive control: most
assertions here are "names X" or "names nothing", and a parser wired to the
wrong stream would make every negative case pass for free.

Written as pytest rather than bash on purpose. scripts/run-tests.sh — the
flake gate — takes `scripts/tests` as a pytest target, so it collects test_*.py
only; the two .sh suites in this directory are run by hand and by nothing else.
The stub-binaries-on-$PATH technique is still test_release_wrapper.sh's.

Red at 0294b82 (8 failed / 18 passed, all real AssertionErrors), green at HEAD.
A mutation broadening the fallback to `*[Hh][Aa][Nn][Dd]*.md` — a plausible
"match handoff in any case" edit — SURVIVED all 26 cases, because not one decoy
document contained the letters HAND. The decoys were all real civitai-manager
filenames, which made the set representative but not adversarial: it ruled out
exactly the over-broad globs I had imagined.

Adds three HAND-but-not-HANDOFF decoys (HANDBOOK.md, SHORTHAND-NOTES.md,
handling-errors.md) so any glob looser than the exact uppercase substring
sweeps them in and fails. The mutation is now killed; 29 cases green.

Deliberately NOT guarded: a widening to case-insensitive `*handoff*` would
also match e.g. session-handoff.md, which is a defensible future feature
rather than a bug. Pinning against it would be a guard that forbids its own
fix.
…ripwire a positive control

Two defects in the suite as first committed, both found by measurement rather
than review.

1. The stubs hand-wrote `#!/usr/bin/env bash`. test_runtime_shebangs.py — the
   repo-wide guard that exists for exactly this — went red: /usr/bin/env does
   not exist in the nix build sandbox, where the authoritative gate runs, and
   patchShebangs cannot reach a file a test writes at runtime. Green on this
   host, red only on the tier that gates merges. Now goes through
   testlib.mockbin.write_exec, which owns the shebang (/bin/sh).

   Caught by diffing the FAILURE SETS of `pytest scripts/tests` at
   origin/main vs HEAD, not the counts: both runs reported 26 environment
   failures from an ad-hoc nix-shell, and the one new entry was mine.

2. test_no_network_tool_is_ever_invoked asserts a ZERO, and a zero is
   indistinguishable from stubs that cannot exec at all — precisely what
   defect 1 would have produced. Adds a per-tool positive control that drives
   each stub directly and asserts it logs its argv and exits 1. The pair is
   now "1 on the positive control, 0 under test" rather than a bare zero.
…ssing handoff

The /resume skill duplicated resume-state.sh's blind spot in prose: step 1 told
the model to glob `claudedocs/handoff-*.md` and, failing that, to give up. So
fixing only the script left the model-facing half still missing
civitai-manager's SESSION-HANDOFF.md — the predicate lived in two places and
only one was fixed (RULES.md → "One rule, one place").

Step 1 now names the same two-tier order the script uses, and step 3 says to
read the `handoff:` line BEFORE the `DRIFT` block: a git-only digest reconciled
against nothing, which is not the same as finding no drift.
…red to nothing

run_resume() built `env` (stub PATH, STUB_LOG, git-config isolation) and then
called subprocess.run WITHOUT env=, so the subject inherited os.environ. The
stub PATH never applied and STUB_LOG was unset, which means
test_no_network_tool_is_ever_invoked was asserting a STRUCTURAL zero: the
script could have shelled out to the real gh/kubectl/curl on every run and the
log would still have been empty.

That is precisely the wired-to-nothing counter the positive control was added
to prevent, and the control did not catch it because it execs the stub DIRECTLY
with env=env — a path the subject never took — so it validated the stub rather
than the tripwire. make_repo() did pass env=env, which is what made this read
as an oversight rather than a design.

Measured both directions with a `gh probe-injected-by-mutation` call spliced
into resolve():
  before this fix: tripwire GREEN (4 passed) — the injected call was invisible
  after  this fix: tripwire RED, log shows 4x "gh probe-injected-by-mutation"

Also restores GIT_CONFIG_GLOBAL/SYSTEM isolation to the script's own git calls,
which had never reached them either.

Found by a blind adversarial audit of #326.
…nswered source "clean"

Two findings from a blind adversarial audit of #326. Both are cases where the
digest states something false, which is the harm this PR exists to remove — as
it stood it deleted one false green and added two fabricated facts.

🔴 FABRICATED BRANCHES. zach/ feat/ fix/ docs/ chore/ are branch prefixes AND
ordinary directory names, so a handoff that merely QUOTES A PATH minted a
phantom branch, which the loop then reported as "no longer exists (merged &
pruned?)". Measured live in both repos the SESSION-HANDOFF fallback newly
reaches — 2 fabricated lines out of the 6 new DRIFT lines they produce:

  civitai-manager  `docs/configuration.md`         -> a real 15,276-byte FILE
  naida-ai         /home/zach/workspace/scratch/…  -> zach/workspace/scratch/naida-ai

Three filters, two textual and one repo-aware:
  1. the leading boundary now excludes `/` — `\b` matched after a slash, so any
     absolute path containing /zach/ or /docs/ produced a token. `.` and `-`
     still delimit exactly as `\b` did, so `my-fix/x` still matches and
     `notafix/x` still does not; `/` is the only change.
  2. a trailing alphabetic file extension disqualifies a token, so `.md`/`.sh`
     drop while `fix/v1.2` and `fix/thing.v2` survive.
  3. `git cat-file -e HEAD:<tok>` in the branch loop drops anything naming a
     real tracked path — the extensionless case, e.g. a quoted `docs/architecture`.

Verified after: both fabrications gone, and every genuine branch in both repos
still reported (naida-ai keeps feat/sales-navigator-import-polish and
feat/search-safety-throttle; civitai-manager keeps all three).

extract_branches is pre-existing and was untouched by this PR's diff, but this
PR is what makes it fire on these repos, so it is in scope here.

🔴 THE FALSE GREEN SURVIVED ONE LAYER UP. `gh pr view` failing — offline,
unauthenticated, rate-limited, no access — was swallowed by `|| continue` with
NO diagnostic printed, and DRIFT still said "(none detected — live state
matches the handoff's claims)". Same sentence, same harm class, one layer up.
The block now counts what actually answered and reports the ratio, and DRIFT
degrades to "(nothing detected, but a source did not answer — NOT a clean bill
of health)". Gaps print alongside real findings too, since a list of findings
reads as complete unless its incompleteness is stated next to it.

No cause is attributed: gh returns non-zero for a genuine 404 and for an auth
failure alike, so a classifier would be guessing. The honest report is the
ratio plus the list of causes it could be.

A handoff referencing NO PRs is deliberately NOT downgraded — there is nothing
for gh to answer, so its absence costs no coverage, and a warning that fires on
every non-GitHub repo is noise people learn to ignore.

Also fixes an exit-code bug introduced while writing the above: a trailing
`[ … ] && printf` is the last statement of its branch, so a false test made the
whole script exit 1 on every run that found drift with nothing unreconciled.
Now a full `if` block. Caught by the new tests, which assert rc 0 on every run.

Also corrects a comment that credited bash's case-sensitive globbing for
protecting the lowercase family. That reason is inert — the fallback is only
reached when the lowercase globs found nothing, so there is nothing left to
poach whatever the case rules are. Being tried LAST is the only thing doing
that work.
… three unpinned guards

44 cases, all hermetic. New coverage, each with its own positive control
because most of these assert an ABSENCE and an absence is also what deleting
the feature produces:

BRANCH FABRICATION (🔴-2)
  - a quoted `docs/configuration.md` with the file really tracked -> no branch
  - an absolute path /home/zach/workspace/scratch/… -> no zach/workspace/… branch
  - a quoted tracked directory `docs/architecture` -> no branch
  + POSITIVE CONTROLS: a genuine missing branch still reports GONE *and* DRIFT;
    an existing branch reports exists and produces NO drift. Without these,
    deleting extract_branches outright would pass the three tests above.
  + the boundary change is pinned in both directions: `my-fix/x` still matches,
    `notafix/x` still does not.

UNANSWERED SOURCES (🔴-3)
  - gh present + remote present + every `gh pr view` failing -> DRIFT must not
    claim a clean reconciliation, must say a source did not answer, and must
    quote the ratio (0 of 3)
  - the gap is reported ALONGSIDE real findings
  - a handoff naming no PRs is NOT downgraded by gh being absent
  + POSITIVE CONTROL: the same handoff with a gh that ANSWERS gets the clean
    line back, proving the warning is driven by failure rather than being
    unconditional. The gh stub now answers with $STUB_GH_JSON when set, so both
    directions are exercised without a network.
  test_drift_keeps_its_clean_message_when_a_handoff_did_load now also asserts
  the absence of the warning, and its docstring says why its handoff (no PR
  refs) is entitled to the clean line at all — the audit was right that it was
  asserting that string on a run which reconciled nothing.

THREE GUARDS THAT EXISTED BUT WERE NOT PINNED (mutants survived all 32 cases)
  - slug anchoring: broadening `handoff-"$arg"*.md` to `*"$arg"*.md` survived
    only because the decoy was SOME-DESIGN.md and the slug `design` — a case
    mismatch. A lowercase decoy modelled on devrc's real
    browser-bridge-usage-audit-2026-08-02.md removes the coincidence.
  - directory scoping: `claudedocs/*HANDOFF*.md` -> `*/*HANDOFF*.md` survived,
    though the comment claims claudedocs/ only. Now pinned at the repo root and
    in a sibling directory.

Docstring timing corrected to the measured ~3.2 s cold / ~2.0-2.9 s warm; it
claimed "well under a second", which was never measured.
Both found by mutations that SURVIVED the 44-case suite.

1. test_a_quoted_file_path_is_not_reported_as_a_branch was OVER-DETERMINED:
   its fixture tracks docs/configuration.md, so the `git cat-file` probe
   rejects the token and the file-extension filter is never load-bearing —
   deleting that filter left all 44 green. Adds the discriminating case where
   the quoted path does NOT exist in this repo (handoffs routinely cite paths
   in other repos, or files since deleted), so only the extension filter can
   reject it. The real measured fixture is KEPT beside it rather than edited
   away, and the new one also asserts a genuine branch in the same prose still
   survives — so it cannot pass by extracting nothing.

2. The no-remote / gh-absent arm of the unreconciled logic had no test of its
   own. A handoff naming three PRs in a repo with no origin means nobody
   checked them, and the verdict must degrade exactly as when gh runs and
   fails.
@ZacxDev

ZacxDev commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

⚠ Correction — the original PR body contained a fabricated fact, presented as success evidence

A blind adversarial audit returned three 🔴 findings. All three are fixed in 1d14679, 6fa2f93 and 1b5f2ad. One of them requires a public correction rather than a silent body edit, because it is possible someone has already read and believed it.

The "after" digest quoted in the original PR body included this line:

  branch docs/configuration.md referenced by handoff no longer exists (merged & pruned?)

That statement is false. docs/configuration.md is a real 15,276-byte file in civitai-manager, backtick-quoted in that repo's handoff prose. It is not a branch and never was. extract_branches matched it because zach|feat|fix|docs|chore are branch prefixes and ordinary directory names, and \b matches after a slash.

So the PR as originally submitted removed one false green and introduced two fabricated facts — the second being zach/workspace/scratch/naida-ai, minted in naida-ai from the prose "local checkout /home/zach/workspace/scratch/naida-ai". That is 2 of the 6 new DRIFT lines those two repos produce. I cited one of them as evidence the fix worked, which is exactly the failure mode this PR is about.

The corrected digest for civitai-manager, measured after 1d14679:

  handoff: SESSION-HANDOFF.md
  branch feat/breadcrumbs: exists (origin/feat/breadcrumbs)
  branch feat/comfy-model-cache: GONE (deleted or never local)
  branch fix/copy-reduction: exists (origin/fix/copy-reduction)
DRIFT
  - branch feat/comfy-model-cache referenced by handoff no longer exists (merged & pruned?)

One genuine finding, no fabrications. naida-ai likewise keeps both of its real branches and loses the phantom.

The PR body has been updated as well, but this comment is the durable record.


The other two 🔴 findings

🔴-1 — the hermeticity tripwire was wired to nothing. run_resume() built env (stub PATH, STUB_LOG, git-config isolation) and then called subprocess.run without env=, so the subject inherited os.environ. test_no_network_tool_is_ever_invoked was asserting a structural zero. Verified in both directions with a gh call spliced into resolve(): green before the fix, red after (log shows one probe per run). The positive control I had added did not catch it because it execs the stub directly with env=env — a path the subject never took — so it validated the stub rather than the tripwire.

🔴-3 — the false green survived one layer up. With gh present and every gh pr view failing, || continue swallowed it with no diagnostic and DRIFT still said "(none detected — live state matches the handoff's claims)". The block now counts what actually answered, reports the ratio, and DRIFT degrades to "(nothing detected, but a source did not answer — NOT a clean bill of health)". No cause is attributed — gh exits non-zero for a genuine 404 and for an auth failure alike, so a classifier would be guessing. A handoff referencing no PRs is deliberately not downgraded, or the warning would fire on every non-GitHub repo and become noise.

A bug the new tests caught in my own fix

The first version of the DRIFT change ended a branch with [ … ] && printf, which returns 1 when the test is false — making the whole script exit 1 on every run that found drift with nothing unreconciled. Now a full if block; run_resume asserts rc 0 on all 46 runs.

Updated matrix — 20 mutations, all killed

Each verified to have landed (git diff --stat), to leave bash -n passing (so it broke behaviour, not parsing), and to fail with a real AssertionError in the expected test. Suite: 46 passed, ~2 s; no failure at HEAD that is not also at base 0294b82 (26 pre-existing environment failures, identical sets).

Four mutations initially came back wrong, and the split is worth recording:

cause
\b boundary restore my battery's bug — the replacement wrote a literal \\b; killed once corrected
if [ -n "$prs" ]true my expectation's bug — pointed at the wrong test; the guard is covered
never-record-unanswered-gh my battery's bug — left unbalanced quotes, so it was a parse error exercising no assertion
drop the file-extension filter a real gap — see below

The real gap: test_a_quoted_file_path_is_not_reported_as_a_branch was over-determined. Its fixture tracks docs/configuration.md, so the git cat-file probe rejects the token and the extension filter was never load-bearing — deleting it left all 44 tests green. Fixed by adding the discriminating case (a quoted path that does not exist in this repo, which handoffs routinely cite) rather than editing the real measured fixture away. Two mutations that had no test at all also gained one, including the gh-absent arm of the unreconciled logic.

Three 🟡 guards the audit flagged as existing-but-unpinned are now pinned — slug anchoring (its green was a case-mismatch coincidence; a lowercase decoy modelled on devrc's real browser-bridge-usage-audit-2026-08-02.md removes it), claudedocs/ scoping, and the gap-alongside-findings path. The case-sensitivity claim was removed from the comment rather than pinned: it is inert, since the fallback is only reached when the lowercase globs found nothing, so there is nothing left to poach. Being tried last is the only thing doing that work.

🟢 Docstring timing corrected to the measured ~3.2 s cold / ~2.0–2.9 s warm; it claimed "well under a second", which was never measured.

Still MERGEABLE / CLEAN against current main, which has moved to 481816f — no file overlap with this branch.

ZacxDev added 2 commits August 4, 2026 10:00
…pped (F3 regression)

Excluding `/` from extract_branches' leading boundary killed the path
fabrication — and also killed every reference that legitimately CARRIES a
slash-bearing prefix: origin/fix/x, upstream/feat/x, refs/heads/fix/x, and
GitHub /tree/ and /compare/ URLs. All five yielded a token under `\b` and none
under my change.

Measured across 211 real handoff docs, one live casualty:
`origin/zach/engaged-models-client-store` in datapacket-talos's
handoff-dp-prod-trpc-serialize-freeze-arc-2026-07-09.md:39. It is the ONLY form
that branch appears in and the branch is genuinely gone, so the pre-regression
DRIFT line was CORRECT and the regressed code was silently mute. Re-measured
here on the real file: base -> the token, my regression -> nothing, fix -> the
token.

That is the symmetric failure of the one this PR set out to fix, and in a
go/no-go tool the omission is the worse polarity, because silence reads as "no
drift" rather than announcing itself.

Fix: strip the ref-ish prefix BEFORE matching. Each stripped form is a strong
positive signal that what follows is a ref — precisely what a bare filesystem
path lacks — so `/home/zach/workspace/scratch/naida-ai` and
`docs/configuration.md` still yield nothing. Pinned together in one test, since
the two fixes pull in opposite directions.

Two 🟢s taken while here:
- The tracked-path probe ran BEFORE the branch-existence checks, so a token
  that was both a live branch and a tracked path was silently dropped. Now the
  probe is the third arm: a token must fail BOTH branch lookups before the path
  probe can rescue it from GONE, so the anti-fabrication guarantee is unchanged.
  0 such collisions across 2893 real branches — a latent wrong-drop, not a live
  bug.
- alerts_block's `[[ … ]] && DRIFT+=(…)` is now a full `if`. Same class as the
  exit-1 bug fixed in `main` last round; harmless here only because
  alerts_block is not `main`'s last statement, i.e. one reordering away from
  being real.
…er (F3/F2/F4)

55 cases.

F3 — test_the_word_boundary_behaviour_is_preserved was DOCUMENTED as guarding
against "silently dropping real branch references" and structurally could not
see the class that actually regressed: it exercises only `-` and `notafix/`.
Adds a parametrised sweep over all six slash-bearing ref spellings
(origin/, upstream/, refs/heads/, refs/remotes/origin/, /tree/, /compare/), each
asserting the EXACT extracted token; a combined test proving the prefix
stripping does not revive path fabrication; and one for the branch↔path
collision the probe reorder fixes. The old test keeps a note saying what it
does not cover.

F2 — the partial-answer branch was unreachable: the fixtures could only make gh
answer for all or none, so mutating `elif [ "$n_ok" -lt "$n_try" ]` to `-lt 0`
survived all 46 tests. The gh stub gains a selective mode ($STUB_GH_OK_PRS) and
the new test asserts the preconditions (two PRs reported, the third absent)
before asserting the "2 of 3" verdict — so a fixture that silently degrades to
all-or-none fails loudly instead of passing.

F4 — claude/commands/resume.md still described only the missing-handoff gate.
It now names both conditions that make an empty DRIFT meaningless, including
the `!` gap lines, says which single wording is an actual all-clear, and flags
that even that one is not yet airtight (the tracked follow-up).
ZacxDev added 2 commits August 4, 2026 13:15
…hat it pins

F1 — delete `|compare` from the URL pre-strip. All three of the audit's
mechanical claims reproduce:
  * UNPINNED — deleting it left all 55 tests green.
  * REDUNDANT — a compare URL's `main...feat/x` already matches without it,
    because the `.` in `main...` satisfies the grep boundary.
  * WORSE on a compare whose LEFT side carries a slash: stripping turned
    `…/compare/zach/a...zach/b` into the junk token `zach/a...zach/b`; not
    stripping yields `zach/b`, the head of the compare, which is the ref a
    reader means.

⚠ ONE PART OF THE FINDING DID NOT REPRODUCE, and it is the part that framed
this as urgent. The audit reported base -> `zach/b` vs HEAD -> `zach/a...zach/b`,
i.e. a fabrication this PR introduced. Measured end-to-end through the real
script with a handoff BOTH versions can resolve, base and dfcb800 are IDENTICAL:
both emit `branch zach/a...zach/b: GONE`. The junk token is PRE-EXISTING, not a
regression from this branch.

The first A/B I ran did show base printing nothing — because base cannot resolve
SESSION-HANDOFF.md at all, so it returned before the branch loop. That silence
means "no handoff loaded", not "no fabrication": an empty result cannot
distinguish the two mechanisms. Re-running with a handoff-*.md fixture is what
made the comparison valid. Recording it because the same trap is what the
fixture had to be rebuilt to avoid.

So this lands as an improvement over base rather than a regression fix, and the
`+` in `(refs/(heads|remotes)/)+` goes too — untested defensive complexity for a
doubled prefix nothing produces.

F2 — the ref table's third column now names WHICH prior version each row goes
red against, measured by replaying every spelling through all three (base / the
round-2 regression / dfcb800). The result is worth stating plainly: against the
PRE-PR base, every one of the first six rows is an INVARIANT — base's `\b`
already handled them all. What they actually pin is round 2's own regression.
The `compare/main...` row pins nothing at all against any version and is now
labelled that way instead of being counted as coverage. A meta-guard pins the
shape so the split cannot be quietly relabelled away.

F3 — the `origin|upstream` rule's leading bound was an unguarded tightening and
is now tested: it is what stops `/home/zach/repos/origin/fix/x` having its
`origin/` stripped and minting `fix/x`, which is the exact fabrication class
this function exists to prevent.

F4 — alerts_block carries a comment recording that NO test reaches it (the
hermetic fixtures have no prod-kubeconfig, so it always returns at the WL_NS
guard), so the suite's green is not read as covering the hygiene fix there.
The guard added one commit ago was VACUOUS, and the battery caught it:
mutating the bound to `s#(origin|upstream)/##g` left all 58 tests green.

Its fixture was `/home/zach/repos/origin/fix/x`, chosen from the rationale
rather than from measurement — and that shape cannot discriminate. Strip
`origin/` from it and the result is `/home/zach/repos/fix/x`, where `fix` is
still preceded by `/` and the grep boundary rejects it regardless. Both
spellings yield nothing.

Measured the loosened variant across five shapes to find one that does:

    /home/zach/repos/origin/fix/x  -> []        (identical — no signal)
    /var/log/my-origin/fix/x       -> [fix/x]   <- FABRICATED out of a path
    .origin/fix/x                  -> [fix/x]
    my-origin/fix/x                -> [fix/x]
    origin/fix/x                   -> [fix/x]   (correct in both)

The bound earns its place on a remote-like segment glued to a WORD inside a
path, not on a bare `/origin/`. Test and comment now both say that, and the
mutation is killed.

Accepted cost, now stated where it is made: a genuinely remote-qualified
`my-origin/fix/x` yields nothing. That is an omission and fabrication is the
worse direction, so the bound stays.
@ZacxDev

ZacxDev commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

Round-3 audit fixes — |compare deleted, ref table relabelled

Commits 7a48513 and d2e02d4. 26 mutations, all killed. 58 tests, ~2 s. No failure at HEAD that is not also at base 0294b82 (26 identical pre-existing environment failures; 1100 passed at HEAD).

🟡 F1 — |compare deleted

All three mechanical claims reproduced, so the token is gone:

  • Unpinned — deleting it left all 55 tests green.
  • Redundant — a compare URL's main...feat/x already matches without it; the . in main... satisfies the grep boundary.
  • Worse on a slashed left side — stripping turned …/compare/zach/a...zach/b into the junk token zach/a...zach/b; not stripping yields zach/b, the head of the compare, which is the ref a reader means.

⚠ One part of the finding did not reproduce — and it was the part that framed this as urgent

The audit reported this as a fabrication introduced by this PR:

base: branch zach/b: GONE
HEAD: branch zach/a...zach/b: GONE

Measured end-to-end through the real script, base and dfcb800 are identical — both emit branch zach/a...zach/b: GONE. The junk token is pre-existing, not a regression from this branch. Deleting |compare is therefore an improvement over base, not a regression fix. It still lands, on the unpinned + redundant + strictly-better grounds above.

Worth recording why the first A/B looked like it confirmed the audit: my initial fixture named the handoff SESSION-HANDOFF.md, which base cannot resolve at all — so base returned before the branch loop and printed nothing. That silence reads as "no fabrication" but means "no handoff loaded". An empty result cannot distinguish two mechanisms; re-running with a handoff-*.md fixture is what made the comparison valid.

🟢 F2 — the ref table now names which regression each row pins

Measured by replaying every spelling through all three prior versions, rather than asserted:

row base r2 (round-2 regression) r3 (dfcb800) pins
origin/fix/wanted same RED same r2
upstream/feat/wanted same RED same r2
refs/heads/fix/wanted same RED same r2
refs/remotes/origin/zach/wanted same RED same r2
…/tree/feat/wanted same RED same r2
…/compare/main...feat/wanted same same same nothing
…/compare/zach/a...zach/b RED same RED base + r3

Note the first column: against the pre-PR base, all six original rows are invariants — base's \b already handled every one. What they actually pin is round 2's own regression. Saying "regression coverage" without naming the reference point is how a table reads as more than it is. A meta-guard now pins the shape so the split cannot be quietly relabelled away.

🟢 F3 — and a vacuous guard the battery caught in my own fix

The origin|upstream leading bound is now tested. The first version of that test was vacuous and the battery caught it: mutating the bound left all 58 green, because the fixture I chose (/home/zach/repos/origin/fix/x) cannot discriminate — strip origin/ there and fix is still preceded by /, which the grep boundary rejects anyway. I had picked the fixture from the rationale instead of from measurement.

Measured five shapes with the bound loosened to find one that does:

/home/zach/repos/origin/fix/x  -> []        (identical — no signal)
/var/log/my-origin/fix/x       -> [fix/x]   <- FABRICATED out of a path
.origin/fix/x                  -> [fix/x]
my-origin/fix/x                -> [fix/x]
origin/fix/x                   -> [fix/x]   (correct in both)

The bound earns its place on a remote-like segment glued to a word inside a path, not on a bare /origin/. Accepted cost, now stated at the site: a genuinely remote-qualified my-origin/fix/x yields nothing — an omission, and fabrication is the worse direction.

The + in (refs/(heads|remotes)/)+ was also dropped as untested defensive complexity for a doubled prefix nothing produces.

🟢 F4 — alerts_block coverage gap recorded at the site

A comment there states that no test reaches the block (the hermetic fixtures have no prod-kubeconfig, so it always returns at the WL_NS guard), so the suite's green is not read as covering the hygiene fix. Verified by reading, not by a guard, and it says so.

Battery note

Two rows came back !! during this round and both were my battery's bugs, not surviving mutants: a stale mutation target after the sed changed (caught by the battery's own assert, not by a silent no-match), and an expectation still naming a test I had renamed. The mutation had in fact gone red with 2 assertion failures both times.

Real-document behaviour is unchanged by this round: datapacket-talos still yields zach/engaged-models-client-store, naida-ai its two real branches, civitai-manager its three — no fabrications in any.

@ZacxDev
ZacxDev merged commit f52427e into main Aug 4, 2026
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