fix(star): close the #66 wiring and mechanize the model-id collision - #81
Merged
Merged
Conversation
Three defects the audit named and the earlier PRs did not deliver, plus the last file with no mutation coverage. ENSURE-SKILL TOOK THE WRONG ROOT. The Arm section forbids inlining `$(git rev-parse --show-toplevel)` for `--session-root`, and fan-out step 3 then instructed exactly that substitution for `ensure-skill --repo`. The two resolve differently in precisely the case #66 is about: by fan-out the egress guard has pushed the primary into the repo that owns the doc, while the dispatched subagent inherits the SESSION cwd — so the skill bundle materializes into a repo the reviewer never sees and the round dies as a wait-bound timeout. Now takes the captured `<session-root>`, and the flag keeps its value on the same line so an agent copying the runnable line does not copy a bare flag. THE CAPTURE CAME TOO LATE. "Capture the session root FIRST" was the sixth Arm bullet; the egress guard that forces the directory change was the first. A primary executing bullets in order has already lost the original cwd by the time it reads the instruction, and `git rev-parse` then returns the doc's repo — the wrong value, silently. Ordering IS the guarantee, so the capture is now the first bullet and says why. THE COLLISION WAS DEFENDED BY PROSE. The self-response guard is parse-fatal by design, but it fires only once the colliding response is already written — and `_table` underlies `_structural_consistency`, so from that moment merge's pre-check, verify, gate-summary, round-stats and compose-review all fail too. The review is stuck in both directions: the primary cannot respond without tripping the guard, and cannot converge without responding. Recovery means hand-editing the doc or disclosing a false id. The trigger is a SUPPORTED configuration, not operator error: `fable` is a selectable session model, so a fable-powered primary discloses exactly the string its floor secondary does. New `check-primary-id <doc> <primary-model-id>` (exit 3 on collision) is run before the first response of a primary turn. It reads the RAISER's disclosure only — the `> — via` immediately after a `> [finding:` — never any `> — via` in the doc, because the primary's own responses carry one and matching those would refuse every round after the first. That case is asserted. Guards: six entries. Four for the above, and the first two for core.sh, which had none despite being the marker engine every other script parses through. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Nm3hNXA4WHbgKjFbxX7VUE
Three conflicts, all resolved by keeping both sides — the branches added independent test blocks and mutation entries, not competing edits. One needed care: the conflict boundary in multi-review-packaging.test.sh cut through this branch's #66 guard block, leaving its two closing `fi`s on the other side. Keeping both sides verbatim dropped them and the file stopped parsing. Restored, and every guard from BOTH branches verified to still fire — a merge that swallows a closing brace is exactly how a guard goes silent while the suite still looks plausible. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Nm3hNXA4WHbgKjFbxX7VUE
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.
TL;DR: Three things the audit found that the earlier PRs said they'd fix and didn't. Two are wiring bugs where the command tells the primary to do the exact thing another section of the same file forbids; the third replaces a prose warning with an actual check, for a failure that leaves a review permanently stuck.
Completes #66's wiring. Relates to #71/#47.
1.
ensure-skilltook the wrong rootThe Arm section forbids inlining
$(git rev-parse --show-toplevel)for--session-root, with a paragraph explaining why. Fan-out step 3 then instructed exactly that substitution forensure-skill --repo.They resolve differently in precisely the case #66 is about: by fan-out the egress guard has pushed the primary into the repo that owns the doc, while the dispatched subagent inherits the session cwd. So the skill bundle materializes into a repo the reviewer never sees, and the round dies as a wait-bound timeout whose reason describes the symptom.
Now takes the captured
<session-root>. The flag also keeps its value on the same line — it was wrapped such that an agent copying the runnable line would copy a bare--repo. My own guard caught that, which is a decent sign it's checking the right thing.2. The capture came after the thing that destroys it
Capture the session root FIRSTwas the sixth Arm bullet. The egress guard that forces the directory change was the first.A primary executing bullets in order has already lost the original cwd by the time it reads the instruction — and
git rev-parsethen returns the doc's repo, which is the wrong value, silently. Ordering is the guarantee here, so the capture is now the first bullet and says why.3. The collision deadlock was defended by prose
The self-response guard is parse-fatal by design, but it fires only once the colliding response is already written.
_tableunderlies_structural_consistency, so from that moment merge's pre-check,verify,gate-summary,round-statsandcompose-reviewall fail. The review is stuck in both directions: you can't respond without tripping the guard, and can't converge without responding. Recovery means hand-editing the doc or disclosing a false id.This is not operator error waiting to happen — it's a supported configuration.
fableis a selectable session model, so a fable-powered primary discloses exactly the string its floor secondary does. The only defense was one sentence of prose.New subcommand, run before the first response of a primary turn:
It reads the raiser's disclosure only — the
> — viaimmediately after a> [finding:— never just any> — viain the doc, because the primary's own responses carry one and matching those would refuse every round after the first. That case is explicitly asserted.Guards
command/ensure-skill-session-rootcommand/session-root-first-claimcommand/check-primary-id-gatestar/check-primary-id-raiser-onlyviainstead of the raiser'sAll four verified caught.
One is named for less than it sounds like. A single-line replace cannot actually reorder two bullets, so
session-root-first-claimcovers the claim's presence, not the order. The order itself is asserted by comparing line numbers, which only a real reordering exercises. Named for what it covers rather than what I'd like it to cover.core.shmutation coverage: attempted, withdrawn, recordedI tried to close the last zero-coverage file and could not do it honestly. Two blockers, both measured:
core.shis vendored into.agents/skills/multi-review/scripts/. Any mutation to the source makesmulti-review-reviewer-bundle.test.shfail first withbundled script missing/drifted— a real guard firing for an unrelated reason. Everycore.shmutation is therefore MISCREDITED: the gate goes red, but never via the assertion being claimed.multi-review-core.test.shstayed green with the duplicate-marker guard ((( n > 1 ))) mutated — so that line has no coverage in its own suite either, and themarker fails with duplicate markersassertion is satisfied by a different mechanism.Rather than credit either entry via the drift message — which is exactly the "credited by the wrong evidence" failure the runner exists to prevent — both are withdrawn and the reason is recorded in the table, the same way the #37 egress gap is. Fixing it needs the runner to mirror a mutation into the vendored copy (or exempt it), which is its own change.
Verification
scripts/*.test.sh(15 suites)multi-review-version-check.sh1.19.0 → 1.21.0 (ok)Minor version:
check-primary-idis a new subcommand.Not run locally:
shellcheck(not installed here); CI covers it plus the bash 3.2 leg and the full sweep.🤖 Generated with Claude Code
https://claude.ai/code/session_01Nm3hNXA4WHbgKjFbxX7VUE