refactor: complete the repo-wide tidy sweep (all 70 groups) - #3710
Conversation
…st count (G49) Exactly one line of production code changes. `_rlg_spool_dispatch` declared its two paths in a single `local` statement that repeated the parent path literally; it now declares `dir` first and derives `spool` from it. The rest is comments and test-side deduplication. - statusline-tee.test.sh: four copies of a find-and-count pipeline become one `count_spool_records` helper. - Four comments in statusline-tee.sh and one in bench.test.sh drop history narration for the present-tense mechanism, keeping every measurement. Removed narration, preserved here: ", which is exactly what this file did before"; "The unprobed fallback keeps a DIRECT call ... behaving exactly as it did."; "it was spending that process 29 times out of 30"; "a direct run is byte-for-byte what it was"; and "the old inline \"0.%03d\" printed 1000 ms as \"0.1000\"". Verified by an independent fresh-context refutation verifier, which built the wrong version to prove the right one: - The single `local` was safe ONLY because it repeated the literal path. The verifier constructed the tempting alternative, one `local` deriving spool from `$dir`, and ran a real render through it: bash does not expand a same-statement `local` assignment, so under this file's `set -u` it dies with "dir: unbound variable", empty stdout, exit 1. A total statusline outage. The split is the safe direction, and the old form was one refactor away from that failure. - Hot-path cost is unchanged, measured with strace rather than argued: execve, clone and openat counts are identical across three modes and both cold and primed renders, and the full syscall multiset matches. The primed render spawns two processes and touches two files, before and after. - 27 artifact comparisons (3 modes x 9 artifacts) are byte-identical, with every load-bearing artifact asserted non-empty so the comparison cannot pass vacuously. Pointed at the mutant, the same harness reported divergence on 8 artifacts, proving it discriminates. - The extracted test helper was mutation-tested three ways, including a plausible off-by-one; all four call sites still fail. The extraction did not weaken the suite. - Each rewritten comment's new claim was executed, not read: the user-scope fallback really does yield DISABLED from the settings file, the 29-of-30 drain arithmetic re-derives from the configured interval, `printf "0.%03d" 1000` really does print 0.1000, and a sourced run really does suppress main. One benign widening the verifier named that the worker did not: the extracted helper adds `2>/dev/null` to a call site that previously let find's stderr through on a missing directory. The count is 0 either way, the directory provably exists at that point, and the suite runner gates on exit code rather than stderr, so nothing observable changes. Two simplifications were considered and correctly REJECTED, and the verifier confirmed both, strengthening one: - Replacing the read-loop in lib-bench.sh's `median` with mapfile would break empty input: a herestring appends a newline, so unfiltered sort yields one empty element, the guard never fires, and the report line fails its `median=[0-9]+` regex. The existing unit test feeds a PIPE, which both forms answer 0, so this regression would have shipped past the suite and surfaced only in bench-load. - Collapsing `_rlg_absorb_jq_lines` to mapfile would break bash 3.2, which this file explicitly targets. The verifier forced the version gate and confirmed that path really does reach the function. Pre-existing bug recorded, not fixed here: bench-idle.sh aborts with a division by zero when given a zero argument, while its sibling bench-load.sh guards the identical expression and returns 0. Reproduced against a pristine origin/main. Two measurement cautions for anyone rechecking this: grepping strace output for the plugin name yields a spurious delta because the script's own path contains it, and affected-tests.sh prints its selection lines to stderr, so capturing with 2>/dev/null silently reports zero suites. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
Covers G49. check-changelog-parity.sh green in all four modes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
…alse comments (G09) - parse-briefing.js: `flattenInline` drops three branches the trailing `else if (n.children)` fallback already covered. `strong`, `emphasis` and `link` each did exactly `out += flattenInline(n.children)`, with no delimiters and no URL appended; `text` and `inlineCode` both did `out += n.value`. - emit-slides.js: `bucketKey` loses an exact-equality return that its own `startsWith` on the next line subsumes, and two tier loops use `Object.entries`/`Object.values` instead of `Object.keys` plus index lookup. - brand-overlay.js: a mutable schema object plus a follow-up mutation loop become one strict `z.object` built from two spreads, with the font keys hoisted beside the existing colour and logo lists. - paths.js: `envDir` reads and trims the variable once instead of twice, deliberately keeping `||` rather than `??`. Two comments deleted because the code contradicts them, preserved here: "HIGH split into chunks of <=5 with topical title; MED/LOW single slide w/ 2-col when >7" and "MED/LOW too dense even in 2-col -- split into multiple condensed slides". Both assert a two-column layout above seven items. The verifier read the sources independently: build-css.js gives `.news-list.compact` `flex-direction: column` with its own note that MED stays single-column for prominence over density, build-sections.js applies `compact` to every non-high tier with no count test anywhere, and the only 7 in the file is `balanceTiers`' demotion trigger. Two doc comments were corrected the same way: the real split caps are `MAX_HIGH = 5` and `MAX_MED = 14`, and `parseBulletParagraph` returns a `date` its signature omitted. Verified by an independent fresh-context refutation verifier: - `flattenInline` compared across 37 mdast node types plus deep nesting: zero divergences. The one difference found is unreachable and strictly safer -- `children` set to a falsy non-iterable made the old code throw where the new returns "" -- and remark never emits that shape. - The schema rebuild is identical in key set, KEY ORDER, per-key schema, strictness, and error message text across 29 theme and 6 overlay cases. The two spreads were confirmed disjoint, so later-wins cannot apply. - `bucketKey` was swept over 162 curated headings and 32,768 brute-forced strings; 35 curated cases actually reach the removed line. Zero divergences. - The `envDir` change was tested against a 13-case environment table WITH THE G08 BUG AS A NEGATIVE CONTROL: the `??` variant diverges on five inputs (empty, whitespace, tab/newline, single space, non-breaking space), while this rewrite diverges on none. The harness was proven able to catch the bug class before its clean result was accepted. - End-to-end, three CLI runs including one through a real brand overlay produce byte-identical decks (md5 match), with non-vacuity asserted at 26 slides and 69 bullets. The verifier CORRECTED two of the worker's own claims, both reporting errors rather than defects: - The font-key list is NOT netted, contrary to the worker's table. Dropping three of the four keys leaves the suite green, because the only relevant test asserts rejection and a strict schema still rejects a key removed from the shape. The same holds for ten of eleven colour keys. - `envDir` is partially netted: replacing it with a constant null does fail three tests, so the function is reached; only its blank-value semantics are uncovered. Newly documented gaps: the schema's strictness, both split caps, and `flattenInline`'s `break` arm are unnetted, and `emit-slides.js` has no test file at all. Of 20 mutants, the shipped suite killed 5. Findings recorded, all pre-existing and untouched: - parse-briefing.js crashes with a TypeError on a briefing containing no `##` heading, because an unset bucket index dereferences `children[-1]`. Reproduced on both trees; also fires on an empty file, an H1-only file and prose-only. - On url-policy.js the worker's reasoning holds, with a caveat the verifier added: only the RANGE clause of that guard is unreachable (0 hits across 40,000 brute-forced literals). Its sibling length check fired 9,581 times and is load-bearing, so the block must not be read as deletable. - `## Trends` is recognised then excluded, so its content is silently dropped either way. Confirmed end to end: zero occurrences in the emitted deck. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
Covers G09. check-changelog-parity.sh green in all four modes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
… (G20) `rank` and `unrank` in zone-crossing-inject.sh printed their result, so all three call sites paid a command-substitution subshell. They now set `REPLY` and the callers read it directly, removing three forks from a hook that fires once per tool batch. `unrank` is hoisted out of an `elif` condition into `next_armed`. Also: zone-gate.sh drops a `shopt -u nocasematch` that sat immediately before an unconditional `exit 0`; zone-gate.test.sh reshapes an array so its expansion is never empty; statusline-tee.sh renames an unused loop variable to `_` and drops the now-inert pragma that suppressed a finding for it; and comment passes across five files trade history narration for the present-tense mechanism. Removed narration is preserved in the file history; the measured facts it carried (the former six-process resolve budget, the per-shape zones.json reads, the dirname and jq-per-field counts) are restated as present-tense budgets that the trace assertions pin. Verified by an independent fresh-context refutation verifier, which went after the specific hazards this conversion introduces: - REPLY is a SHARED name: bash's bare `read` and `select` both write it. The verifier grepped the file and its full source closure and found zero bare reads, zero `select` compounds, and no other REPLY access. It then traced execution order: every `read` in the closure runs 117 lines before the first `rank`, and all three call/consume pairs are adjacent statements with nothing between them. No two REPLY values are ever live at once. - Command substitution strips trailing newlines while a variable does not, so byte identity was checked across 24 inputs including empty, whitespace-only, embedded newline and tab, and hostile values. All identical. - The `elif` hoist DOES add paths where `unrank` now runs and previously did not. The verifier found them (mkdir failure, zone-write failure), confirmed the added cost is one in-shell `case` and zero processes, and proved the result is unread on those paths across 576 fail-path cases. - Differential runs over 1,152 payload cases plus 144 telemetry cases compared stdout, stderr, exit code and both state files byte for byte: identical, with 588 cases emitting non-empty output so the comparison is not vacuous. Repeated under a locally built bash 4.3 as well as 5.2. - The fork saving was measured with strace, not asserted: 11 to 8 on the steady path and 24 to 21 on a crossing, with an identical exec census. Exactly three removed, none added. - Mutation testing killed 11 of 11, including the two hazards specific to this refactor: inserting a bare `read` between a call and its consumption, and shadowing REPLY with a `local`. Both fail loudly. - The bash-4.4 array claim was verified by BUILDING BASH 4.3.0 FROM SOURCE and reproducing the unbound-variable error in the test's exact shape. - The deleted `shopt` was confirmed dead: nothing in the repo sources this script, and `exit 0` on the next line ends the process before the setting could be observed. Findings recorded, none blocking: - REPLY has no `local` discipline, so the three call and consume pairs must stay adjacent. Today that is netted by the suite; a future edit inserting a bare `read` between them would corrupt the value silently. - The fork saving is invisible to this plugin's own trace budget test, which counts execs in command position and so could never have seen three subshell forks appear or disappear. - The array reshape is prophylactic rather than a live fix: every current call site passes a non-empty argument, and the unmodified test is green on bash 4.3. Two detector findings were deliberately kept as false positives, and the verifier agreed independently: one is dated provenance about an upstream document that no longer states a version floor, and the other describes runtime state within a single execution, not code history. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
`emit-findings.test.sh` had a case that routed a host skip through `pass()`,
contradicting the rule stated thirty lines above it in the same file: a skip
"never routes through pass(), so a proof this host could not run can never be
read off the summary as one that did". It now calls the file's own `skip()`.
The honest count on a root-uid host is 384 passes and 1 host skip, not 385
passes; 384 + 1 = 385, so no case vanished. The real assertion still runs
wherever `chmod a-w` actually bites.
Also in this group: `fingerprint.mjs` extracts `shingleAt` and `sharedCount` from
expressions duplicated across two functions each, and drops a `jaccard` guard the
surviving union check already covers; `extract-breadcrumbs.sh` drops a write-only
awk global; `extract-breadcrumbs.test.sh` drops a helper defined but never
called; `score-golden.sh` collapses a two-process jq pipeline into one; and
sixteen history-narration comments become present-tense hazard statements.
Removed narration is preserved in the file history. The hazards it carried
survive, including the one worth restating: two scripts sharing a rule means the
cross-script agreement their suites assert is blind to a defect they share, so
both suites pin the count itself and not just the agreement.
An independent fresh-context refutation verifier returned FAIL on one change,
which this commit fixes before landing. In `score-golden.sh`, replacing
`map(select(. == $id)) | length == 0` with `index($id) == null` looked equivalent
and is not: jq's `index` does SUBSTRING search on a string, where `map` iterates
and aborts. `cases_run` comes from a model-authored sidecar validated only as
"parses as JSON", so a string there is reachable. With `"cases_run": "c1-long"`,
the old form exits 5 with a type error while the new form exits 0 and scores case
`c1` as covered, because "c1" is a substring of "c1-long". That is a loud failure
turned silent, in a script whose header says it "refuses to guess". The verifier
supplied the fix, `any(. == $id) | not`, which reads as well and still aborts;
this commit carries it, confirmed against a table where it matches the old form
on every array case and reproduces the abort on a string.
The rest of the verifier's evidence:
- The other two jq changes are safe. The slurp rewrite keeps `split("\n")`, so it
still yields an array; 17 input shapes agree, including empty input, missing
trailing newline, embedded quotes, backslashes, CRLF and control characters.
The retained `. as $c` binding is necessary: without it, `.` inside `index(.)`
rebinds to the array being searched and no stray case is ever detected.
- The awk global removal is safe for a stronger reason than the comment gives:
old and new read RSTART and RLENGTH at the identical program point, so any awk
that clobbered them on `sub()` would break both equally. Confirmed byte-
identical over 1,201 files and 2,606 URLs plus an adversarial corpus.
- Both extractions were byte-identical at every call site, checked over 400
randomized trials plus boundary indices. The dropped `jaccard` guard returns
literal 0 for two empty sets, not NaN; measured with Object.is, not argued.
- Comment-only claims proved by stripping comments and diffing: zero executable
difference in the three files claimed. The detector goes from 16 findings to 0.
Coverage stated plainly: four of these changes landed with no test net (the awk
inline, the jq slurp, the jaccard guard, and the skip fix), and the verifier
confirmed each gap is pre-existing by reproducing it against HEAD. Their
substitutes are the differential runs above and a 385-case arithmetic check.
One worker claim was wrong and is corrected here: this diff carries 14 code-
bearing hunks across 6 files, not 5.
The whole-repo failure the worker could not name is resolved as foreign: two
suites fail, one pre-existing on main (typos-format) and one flaky only under
parallel jobs (work-items). All six provenance suites pass in the same run.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
…ead awk guard (G26) - glob-tools.sh: the per-pattern match count built a `mktemp`, appended to it, sorted it and removed it. It is now a direct pipeline into the same `LC_ALL=C sort -u`, removing a temp-file lifecycle per pattern. - lib/discover.sh: an awk guard that could never fire is removed, along with the state variable that existed only to feed it. Line 1 either exits or sets the flag and moves on, so the guard's condition is unreachable from line 2 onward. - detect.sh: two `trap ... EXIT` registrations where the second silently replaced the first are merged, two `BEGIN` blocks are combined, and `flush_section` collects its markers directly instead of building a comma string and splitting it back into an array to sort. - render-index.sh: five changes, the largest being a row array that was sorted up to three times per render and is now sorted once. - index-drift.sh: a two-branch `case` whose default arm was a bare no-op becomes an `if`, with the rationale kept as a lead-in comment. - Four test files adopt helpers that already existed in this plugin. Verified by an independent fresh-context refutation verifier, roughly 250 differential comparisons, zero divergences: - The removed `sort -u` scaffolding was the highest risk, because per-pattern and global deduplication produce different output. The verifier established the old temp file was created INSIDE the per-pattern block, so the scope was already per-pattern and cannot have changed. Confirmed across 88 micro-cases (including overlapping expansions, duplicate matches, match order differing from sort order, spaces, tabs, unicode and a 500-file set) and 52 fixture-repo runs, each under four locales. Both versions pin `LC_ALL=C`. The old code also leaked its temp file on an abort because it was never in the trap; the new code creates no temp file there at all. - The dead awk guard was instrumented in the ORIGINAL rule set and hit zero times across 20 input shapes: empty file, first line not the opener, opener with no closer, CRLF, CR-only, no trailing newline, BOM, and more. Output and exit status identical across all 20 and across all 1,389 tracked markdown files. - `flush_section` emits byte-identical markers across 15 fixtures. The new `norm_hits > 0` condition adds nothing and skips nothing, because the old build loop's body could not run when no marker was seen. The removal also fixes a latent bug: the old split-on-comma round trip would have shredded any marker containing a comma, which the marker vocabulary happens never to contain. Whole-repository proof: 25,689 lines, 2,203,663 bytes, byte-identical. - For `render-index.sh`, 80 render comparisons byte-identical, plus this repo's own generated index unchanged and still reporting IN-SYNC. The `grep -qF` to count substitution was checked at the case that diverges in principle, two markers on ONE line: a pre-existing guard exits before the counts can differ. The sort hoist was proved by instrumenting each of the three consumers to recompute the old sort at its own point and compare; zero mismatches. - The hot-path hook was traced: identical external-command counts, one builtin removed, 11 ms per run before and after. - Test helpers were mutation-tested. One survivor was proved pre-existing by applying the same mutation to the unmodified call sites, where it also survives: `git ls-files` reads the index, so the `git add` is load-bearing and the commit never was. The worker corrected an error in its own dispatch brief, and the verifier confirmed it: all seven scripts in this plugin have paired suites, not just one. That mattered, because my brief would have wrongly downgraded six files to propose-only for lack of a test net. Two pre-existing findings recorded, both reproduced by the verifier and untouched by this diff: - detect.sh runs two awk passes that DISAGREE on what a heading is, one capping at six hashes and one accepting any number. A file whose line 9 opens with seven hashes emits a hint keyed to line 9 while no section row declares a section there, so a consumer joining the two on the start line silently drops it. A second instance: a language mention before the first heading is keyed to section 0, which likewise never exists. - Two array expansions run unguarded under `set -u` on reachable paths where the array is legitimately empty, which errors on bash below 4.4. Not reproducible on this host's bash 5.2, and the verifier confirmed no compat level restores the old behavior. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
…enance 0.5.3 Covers the context-guard fork reduction (G20), the instruction-placement temp-file and dead-guard removals (G26), and the provenance skip-as-pass fix plus its jq membership correction (G48). check-changelog-parity.sh green in all four modes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
Simplifications, all proven behavior-identical by differential execution against the pre-edit copies: - export-sheet-frame-index.js: dropped the local 16-element CELLS array in favour of the CELL_IDS registry already imported elsewhere in the tree, and replaced the bare inputFiles[8] literal with a named MID_CELL_INDEX. The two cell lists were compared element by element and are identical at every index; the produced sheet-frame-index.json is byte-identical across cell counts of 2, 9, 16 and 20. - expand-visual-gaps.js: rewrote the accumulate-into-array loop as filter/map. regionMin carried no cross-iteration state despite the name, so the rewrite is a straight transliteration. Verified over 38 curated cases (both window boundaries, inverted and zero-width windows, duplicates, out-of-order input, NaN and Infinity, fractional and negative seconds) plus 20,000 fuzz iterations: zero mismatches. - repair-synthesis-promotions.js: extracted a promotedDecisions helper, shed two unused parameters from applyFileRenames, and hoisted the decisions write to the caller. The write remains the first statement executed inside the !dryRun branch, so it still precedes every rename. Confirmed by an instrumented op-trace over six sliceDir spellings and by crash injection at eight boundaries: the resulting trees are byte-identical in all eight. - rebuild-visual-frames.js: dropped a row field nothing reads. - list-promotion-candidates.js: named the per-session candidate floor. - Eighteen redundant trailing newlines removed across nine files. writeStdout and writeStderr append a newline unconditionally, so each one was emitting a blank line. Measured per CLI: every delta is exactly -1 per emission executed, exit codes unchanged, text identical once blank lines collapse. Adds expand-visual-gaps.test.js. The file previously mapped to zero test suites, which scripts/affected-tests.sh reports as an error rather than an empty selection; the no-suite allowlist is for prose and manifests and explicitly not for code. The new suite covers gap detection, boundary inclusivity, window order, the minute-rounded region label and the empty-window case. Mutation-tested: inverting the gap filter kills 4 of 5 cases, rounding to a floor kills 1, and making either window boundary exclusive kills 3 and 1 respectively. Verification: 72 test files / 514 tests pass; tsc --noEmit clean; affected-tests.sh --explain exits 0 over the whole group with no UNMAPPED file. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
worktree-add-claim-gate.sh (a live PostToolUse hook): - Removed the `notes` array. It was declared once and appended to twice, and nothing read it: the hook's only agent-visible output, `ctx`, is built from the `claimed_any` and `foreign_any` flags alone and names no target. With `notes` gone, `claim_err` and its `cat` fork were dead too. One fork fewer per claimed target. - Rewrote `if [[ ! -f "$CLAIM" ]]; then exit 0; fi` as `[[ -f "$CLAIM" ]] || exit 0`, matching the four guards directly above it. The file runs `set -uo pipefail` without `-e`, and the statement is top-level rather than the last of a function, so no exit status changes. Test suites: `pr-body-linkage-gate.test.sh` extracts `mk_payload`, replacing four spellings of the same two-line `jq -n` construction. `pr-linkage-mcp-gate.test.sh` drops a `dir` parameter that `run()` bound and never read, at all 26 call sites; every payload already carries its own `cwd`. `worktree-add-claim-gate.test.sh` extracts `wt_stanza` for a `worktree list --porcelain | awk -v RS=` pipeline written out 11 times, and `worktree-create-gate.test.sh` extracts `native_path` for a duplicated `cygpath -m` block. One `shfmt` conformance fix in the mcp-gate suite. Verification. A 20-case accept-and-refuse corpus drove pre-edit and post-edit mirrors of the gate over the accept and no-op set, the claim path, both `claim_rc == 4` branches, the combined claimed-and-foreign context line, the kill switch, the helper-missing branch the `[[ -f ]]` rewrite sits on, an empty session id, helper exits 5 and 2, and a `mktemp` failure. All four transcripts (two runs each side) hash identically at 443 lines, so the corpus is deterministic as well as equal. The corpus was then shown to discriminate, against four mutants of the edited gate: inverting the `[[ -f ]]` guard differs on 30 lines, deleting the stderr redirect on 5, dropping the `mktemp` failure `continue` on 1, and clearing `foreign_any` on 4. The stderr mutant is what proves the removed `cat` did not change where the helper's stderr lands. The 26 call-site edits were checked by recording every `run()` invocation in both mirrors: 26 calls each side, arity 4 to arity 3, and the surviving argument triple byte-identical at every site. Helper extractions were checked with a `jq` argv-logging shim (2052 and 44 invocations, all argv identical) and mutation-tested; `native_path`'s Windows branch was executed through a `cygpath` stub. The one surviving helper mutant was chased down and shown equivalent, not a coverage loss, by applying the same mutation to the pre-edit suite. All five affected suites green and unchanged: 146/0, 28/0, 24 cases, 37 cases, plus check-hook-wiring-liveness. shellcheck, shfmt, portability and em-dash gates clean; `affected-tests.sh --run` exit 0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
#3702 squash-merged, so the branch's earlier commits are already in main. Merging brings the branch onto the current base (the ci.yml collapse, the docs-only-gate rework and the check-rename-sweep removal) and clears the changelog-parity version collision that stacking on merged history produced. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
- actionlint-check.test.sh: three identical six-line fake-bin builder loops
become one `wrap_real_tools <dir> [extra-tool ...]`. Byte-identity was proven
at all three call sites, contents and file modes, including the site that
passes `rm` as an extra tool.
- ai-slop/detect.sh: dropped a redundant intermediate array copy. The old code
built `TARGETS` from `EXPANDED` and then re-read it; the new code sources one
`mapfile` directly from `EXPANDED`. The deleted line was a faithful copy
rather than a word-splitting step: the inner quotes in
`${EXPANDED[@]+"${EXPANDED[@]}"}` survive the unquoted outer expansion, which
was confirmed by probe against elements containing spaces and glob
metacharacters.
- ai-slop/emit-findings.sh: deleted a history-narration tail. The two retained
sentences state the whole contract, preference order and fail-open, and the
deleted sentence carried only the fact that today's behavior was once a bug's.
- ai-slop/detect.test.sh: T1 residue rewritten, and a stale count fixed. "all
14" had already drifted; the roster is 15, a number that survives three lines
above inside a test-enforced assertion string, so the wrong literal is
replaced by a phrase the loop below it makes exact.
- bash-format.test.sh: the second `REPO_IGN` fixture becomes `REPO_TRANSIENT`.
One identifier was carrying two unrelated repositories; pointing the renamed
site back at the original turns the suite red, which is what proves they were
distinct rather than deliberately shared.
- context-budget/measure.mjs: a ReDoS comment moves to present tense, a
`flagOnly` local is hoisted to a module-level `FLAG_ONLY`, and a `return null`
the code itself declared unreachable is deleted.
- context-budget/levers.test.sh: `report_clean` extracted; measure.test.sh gets
one shfmt conformance fix.
Verification. Both sides of the change were run, not just the new one. All five
affected suites match at HEAD and here, and the full assertion-name output of
each was diffed line for line, not just the counts: actionlint 45/0 (47 lines),
ai-slop 202 cases (204), bash-format 51/0 (54), levers 3/0 (5), measure 61/0
(63), every one identical.
The `mapfile` removal was compared across 11 input shapes (empty, single,
multi, spaces, globs, duplicates, tabs, backslashes, leading dash, empty-string
element, and a combination) and 11 end-to-end invocations against fixtures
chosen to actually fire rules, on bash 5.2 and again on bash 4.3.
`degrade()` was proven non-returning by execution rather than by reading: a
tripwire inserted immediately after the call never fired, and the counterfactual
that neuters `process.exit` shows the deleted line's only observable effect
lives on a path `degrade()` never takes. The `FLAG_ONLY` hoist was checked for
evaluation-timing equivalence across 13 argv shapes.
Helpers were mutation-tested: dropping a wrapped tool and wrapping into the
wrong directory both turn the suite red, as do inverting `report_clean`'s
comparison and breaking three levers. One mutation stayed green, which is
recorded rather than hidden: nothing asserts on `wrap_real_tools`' extra-tool
argument. That gap is inherited, not introduced, and is closed here by direct
byte comparison instead.
Two pattern-boundary defects in ai-slop's own rules were found and deliberately
NOT fixed, because the detector is the instrument this sweep is measured with
and changing what it matches mid-run makes earlier and later groups
incomparable. Recording them so they are not lost:
- `challenges (remain|ahead|persist)` has no word boundary on either side. It
fires on "challenges remained", "challenges remainder", "challenges
remaining", "challenges persisted", "challenges persistence", "challenges
aheadroom", and on "subchallenges remain". It does NOT fire on
"challenges-adjacent", which the pattern cannot match.
- `not (just|only|simply|merely) [^.]{0,80}but` fires on any following word
beginning "but": "button", "buttress", "butterfly", "rebuttal".
affected-tests.sh --run exit 0 over 21 suites; shellcheck, shfmt, node --check,
portability, silent-skip and discriminating-skip gates all clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
…dget 0.6.20 Covers the G65 tidyings. The ai-slop entry also records, under Known issues, the two rule patterns whose missing word boundaries make them fire on unrelated words. Those are left unfixed on purpose: the detector is the instrument this sweep is measured with, and changing what it matches mid-run would make earlier and later groups incomparable. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
- dead-code-scan.sh: removed the `SCOPE` array, genuine dead code inside the dead-code scanner. It was declared once and appended to once, with zero reads anywhere in the repository. That claim needed care because this file drives five namerefs, so "write-only" is exactly what a dynamic binding could falsify; every `local -n` was enumerated and every call site passes a string literal (`roots`, `root_nested`, `TS_FILES`, `GO_FILES`, `mod_files`). The script is never sourced and `SCOPE` was never exported, so no child could read it either. - dead-code-scan.sh: declared the four `read` loop variables `local` in `lane_vulture`, `lane_gopls` and `lane_knip`. Only `lane_grep` already did this; leaving one lane out would have made three of four consistent and one not. None of the twelve names is read outside its own lane body, and no lane recurses or runs in a subshell that relied on the leak. - open-pr-count.sh: dropped the `-z "$count" ||` arm. An empty string cannot match `^[0-9]+$`, so the empty case already routed to `emit_unknown`; the only side effect the short-circuit suppressed was `BASH_REMATCH`, which nothing reads before exit. - changed-code-files.test.sh: added `assert_equal` and moved two line-count comparisons onto it. Both were calling `assert_exit`, so a real failure printed "expected: exit 1 / actual: exit 3" for a count. Same predicate, accurate diagnostic. - detect.test.sh: replaced an unresolvable version back-reference. The note read "stays as 0.13.3 wrote it"; the constraint it guards is unchanged and the sanctioned `(#3126)` citation two lines above already anchors the work. Verification. A 76-invocation differential over pre-edit and post-edit mirrors, covering every lane targeted and whole-repo, every usage-error path, the degraded, drift, empty-output, parse-error and CRLF cases per lane, foreign-nested-module dropping, non-git and subdir working directories, and three runs against the real repository: zero divergences in stdout, stderr and exit code. That corpus was then proven able to fail, against nine mutations. The decisive one re-introduced a real read of `${#SCOPE[@]}` into the pre-edit mirror and diverged on 54 of 76 cases, which is what establishes the array was write-only rather than merely untested. Swapping `read` field order in the vulture and gopls lanes diverged on 23 and 7; making the newly-local variables readonly diverged on 30, confirming the corpus reaches the changed lines. The `-z` removal was checked over 41 self-built invocations covering empty output, a lone newline, CRLF, a lone CR, space, tab, whitespace-only, leading zeros, negatives, floats, JSON, three nonzero exits and gh absent from PATH. Mutating the guard diverged on 30 of them. Both migrated assertions were mutation-tested independently and go red with the corrected message. The plugin's own suites are unchanged on both sides: 162, 53, 11, 9 and 12 checks. affected-tests.sh --run exit 0 over 20 suites, with each file also explained individually and none unmapped. The audit-comment-residue detector and its shape library are deliberately untouched and were confirmed hash-identical to HEAD. They are the instrument this sweep is measured with; changing what they match mid-run would make earlier and later groups incomparable. One defect in them is recorded rather than fixed: `see[[:space:]](pr|mr|issue)` has no word boundary on either side, so it fires on "see PROJECT", "see MRI" and "see PRESENT", and the same missing anchor makes `pr[[:space:]]#?[0-9]` fire inside "expr 3", `issue` inside "reissue 4" and "tissue-2", and `linear` inside "linear-1". This is the third sighting of that defect class in the run, across two independently owned detector libraries. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
- audit-encapsulation/detect.sh: extracted `resolves_into_self()` from two
branches that had spelled the same relative-cite resolution twice. The two
bodies differ by no code token at all once the one prefix is substituted;
only their comments differed. The absolute-cite tests were deliberately NOT
pulled into the helper: the `.claude/skills` branch uses a plain substring
match and the `plugins/*/skills` branch a root-anchored one, so they answer
differently for a string like `xR/skills/S/`, and that difference is kept.
Also dropped two `[[ -s ]]` guards whose files are re-created by a redirect
on the line immediately above each loop, a dead `rel` alias, and hoisted the
self-prefix to a quoted variable at both sites.
- audit-noise: extracted `no_targets()` for a two-site status contract and
`count_negations()` for a pipeline written out eight times; simplified
`resolve_existing_path`. emit-findings.sh is comment-only: an escaping note
moved to sit above the function it describes.
- compress: dropped a `${path_hits:-0}` default that could never apply, since
`wc -l` prints a count on every path including a failed grep; moved the
caveman suite's stub directory into `mktemp -d` so a run leaves nothing in
the plugin tree.
Fixed a real bug in two suites. Both registered fixture directories in a bash
array, but the constructor runs inside a command substitution, so the append
happened in a subshell and never reached the trap. The ledger cleaned up
nothing. Measured with an isolated TMPDIR: audit-encapsulation leaked 27
directories per run and audit-progressive-disclosure 6. Both now leak zero,
and a forced-red run leaks zero where HEAD leaked 27.
The ledger is a file, and its records are NUL-delimited rather than
newline-delimited. With newline-delimited records a newline inside TMPDIR
splits one path across two records and the trap removes the truncated prefix,
which is a directory outside the fixture set. Probed directly: the prefix
directory survives now and was deleted before the change.
Verification. Both detector revisions were run over the same pristine tree
(3,523 files, 1,300 markdown) rather than over their own working copies, which
removes the self-scan confound: output is byte-identical across ten
invocations, including 887 raw hits, 717 filtered rows, 38,067 lines of
audit-noise output and 845KB of emit-findings output.
The extracted predicate was compared against the two original inline bodies
over 20 cite texts by 7 source-line prefixes by 2 roots plus missing-line and
missing-file probes: 284 checks, zero mismatches, with 5 of 6 injected mutants
killed and the survivor shown to be a genuinely equivalent mutant. The seven
`write_block` call sites were reproduced by executing each original block and
comparing with `cmp`: all seven byte-identical, including the one where a
`\|` moved from a printf format string to a `%s` argument. emit-findings.sh
was checked by numbering its non-comment lines and hashing them, which proves
no awk source line moved relative to another.
Fixture isolation is pinned rather than assumed: a mutation that makes two
cases share one fixture directory is killed by the suite at both revisions.
All nine suites unchanged on both sides: 11, 77, 201, 35, 38, 6, 14, 17 and
the pairing suite. affected-tests.sh --run exit 0 over 19 suites, with every
file also explained individually and none unmapped.
Three defects found in the detectors and left unfixed, since these are the
instruments this sweep is measured with. `from the feature branch` in
noise-shapes.sh terminates on a bare word where every sibling alternative ends
on a digit class, so it fires on "feature branching", "feature branches" and
"feature branchless": four findings where one is intended. Five
`for (k in declined_*)` loops iterate awk associative arrays, whose order
POSIX leaves unspecified, over a parsed contract surface; only one awk exists
on this machine so no order flip could be exhibited, and it is recorded as
latent rather than observed. And one awk program uses `\x27` a few lines after
a comment stating that `\x` escapes are not portable across awks.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
The `lint` job's editorconfig check failed on this file, the only failure in a 54-check roster. `.editorconfig` sets `indent_style = space` for every file type, and the JS section overrides only `indent_size`; the checker config disables IndentSize and MaxLineLength but not indent style. The file was tab-indented because I formatted it by running biome from the repository root. The only biome.json in the tree is under plugins/miro, so a root invocation falls back to biome's own defaults, and biome defaults to tab indentation. Every sibling suite in this directory is space-indented. Verified with editorconfig-checker 3.4.0 against the repo's own .editorconfig-checker.json: exit 0 on this file, and exit 0 across all 62 files this branch changes. The suite still passes 5 of 5 in isolation and tsc --noEmit is clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
Twenty-two files reviewed in full; two changed. No gate script was modified, confirmed by hashing all 52 tracked files under plugins/guardrails against HEAD: exactly two differ, and both are suites. - block-noncanonical-commit.test.sh: replaced a three-line inline copy of the shared `report` helper with a call to it. This was the only one of the plugin's 17 hook suites not using the helper it already sources. - require-jq-notice-isolation.test.sh: removed a `fired_count=0` pre-initialisation that is unconditionally overwritten eleven lines later by a `grep -c` capture with no read in between. Verification. The terminal check changed form from `((FAIL == 0))` to `[[ $FAIL -eq 0 ]]`, so the two were compared by execution across 14 inputs under the file's real `set -uo pipefail`: 0, 1, 2, unset, empty, a non-numeric string, `08`, `007`, both integer extremes, `0x10`, a spaced value, `1+1` and `-1`. Exit codes are identical in every case. The leading-zero input is not a divergence: both forms emit the same base error and both return 1. The suite's ability to fail was then proven rather than assumed, under two independent mutation classes. Injecting a failing assertion turns both revisions red with the same counts. Weakening the gate itself, so it exits 0 where it should exit 2, flips eight corpus verdicts and turns both revisions red. The helper reads the same `PASS` and `FAIL` counters the suite increments, so the permanently-green failure mode does not apply; the live run reports 213 and 0, matching the previous wording exactly. A 48-case accept-and-refuse corpus over pre-edit and post-edit mirrors, driving the real dispatch across three hook lanes, diffs to zero: 31 accepts and 17 refusals, covering every distinct refusal branch, eight near-miss strings that must stay green, empty and malformed JSON, four kill-switch paths, and the dependency-missing case. Two gate weakenings confirm the corpus discriminates. Both suites produce byte-identical output on either side apart from the one summary line, across all 214 preceding assertion lines. All 17 guardrails hook suites pass. `grep` over scripts/ and .github/ confirms nothing parses the summary text, and the new wording matches the repo-wide harness format. Zero comments were deleted anywhere in the group; the diff removes one code token and three echo lines. The remaining twenty files were left alone deliberately. Every apparent redundancy in them is documented in-file as intentional: fail-closed belts, sibling guards held divergent on purpose, and generalizations with stated intent. Three near-identical `effective_dir` implementations in particular carry docblocks saying the duplication exists so the sibling guards answer alike, and naming where one copy must NOT reproduce another's behavior. One residual risk is recorded rather than hidden. This change removes the plugin's last suite-local terminal check, so a broken shared helper combined with a weakened gate would now leave 0 of 17 suites red where 1 previously stayed red. That protection was accidental rather than designed, it was already absent for the other 16 suites, and both single-fault mutation classes above still fail loudly. The mitigation is a self-test of the helper, which belongs in a file outside this group's scope and is routed to the group that owns it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
Twenty-two files reviewed in full; two changed, both one-line import cleanups.
- overlap.py: `Path(os.getcwd())` became `Path.cwd()`, and the now-unused
`import os` was dropped.
- test_install_state.py: dropped a `from contextlib import redirect_stdout` and
qualified its single call site, matching the same-plugin sibling suite. The
module import it needs was already present, ten lines above the call.
Verification. The dropped import is the risky half, so it was proven rather
than grepped: an AST scan over the pre-edit file covering Name and Attribute
nodes, every import form including aliases, Global/Nonlocal, `del`, and every
string constant found exactly two references, the import and the one call.
There is no `__import__`, `importlib`, `eval`, `exec`, `globals()`,
`sys.modules`, `getattr` or `__all__` anywhere in the file, so no dynamic path
could reach the name, and no module imports anything from this one but its own
suite. The repo's pinned ruff selects F, so F401 and F821 are both live; probes
confirmed each fires, which means the removed import and the removed use
balance exactly.
`Path.cwd()` is not merely equivalent here, it is the same expression: CPython
3.11's pathlib defines `cwd` as `cls(os.getcwd())`, and the file pins a 3.11
minimum. Seven probes agree on value, equality, type, string round-trip and
parts, including a symlinked working directory, a 1190-character path, a
directory deleted out from under the process (identical FileNotFoundError), and
paths with spaces, newlines and unicode.
A 496-pair differential compared both revisions across four repository shapes,
seven working directories (including two symlinked ones and one outside the
repo), all three subcommands, every flag, both write paths and the whole
argparse surface, comparing exit code, stdout, stderr and a hash of the
resulting file tree: zero divergences. Eleven mutants establish the corpus
bites, killing `.parent`, `Path(".")`, `Path.home()`, a trailing-separator
variant, a PWD-based spelling that is symlink-sensitive, and a relative-path
spelling, at up to 316 divergences each. Two mutants survived and both are
meant to: a `.rstrip('/')` that `.resolve()` absorbs, and the control that
re-injects the original expression, which is the equivalence claim confirmed
from the other direction.
The changed test line was proven to execute rather than assumed: a line-level
trace ties it to three named tests, with eight executions across the suite.
All six Python suites are unchanged at 10, 50, 77, 45, 96 and 31, and their
full verbose test-name output is identical on both sides.
Two things this group deliberately did not touch. `lib/spawn_noise.py` is a
registered sync-cluster canonical whose carried copy in the performance plugin
must stay byte-identical, so any edit at all, including a comment, would need a
fleet sync and a second plugin's version bump; `sync-spawn-noise.sh --check`
and `--check-bump` both pass, and the canonical and its copy hash equal. And
`known-issues/scripts/registry_manager.py` maps to zero test suites, which
`affected-tests.sh` reports as an error rather than an empty selection, so the
worker stopped instead of changing it. That file is byte-identical to the
previous revision and is correctly absent from the no-suite allowlist, which
covers prose and manifests rather than code.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
- restart-consumer.sh: four within-file extractions. `telemetry_fully_fixtured` replaces one predicate spelled two different ways in `require_gh` and `resolve_target_repo`, which must never disagree about whether a run touches the forge. `remove_lock_dir` replaces an `rm -f` of three lock files plus an `rmdir`, duplicated in `release_lock` and the `acquire_lock` reclaim path. `lock_uint_file` backs `lock_stamp` and `lock_owner_pid`, which were identical but for the filename. `print_report_header` replaces three `info` lines duplicated between the lock-skipped tick and a full run. - telemetry-upsert.sh: `require_value "$@"` replaces five copy-pasted argc guards. Deliberately argc-based rather than emptiness-based, so `--marker ""` still fails on the marker regex rather than on "requires a value". - machine-behavior.sh: renamed a top-level loop variable whose old name implied a `local` it could not have. - lane-launcher.sh: comment only, proven by diffing the files with comment lines stripped. A migration narration becomes present tense, which is the more accurate tense: the pre-move layout is not history but a live path `resolve_config` still reads under a deprecation warning, and the sentence above it still records which layout superseded which. Verification. A 73-case differential over pre-edit and post-edit copies of restart-consumer, comparing stdout, stderr, exit code, the lock file tree, the ledger tree and contents, and the launcher argv log: zero divergences. Coverage includes every refusal branch, six breaker states, fifteen lock paths including stale reclaim, a reused pid across boots and the hard ceiling, five unusable store shapes, and both call sites of the merged predicate. Seven mutants confirm it discriminates, at up to 47 divergences. The merged predicate was checked against both original spellings over a 47-row truth table: they agree on every row, and across the whole reachable domain all three forms agree. Four rows diverge only for values of two flags that the script itself can never produce, since both are initialised to 0 and set only to 1 by argument parsing, with no eval, nameref or environment read anywhere. The two lock-directory removal sites were shown identical modulo indentation, and a three-way harness over 14 filesystem states plus four unprivileged permission cases found no difference in caller-visible status or resulting tree. `lock_uint_file` was compared against both originals over 50 inputs including missing, empty, whitespace, CRLF, leading-zero, negative, float, huge, directory, dangling-symlink and unreadable cases: zero divergences. The argc guard was verified at all five sites over 39 whole-script invocations with exit codes and messages preserved exactly, including the case that motivated the design: `--marker ""` still reaches the marker regex. A mutant that switches to an emptiness check diverges there, which is what proves the distinction is load-bearing. Suites are unchanged on both sides of the change: 213, 26, 24, 153 and 91. Three of the worker's own claims were corrected before this message was written rather than repeated. It reported that the two merged lock readers had already drifted, one initialising its fallback to an empty string and the other to zero; both in fact initialise to an empty string, and the functions were identical modulo variable and file name. It reported six argc guards; there are five. And it counted a sixth suite that `affected-tests.sh` does not select for these files. One residual difference is disclosed rather than normalised away. With line numbers left unmasked, four of the 73 cases differ only in the line number bash prints in its own redirection diagnostics, two of them inside functions this change never touches. The message text, the path named, the value returned and the exit code are identical, and the suite case asserting that such diagnostics never leak into the report passes on both sides. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
Fourteen files reviewed in full; one changed. The low-fd case ran `batch_read_lines_into` inside a `bash -c` subshell that declares its own `LINES` and asserts on the subshell's stdout, so the outer `LINES=()` was never read. It mimicked the sibling cases that do assert on the outer array, which made it look load-bearing. A comment now records why this case is the exception. Verification. Every reference to the array in the file was enumerated in line order: eight callers each reset immediately before their own call, twelve reads all sit before the deleted line, and the three references after it are inside a single-quoted `bash -c` string, so they belong to a child process. `bash -c` is a separate process and the name is exported nowhere, confirmed by probe. The reset is load-bearing for the other callers because the read function appends rather than assigns, which is why only this one case could lose it. The cross-case leakage risk was tested adversarially rather than argued: with a stale three-element array injected immediately before the case, so that the edited file reaches it populated where the original would have wiped it, output is identical on both sides. The skipped case was also forced down its non-skip branch, and both revisions behave identically there too. Five mutants of the library under test, including a restoration of the original file-descriptor defect this case exists to guard, fail identically at both revisions with the same assertion sets. No mutant survives here while dying before the change, so nothing the suite could previously catch has been lost. The suite is unchanged at 28 passed, 1 skipped, 0 failed, with byte-identical assertion output. The skip is a permission case that cannot be enforced when the runner is root. All thirteen other files in the group hash-identical to the previous revision, including every destructive and selection script. One deferral is worth recording because it was proven rather than asserted. Merging `manifest_child_token` and `tier_repo_token` in `clean-batch.sh` looks like an obvious two-function dedup, and the in-file comment saying they must stay distinct is correct: with them merged, a plan built for the build tier is authorized under `--tier git` and applies, printing `Tier: git` while removing build output that tier never gated. Reproduced end to end. The repository's own suite does not catch it, because no case feeds a build record to `--tier git`, which is the only input where the two functions differ. That is a pre-existing coverage gap, recorded here and left for a group that owns the file. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
…tidyings Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
- dedupe-synthesis-dir.js: unexported an internal-only `hashFile`. Two references exist repo-wide, both inside the file. The module has no barrel, no namespace importer, no dynamic import, no string-key access, and its package is private with neither a `main` nor an `exports` field, so nothing outside could reach it. Confirmed by loading the module both ways: the namespace goes from two keys to one, and both real importers take only `dedupeSynthesisDir`. - merge-triage-json.js: `?? 16` became `?? CELL_IDS.length`, with `CELL_IDS` added to the import specifier that module was already using. This is tighter than the literal, since the validator it feeds slices the registry by that number, so the fallback now means "the whole registry" rather than "a number that happens to equal it". - Eight redundant trailing newlines across four files. The shared emit helpers append a newline unconditionally, so each explicit one was emitting a blank line. Two of the files were internally inconsistent: the other call in the same block already omitted it. Removing those newlines left four call sites wrapping a single expression in a template literal that no longer did anything, so they were reduced to a bare argument, matching the two established precedents in this directory. That reduction is not cosmetic and was verified rather than assumed: the emit helper is not a plain string conversion, it formats an Error as its stack and an object as JSON, so a bare argument and a template differ for anything but a string. All four wrapped expressions are strings, proven by execution, with every throw source of the one ternary enumerated: hand-thrown Error, JSON syntax error and filesystem ENOENT all yield a string message. The one template still doing work was left alone. Verification. A 17-scenario differential over pre-edit and post-edit copies of the file that deletes files, comparing kept lists, removed lists and on-disk survivors: zero divergences. The corpus carries the near-miss keeps as well as the deletions, including singletons, similar names with different bytes, duplicate non-image files, a case-variant pair and an empty and a missing directory. Four seeded defects are caught at two to eight scenarios each, and two equivalence controls score zero, so the corpus discriminates without being merely hypersensitive. The changed fallback is covered by no existing test, so it was driven deliberately with a purpose-built probe rather than left unverified: ten cases, five of which take the fallback, with identical manifest bytes, hashes and thrown message text on both sides. Every affected command was spawned on both sides: exactly one byte less per emission, exit codes unchanged, text identical once the blank line collapses, and every on-disk artifact byte-identical through the production orchestrator. No consumer parses these streams; the one caller that spawns them inherits stdio without capturing. Suites unchanged at 72 files and 514 tests with identical test-name output, and `tsc --noEmit` clean on both sides. Two findings on the deletion path were confirmed and deliberately not fixed, both outside this group's files. `synthesisNameQualityScore` is not a total order, so duplicates that tie are resolved by directory iteration order; forcing both orders deletes opposite files, which makes it latent data-loss nondeterminism rather than a stylistic wrinkle. And two files disagree by one cell about which cell is a sheet's midpoint, one hardcoding it and the other computing it. Twelve further sites in this directory still pass a redundant newline; they belong to files outside this group and are left for whoever owns them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
Twenty-two files reviewed in full; two changed, both comment work. - go-format.sh: two disclosure-take comments move from past to present tense, at the syntax-error arm and the tool-break arm. This file is a live PostToolUse formatter and was frozen for behavior changes for this sweep, so comment-only was proven mechanically rather than asserted: two independent comment strippers, one using shfmt's own bash parser and one a quote- and heredoc-aware parser, both produce byte-identical code from either revision. Each stripper was itself shown sensitive by three seeded code mutations, including one that only changes quoting form. Every changed line classifies as a comment, and the tracker citations survive verbatim. - eol-normalizer.test.sh: a history-narration paragraph above the banned-process list becomes a present-tense statement of why each named process must not appear. That second file also carries one change nobody asked for, disclosed rather than hidden. Editing it fired this repo's own bash-format PostToolUse hook, which ran shfmt over the whole file and expanded a one-liner into its multi-line form. The file was non-conforming before and is conforming now. It cannot be reverted with the tools a worker is permitted: the only revert path is a git restore, which would also destroy the intentional comment fix, and any Edit re-fires the hook. Confirmed by firing the real hook against a scratch copy and watching it rewrite the same line. The expansion is inert, which matters because it wraps an `eval` inside a command substitution. A 25-probe differential ran the original one-liner against the reformatted block over empty, comment-only, blank-line, trailing-newline and line-continuation bodies, a body writing to stdout, one returning non-zero, one calling exit, one unsetting a variable under `set -u`, and inputs with trailing slashes, tabs, spaces and UTF-8. Zero divergences in captured value, exit status, and the outer variables after the substitution, which were poisoned beforehand to prove nothing leaks out of the subshell. The whole file also minifies to byte-identical output, so every remaining difference is comment text or layout. Verification. A 23-case differential over pre-edit and post-edit copies of the formatter compared seven channels per case: both streams, exit code, a hash of every fixture file afterwards, the argv and working directory the tool was invoked with, files left in an isolated temporary directory, and the telemetry envelope. 161 artifacts, zero divergences. Ten seeded mutants were all caught. Two of them matter especially: the mutants that delete each disclosure take are caught by exactly one case each, the fixtures where the tool writes the file and then fails. Without a write-before-failure case those arms are unobservable, so the arms whose comments changed here are genuinely covered rather than nominally so. Both suites pass identically on either side, 51 and 54 assertions. Three findings outside this group's files, recorded rather than fixed. The go-format suite silently no-ops when its tool is absent from PATH, and `affected-tests.sh --run` reports a suite that printed only a skip line as passing, so the gate cannot distinguish 54 assertions passing from none running. A shared discovery suite has a load-dependent false failure: two pipelines under `set -uo pipefail` let a grep close the pipe, the producer dies of SIGPIPE, and `pipefail` promotes 141, so a present field reports as missing; measured here at zero spurious in 1500 idle runs and 47 in 1200 under load, every one status 141. And the selector's own false-coverage direction is live: three files are selected only by basename collisions that never test them, so the gate exits 0 over zero real coverage. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
Eight files reviewed; one changed. guardrails 0.31.4 -> 0.31.5. The suite for the pre-commit content-invariants hook carried a GitHub-PAT-shaped token at line 74 and an OpenAI-shaped one at line 98 as contiguous literals in its own source bytes. So `secrets::scan_text` returned rc=1 on the file that tests the scanner, naming both by line; the hook would refuse a commit staging its own test file; and the Write-time guard blocked edits to it. Scanning every tracked file against all twelve patterns in SECRET_PATTERNS found these two hits and no others in the repository. Both fixtures now assemble at runtime, the discipline the sibling secret-pattern-detection suite already documents and uses. Verification. The load-bearing claim is that the assembled values are the same bytes, and it was checked as bytes rather than read: the assembly was executed in isolation under set -euo pipefail, none of which the suite itself sets, and the results compared with cmp against the literals extracted from HEAD. 40 bytes and 23 bytes, identical. Suite stdout and stderr are byte-identical on both sides, from mirrored trees, with no normalisation needed because the suite emits no timestamps and no absolute paths. Seven mutations were run against both versions with identical scores. Two make the gate wrongly allow (deleting the PAT pattern, blanking the Linux home-path body): two assertions fail each. Three make it wrongly refuse (deleting the .env.example allowlist arm, deleting the tests/fixtures arm, and making the hook fall back to reading the worktree): one assertion fails each. The .env.example flip is what proves the fixture is not vacuous, because a fixture that had stopped matching would let that mutant pass. Two equivalence controls, an internal local rename and a swap of two adjacent allowlist arms, both score ZERO, so the corpus discriminates rather than firing on everything. Five claims corrected rather than carried forward. CI does scan for secrets. The gitleaks lane runs un-gated on every diff. It was established empirically why it missed this: running gitleaks with this repo's own config over the pre-fix bytes reports no leaks, while the same config over a high-entropy PAT reports one. The default github-pat rule carries an entropy floor that thirty-six identical characters falls under, and the default OpenAI rule needs more than a bare prefix plus twenty. This repo's own scanner has no entropy floor, which is why only it fired. An `ok:` count equal to a PASS count proves nothing about vacuous assertions. The shared helper prints and increments in one unconditional body, so the two counters cannot disagree; the identity is tautological. The mutation corpus is the evidence. `check-purged-em-dashes.sh` does not cover this file. Its positive list carries zero guardrails entries; it is a list of prose surfaces. Citing its pass for a shell file is a non-sequitur. The added lines were grepped directly instead. The allowlist arm count of eight describes the secret predicate only, and spans twenty globs; the path predicate has seven arms and sixteen globs. Both were sourced in isolation and both return 1 for this file's path in three spellings. The comment-residue count of one is scope-dependent and the scope was not named. The changed file alone scores zero on both sides. The one finding sits in a different file, and it is a false positive: `git log -L` shows the comment and the expression it describes landed in the SAME commit, so the prose is a counterfactual about the code as written, not a narration of history. Recorded, not fixed. The hook is not installed in this checkout, so nothing was actually blocked here; it would have bitten anyone who ran the setup skill and then edited this plugin. And `machine-path-patterns.sh` is named by no suite directly: its selection set and `hardcoded-path-patterns.sh`'s are byte-identical at 150 suites, which is 38 percent of the repository's 397, so that is hub saturation rather than coverage. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
Twenty-one files reviewed; eight changed. source-control 0.55.43 -> 0.55.44. is_owner_repo_pair holds the owner/repo segment rules for the PR-reference and scope-key parsers, which kept two hand-maintained copies. record_mutation_ledger_entry merges save_state's two ledger folds. legacy_check_identity_keys replaces a tuple literal written out four times. unscoped_queue_run names a predicate spelled at five sites. Two GraphQL walks now use the package's own dig instead of hand-rolled nested narrowing. Six tests added, each closing a gap that was silently open. Verification. The changed code is behaviour-preserving on every path anyone could construct: three independent differentials totalling about 14,370 invocations with zero divergence. find_open_prs_for_head_ref is only ever mocked by the suite, proven by two wrong-key mutants surviving all 649 tests, so its rewrite is carried by 844 row shapes including every raise path, with a wrong-key control discriminating on 84. The parser extraction ran to 13,475 invocations against both pre-images, with a traversal-permissive control discriminating on 18 pairs and 72 triples. Fifteen kill-intent mutations, nine killed; ten equivalence controls, ten surviving. The decisive check is the counterfactual: applying the same intents to the pre-change tree, six of them SURVIVED there, and their post-change counterparts are killed by the new tests specifically. The new tests are what made both the over-acceptance and over-refusal directions discriminate; ten controls surviving is what says the corpus is not merely trigger-happy. The suite went 643 to 649 by test-id inventory diff, not by counting: exactly six ids added, none removed or renamed. Two claims are corrected rather than carried. The segment rule had FOUR copies, not two. babysit_resolve_thread.py spells the same rule against the same two regexes twice more, and its own comment already worries about that drift. Both sites are individually tested, so this is a missed dedup rather than a hole, but the docstring here claimed to be the one place the rules live and that was false. It now says what is true and names the other two. Two of the four deduplicated comprehensions were not interchangeable. The two reading prev wrapped their iterable in json_array(); the two reading checks did not. Over 17 inputs the current form diverges from the helper on five: None and 5 raise TypeError where the helper yields an empty set, and a string yields per-character keys. Unreachable in practice, since classify_checks builds those lists with comprehensions and checks is local to classify_pr. The helper is the stricter of the two, and the divergence is recorded rather than assumed away. Three findings outside this diff, recorded rather than fixed. A routing gap defeats the integration test written to protect the ledger. affected-tests.sh selects only test_babysit_state.py for babysit_state.py. Under a ledger-overwrite mutation that suite stays green, and test_integration.py, the only suite that discriminates, is never selected. The gate reports success over zero real coverage of exactly that invariant. Two mutations survive all 649 tests, both pre-existing. Reducing unscoped_queue_run to `scope is None` makes in_scope_keys the whole file in non-queue mode; dropping the `if merged:` guard writes an empty ledger entry. Naming the first is the natural place to test it. save_state's first ledger fold is undiscriminated but not dead. Deleting it leaves all 649 tests green, and instrumentation shows seven tests reach it across thirteen invocations with none of the thirteen changing the ledger, because persisted_pr_state retains all three fields it reads. It is not migration-era code: load_state raises on any schema_version other than 1. It is a live self-heal for a schema-1 file with a missing mutation_ledger key, demonstrated by rebuilding an entry from an on-disk record. Formatter churn, so it is not mistaken for hand editing. The ruff-format hook reflowed four files on save, measured at 404, 168, 127, 14 and 13 changed lines. Reproduced by running the pinned formatter over the pre-change copies: the residual is exactly the intended edits and nothing else. Twelve other Python files in the same directory are formatter-dirty and untouched, which is what confirms this is edit-triggered rather than a sweep. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
Eighteen files reviewed; ten changed. source-control 0.55.44 -> 0.55.45. worktree-create.sh documented two exit codes wrongly, and one of them told a caller the opposite of the truth. Exit 5, the tree was created but `git worktree lock` failed, has shipped since #2389 and appeared in neither the header table nor usage(). Exit 4 was described as "not a git repo, or `git worktree add` failed", but it also fires when the tree WAS created and a .worktreeinclude file then failed to copy. That case has exit 5's shape, a tree on disk that is not what the caller asked for, so a caller reading 4 as "nothing was created" is wrong for it. Both rows now say so. exec-bit-check.sh's two synopses disagreed with each other and with the file's own Modes block: usage() was missing both --list0 and --all, the header was missing --all. Both now list all four modes plus --all. Six files had past-tense narration rewritten as the rule it encodes. landed-work.sh gained a nested flush_record for two byte-identical five-line call sites, the same idiom worktree-claim.sh already uses. Verification. Comment-only was established mechanically, not by reading: two quote- and heredoc-aware shell parsers agree across all ten files, and the comparison was shown to discriminate heredoc body text, numeric literals, single-quoted string bodies and statement reordering, while returning unchanged for three comment-reword controls. Two files in this very diff are live positive controls for it, one heredoc-only and one reordering-only, and both register. Exit 5 was verified against an unmodified copy with a git shim that fails `worktree lock`: rc=5, exactly one stdout line, the tree present, and no `locked` line in `git worktree list --porcelain` where the control has one. The reflowed paragraph beside it is word-for-word identical, 104 words each way. flush_record was checked by differential over nine porcelain fixtures, including an empty input, a missing trailing separator, a detached-first ordering, a newline-in-path and a bare repository: identical rows in every case. Ten mutations were run on both sides of the change with identical scores, seven caught including four over-refusals, and three equivalence controls scoring zero. Sixteen shell suites pass with per-suite assertion counts matching a pre-change baseline, six of them additionally compared against a mirror of the unmodified tree. Total skips across eight suites: three, each printing its reason, and zero discriminating skips. One worker claim is corrected. A mutation that drops the "(detached)" label inside flush_record was reported as an uncaught pre-existing coverage gap. It is not a gap: the label is re-derived at every read, so the mutant leaves stdout and stderr byte-identical on a real detached-HEAD worktree, and dropping BOTH sites is caught by the suite. The conclusion, that the mutant scores the same before and after, was right; the reason was not. That correction surfaces a live question this diff deliberately does not settle. The assignment inside flush_record appears redundant, and a tidy pass would delete it rather than hoist it into a named helper. Whether a bare or non-git row, which returns early before the re-derivation, can observe it is unresolved between two readings of the control flow, so it stays until someone settles it rather than being deleted on an unverified one. Recorded, not fixed: neither the exit 5 contract nor the new help line is test-covered. The suite asserts nothing about exit 5, the lock failure, or the "created but not locked" wording. The contract is documented but unpinned. Also left alone deliberately: fetch-all-pr-comments.sh's if/then/fi merge block, which looks like it wants to be `&&`. The `&&` form returns 1 on an empty last surface and fails the pipeline under pipefail, which is the defect that file's Case 14 pins. Confirmed empirically, including that only the LAST surface matters, and that reverting the three arms fails exactly three assertions. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
#3706 merged as 1bde828 and its branch was auto-deleted. This brings the branch onto the new base so the remaining tidy waves land in a successor PR rather than stacking on already-merged history. origin/main also gained #3707, a miro dependency bump and bundle rebuild. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD # Conflicts: # plugins/source-control/.claude-plugin/plugin.json # plugins/source-control/CHANGELOG.md
Seventeen files reviewed; two changed. work-items 0.39.54 -> 0.39.55. The gitea repo-label pagination walk re-ran `jq 'length'` over the response body to get the row count the previous iteration had already recorded. LABEL_GOT is now seeded from page 1 and read directly: one fewer jq process per label page, and three spellings of "page length" collapsed to one. Two jq calls fed a here-string of `null` to programs that never read `.`; they now use -n, the idiom the same file uses three lines later. Verification. Behaviour was established two independent ways, not by reading. An end-to-end differential ran 23 scenarios against both versions on the same mock, comparing exit code, stdout, stderr AND the full recorded request log: zero divergence, across an exactly-full last page, an empty page, a single page, a label on the last page, four page sizes, a total-count header present and unsatisfiable, an unseeded page 2, a non-array page 2, duplicate names across pages, and a four-page walk. Then an instrumented probe recomputed the OLD value at the top of every iteration and compared it to the new one: 22 iterations across 12 scenarios, zero divergences, including the first iteration in every one, which is where a seeding error would live. The claimed spawn saving was measured with a counting shim: 45 total jq spawns and 8 `jq 'length'` before, 42 and 5 after. The -n change was checked by reading both programs in full for any indirect read of `.` and then empirically over five argument values crossed with six stdin values. The only divergence is on empty stdin, which the here-string form cannot produce. The new test case is load-bearing, and this was measured rather than asserted: instrumenting the loop body shows it executed ZERO times across the suite's 49 cases before, and once after. Three mutations of the changed line all survive the old suite. Twelve mutations and five equivalence controls in total, killed and surviving 8 to 4, with every control scoring zero. One defect is corrected rather than shipped. The worker rewrote a past-tense comment into the present tense, and the present-tense form is FALSE: it said an empty jq length makes the page-length arm an arithmetic error and the walk continues into page 2. That was true only of the pre-#3651 inline spelling. The current arm reads an assigned variable, where empty evaluates to 0 and the break fires; driven directly, page 2 is never requested. This same diff deletes the #3651 fix line, so a reader would have had nothing nearby to recover the true reading from, and the comment would have told them a closed bug was live. The clause is deleted rather than re-tensed, which is the residue skill's own treatment of history narration. Recorded, not fixed. Dropping -n from the label-id jq call is caught by NO test: it leaves the id list empty, the payload build dies on invalid JSON, and the issue is POSTed with no body at all while the suite still reports success. So the -n change is carried by the static proof above, not by the test net. Relatedly, mock.sh records only method and URL and never a request body, so no assertion in any gitea suite observes the POST payload; label-name to label-id resolution, the whole purpose of that block, is asserted only through the exit code. Three further mutations adjacent to the walk also survive, all pre-existing. Coverage, quantified rather than labelled. create-item.sh selects 202 suites, of which exactly ONE exercises it. One more references it only as a file-exists check that would pass against an empty file. Three are same-named suites in sibling adapter directories that each run their own copy. About 197 are transitive fan-out on generic basenames, and ten of the 202 mention gitea at all. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
Seventeen files reviewed; five changed. repo-fleet-hygiene 0.23.15 -> 0.23.16, prototype 0.10.1 -> 0.10.2. audit-fleet.sh had three copies of an order-preserving linear scan and a duplicated porcelain-record flush; they are now array_contains and push_worktree_record. apply-plan.sh had one env prefix spelled out at five mutation sites; they share git_mutate. Both allowed-tools-pairing.test.sh copies in this group were shfmt-formatted in step. The test the worker removed is restored, because removing it was wrong. Instrumenting every array_contains call shows 152 calls across the suite with exactly TWO hits, both from the single fixture that puts two findings on one target. So the dedupe IS exercised, and an over-firing dedupe emits that target's whole thirteen-line block twice while every count the suite checks still matches. The worker measured only the repo_verdict site, found zero hits there, and generalised that to all three. It is right about that one site: over-firing it alone is a genuinely equivalent mutant with zero difference in any artefact the suite writes. It is wrong about the other two. The restored assertion is whole-line, which matters: the roll-up prints the same path with a "(N linked)" suffix, and a substring match counts that as a second block and fails on correct code. That is not theoretical, it is what the first version of this assertion did. It now passes on the real code and fails on the over-firing mutant with the expected count of two. Verification. Formatting-only was established mechanically: two independent quote- and heredoc-aware shell parsers agree on both files, with sensitivity proven by nine seeded semantic mutations, every one caught by both parsers, against two controls that correctly do not fire. Comment lines are identical at 35 each. Runtime output from a full plugin tree is byte-identical at nine lines, exit 0. array_contains was diffed against the pre-image over fifteen adversarial inputs including glob metacharacters, empty strings in every position, embedded newlines, a leading -n and interleaved duplicates: fifteen of fifteen identical, order preserved. git_mutate's five sites were confirmed to carry ONE spelling of the prefix by extraction, not by reading. A live fleet of two repos with merged branches and linked, prunable and nested worktrees produces a 121-line report differing only on the lines carrying $0 and the plan path, with byte-identical plan JSON and identical stderr. Twelve mutations and four controls. Killed: array_contains always-true at 65 failures, its shift removed at 65, push_worktree_record's guard inverted at 28, a parallel-array misalignment at 95, git_mutate as a no-op at 3. Two corrections carried from verification rather than the worker's numbers. The guard-inverted mutant is 28 failures against the shipped suite, not 27; 27 was the count before the new assertion existed. And drift across the five-copy pairing family fell in NET, 252 differing lines to 228, with four copies now differing pairwise by exactly their SKILLS= line, but it GREW by twelve lines against the repo-hygiene copy, which is a genuine superset and now the family's only unformatted member. "Drift reduced, not widened" was true in net and false against that copy. No cross-plugin consolidation was made, and the drift gate still reports the family as differing rather than identical, which is what keeps it green. A hazard-list correction worth carrying beyond this group: prototype does NOT have three copies of a detector. scripts/detect-ecosystems.sh is the detector; the two skill-level files are seventeen-line exec wrappers whose executable bodies are byte-identical, differing only in a comment naming the sibling skill, and their suites assert exactly that byte-identity plus the header's rationale phrases. Nothing was drifting and nothing was consolidatable. Recorded, not fixed. The worktree-lane OID-drift gates have NO coverage at either end: disabling the plan-time and execution-time gates together leaves the suite at 23 passing, 0 failing. The branch lane is covered by that same pairing, at 2 failures. This is pre-existing and is the first time it was measured. Separately, a prefix-glob comparison in array_contains escapes the suite undetected. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
… (G55) Twenty-one files reviewed; three changed plus one test added. source-control 0.55.45 -> 0.55.46. babysit_resolve_thread.py spelled the owner/repo segment rule out twice against the same two regexes the shared helper wraps. Both now call is_owner_repo_pair, and the file's own comment at the second site, "keeps one rule instead of two", is finally literally true. babysit_merge.py's seven refusal sites share one _refuse closure, the idiom the sibling guarded CLI already uses at thirteen sites. A test is added because the refactor CREATED a failure mode, and that is the important part of this commit. Passing the pair in the wrong order is something the previous spelling could not express: it named the two regexes explicitly. Once both go through one helper, a one-token transposition silently weakens a path-traversal guard whose result is interpolated into a gh api URL, and it was killed by ZERO of the 649 tests. Every existing head-repo fixture uses a name and an owner that both regexes accept or both reject, so the transposition was invisible to all of them. A dot is legal in a repository name and illegal in an owner, so a my.repo fixture clears validation only when the arguments are the right way round. Against a scratch baseline the transposed build differs from the control by exactly this one test and nothing else. Verification. Both pre-images were compared character by character against the helper's body: identical, including short-circuit order under the enclosing not(). The refusal contract was checked over a 77-shape corpus comparing exit code and stdout and stderr bytes, with zero divergence, covering all seven routed sites, empty envelopes, JSON-escaping payloads with quotes, backslashes, control characters, CJK and emoji, and nine shapes that trip two sites at once. Exactly three stdout key orders exist and both versions produce the same one per shape. Each site's exit code was flipped individually; all seven are guarded. Fifteen mutations reproduce the worker's numbers exactly, with four equivalence controls scoring zero. One claim is corrected. The parse-failure refusal was described as the one with no usable pr value; args.pr does exist and holds the raw string. The exception is nonetheless necessary, shown by the differing output: routing it through _refuse adds a pr field naming a PR nobody can resolve. The selector finding this group inherited is worse than reported, and it lands on this package hardest. affected-tests.sh seeds its reverse lookup with the basename INCLUDING .py, so a suite that says `import foo` rather than naming `foo.py` is invisible. babysit_review_trigger.py maps to zero suites while two suites exercise it, one calling ten distinct symbols. No test imports refresh_pr_branch.py at all; its only coverage is a guard-contract row enforced by read_text plus assertIn, which is a source-text grep and never an execution. Two sibling suites for the same module differ purely because one spells the literal filename in a subprocess argv. And babysit_gh.py selects ONE suite despite twelve importing modules and three importing suites, because the only file in the repository containing the string "babysit_gh.py" is a changelog. Had this group trusted the selector for that file, it would have missed the very suite whose eighteen kills cover the two new call sites. Recorded, not fixed: reordering the envelope keys, dropping the pr key, and routing the parse failure through the helper each survive the full suite. All three were equally unprotected before, but the refactor concentrates the risk from seven edit sites to one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
Eleven files reviewed; six changed. source-control 0.55.46 -> 0.55.47.
fetch-annotations.sh --help sliced its header with a hardcoded sed -n '2,20p'.
The header runs to line 23, so the banner stopped three lines short: it printed
"Exit codes:" and "0 success" and then ended, never showing 1, 2 or 5. Measured
rather than inferred, by running both versions from clean extractions: the old
form printed 19 lines and exactly one exit code, the new blank-line-terminated
form prints 23 and all four. That form is already used by three other scripts
here and removes the line-number coupling that caused the drift.
Three assertions were added beyond what the worker wrote, each closing a gap the
verifier proved was open by mutation.
fetch-failed-logs.sh had NO --help coverage at all. An under-slice dropping exit
codes, an over-slice leaking `set -uo pipefail` and the whole variable block, and
a usage() emitting zero bytes each left that suite green at 14 of 14. It now has
the same two-direction guard, and both the under-slice and over-slice mutants
fail it.
check_run_name had no value assertion. The schema check used has(), which is
presence-only, so dropping .name from the jq projection scored zero across all
ten assertions while every emitted record silently carried the string "null". The
field is emitted and read by nothing else, so this was the only place its value
could be pinned. The mutant now fails with "expected test got null".
Verification. The jq shorthand was checked byte-identical including key order over
ten object shapes, among them absent keys, nulls, nested objects, duplicate keys,
bignums and escape sequences, plus four non-objects where the error text also
matches. Every gh and curl invocation line is identical to the pre-image, so no
request method, URL, header or body changed. Mutations cover both gate directions,
including one that drops a single exit code from the header and one that inserts a
blank line INSIDE the header, which is the failure mode the new slice form could
plausibly have introduced; both are caught. Two equivalence controls score zero.
A landmine was avoided and is worth recording. nesting-invariant-ssot.test.sh has
explicit FAILED=0 and CASE_NUM=0 that look redundant against the shared helper's
`: "${FAILED:=0}"`. The plugin's own changelog records that exact removal being
proposed, refuted and reverted: the helper form preserves an environment-inherited
value, the explicit form forces a reset, and they are not the same. Left alone.
Three findings recorded rather than fixed.
The same truncation bug survives in two more scripts, the byte-identical
resolve-convention-pattern.sh pair, whose sed -n '2,40p' cuts a 43-line header and
drops all three of their exit codes. The fix here is NOT transplantable: those
headers have no blank line before the code, so the terminator used here would leak
executable lines into their banner. They are also a registered sync-cluster pair,
so they need one deliberate change applied to both.
fetch-failed-logs.sh's help output was byte-identical before and after only
because the hardcoded 41 happened to land exactly on the blank line. That was luck
the next header edit could have taken away.
And the completed dispatch table still lists generic routes before specific ones
while the code matches specific-first, so read top-down as a dispatch order it
gives the wrong answer for two fixtures. Pre-existing, and the completion
preserved rather than introduced it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
Nineteen files reviewed; six changed. performance 0.1.0 -> 0.1.1. This plugin arrived on main mid-run, so it was not in the original inventory and its file list was enumerated fresh and verified against the tree. spawn-census.test.sh called assert_not_contains at two sites and never defined it. The suite defines five functions and that is not one of them, and it sources no helper file that could have supplied it. Both calls died as `command not found` on stderr, incremented no counter, and the suite still exited 0 with 28 PASS lines against 30 call sites. The two dead assertions guarded exactly the false green this plugin exists to refuse: a census line printed for a subject that never ran. That is not an argument, it is measured. Emitting `spawns=0 rc=127 []` before the never-ran refusal leaves the OLD suite at exit 0 with zero failures, and fails the fixed suite twice, naming both the 127 and the 126 arm. The added helper was checked against its call sites rather than assumed: argument order is label, needle, haystack, matching this file's assert_contains and NOT the opposite order used by a sibling suite elsewhere in the repo, and both call sites are paired with a preceding positive pin so neither can pass vacuously on empty output. Also fixed: an assertion label that contradicted its own expectation, reading "an unresolvable denominator still exits 0" while asserting 2. Exit 2 is a refusal. Plus a dead mkdir for a fixture directory nothing references, proven unreferenced beyond the file itself, and duplicate section-header numbers in two suites. The formatter reflow, recorded so it is not mistaken for hand editing. spawn-census.sh carries a 100-line diff from the bash-format hook, which runs shfmt without -ci while .editorconfig sets no switch_case_indent, so case arms de-indent from four spaces to two. It is provably semantics-free, and the proof matters because the obvious one is invalid: a double space inside a string literal is a real content change that BOTH `git diff -w` and a whitespace-stripped hash miss. Three orthogonal checks agree the file is unchanged in meaning, and that combination was shown sensitive by six seeded mutations it catches against three controls it correctly ignores. The suite's output is byte-identical against both versions. Two findings recorded rather than fixed. The spawn instrument has four undocumented blind spots. Counting via PATH-prepended shims is sound for indirect spawns, verified over a subshell, a command substitution, a pipeline, xargs, a nested script and a backgrounded job. But a subject invoking an absolute path, resetting PATH, running under `env -i`, or forking without exec is counted as ZERO. Three of those emit a tidy `spawns=0 rc=0 []`, which is the confidently-wrong-number shape this script's own header exists to refuse, and nothing in the plugin's documentation mentions it. pathfix.py is under-selected by the test mapper: four modules import it and none of their suites is selected, because the selector seeds its reverse lookup with the basename including .py while an `import pathfix` reference carries no extension. Latent rather than live, since mutating it is still caught by its own co-located suite, which drives the whole public surface. The registered sync-cluster copy plugins/performance/lib/spawn_noise.py was not touched. Its canonical is plugins/claude-ops/lib/spawn_noise.py, not the path an earlier note in this run gave; both sync checks are green. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
Sixteen files reviewed; five changed. typos-format 0.6.37 -> 0.6.38,
skill-quality 0.20.11 -> 0.20.12, songwriting 1.4.21 -> 1.4.22,
testing 0.7.12 -> 0.7.13.
The typos-format suite measured process spawns by exporting PS4 and reading the
trace. Bash overwrites and re-exports PS4 at startup, so the tracer matched 0 of
802 lines: `env PS4='SENTINEL ' bash -c 'declare -p PS4'` reports
`declare -x PS4="+ "`, and prefix assignment, env(1) and export are discarded
alike. dash honours it; bash does not. Four assertions were therefore measuring
an empty word list and passing, and the fifth failed. PS4 now arrives through a
BASH_ENV preload, which the traced shell performs itself and which preserves the
${FUNCNAME[0]} attribution the tracer depends on, where `source` would not.
765 of 803 lines are now marked, and a new assertion fails loudly if that ever
returns to zero.
With the instrument live the jq expectation was wrong: it asserted 2 and the true
count is 1. That was established with a counting jq shim on PATH, deliberately NOT
with the repaired tracer, so a tracer bug could not replace one wrong number with
another. Only hook::buffer_stdin's `jq -e .` runs; hook::read_file_path takes the
builtin fast path on a single-chunk payload and never reaches its jq fallback.
This corrects a claim this run repeated for hours, and it was wrong in both
halves. The failure was the broken instrument, not the container. And CI never
ran the block at all: the suite gates on a real typos binary, the typos action
lives in the lint job while the plugin contract tests run in test-linux, separate
jobs with no shared PATH, and typos is in neither the CI Python requirements nor
the npm devDependencies. Measured by stripping typos from PATH: 87 of 144
assertions run, so 57 have never executed in CI, including telemetry, config
precedence, symlinked roots and the write-mode allowlist. The dark region is the
whole real-binary tail, not just the trace block.
check-skill.sh loses a line that could never change anything: the preceding
expansion already yields exactly SKILL.md, since SKILL_MD is $SKILL_DIR/SKILL.md
and both are assigned once. Proven three ways rather than read: 374 adversarial
root and name pairs replaying both real call sites with zero divergence, a
differential over ten real skills with byte-identical output, and the symmetric
check that re-inserting the line changes nothing.
datamuse.sh was reflowed in full by the bash-format hook, which is hook output
rather than a hand edit; the file was not shfmt-clean before. The live API
contract is untouched, verified four ways including bash's own parse-tree
re-serialiser and a 36-case harness with argv-capturing curl and jq shims driving
adversarial words, with zero divergence in exit code, output or argv multiset.
Mutation evidence, in the direction that matters: the pre-change test scores
IDENTICALLY on every one of four mutants, catching none, while the repaired suite
catches all four. Two equivalence controls score zero. A third candidate control
was correctly rejected by the worker for scoring 1, and the reason is worth
keeping: the suite reads that constant out of the hook by literal source text,
not by behaviour.
Three findings recorded rather than fixed. The repaired tracer is still blind to a
`command`-prefixed external, because the traced word is `command`, whose type is
builtin, so even the ceiling misses it; latent, since the hook's only use is
`command -v`. A result-cap mutation in datamuse.sh's syllables arm survives its
suite. And the coverage numbers here are mostly fiction: check-skill.sh selects
155 suites of which 2 execute it, three name it only in a comment, and 76 of the
155 selection reasons name some other file entirely.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
Twenty-three files reviewed; seven changed. work-items 0.39.55 -> 0.39.56. validate.mjs cited source locations for the queries it checks, and eleven of eighteen were stale: eight into common.sh, three into create-item.sh. Every one landed on a comment, a bare closing brace, or unrelated code. issueCreate claimed line 151, which is a `while :; do`, against an actual 216. All eleven are corrected AND the seven that were already right were confirmed right rather than churned, because a pointer "corrected" to a new wrong line looks fresh and is harder to catch next time. Both edited hunks are two lines for two, so nothing shifted underneath another pointer. reclaim.test.sh had two probes wrapped in `2>/dev/null || echo 0` around a jq count whose expected value IS 0. A probe broken outright therefore scored exactly like a passing assertion. With the jq program deliberately broken, the old form reports 39 passing and exits 0; the new form reports two failures and exits 1. The legitimate empty and missing cases still yield 0, so nothing over-rejects. The cross-group handoff was re-proved rather than inherited. A sibling adapter replaced `jq … <<<'null'` with `jq -n` after proving equivalence for ITS programs; these are different programs. Neither reads `.` even indirectly, the only reachable identity being select's pass-through which the following `| $n` discards. Output is identical across a 560-pair matrix of arguments and stdin values including invalid JSON, a closed stdin, a blocking FIFO with a live writer, and a 64 MiB stream. All 297 recorded GraphQL request bodies across the nine verb suites are byte-identical before and after, with a working one-field tamper control proving that comparison can fail. The re-tensing caution was applied in BOTH directions and each decision settled by mutation, not by reading. One clause was DELETED: removing the guard it describes now produces a loud failure at exit 1, not the silent success-with-no-output the text claimed, so a present-tense rewrite would have shipped a false statement. One was RE-TENSED: reducing the guard to a name-only compare fails exactly three cases, so the counterfactual is true. The schema lane was actually executed, not assumed: a 1.31 MB Linear SDL fetched into scratch, graphql installed there, and validate.mjs at 18 of 18, negative.mjs at 10 of 10, fidelity.sh at 17 verbatim and 0 mismatched, byte-identical to the pre-change baseline. Nothing was written into the repository to make it work. One correction to the worker's bookkeeping. It reported executed-equals-contained across nine suites; it holds for eight. get-item.test.sh has 39 static call sites and executes 44, because two `for` loops multiply single sites. The stated derivation never mentioned loop expansion, and that is the one suite where it matters. It is not among the changed files. Recorded, not fixed. Four assertions in claim.test.sh share a residual blind spot with the two probes repaired here: an assertion whose expected value equals what an EMPTY probe yields cannot tell "nothing was written" from "the right thing was written". The suites as wholes do fail under that mutation, so it is a per-assertion gap rather than a blind suite, and a positive control asserting that some update WAS recorded would close it. It is the natural next step of the same reasoning this commit acts on. Also recorded: linear's mock DOES record the request body and 33 assertions across eight of nine verb suites read it, unlike the gitea and github mocks. What nothing here records is the HTTP method, the header set including the API key, and the curl flag set. And nothing guards the loc: pointers, which is how eleven of eighteen went stale. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
Twenty-three files reviewed; ten changed. work-items 0.39.56 -> 0.39.57. Seven `printf '%s\n' "$X" | jq …` pipelines became `jq … <<<"$X"`, the idiom the file and every seam lib already use, plus one merged `local` declaration and one stub variable dropped from a line where it is unreachable. The `case`-body re-indentation in seven files is the repo's own formatter output: bash-format.sh runs shfmt with no layout flags, driven by .editorconfig. Byte safety, and a hypothesis I put to the verifier that turned out to be wrong. I briefed it to expect divergence when the value already ends in a newline, is empty, or is a lone newline, on the theory that a herestring adds a newline only if one is missing. That is not how bash behaves: a herestring appends exactly one newline unconditionally, so all three cases match `printf '%s\n'` byte for byte. Seventeen payload shapes compared at the level of the bytes reaching jq's stdin, seventeen identical. NUL is unreachable because all seven sites take a value from a command substitution, which strips it. No site reads PIPESTATUS or depends on an assignment surviving the pipeline, and the pipeline form carried a latent pipefail plus SIGPIPE hazard that the herestring removes. Driving the real verbs against a stub over eight payload shapes gives byte-identical stdout and identical exit codes in 32 of 32 cases, with eleven distinct output checksums proving the matrix can tell outputs apart. The manual delta was isolated mechanically rather than eyeballed: running shfmt over the pre-change files and diffing against the working tree leaves exactly the seven rewrites, the local merge, the dropped variable and the header edit, and nothing else. That is 22 insertions and 18 deletions across six files, out of a headline 95 and 91; four of the ten files are whitespace-only. Coverage was measured, not reasoned. Poisoning each file with an early exit and counting which suites notice: common.sh is exercised by 12 suites, reclaim.sh by 2, list-items.sh by 1. The selection is 202 for each, of which 193 are runnable shell suites, so for common.sh 181 of 193 selections are false. The method also detects a suite that SOURCES the file rather than running it: common.test.sh exits with the poison code itself, distinctly from the child-process suites. Three claims are corrected rather than carried. "github was the only adapter out of shfmt line" is false: local-markdown has four dirty files, at HEAD and still. The seven dirty github files were exactly the seven re-indented here, so the justification stands, but the comparison did not. The 202 denominator is the selection count, not the runnable count, which is 193. And the redundancy found in `wit_map_gh_error` is SYMMETRIC: deleting the "HTTP 404" arm is uncaught, and so is deleting the "Not Found" arm, because one fixture string contains both. Killing the whole arm IS caught, so the assertion is live and the cause is masking rather than absent coverage. The finding is twice the size reported. Every uncaught mutant was proven pre-existing by running the same battery against a clean pre-change tree: fourteen mutants, identical scores on both sides. This change introduces no coverage regression. Recorded, not fixed, and the first is the one that matters. The lease protocol's three writing verbs have NO assertion on what they write. The stub logs a PATCH id and a bare POST_COMMENT token and never records the request body, so renew-lease can PATCH back a body whose renewed_at was never bumped, which is the verb's entire purpose, and reclaim can leave a reclaimed lease without superseded_at, active forever. Both mutations pass every suite. Two suites lose assertions silently without jq: common.test.sh drops 28 to 16 and create-item.test.sh 10 to 4, both still exiting 0, while a sibling in the same directory fails loudly under the same condition. Neither emits the repo's SKIP convention, so --strict-skips cannot see them, and check-silent-skips.sh cannot either: it scans hooks rather than suites, and only the negated `if ! command -v` form. And conformance/bindings/github.test.sh is selected by none of these ten files. A change to a sibling adapter's common.sh pulls in four conformance bindings; a github adapter edit pulls in none, and that suite deliberately does not run the abstract suite anyway. The github adapter has no conformance lane reachable from a github adapter edit. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
Eleven files reviewed; seven changed. work-items 0.39.57 -> 0.39.58. preflight.sh loses a normalize_path wrapper with two call sites, replaced by the fork-free norm_path/$NORM_OUT protocol ten other sites already use. The loop it sat in was paying exactly the fork the function's own header says it exists to avoid. Checked over 30 hostile inputs: 27 identical, and the 3 that differ are trailing-newline shapes the loop cannot produce, since read -r strips them. Across 24 newline shapes there is no fail-open case in either direction; the new code only ever reports MORE gaps. Three assertions were added, each closing a mutant proven live against an isolated pre-change tree: the needs-confirmation path's stdout was unasserted, the generated upper-cased provider spelling was unpinned, and a want-from-NORM_OUT detachment was invisible. All three exit 0 before and 1 after. Two tidies are REVERTED before shipping, on a precedent this plugin already set. Version 0.39.24 records a printf-pipe conversion in evaluate-schedule-precondition.sh being refuted and reverted because it shifted a line number into a stderr diagnostic on a reachable error path. Both of these were the same class, in that same file family. Dropping the `printf '%s\n' "$( … )"` wrapper is NOT newline-neutral, though it was reported as identical. Command substitution collapses trailing newlines to one; the direct pipeline passes them through and puts a blank line before the needs-confirmation marker. Measured over seven prompt shapes, two diverge. The wrapper is restored with a comment recording that it is load-bearing. And `$(cat "$file")` to `$(<"$file")` changes the missing-template diagnostic from one naming only the template path to a bash error carrying THIS script's line number. That is precisely what 0.39.24 rejected. Restored, with the precedent named in the comment so the next sweep does not re-propose it. Verification. The three reformatted files are semantics-free, established with two independent parsers plus a comment-stream diff, and the combination was proven sensitive by eight seeded mutants including a double space inside a string literal, which `git diff -w` cannot see. Isolating the manual delta that way matters here: `git diff -w` also cannot see semicolon-separated one-liners being split, which is most of one file's diff. The generator's output is contract-identical across 20 spec shapes including seven rejection paths: generated tree bytes, stdout, stderr and exit codes all match. Templates were not touched. Three of the worker's claims are corrected rather than carried. normalize_path had TWO call sites, not one. The preflight differential's "0 differences" holds for 167 fixtures but not for 240: two trailing-newline roots diverge, which is the shape the smaller matrix omitted. And the suites do not call skip_suite; they hand-roll an echo-and-exit-0, which lands in the same blind spot. Recorded, not fixed: preflight.test.sh and generate-adapter.test.sh degrade silently without jq, and check-silent-skips.sh cannot see them because it scans hooks and top-level scripts rather than plugin suites. CI installs no jq explicitly, so their coverage rests on the runner image. Separately, preflight.sh selects three suites and one exercises it; the other two are basename collisions with repo-hygiene's own preflight.sh. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
Twelve files reviewed; four changed. work-items 0.39.58 -> 0.39.59. Two concurrent conformance runs on one host clobbered each other. The overlay case derived its path from `dirname` of the binding file, and every binding mktemps that file straight into TMPDIR, so the overlay resolved to one fixed path shared by every run on the machine. The binding is now re-homed into a run-private `mktemp -d` right after cb_setup, and the trap removes it. Measured on separate extractions of both trees. Eight jira plus eight local-markdown in lockstep: 9 of 16 red before, 0 of 16 after. Ten jittered pairs: 19 of 20 red before, 0 after. A 25-round reproduction of the CI shape: 15 of 50 red before, 0 after. A 40-way stress run: 0 red. 130 runs on the fixed tree, none red, case counts always 34 and 81. Planting a poisoned overlay at the shared path makes it deterministic: 38 cases with 9 failed before, 34 with 0 after. The failure is whole-suite poisoning, not the two cases first reported. Once one run leaves a foreign provider at the shared path, every tracker invocation in every concurrent run exits 3, the provider resolves empty, and verb_supported reads every verb false, which CHANGES the reported case count. So matching case counts is not by itself a sufficient regression guard. The attribution is narrowed, because the first wording would have put a false statement into a bug tracker. scripts/run-plugin-tests-serial.txt lists two entries as unexplained under --jobs 4: plugins/discovery/agents/tool-honesty.test.sh and this plugin's bindings/jira.test.sh. It does NOT list local-markdown.test.sh anywhere. This mechanism explains the JIRA entry only, and the evidence for that is an asymmetry the first pass left on the table: under the CI shape jira loses the race 13 times in 25 while local-markdown loses 2, so the mechanism predicts which of the pair got listed. tool-honesty.test.sh is a markdown contract test with no reference to the tracker, no mktemp and no shared path; this cannot explain it. The record's own rule is that BOTH entries come off the list when the cause is found, so #3694 stays open. Also worth stating plainly: the collision cannot fire in the lane as configured today, because jira.test.sh is serial-listed and never runs beside the only other runner-invoker. This is a precondition for delisting it, not a repair of a currently red lane. Fix correctness, checked independently. No consumer resolves the binding by its old path; the only binding-relative resolution in the seam takes an absolute value from every conformance binding. Nothing leaks: teardown still removes the original and the trap removes the copy, with /tmp entry counts unchanged across 40 concurrent runs. Trap coverage was measured by signalling a parked instrumented copy: SIGTERM, SIGINT, SIGHUP, normal exit and failure exit all clean; SIGKILL leaks one directory, uncatchable, and the pre-change code leaks its own temp file there identically. Every other write in the runner was audited for the same shape and all were already unique, so this was the only fixed shared path. Fifteen mutants plus controls. Two prove the new lines are load-bearing rather than cosmetically dead: emptying the copy and forcing the new status capture to zero both fail the suites outright. Two more show the private directory and its export are each individually load-bearing under concurrency. Three equivalence controls score zero, and reverting the fix is killed only in parallel, which is exactly why this went undiagnosed. Recorded, not fixed, and the last one is sharp. e2e-probe.sh's 16 assertions have never been executed by any suite, and the reclaim block's 13 never run in CI, both confirmed by planting an early exit and watching nothing notice. bindings/github.sh's success path is likewise unexecuted; its suite asserts only that setup refuses without a target. The consequence: redirecting e2e-probe.sh's `gh issue close` to a DIFFERENT REPOSITORY leaves every automated suite green. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
Twenty-one files reviewed; ten changed. work-items 0.39.59 -> 0.39.60. This is
the last of seventy groups in the repo-wide sweep.
renew-lease.sh reported a renewal it had not persisted. When the store rewrite
could not run, mktemp failure left the temp path empty, the redirect failed, `&&`
short-circuited past the move, and the script's status came from the trailing jq.
Reproduced with a failing mktemp: exit 0, a renewed_at on stdout, and a store
still holding the older timestamp. It now exits 1, the code CONTRACT.md defines as
internal and that claim.sh already used for this same class. The conformance suite
is byte-identical at 81 cases, so this moves toward the contract rather than away.
Its suite had an assertion comparing two empty greps. It derived the item path
from the outer store variable, and when that path is wrong both greps return
empty and "marker unchanged" compares "" to "". Pointing it at a nonexistent file
leaves the pre-change suite green at exit 0 with eight passing lines. Paths now
come from each item's own reported url. Stated precisely rather than as the worker
put it: the class can no longer pass silently because a sentinel assertion fails
first, but the trailing comparison is still empty-versus-empty under a forced bad
path, so this guards the suite rather than making that one assertion
self-sufficient.
A leading-zero item name broke allocation. `08.md` passes the item filter and bash
read the bare 08 as an invalid octal literal. This was NOISY, not silent as
reported: the walk emitted an arithmetic error on stderr and skipped the file, so
a store holding 08.md and 7.md allocated 8 and wrote 8.md beside it, two files
with one numeric identity and one unreachable. Base 10 is forced now, and the
maximum derives from the walk's numeric tail, which cannot collide by
construction. The old skipping was the collision hazard, not a protection against
one.
Two defects in the group's OWN new code, both found at verification and fixed
here rather than shipped.
The new cleanup line was `rm -rf "$STORAGE" "$(dirname "$LIVE_FILE")"`. LIVE_FILE
comes from the created item's reported url, so any upstream failure leaves it
empty or the string null, and dirname of either is ".". Unguarded, that asks rm to
delete the runner's working directory, and only GNU rm's own refusal to remove "."
stood in the way. It is now guarded on an absolute existing path, with the reason
recorded.
And the new store-walk assertion could not detect what it claimed to pin.
Allocation derives its maximum from the tail of the walk, so numeric ordering is
load-bearing, but the fixture's lexical and numeric orders coincided and a
degraded sort scored zero. My first correction was wrong in the same way: {1,10}
also agrees in both orders. The fixture is now {2,10}, which under a lexical sort
returns 1,10,2 and allocates 3, an existing item. Verified in both directions: the
real code passes, the degraded sort fails both assertions with exactly those
values.
Verification. Twenty-two added assertions across five suites, each closing a
mutant confirmed to survive the pre-change tree. The claim record rewrite is
byte-identical on stdout including key order across 28 flag and value shapes,
among them a session id containing the marker terminator, a ttl above 2^53,
newlines, tabs and unicode. Coverage measured by poisoning: common.sh is exercised
by 13 of its 202 selected suites, so 189 selections are false; because it is
sourced, the poison surfaces both as exit 99 in the sourcing suites and exit 1 in
the verb-running ones. Two surviving gate mutants were shown to be genuinely
masked rather than uncovered, by checking every adapter-reachable input yields an
identical exit code. Three equivalence controls score zero. All eleven adapter
suites green, conformance 81 of 81.
Three of the worker's framings are corrected rather than carried: there were three
copies of the name filter and four of the store walk, not two, and two filter
copies remain; the octal behaviour was noisy rather than silent; and
superseded_at is not written only by reclaim, the accurate premise being that no
local-markdown script writes it at all.
Recorded, not fixed. renew-lease reports a record that computes as EXPIRED while
its own store computes LIVE, because its projection hand-lists fields and drops
ttl_minutes, which claim reports and the store keeps. Pre-existing, but CONTRACT.md
says renew-lease emits the same shape as claim and this falsifies it. The same
unchecked-write shape as the headline fix survives in add-sub-item.sh, which
reports linked true after an unchecked write, and in link-blocks.sh. And one suite
came back red once in a 202-suite baseline, green in an identical re-run, and
could not be reproduced in 440 targeted runs under contention; it is recorded
rather than attributed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
guardrails 0.31.5 -> 0.31.6. Cross-group resolution, not a group of its own. G57's verifier found this while checking an unrelated diff: the same hardcoded header slice that truncated fetch-annotations.sh survives in resolve-convention-pattern.sh, whose `sed -n '2,40p'` cuts a 43-line header. Its --help ended on the words "Exit status:" and never showed 0, 1 or 2. Reproduced before the change and after: three exit-code lines now print and no executable line leaks. The fix is deliberately NOT the one used on the sibling scripts. Those terminate the slice on the first blank line; this header runs straight into `set -uo pipefail` with no blank line between, so that terminator would leak code into the banner. The verifier flagged exactly that, which is why this was left for a considered fix rather than a transplant. The slice now stops at the first non-comment line, which cannot drift as the header grows. The pair is a registered sync cluster. The canonical was edited and scripts/sync-resolve-convention-pattern.sh propagated it; the two are byte-identical and the drift gate is clean. All four covering suites pass: resolve-convention-pattern, block-convention-violation, require-jq-posture and commit-msg-convention. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Claude finished @kyle-sexton's task in 9m 6s —— View job Claude finished the
|
|
Claude finished @kyle-sexton's task in 2m 19s —— View job Security review complete
No security issues found in this diff. Notable, already fixed correctly within the PR itself: the consolidation of owner/repo validation into Areas specifically checked and found clean:
Per the skill's scope, this excludes style/naming/coverage commentary (that's |
|
Last security-reviewed head: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ee0509d6b7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Claude has reviewed this PR 1 time. The lane skips further automatic reviews after 5; deleting this comment resets the count. |
An earlier commit on this branch replaced `tr '[:lower:]' '[:upper:]'` with
`${PROVIDER_FUNC^^}` in onboard-adapter/generate-adapter.sh. The case-folding
expansions are bash 4.0+, the script carries no version gate to keep one
behind, and its shebang is `/usr/bin/env bash` - so on a stock macOS, where
that resolves to the system bash 3.2, `^^` is a fatal expansion error and
every valid spec aborts there before an adapter is written.
Reported by an automated reviewer on #3710 as a P1. Verified rather than
taken on trust:
- The rule is the repo's own, not the reviewer's. scripts/check-drive-root-litter.sh
states it at line 143 and gates its `${var,,}` folds behind a Windows host
check for exactly this reason; lib/hook-utils.sh documents 3.2+ support.
plugins/work-items/README.md describes the skills' mechanics as POSIX-shell
and declares no bash-4 floor.
- Audited the whole branch diff for the same class rather than just the one
line reported: case-folding, `declare -A`, mapfile/readarray, `&>>`, the
`${var@X}` transforms, negative array indices, coproc, globstar, `wait -n`,
`read -N`, `printf '%()T'`. Three case-folding hits, of which two
(preflight.sh `${p,,}`) are pre-existing - they show as additions only
because an shfmt reindent moved the whole `case` block, and both appear
unchanged on the deletion side. One genuine regression, the one reported.
The code is now byte-identical to what it replaced. A comment names the
constraint so a later tidy pass does not re-apply it, matching the note
already in this file for `$(<"$file")`.
Recorded as a Known issue rather than fixed here: check-shell-portability.sh
reasons about GNU-vs-BSD userland, not bash version, so `${var^^}` and
`${var,,}` pass it. That blind spot is why this went green through every
lane. Widening that gate changes the gate's contract, which is not this
PR's to do.
Verification: generate-adapter.test.sh 141/141; affected-tests.sh --run
232 shell suites pass (exit 3, NOT-RUN lanes only, none touched by this
delta); shellcheck, shfmt -d, editorconfig-checker, check-shell-portability
against origin/main, em-dash purge, and all four changelog-parity modes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
`source-control/CHANGELOG.md` carried a Known-issues bullet saying the `--help` truncation bug "survives in two more scripts" and that they "need a different terminator" - written mid-sweep, before the fix existed. The fix shipped later on this same branch: the awk first-non-comment-line terminator in `lib/resolve-convention-pattern.sh`, propagated to the guardrails copy and recorded under guardrails 0.31.6. A reader of the merged source-control changelog alone would have been told an open bug was still open. Verified before changing it: the bullet names exactly the sync-cluster pair that 0.31.6 fixes, and its stated reason the blank-line terminator was not transplantable is the same reason 0.31.6 gives for using awk instead. Rewritten as past tense and folded into the Fixed entry it belongs to, so the discovery is still recorded without the stale warning. It is not claimed as a source-control fix, because it is not one - the cross-reference names where it landed. No version bump: this edits prose in an entry this branch added, which has not shipped. Reported as a non-blocking documentation note by the /review:code-review lane on #3710, whose broader pass found no correctness or maintainability defects. Verification: all four changelog-parity modes, em-dash purge, editorconfig-checker. The file is on the affected-tests no-suite allowlist (a non-shell CI lane covers it), so no suite maps to it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD
…iation main advanced again while this branch was running: #3710, the competing repo-wide tidy sweep, merged in full. Far smaller than the first reconciliation, which is what convergence looks like: 15 overlapping files against 69 last time, and 10 real conflicts (7 CHANGELOG, 1 plugin.json, 2 source) against 52. Version and changelog conflicts resolved to main's side again, on the same verified premise as before: this branch's only edit to any plugin.json is the "version" line, so nothing of main's is lost. The renumbering follows in the next commit, because main has since published versions this branch was already carrying. The two source conflicts: - repo-fleet-hygiene/skills/audit/scripts/audit-fleet.test.sh: both sweeps independently wrote a comment explaining that the _file assert forms are the general ones and the two-argument forms the common case. Same content, two placements. Took main's, per the standing rule that equivalent restatements resolve to the published base. Resolved the two hunks in place rather than taking the whole file, so this branch's earlier content elsewhere survives. - source-control/skills/pull-request/scripts/fetch-annotations.sh: genuinely two-sided. Ours (G85) is one jq pass that projects and filters together; main kept two passes with an early exit when there are no check-runs. Took ours, because it is the verified side: G85 drove it over 240 payloads against the two-pass form it replaced with 0 mismatches, plus a positive control showing the dropped intermediate was dead on the --failed path and live on the other. The empty case is still handled, one guard lower, and its comment is the more accurate of the two ("--failed can legitimately match none"). Adopted main's `{id, name, conclusion, status}` shorthand, which jq expands identically. Worth recording: main independently FIXED the --help truncation defect G85 had found and deferred in that same file. Its `usage()` now terminates the header slice on the first blank line (`sed -n '2,/^$/p'`) instead of a hardcoded line 20, so the banner stops swallowing exit codes 1, 2 and 5, and main added two tests pinning it. That fix sat outside the conflict and merged cleanly. Verified after resolving: `--help` prints all four documented exit codes and both new tests pass. The Known-issues entry this branch wrote about it is now false and is dropped in the renumbering commit rather than left to mislead. Verification: no conflict markers anywhere in the staged tree; shellcheck and shfmt -d clean on both resolved files; fetch-annotations.test.sh green including main's two new --help assertions. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
No related issue: repo-wide maintenance sweep run interactively from a Claude Code session; no tracker issue exists for it.
Summary
The final PR of a whole-repository code-tidying run. Waves 1-5 merged as #3635, 6-7 as #3700, 8 as #3702, 9-12 as #3706; this branch carries the rest and completes the sweep.
All 70 groups are done. Every sweepable code file in the marketplace was covered, in dependency-ordered groups, with three skills applied per group in order:
/code-tidying:audit-comment-residue(APPLY),/code-tidying:dissolve-comments,/code-tidying:batch-simplify repo.The method is the reason this is worth reading. One worker per group, then a fresh-context refutation verifier whose job was to fail to construct a behavior-difference counterexample before the group could commit. No human read these diffs, so the verifier was the only line of defence, and its evidence is quoted in each commit message.
That layer earned its cost. Verifiers corrected their workers on nearly every group, and in several cases the correction was the finding.
Excluded by design: markdown and prose,
.claude/**,.github/**, fixtures, vendor and evals trees, JSON/YAML manifests and schemas, lint configs, generated files, and ten generated-then-owned adapter files whose canonical copy is ambiguous. House doctrine enforced throughout: bare(#N)comment citations are sanctioned and preserved, dense rationale comments are deliberately kept, no cross-plugin deduplication, no new GNU-only shell constructs.Fix
Most of the diff is ordinary tidying: dead variables and fields removed, duplicated predicates extracted, hand-rolled loops replaced with the idiom the file already used, comment residue deleted or re-tensed. The findings below are the ones that are not tidyings.
A concurrency bug in the conformance runner. Every tracker binding
mktemps its binding file into$TMPDIR, and the overlay test case derived its path from that file's directory, so the overlay resolved to a single fixed path shared by every run on the host. Two concurrent conformance runs clobbered each other. Measured on separate pre- and post-change trees: 19 of 20 jittered parallel pairs red before, 0 of 130 runs red after, with a deterministic reproduction by planting a poisoned overlay. The failure is whole-suite poisoning that also shifts the reported case count, so matching case counts was never the regression guard it looked like.Scope, stated carefully because it is easy to overstate: this explains the
jira.test.shentry inscripts/run-plugin-tests-serial.txt, and the evidence is an asymmetry the mechanism predicts (under the CI shape jira loses the race 13 times in 25 while its partner loses 2). The other listed entry,tool-honesty.test.sh, is a markdown contract test with no reference to the tracker; this cannot explain it. #3694 stays open. The collision also cannot fire whilejira.test.shis serial-listed, so this is a precondition for delisting it, not a repair of a currently red lane.A lease verb reporting a write that never happened. When the store rewrite could not run,
mktempfailure left the temp path empty, the redirect failed,&&short-circuited past the move, and the exit status came from a trailingjq. Result: exit 0, arenewed_aton stdout, and a store still holding the old timestamp. Now exits 1, the code the contract defines for this class.Two test suites that were silently lying.
spawn-census.test.shcalledassert_not_containstwice and never defined it. Both calls died ascommand not found, incremented nothing, and the suite still exited 0 with 28 passing lines against 30 call sites. The two dead assertions guarded exactly the false green that plugin exists to refuse. Proven by mutation, not argued: emitting the false-green shape left the old suite at exit 0 with zero failures.typos-format.test.sh's spawn tracer had never worked. It deliveredPS4as an exported variable, but bash overwrites and re-exportsPS4at startup, so the tracer matched 0 of 802 trace lines and four of five assertions passed on an empty word list. Repaired via aBASH_ENVpreload; 765 of 803 lines now marked. The stale jq expectation was corrected 2 to 1, confirmed with a counting shim rather than the repaired tracer, so a tracer bug could not substitute one wrong number for another.A
--helpthat dropped three of its four exit codes.fetch-annotations.shsliced its header with a hardcodedsed -n '2,20p'against a 23-line header, printingExit codes:and0 successand then stopping. The same bug was then found surviving in a synced pair elsewhere, where the first fix was not transplantable (no blank line before the code), and was fixed separately on the canonical.Test-integrity fixes. Two suites registered fixture directories from inside a command substitution, so the append never reached the cleanup trap and they leaked 27 and 6 directories per run. Two probes wrapped a
jqcount in2>/dev/null || echo 0where the expected value is0, so a broken probe scored identically to a passing assertion. One suite compared two empty greps because it derived a path from the wrong variable.Coverage findings, which became the run's largest non-tidy result. The repository's answer to "is this file covered?" is unreliable in ways that need different fixes, so they are not one finding:
gate_common.pyreads as zero-coverage but 190 of its 392 entries execute across two suites.import foois invisible; a bare file-exists check that would pass against an empty file; and a suite thatmkdirs its own fake adapter directory and never runs the real file.The sharpest instance: one adapter script selects 202 suites, of which exactly one exercises it. That number is measured, not reasoned — the method was to poison the file with an early
exit 99on a copied tree and count which suites notice.And the sharpest consequence:
e2e-probe.sh's 16 assertions have never executed, so redirecting itsgh issue closeto a different repository leaves every automated suite green.Silent-skip findings.
powershell-format.test.shreportsPASS=15 FAIL=0while skipping 56 of its 71 assertions.check-silent-skips.shcannot see it: line 159 excludesplugins/*/hooks/*.test.shas fixtures and line 167 scans onlyscripts/*.test.sh. Separately, roughly 40% oftypos-format.test.shhas never run in CI at all, because it gates on a realtyposbinary that lives in a different job with no shared PATH.Verification
Per group, before commit: the repo's own
scripts/affected-tests.sh --runwith NOT-RUN ecosystems executed manually, shellcheck from the repo root,check-shell-portability.sh,editorconfig-checker,run-ruff.sh, and the package's own suites. Then a fresh-context verifier whose evidence is quoted in the commit.Union verification over the whole diff: 232 shell suites pass, all 24 NOT-RUN lanes run manually and green (650 babysit-prs tests plus 8 others), and every static gate passes: ruff, shellcheck,
shfmt -d,node --check, awk parse, editorconfig-checker, shell portability, em-dash purge, both sync-cluster checks, silent-skips, discriminating-skips, and all four changelog-parity modes.The verifiers went well past reading diffs. Representative work:
Corrections the verifiers made, which are the reason the layer exists:
gh apicall. Killed by zero of 649 tests. A discriminating test was added.Two verifiers also caught their own instrument failures: mutation batteries that silently failed to apply, which would have produced false confirmations, detected by explicit applied-counters and re-run.
One regression survived all of that and was caught on review, which is worth recording plainly. A simplification in
generate-adapter.shreplacedtr '[:lower:]' '[:upper:]'with${PROVIDER_FUNC^^}. The case-folding expansions are bash 4.0+, that script has no version gate to keep one behind, and its shebang is/usr/bin/env bash, so on a stock macOS the generator would abort on every valid spec before writing an adapter. Reverted in 0.39.61; the line is byte-identical to what it replaced. The branch diff was then audited for the whole class rather than the one line reported (case-folding,declare -A,mapfile/readarray,&>>, the${var@X}transforms, negative array indices,coproc,globstar,wait -n,read -N,printf '%()T'): three case-folding hits, two of them pre-existing${p,,}inpreflight.shthat read as additions only because anshfmtreindent moved their wholecaseblock. One genuine regression, now fixed.Related
Completes the series begun in #3635 and continued through #3700, #3702 and #3706, each of which merged mid-run and could not carry follow-up work. This branch was reconciled onto the current base after each merge.
Findings recorded in the relevant plugin changelogs under Known issues rather than fixed here, because each is a product or contract decision rather than a tidy:
PATH, running underenv -i, or forking without exec. Three of those emit a tidyspawns=0 rc=0 [], the confidently-wrong-number shape that script's own header exists to refuse.ai-sloplack word boundaries and fire on unrelated words. Left unfixed deliberately: that detector is the instrument this sweep is measured with, and changing what it matches mid-run would make earlier and later groups incomparable..pyfiles are formatter-dirty at HEAD with no CI gate enforcing the formatter, so hook-driven reflow will keep riding into unrelated diffs.scripts/check-shell-portability.shreasons about GNU-vs-BSD userland (grep/sed/date/stat/mktemp/sort), not bash version, so${var^^}and${var,,}pass it. That is the blind spot thegenerate-adapter.shregression above went green through. Widening the gate changes the gate's own contract rather than fixing a plugin, so it is filed rather than done here.🤖 Generated with Claude Code
https://claude.ai/code/session_01LRWf55tWpxcSdpxEMh2eJD