refactor: behavior-preserving simplification sweep (all 74 groups) - #3712
Conversation
… 2.1.251 Batch-simplify group G01 (root config). Dependabot #3500 bumped the @anthropic-ai/claude-code devDependency to 2.1.251 but left the allowScripts pin at 2.1.246, so the allow entry no longer matched the installed version. Same fix shape as the prior sweep's 2.1.209 lockstep restore (7cd56c9). All other root config surfaces reviewed and left unchanged deliberately (deliberate pins, universal-base design, decision rationale comments). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
…mmar branch (G04)
Batch-simplify group G04 (root scripts chunk 2). Two behavior-preserving
edits: collapse check-drive-root-litter.test.sh run()'s duplicated
if/else invocation into one call ('-' maps to the empty mount root the
SUT reads identically, per the helper's own comment), and replace an
`if X; then :; else` shape with the file's existing `if !` idiom in
check-fleet-audit-doc-grammar.sh. Remaining 20 files reviewed, no change
needed (self-containment and anti-assoc-iteration idioms are deliberate,
branches test-pinned). Suites: 26/26, 10/10, affected-tests fan-out
green (4 suites).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
…est variable (G03) Batch-simplify group G03 (root scripts chunk 1). Two behavior-preserving edits: extract the verbatim-duplicated block-violation report in check-discriminating-test-skips.sh's awk (depth==0 close vs END) into one flag_block() function and reuse is_any_skip in is_bad_skip; inline the single-use `sedless` variable in affected-tests.test.sh. Messages byte-identical; differential worktree proof run for the suite-uncovered END path. Remaining 20 files reviewed, no change (selector doctrine, reversion records, and measured rationale comments are load-bearing). Suites: 7/7, 59/59, affected-tests fan-out 10/10 suites green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
…up (G05) Batch-simplify group G05 (root scripts chunk 3). Two behavior-preserving one-line removals: check-silent-revert.sh's `: >"$file_attr"` (the next line's redirect truncates the same file unconditionally) and check-rename-sweep.test.sh's `rm -f "$seed"` (the EXIT trap owns that cleanup; the seed's last use is above). The repo's bash-format hook additionally shfmt-normalized both files; `git diff -w` confirms the one-line semantic deltas. Remaining 20 files reviewed, no change (portability gate's "redundancies" are measured ablation decisions). Suites: 3/3, 130/130, affected-tests fan-out 3 suites green, silent-skips and portability gates re-run clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
… from single sources (G06) Batch-simplify group G06 (root scripts chunk 4). Two behavior-preserving edits: generate-catalog.mjs drops the KNOWN_CATEGORIES Set (byte-duplicate of byCategory's key set, both built from CATEGORY_ORDER) in favor of byCategory.has(); check-skill-portability.test.sh's verbatim-pin loop now iterates STAGED_COVERAGE's even indices so the eight staged ecosystem literals cannot drift from their pins. Catalog output proven byte-identical via `node scripts/generate-catalog.mjs --check` (validate-plugins.sh's own invocation); suite 92/92 pre and post. Remaining 20 files reviewed, no change (sync manifests are data contracts; infrastructure wording frozen). affected-tests exit 3 with the named Python lane run green (17 tests). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
…cts case 8 (G07) Batch-simplify group G07 (root scripts chunk 5). One behavior-preserving edit: case 8's write_registry call duplicated what reset_fixture had just written, and the next block overwrites the same file; sibling cases 7/2b carry no such call. Remaining 17 files reviewed, no change (sync manifests are data contracts; validator sections, review-lane rulings, and git-isolation decisions are all pinned or issue-cited). Suite 13/13 including the live end-to-end corpus validation; affected-tests green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
… validate.js (G09)
Batch-simplify group G09 (ai-briefing build tests + validate.js +
runner facade). One behavior-preserving dedup: pathToFileURL(HTML).href
was computed at the main render goto and again inside the gate-7
responsive loop; now a single HTML_URL const beside the other path
consts. Tests and facade reviewed, no change (assertions frozen,
per-file helpers each earn their keep, facade verbs preserved as
{install|test|all}). Suite 41/41 pre and post; affected-tests exit 3
with every named NOT-RUN lane self-run green (incl. knowledge 501/501).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
…lint and bash-format (G08) Batch-simplify group G08 (formatter-hook family: actionlint, bash-format, biome-format). actionlint-check.sh: hoist FINDINGS_JSON='[]' so the duplicated ok-emission arm collapses to one emission point, and align build_data_json's rationale comment with the sibling plugins' full text. bash-format.sh: remove the AGENT_CTX temp and duplicated emit_channels call (NOTICE composes into CTX/SYSMSG in place, all four composition shapes preserved per the #3406 suite) and drop a dead probe_err init. No spawn-count changes; biome-format and all tests reviewed, no change. Suites 45/51/46 green; hook-exec-form, silent-skips, cross-plugin-drift, affected-tests all green. Version bumps for the two touched plugins land in the run's consolidated bump pass. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
…se (G13) Batch-simplify group G13 (autonomy: lane hooks + setup mjs pipeline). One behavior-preserving edit: loadBinding's absent-case object carried a reason field with zero readers (only present/path/declarations/surfaces are consumed; the field never reaches stdout JSON). All hooks and the security-binding checker reviewed in full, no change (fail-open/closed choices, trust anchors, and rulings are deliberate and pinned). Fixtures 22/22 incl. byte-identical reproducibility; slice suite 4/4; affected-tests exit 3 with the named Node lane run green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
…efing meta doc (G11)
Batch-simplify group G11 (ai-briefing build pipeline). build-pptx.js:
decorate()'s showFooter/showLogo options were never overridden repo-wide
(footer block now unconditional, logo guard reduced to its data check),
plus a redundant template literal around an already-string padStart
expression. lib/parse-briefing.js: comment-only correction of the header
doc's meta shape to the frozen-test-asserted { meetingNumber, window,
sourcesLine }. Remaining 20 files reviewed, no change (sink emitters are
byte contracts; the EXTRAS sub-tier branch is live via
buildPatternsSlide). Suite 41/41 pre and post; PPTX archives
byte-compared entry-by-entry across an 11-slide-type fixture (60 entries
identical modulo wall-clock docProps timestamps).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
…s (G16) Batch-simplify group G16 (claude-config canonical libs + audit scripts). One behavior-preserving edit: the four action-plan jq extraction blocks shared an identical select/sort frame over $INPUT_JSON; now one findings() helper taking the static per-list suffix, with the file's injection posture preserved (suffixes are literals, plugin names stay --argjson-bound). Canonical managed-scope.sh/state-key.sh and permission-patterns.sh reviewed, no change (every function has live cross-plugin callers; no sync regeneration triggered). Suite 29/29; affected-tests fan-out 4 suites green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
… (G12)
Behavior-preserving simplifications from the repo-wide batch-simplify sweep:
- ai-slop detect.sh: feed the sort -u dedup directly from EXPANDED instead
of copying it into TARGETS first; the copy was overwritten by the very
next mapfile.
- plugin-quality packet-seal.sh: drop the record-loop count accumulator;
every enumerated file is either digested or aborts the run, so the sealed
count is exactly ${#files[@]}.
- testing cant-fail-scan.sh: remove the write-only x_cf2 exempt tally.
Nothing reads it: the line-scoped rule feeds no fired/declined math, and
the aggregate exempted counter already counts the record. The slug stays
a recognized case arm so it cannot fall through to the engine-drift arm.
The bash-format hook also normalized the file to the repo-root shfmt
shape (whitespace-only; the HEAD version was not shfmt-clean in-repo).
Verified: shellcheck and shfmt -d clean on all three; detect.test.sh
(188/188), packet-seal/packet-prune suites, and cant-fail-scan.test.sh
(92/92) pass; byte-identical outputs vs the parent revision for detect.sh
(mixed repo target), cant-fail-scan.sh --check and --findings (date line
excluded), and packet-seal.sh record/verify/empty-packet; affected-tests.sh
--run over the three files selected 18 suites, all green; cross-plugin
source-drift check green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
…k guard (G17) Batch-simplify group G17 (claude-config audit-instructions/audit-pass/ audit-permission-grants scripts). conflict-scan.sh: remove the redundant `if (!(ent in entities))` guard before an idempotent assignment (awk `in` does not autovivify; the value is always 1). emit-findings.sh: the `## Surfaces` zero-result list retyped all four rule-id strings its own rule_id() owns; now a loop composing them through rule_id(), closing the hand-copy drift class conflict-scan's COORD_ERE comment documents a shipped bug from. Frozen yaml_scalar predicate untouched. Remaining ten files reviewed, no change. Suites 48/48 and 119/119; differential runs byte-identical; affected-tests fan-out 6 suites green (incl. the cant-fail-scan coupling pin). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
…ard (G18) Batch-simplify group G18 (claude-config audit-permission-state + draft-auto-mode-rules scripts). managed-conformance.sh and permission-plane-lint.sh: redundant inner parentheses in awk SUBSEP membership tests removed, matching each file's own idiom elsewhere; outputs byte-identical. permission-state.test.sh: dead `[[ -n "$src" ]] || continue` after `src="$(command -v ...)" || continue` removed (success implies non-empty), plus formatter-hook whitespace normalization. Zero-writes property untouched (proof suite unmodified, 12/12). Suites 37/37, 69/69, 53/53; affected-tests 4 suites green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
…rip handling (G20)
Batch-simplify group G20 (claude-ops python audit engines + tool-failure
hook + spawn_noise lib). install_state.py: scan()'s setdefault loop could
never hit its already-present branch (counts starts empty,
count_by_entry keys are unique), now a dict comprehension. overlap.py:
frontmatter_description's quoted-scalar branch computed body.rstrip()
three times and carried a dead `!= ""` conjunct ("".endswith(quote) is
already False); hoisted once — the join/split normalization at the
return makes the value byte-identical in every case. Canonical
spawn_noise.py reviewed and untouched (no sync needed). ruff (pinned
wrapper) clean; suites 50 and 77 tests OK; affected-tests exit 3 with
both named Python lanes run green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
…y suites (G22) Batch-simplify group G22 (claude-ops observability/otel + plugins-skill scripts). Two behavior-preserving edits: claude-observability.test.sh drops skip_case/assert_exit/assert_file_exists (defined, zero callers) and prune-otel-store.test.sh drops assert_exit/assert_file_exists (skip_case kept — 8 duckdb-gated callers), plus the format hook's pass() reflow. cc-otel.sql, the prune family, and the fleet-state scripts reviewed, no change (retention guards deliberate; the lifecycle seam trio is pinned by a bash 5.2/5.3 propagation-bug rationale). Suites 33/33 and 112/112 (duckdb cases SKIP here, CI covers); affected-tests green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
…rds (G21) Batch-simplify group G21 (claude-ops known-issues + lanes + morning-brief scripts). check-all.test.sh: dead skip_case/assert_eq helpers removed (zero callers) plus the format hook's shfmt normalization. restart-consumer.sh: byte-identical lock_stamp/ lock_owner_pid accessors merged into one lock_uint helper (both call sites in acquire_lock; no guard weakened). telemetry-upsert.sh: five identical option-value guards hoisted into need_optarg with error wording preserved byte-for-byte (test-pinned) and the argc check kept so `--body-file -` still accepts stdin. Remaining twelve files reviewed, no change. registry_manager.py confirmed UNMAPPED (pre-existing, unedited, reported not allowlisted). Suites 14/153/91 green; affected-tests 3 suites green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
…n (G23) Batch-simplify group G23 (claude-ops audit-hook family). One behavior-preserving edit: skill-usage-expansion-audit.sh inlined the exact body of hook::jq_field (identical jq program and printf|jq pipe); now the helper call with the same spawn count and the same empty-on-missing/failure contract, comment updated to state it. A hook-telemetry-sink cleanup was attempted and reverted after affected-tests caught the byte-gated replica under .claude/hooks/ (deferred CROSS-GROUP). Suites 28/28 and 16/16; hook-exec-form, silent-skips, cross-plugin-drift green; affected-tests exit 3 with the named Python lane run green (96 tests). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
…xtraction (G23)" This reverts commit 57a618a. The refutation verifier proved behavior equivalence across all input classes but measured (strace) one ADDED fork per execution: the helper's nested command substitution costs a fork the inline form did not pay, on an always-on PostToolUse hook, against the marketplace hook-budget doctrine where spawn count is the cost driver. The commit message's "same spawn count" claim was false. The dedup's value is below that cost; the candidate moves to the run's deferral inventory as a HUMAN-DECISION item (dedup vs hook-budget fork cost). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
…PE array (G24) Batch-simplify group G24 (code-tidying plugin scripts). detect.test.sh: the forward parity loop re-ran the identical printf|sed pipeline mapfile had just captured into audited_paths; it now iterates that array (with the empty-array guard), same items, same order, same current-shell parity_ok mutation. dead-code-scan.sh: the SCOPE array was written and never read (grep-verified across skill, suite, SKILL.md). Remaining nine files reviewed, no change (the five-plugin allowed-tools-pairing cluster untouched; double git status is the fail-loud contract). Suites 162/162 and 53/53; affected-tests 18 suites green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
…ts (G25) Batch-simplify group G25 (context-budget mjs hooks + audit scripts). levers.test.sh: the identical 5-line CLEAN-check/report block appeared three times, now an assert_clean helper (per-suite pattern); the node validator programs pinning catalogue content are byte-untouched. measure.test.sh: five near-identical hermetic engine invocations extracted into an attr helper (flag order only; parser is order-insensitive), all 61 assertions untouched, plus the format hook's case-label re-indent. settings-write-ask.mjs and measure.mjs reviewed, no change (permission-decision shape and output schemas are contracts). Suites 3/3, 61/61, 12/12; affected-tests green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
… form (G26) Batch-simplify group G26 (context-guard zone hooks + statusline scripts). Whitespace-only: two case labels reindented to the canonical 2-space shfmt shape the file otherwise follows (the group failed `shfmt -d` on exactly these lines). All thirteen other files reviewed, no change — zone hysteresis, atomic counters, and the statusline near-fork are test-pinned or rationale-defended; the shim was left aligned with its rate-limit-guard sibling. Suites 16/53/24/73/36/49 green pre and post; affected-tests green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
…op dead local (G27) Batch-simplify group G27 (vendor-update family). Two edits to firecrawl's update.sh: the checkout guard moved after the -h|--help case, matching the boris/skill-authoring/playwright siblings (observable delta confined to `--help` outside a checkout: help + exit 0 instead of error + exit 2, the family behavior; `--bogus` outside a checkout still exits 2 with the same message, probed); and run_apply's dead `local latest=` dropped while keeping latest_cli_version as the registry preflight with a comment naming that intent. The other eleven files reviewed, no change (sibling shape differences investigated and judged deliberate or deferred). Suites 17/17 + three sibling suites green; cross-plugin drift gate green; affected-tests 4 suites green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
# Conflicts: # scripts/affected-tests.test.sh
…etry (G31) Batch-simplify group G31 (disk-hygiene guard/cleaner stack). One behavior-preserving edit outside all guard-decision surfaces: telemetry_enabled() had zero callers repo-wide (only the bash hook::telemetry_enabled exists elsewhere; the telemetry contract doc never names it; no test touches it; emit() self-guards on an unset sink). The guard imports the module but never calls the function. Everything else in the 18-file group is allow/deny/fail-closed surface or deliberately-shaped scaffolding and was left untouched per the safety boundary. ruff (pinned) clean; telemetry suite 3/3; affected-tests exit 3 with the named lane run green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
…d a redundant intermediate (G30) Batch-simplify group G30 (discovery gate scripts + contract suites). check-dispatch-artifact.sh: single-use `index_dir="$slice"` alias removed (output lines and 0/1/2 exit contract byte-unchanged). check-dispatch-artifact.test.sh: dead PREFIX reassignment removed (nothing after it reads PREFIX; fixtures hardcode the names). check-coverage-complete.py: `ok = all(...)` intermediate inlined; the awk twin keeps its flag loop (no all() in awk) and a six-fixture side-by-side probe shows both twins byte-identical on stdout and rc across exit 0/1/2. Remaining files reviewed, no change. Suites all green (58/58 twin suite included); affected-tests 3 suites green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
…p wrappers (G32) Batch-simplify group G32 (docs-hygiene audit scripts). audit-encapsulation detect.sh: three consecutive elif branches with identical bodies (.worktrees/, .claude/worktrees/, .git/worktrees/) merged into one; two `if [[ -s "$FILE" ]]` wrappers dropped around `while read` loops (a while over an empty file is already a zero-iteration no-op returning 0); one-use `rel` alias inlined. audit-noise detect.sh: one-use `abs` temp dropped in resolve_existing_path. compress detect-caveman.sh: no-op `head -1` removed (the jq filter `.[0].id // empty` already emits at most one line, proven directly). Remaining fifteen files reviewed, no change. Differential proof vs HEAD: audit-encapsulation detect.sh over the whole repo in all four flag modes byte-identical (891 and 717 lines), plus a purpose-built .worktrees/ fixture confirming the merged branch still filters; audit-noise detect.sh identical over mixed absolute/relative/ directory targets and from a nested cwd. Suites 77/201/35/14 green; cross-plugin drift, portability, and affected-tests (18 suites, including the yaml_scalar coupling guard) all green. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
… RC capture (G29)
Batch-simplify group G29 (desktop-notification + powershell-format +
ruff-format + typos-format). typos-format.sh: RUN_DIR's fallback
re-derived the file's directory with a `dirname` subprocess even though
the file had already replaced dirname/basename with parameter expansion
for spawn cost and computes FILE_DIR for hook::repo_root; now
`${root:-$FILE_DIR}`, matching ruff-format's `${root:-$FILE_DIR_POSIX}`.
FILE_DIR and `dirname "$FILE"` agree on every shape FILE can take here
(-f-validated regular file), and RUN_DIR is only ever a cd target.
ruff-format.test.sh: dead `RC=$?` removed (case 4c never reads it; 4d
reassigns). The family's FINDINGS_JSON tail-dedup shape does not exist
in these four, and the build_data_json comment is already aligned.
Suites: ruff 59/0, desktop-notification 54/0, powershell-format 15/0.
typos-format is 142/1 — a PRE-EXISTING environmental failure, verified
independently: this container's bash 5.2.21 does not import PS4 from the
environment (`env PS4='+@x@ ' bash -c 'echo "[$PS4]"'` prints `+ `), so
the suite's trace-instrumented spawn counters all read 0; the same
failure reproduces at HEAD with this commit's edits stashed, and an A/B
of the traced run across both hook versions is byte-identical.
hook-exec-form, silent-skips, cross-plugin-drift all green.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
…es, align rationale comments (G35) Batch-simplify group G35 (eol-normalizer + go-format + markdown-format), completing the nine-member formatter family. go-format.sh: the two-step `GENERATED=1` … `[[ $GENERATED -eq 1 ]] && break` collapses to a direct break inside the marker match (GENERATED is only ever set there, so the guard could never be false); plus the truncated build_data_json rationale comment completed to the family's canonical text (the 258e963 actionlint precedent). eol-normalizer.sh: same comment alignment, adapted for its `$1 = action` argument. markdown-format.sh: two dead stores removed (`MDLINT=()` before an if/elif/else that assigns or exits on every arm; `DIGEST_FILE=""` plus its trailing `|| DIGEST_FILE=""`, never read after either write) — the same class as 258e963's probe_err removal. Spawn counts unchanged; no jq pipeline swapped for a helper. Suites 51/54/171 green with baselines byte-identical. hook-exec-form, silent-skips, cross-plugin-drift, portability, em-dash gates green; affected-tests 6 suites green. Note: go-format.test.sh skips entirely without goimports, so the group installed one and ran that suite for real rather than accepting a vacuous skip. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
… fixture (G88) The worktree-pruner suite opened `tempfile.TemporaryDirectory(ignore_cleanup_errors=True)` at 42 sites and converted the result to a `Path` at every one of them. One `scratch_dir()` context manager now yields the `Path` directly, so the cleanup-error decision is stated once instead of being restated per test. Block structure is unchanged, so the tests that assert after the directory is gone still do. Behavior-preserving: the same 45 tests in this module and 650 across the suite, and the result is AST-identical to a mechanical replay of the three rename rules on the ruff-formatted base. Mutating prune_babysit_worktrees.py (attempt_directory_removal always true, the root-containment guard disabled, iter_worktrees dropping unrecognized entries, is_orphaned_entry always false) fails the identical eight tests before and after this change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
…shfmt shape (G99) create-item.sh was the only file across all five work-item-tracker adapters whose `case` branches were indented one level deeper than the `case` keyword, and the only one splitting a `||` guard with a trailing backslash. Both forms disagree with the repo's shfmt/.editorconfig policy and with the sibling gitea/github/linear create-item.sh, which already use the house shape. list-sub-items.test.sh's one-line `cleanup()` is expanded to the statement-per-line form the shell gates parse. Formatting only, applied by shfmt: no token, no control flow and no emitted byte changes. The adapters tree is now shfmt-clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
…items entries No new bumps: 0.55.48 and 0.39.62 are this branch's own unpublished entries. Three things in these bullets are worth the words: G88's fold is justified by MUTATION, not by a green suite. A 22-file test group is the one place where "all tests pass" proves nothing, because the change is to the tests. Four mutations of the module under test produce the same failing set at both revisions (3, then 8), spanning both branches of the rename, so the folded fixtures still catch what they caught before. Suite count held at 650. G93 WITHDREW a tighter form after writing it. Anchoring the sed prefix strip to line 1 is correct for the real input and diverges from the original if a line inside the extracted block also starts with that prefix. Unreachable in practice, refutable in principle, and fidelity.sh has no covering suite, so the form that is exact for every input won. I had reviewed and accepted the tighter version on the practical argument; the agent applied the stricter standard and was right to. G99's change is layout only, but `git diff -w` does NOT come back empty on it, because shfmt moves tokens across line boundaries (a trailing `\` continuation becomes a trailing `||`) and that reads as content to a whitespace-ignoring diff. Recorded so the next reader does not mistake the same signal for a semantic change. The local-markdown conformance binding, the only one that runs without live credentials, passes 81 cases 0 failed. Verification: all four check-changelog-parity modes 0 against origin/main; markdownlint-cli2 0 issues; check-purged-em-dashes 0; suite 650/650; conformance 81/81; shellcheck and shfmt clean on every changed shell file. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
…on (G96)
`create-item.sh` extracted gh's last output line with
`$(printf '%s\n' "$WIT_GH_OUT" | tail -n1)`. The following line already
strips the issue number off that URL with `${created_url##*/}`, so the
same `##` idiom reads the last line without a subshell, a pipeline fork
and an external `tail`.
Equivalent for every input, not only the reachable ones: appending a
newline and taking `tail -n1` yields the text after the final newline,
which is exactly `${var##*$'\n'}`; both collapse to the empty string for
empty input and for a value ending in a newline, and command
substitution has already stripped trailing newlines from `WIT_GH_OUT`.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
…G60) Test-DriveRootLitter.Tests.ps1 assigned $script:BaselinePath in BeforeAll and never read it: every test that needs a baseline passes -BaselinePath to the Invoke-DriveRootLitterAsObject helper, whose own parameter shadows nothing. Assert-CatalogEntry.Tests.ps1 held the catalog text in a single-use $script:Raw before handing it to ConvertFrom-Jsonc. Both are dead-store removals; no assertion, mock, fixture or ordering changed. Full suite before and after: TOTAL=448 PASSED=323 FAILED=124 SKIPPED=1 with a byte-identical failure set (the 124 are the pre-existing Windows-cmdlet failures on this Linux container). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
… (G61) Behavior-preserving cleanup of four Pester suites under skills/audit/tests/windows/lib: - Get-GpuDriverInfo, Get-PnpProblemDevices, Get-VendorUpdateCli: inline the single-use $script:LibPath intermediate into the dot-source. The path string passed to Join-Path is unchanged, so the same lib file is loaded. - Invoke-TrendAnalysis: drop the New-CheckStub -Notes parameter, which no call site supplies. An unbound [string] parameter binds to the empty string, so the stub now sets notes = '' and builds the identical object. No assertion, test name, tag, or fixture value changed. Verification: full tests/windows Pester run reproduces the recorded baseline exactly (TOTAL=448 PASSED=323 FAILED=124 SKIPPED=1, identical FAIL set). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
…shold The comment guarding the builtin `[[ =~ ]]` match cited "reports absent from ~100 KB, hard 141 from ~250 KB". Re-measured at 15 runs per size with the id on the section's first line, counting runs where the `printf | grep -qE` pipeline returned nonzero under `set -uo pipefail`: 2/15 at 64 KB, 7/15 at 100 KB, then 15/15 from 128 KB. It is a race against the 64 KB pipe buffer, not a size threshold, so it starts earlier than recorded and turns deterministic earlier too. The original figures came from single-shot probes that happened to land on the passing side at 100 KB. The intermittent band is the part worth naming: a registered question reported missing only sometimes reads as a transient and invites a re-run rather than an investigation. Comment only; the guard itself is unchanged and remains correct at every size. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
The entry repeated the same imprecise measurement the source comment carried: "correct at 1 KB, wrong from about 100 KB, hard 141 from about 250 KB". The failure is a race against the 64 KB pipe buffer, not a threshold. Re-measured at 15 runs per size: 2/15 at 64 KB, 7/15 at 100 KB, 15/15 from 128 KB. 0.36.2 is unreleased on this branch, so the entry is corrected in place rather than superseded. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
… its function (G97)
wit_linear_lease_comments' doc block sat above wit_linear_activity_since's
own doc block and function, leaving the function it describes with no
comment at all and attaching its "ordered by handle then comment_id"
rationale to the wrong helper. That rationale is load-bearing for claim
arbitration, so reading it against activity_since misdirects exactly the
reader who needs it. The block moves down verbatim, to sit immediately
above wit_linear_lease_comments; activity_since's own doc ("it cannot
reuse wit_linear_lease_comments below") reads correctly either way.
Comment relocation only. Deleting the seven-line block from each revision
leaves the two files byte-identical, so the diff is exactly the move.
Verification: 169-case two-revision differential over all nine verbs plus
capabilities, comparing exit code, stdout, stderr, and the mock's recorded
GraphQL request log (URL + document + variables) — zero mismatches. The
negative control (one extra field in activity_since's query text) was seen
only by the request-log channel, confirming payload changes are observable
here. shellcheck, shfmt -d, check-silent-skips, check-shell-portability,
check-cross-plugin-source-drift, check-fixture-git-isolation and the
adapter's schema-check/fidelity.sh (17 operations verbatim, 0 mismatched)
are all clean; the eleven linear suites, both conformance-binding suites
and the nine Node/Python lane suites pass.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
…h (Phase 6.5 C3) clean-batch.sh and git-tree-reset-batch.sh each carried their own copy of the skip-list plumbing: the SKIP_HITS zero-fill, the per-repo match loop, and the UnmatchedSkip report loop. Move all three into lib/batch-common.sh, which both orchestrators already source, as batch_reset_skip_hits / batch_skip_match / batch_report_unmatched_skips over BATCH_SKIP_INPUTS + BATCH_SKIP_HITS. Behaviour is preserved exactly, including the two properties the duplicated loops encoded: the reported entry is the LAST one that matches, and EVERY matching entry is marked hit so a skip that did protect a repo is never reported UnmatchedSkip. Each call site keeps its own rationale comment. The zero-fill is moved, not dropped: under `set -u` a read of a never-assigned array element is an unbound-variable error, and the report loop reads every slot. Storing a different value there in a parent copy changes 229 of 364 differential cases, so the store is live. Adopting batch_resolve_repos for tree-batch's inline key_seen loop stays declined; the header now records the distinguishing input behind that decision (a repo directory whose name contains a literal backslash resolves under tree-batch's loop but folds to a non-existent path under batch_resolve_repos). Verification: affected-tests.sh --run over the four cluster paths exit 0 (31 suites); shellcheck + shfmt -d clean; check-shell-portability.sh and check-cross-plugin-source-drift.sh --check clean; a two-revision differential driving both orchestrators over 364 generated repo-list/skip-list cases (empty file, blank lines, surrounding whitespace, space/backslash/glob paths, duplicates, comment line, no trailing newline, CRLF) comparing stdout, stderr, exit code, spawn order/cwd/argv, the batch plan and every file written: 0 mismatches, with a first-match-wins mutation in the parent copy detected as 14 mismatches. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
Covers the Phase 6.5 cross-group resolution: the skip-list match loop, the SKIP_HITS initialization and the unmatched-skip report loop move from both batch orchestrators into lib/batch-common.sh. Also records the two rows the cluster declined, with the reasons rather than the verdicts. The repo-resolution row stays declined because a git repository whose directory name contains a literal backslash resolves under the inline loop and folds to a non-existent path under the shared helper. The contract text stays per entry point because it lives in each usage() heredoc, making it program output rather than comment. 0.10.30 is unreleased on this branch, so this extends that entry rather than opening a new one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
…hase 6.5 C6)
bash-format, actionlint-check and biome-format each encoded their findings
array with `printf | jq -R . | jq -s .` on every findings-bearing run.
FINDINGS_JSON has exactly one consumer in each hook, emit_tel, which returns
before doing anything when HOOK_TELEMETRY_SINK is unset. On the default
(unwired) path those two jq processes were pure cost.
Guarding the encode with hook::telemetry_enabled applies the rule the same
files already state for TOOL/FILE_REL. Measured per run with
`strace -f -e trace=clone,clone3,fork,vfork,execve`, findings-bearing payload,
3 reps:
sink unset bash-format 255/255/255 -> 236/248/242 lines, jq execs 3 -> 1
sink unset actionlint 139/144/141 -> 130/124/127 lines, jq execs 5 -> 3
sink unset biome-format 299/299/297 -> 281/282/282 lines, jq execs 3 -> 1
sink wired all three jq execs unchanged (5, 7, 5)
Folding `jq -R . | jq -s .` into a single `jq -R -s 'split("\n")...'` was
tried and is wrong, so the two-process shape stays and the refutation is
recorded at each site. Slurp mode decodes the whole stream as one string, so a
truncated UTF-8 lead byte immediately before a newline absorbs that newline
into a single U+FFFD and merges two findings into one array element; line mode
splits on the raw byte first. Minimal case: `printf 'a\xe2\nb\n'` gives
["a�","b"] through the pipeline and ["a�b"] through the fold.
typos-format needs no gate (its findings array falls out of the classifier it
runs anyway); it only gains the fallback-rationale sentence its three siblings
already carry on build_data_json, adapted to name `jq -c`, the call it
actually makes.
Verification: a two-revision harness outside the repo drove HEAD and working
copy over payload x target x telemetry matrices, comparing rc, stdout, stderr
and the telemetry envelope byte for byte: 42 cases per hook (168 total) plus
110 stub-driven cases for actionlint's AL_STATUS >= 2 branch, 0 mismatches.
Negative controls (inverted guard, altered context string, the refuted fold)
each produced mismatches before being reverted. affected-tests.sh --run over
the four paths: 4 suites, 286 assertions, 0 failures.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
…ner (G100) run-conformance.sh only; no assertion label, exit code, or stderr wording changes. - OVERLAY_PATH: the binding is re-homed into $BINDING_DIR two lines above, so the `cd … && pwd` derivation could only ever name that same directory. Use $BINDING_DIR directly and drop two forks. - Hoist the repeated `jq -c '[.items[].id]'` and `jq -r '.reason'` reads of an unchanged $WIT_OUT into locals, matching the IDS/PIDS idiom the sibling e2e-probe.sh already uses, and drop one jq spawn each. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
…o 0.6.31
Closes the C2 version and changelog discipline the C6 resolution cluster
deferred to the wave orchestrator, since its brief forbade touching manifests
and changelogs.
biome-format still carried the published 0.6.30 while this change set modifies
its hook, which check-changelog-parity --check-bump reports as PUBLISHED VERSION
REUSE; it moves to 0.6.31 with a new entry. actionlint, bash-format and
typos-format already carry unreleased entries on this branch, so the C6 content
extends those rather than opening new ones.
Each entry records the measured spawn counts rather than asserting an
improvement, and records the fold that was tried and refuted: folding
`jq -R . | jq -s .` into a single `jq -R -s 'split("\n")...'` is not equivalent,
because slurp mode decodes the stream as one string and a truncated UTF-8 lead
byte immediately before a newline absorbs that newline into a single U+FFFD,
merging two findings into one array element. Verified directly:
`printf 'a\xe2\nb\n'` yields ["a","b"] through the pipeline and ["ab"] through
the fold, with the replacement character in each first element.
typos-format's entry states why it gets no gate: its findings array comes from
classifier output the hook produces regardless of telemetry, so there is nothing
to guard. Its one-token deviation from the shared rationale sentence is recorded
too, since its build_data_json calls `jq -c` where the siblings call `jq -n`.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
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 2m 48s —— View job Code review in progress
|
|
Claude finished @kyle-sexton's task in 2m 36s —— View job Security review in progress
|
|
Claude has reviewed this PR 1 time. The lane skips further automatic reviews after 5; deleting this comment resets the count. |
|
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: b61fcfc35e
ℹ️ 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".
…ifiable Codex flagged as P1 that scripts/affected-tests.sh reports this file UNMAPPED, so the sweep's changes to its frame-classification and manifest-path logic bypassed the affected-suite validation AGENTS.md requires. The finding is correct, and checking it showed the suggested remedies do not apply. The file is a standalone ESM script, exposed only as the `manifests` npm script and executing a top-level loop on import. It exports nothing, no module imports it, and no suite names it. So there is no co-located suite to add a reference to, and recording it in scripts/affected-tests-no-suite.txt would be false: that file's header defines an entry as a claim that a named non-shell lane covers the class, and the course-digest vitest lane covers the directory, not this file. The three edits were cosmetic and worth four lines: a `!!`-coerced local inlined into the truthiness test that consumed it, a nextFrame/isLastInRun pair collapsed into one optional-chained expression, and an intermediate screenshotsDir folded into a three-argument join. Reverting is the right side of that trade, since the alternative is shipping unexercised changes to frame classification. Also corrects the entry's commit count for these trees, which read thirteen and was already fourteen before this revert. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ
# Conflicts: # plugins/claude-ops/CHANGELOG.md
Fourteen tracker references across ten files cited #3712, which is a pull request for an unrelated repo-wide simplification sweep, not this work. A reader following any of them would land somewhere that says nothing about the guard they were reading. Filed #3719 as the actual tracking issue for this remediation and repointed all fourteen. Verified by reading #3712 rather than assuming the number was right; it was carried over from the audit notes and was wrong from the first commit. No behavior change: every occurrence is inside a comment or a doc sentence. Suites re-run to confirm, since two of the ten files are test files whose comments the sed also touched. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TY2eXP6jpKBfH4XSg2b5mj
Resolves the session-flow manifest and changelog conflict from #3712: the branch keeps 0.35.0 and carries main's [0.34.24] entry beneath it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DeUXtmRdmeWd4Wxxu1b7p6

No related issue: a repo-wide behavior-preserving simplification sweep run on request, not tracking a filed defect. The defects it uncovered are listed under Related so they can be filed separately.
Summary
A whole-repository
code-tidying:batch-simplifysweep. The 3,451-file universe was classified downto 1,190 code files, grouped into 74 dependency-ordered groups, and worked group by group. All 74
groups are complete, plus a Phase 6.5 resolution wave for the cross-group deferrals no single group
was permitted to make.
Every group ran as a pair: a simplifier that applied changes, then a fresh-context refutation
verifier that had not seen the simplifier's reasoning and whose job was to break the claim that
behavior was preserved. A verdict of "looks fine" counted as a failed verification. The passing
verdict is "I could not construct a counterexample, and here is what I tried."
The diff is deliberately small relative to the files read: 150 code files, net −11 lines. It is
close to line-neutral on purpose, and the arithmetic is worth stating rather than hiding. Removals
dominated through the group waves; the resolution wave then added lines back, because the two
changes it shipped introduce shared helpers, and because several refutations are now recorded as
comments at the site so the next reader does not re-derive the same false saving. Lines removed was
never the goal.
Several groups read their whole file list and changed nothing at all, and each is reported as a
result rather than a gap. What the sweep declined to touch is recorded alongside what it changed.
This branch has been merged with
maintwice and reconciled each time. While it ran,mainabsorbed a separate repo-wide tidy sweep, first in part and then in full. The second reconciliation
was far smaller than the first (15 overlapping files against 69, 10 conflicts against 52), which is
what convergence between two independent sweeps looks like.
Fix
Simplifications applied: duplicated logic folded into single helpers, dead stores and unread
accumulators removed, single-use bindings inlined, repeated derivations hoisted, and duplicated
fixture setup deduped in suites. Every plugin whose shipped files changed carries a patch bump and a
specific changelog entry.
One real bug fixed, found while claiming not to change behavior.
plugins/planning/scripts/check-open-questions.shlooked up deferred question ids withprintf | grep -qEunderset -uo pipefail.grep -qexits as soon as it matches,printfis thenkilled by SIGPIPE, and
pipefailpromotes the pipeline to 141, which the enclosingif !reads as"id absent". A question that was present got reported missing and the script died ungradeable.
It is a race against the 64 KB pipe buffer, not a size threshold:
printfonly takes SIGPIPE ifit still has data to write when
grepexits. Measured at 15 runs per size, id on the section's firstline, counting runs where the pipeline returned nonzero: 2/15 at 64 KB, 7/15 at 100 KB, then 15/15
from 128 KB. So small Briefs passed, mid-sized ones failed intermittently, and the failure only
became reliable once a plan grew. No test covered it. The builtin
[[ =~ ]]reads the stringdirectly and cannot SIGPIPE.
The intermittent band is the part worth naming: a registered question reported missing only sometimes
reads as a transient and invites a re-run rather than an investigation. An earlier revision of this
PR described the onset as "~100 KB, hard 141 from ~250 KB" on the strength of single-shot probes; the
100 KB probe had landed on the passing side of a coin flip. Corrected here, in the source comment,
and in the changelog entry.
One deliberate behavior change, stated plainly. In
plugins/firecrawl/.../update.shtheSKILL.md not foundcheckout guard moved after the--helparm, soupdate.sh --helpoutside aplugin checkout now prints help and exits 0 where it previously errored and exited 2. This was
originally logged as behavior-preserving, which was self-contradicting. It is kept because the family
convention supports it: of the six sibling
update.shscripts, three carry both constructs and allthree put
--helpfirst. Firecrawl was the only outlier.The single most useful result produced no diff at all
One group's candidate was to replace three blocking gates' per-field
printf | jq | trpayload readswith the shared
hook::jq_fieldshelper that ten sibling hooks already use. Spawn counts, measuredwith
strace, improved on every path (the claim gate went 28/21 to 23/12 execve/clone on a matchingcall), so against the hook-budget contract it was a clear win.
A 449-payload differential killed it. Three delta classes, two of which turn a blocking gate
permissive:
$()strips trailing newlines andhook::jq_fieldsdoes not, so a.cwdending in\nstopsresolving a relative worktree or
--body-filetarget and the gate goes rc 2 to rc 0..tool_input.commandvalues andblocks, while the helper rejects the over-count with rc 2, which the
|| exit 0converts to apermit. rc 2 to rc 0 again.
affected-tests.sh --runreturned 0 across all seven suites with those weakened gates in place,and every lint gate passed too. Only the differential caught it, on the three files where a false
negative matters most, since these gates are what stop a
--no-verifyor an out-of-containmentworktree. The change was reverted; the deferrals are the handoff.
A second near-miss of the same shape, caught in the resolution wave
The
formatter-hookscluster was sent to collapseprintf | jq -R . | jq -s .into onejq -R -s 'split("\n")…': one fewer process per fire on an always-on hook. It is not equivalent.Slurp mode decodes the whole stream as one string, so a truncated UTF-8 lead byte immediately before
a newline absorbs that newline into a single U+FFFD and merges two findings into one array
element; line mode splits on the raw byte first. Minimal case:
Same for
\xf0; not for\xc3. The fold was refuted (28 mismatches over 231 unit cases) and a"tried and wrong" comment now sits at each site. What shipped instead is the safe half: the findings
encode is gated on
hook::telemetry_enabled, since its only consumer returns immediately when thesink is unwired. Measured with
strace -f -e trace=clone,clone3,fork,vfork,execve, three reps, onthe default unwired path: jq executions 3→1 for
bash-formatandbiome-format, 5→3 foractionlint; with the sink wired, unchanged.typos-formatneeded no gate and took only therationale sentence its siblings carry.
Reverted or corrected after verification
No test suite caught any of these:
claude-opshook viahook::jq_fieldstracemeasured one extra fork per fire on an always-on hook. The commit's own "same spawn count" claim was false.markdown-formatDIGEST_FILE=""removaldocs-hygienehead -1removaljq -rprints a newline-bearing string across lines.knowledgeprocessLessonguard hoistcourse.jsoninto a silently skipped lesson and exit 0. 416 of 3,000 adversarial cases diverged.knowledgegenerate-manifests.js, all three editskindle-dedrmcomment000. It prints000000.instruction-placementspawn claimguardrailschangelog claimplanningSIGPIPE measurementThe
docs-hygieneandknowledgedecisions turned on the same tiebreaker in opposite directions:this repo's fail-loud doctrine. One change was kept because it made failure louder, the other
reverted because it made failure quieter.
On
generate-manifests.jsspecifically, since a reviewer caught what this PR's own descriptionhad understated.
scripts/affected-tests.shreported the file UNMAPPED, which AGENTS.md treats as anerror rather than "nothing to run", so the sweep's edits to its frame-classification and manifest-path
logic bypassed the required validation. Neither prescribed remedy applied: the file exports nothing,
no module imports it, and no suite names it (it is a standalone ESM script exposed only as the
manifestsnpm script), so there is no co-located or referencing suite to point at; and ascripts/affected-tests-no-suite.txtentry would have been a false claim, because that file's headerdefines an entry as a claim that a named non-shell lane covers the class, and the course-digest vitest
lane covers the directory while reaching none of this file. The three edits were cosmetic and worth
four lines, so the file went back to its
origin/mainstate.--explainover all 150 changed codefiles now exits 0.
The Phase 6.5 resolution wave, and why most of it is declines
27 of the sweep's 273 deferrals were CROSS-GROUP: fixes needing files from more than one group's
list, which is exactly what no single group was allowed to do. A resolution wave took them in
clusters, each agent holding the whole cluster. Most came back declined, and a decline with a
recorded reason is a result.
The
allowed-tools-pairing.test.shcluster refuted its own deferral. Three groups hadindependently reported that the per-skill allowlist branch is "dead in four copies, live in one". It
is not dead.
expected_grantedis called and its result immediately tested(
expected="$(expected_granted "$skill")"thenif [[ -n "$expected" ]]), so the four*)-onlycopies are a guarded optional taking a no-op path, which is a different claim. Planting a real
arm into the supposedly-dead
casefires the check(
FAIL: tidy: granted set drifted from the allowlist, rc=1); substituting the true value returns 0.The extension point is reachable, functional and discriminating. Corroborating:
da70c871, thecompeting sweep that landed on main and also ran fresh-context verifiers, touched these exact lines
to reindent them and kept the function.
The
watch/tempDirscluster was billed as "the cheapest genuine win" and is a decline — thefour blocks are byte-identical, but sharing them across four ES modules needs a module to import, and
creating files was forbidden. What it found instead is worth more: two sibling suites
(
render-quality-audit,render-triage-log) clean up withfor (const dir of tempDirs.splice(0))where the other four use
for (const dir of tempDirs) { … }; tempDirs.length = 0;. Those are notequivalent on the throw path.
rmSync'sforce: truesuppresses ENOENT but not EBUSY/EPERM, andsplice(0)empties the array before the loop body runs, so a throw on the first entry leaks everylater directory permanently while the other form leaves them queued for the next
afterEachtoretry. The shorter form that reads as a free one-line saving is the buggier one.
One cluster produced a fix.
repo-hygiene's two batch orchestrators each carried their own copyof the skip-list match loop, the
SKIP_HITSinitialization and the unmatched-skip report loop; thosebecome
batch_skip_match,batch_reset_skip_hitsandbatch_report_unmatched_skipsinlib/batch-common.sh. Two rows stayed declined on evidence rather than caution: adopting the sharedbatch_resolve_reposwas tested against a real git repository whose directory name contains aliteral backslash, where the inline loop resolves it and the shared helper folds the name to a
non-existent path and reports it invalid; and the
--repos-from/--skip-fromcontract text lives ineach
usage()heredoc, making it program output rather than comment. TheSKIP_HITSinit wasmoved rather than dropped because its positive control proved it live: storing a different value
there makes every
UnmatchedSkipline disappear (229 mismatches).What the merges revealed
Three resolutions would have shipped broken on a naive merge:
restart-consumer.shandtelemetry-upsert.sheach auto-merged into an inconsistent stateoutside any conflict marker: a dangling call to a renamed function, and two surviving definitions
of the same function. Neither is visible as a conflict; both were caught by grepping every
identifier after resolving.
observer.pyis the one place where preferring main's side would have been wrong. The siblinglines had already auto-merged from this branch, so main's conflict half would have deleted a
.strip(). Nothing in the 73-test suite distinguishes the two, so it would have merged green.fingerprint.mjswas treated as the highest risk, because this run had already measured that itssuite does not pin the algorithm. A 226-document corpus emitting 3,390 values per variant across
three window sizes confirms the resolution reproduces the merge base, this branch, and main
byte-for-byte, with both negative controls firing at 218/226 and 226/226.
Convergence was measured, not assumed. Every changelog entry was rewritten from the post-merge
diff rather than restored, because an entry claiming work main has since published is false. That
check rewrote fourteen entries after the first merge and more after the second.
Verification
Per group: the repo's own
scripts/affected-tests.sh --run,shellcheck,shfmt -d,check-shell-portability.sh,check-silent-skips.sh,check-hook-exec-form.sh,check-cross-plugin-source-drift.sh --checkandcheck-purged-em-dashes.sh, plus each ecosystem'sown lane (vitest,
tsc --noEmit, the pinnedrun-ruff.sh, Pester).Because the suites here often do not cover what was changed, each group also built a differential
harness comparing a pinned parent revision against the edited one, with negative controls (plant
a bug, confirm the harness detects it) and, for removed assignments, positive controls (put a
sentinel where the dead store was and confirm still-zero mismatches). That is not ceremony: one
assignment that looked exactly like a dead store produced 18 mismatches across 722 cases under
its positive control, proving it was a live default carrier, and it was re-plumbed instead of
deleted. Always-on hooks had spawn counts measured with
stracerather than asserted.Two refinements the later groups added, both after a harness proved blind:
adapter's negative control (one field added to a GraphQL query) was invisible to rc, stdout and
stderr; only an instrumented request-body log caught it. Same for the
watch/cleanup: withrmSyncdisabled outright the suites still reported 4 files / 15 tests passed, and only aleftover-directory check saw the leak.
introduced instead. A comment relocation, for instance, is proved unobservable by relocating and
rewording it again and confirming still-zero mismatches.
The Windows Pester lane does run here, and that changed how two groups were verified.
pwsh 7.6.5and Pester 6.1.0 are installed.Invoke-Pesterovermachine-health'stests/windowsgivesTOTAL=448 PASSED=323 FAILED=124 SKIPPED=1; the 124 failures are Windows-only cmdlets absent onLinux, and the set is deterministic (run twice, byte-identical). Both machine-health test groups
were held to a clean diff against that baseline. Two caveats a reviewer should have:
scripts/affected-tests.shreturns exit 3 for these files (Pester lane selected and NOT RUN), andCI has no Pester lane at all — zero invocations in
.github/workflows— sotests/windowsisunrun in CI and the differential is the only evidence for those groups. A green
test-windowscheckdoes not cover them. Of four negative-control plants against one of those groups, two were not
detected, which is the honest measure of how much the suite covers those particular files; the gap
was closed by driving the dot-source paths directly.
The final union verification, run serially over the changed code files, with every lane the repo
has.
affected-tests.sh --runexits 3, not 0, because 107 non-shell suites are selected and NOTRUN; each was then run directly:
affected-tests.sh).mjs(3 suites)Repo-wide static gates all rc=0:
check-shell-portability.sh --all(1,593 shell files),check-cross-plugin-source-drift.sh --check,check-silent-skips.sh,check-hook-exec-form.sh,check-purged-em-dashes.sh, and all fourcheck-changelog-parity.shmodes.Serially is load-bearing: the runner is deliberately sequential, and two concurrent invocations in
this shared checkout each produced a single non-reproducing failure in a different unrelated gate
suite, both of which pass standalone and neither of which reads any file this PR touches.
The one failure in that table is
acquisition/acquire.test.js > listWorkDirFiles, which recursivelywalks the machine's shared
/tmpunder a 5s default timeout. It passes 8/8 at--testTimeout=60000.Aptly, it failed here because this container's
/tmphad filled with the sweep's own scratchdirectories, which is precisely the "slower the longer a machine lives" property listed below.
A note on this PR's own CI history, since it is a worked example of the thing the sweep kept finding.
While the PR was a draft,
test-linuxandhook-utilsreported success in about twelve secondsand
test-windowsreported skipped, becauseci.ymlgates every heavy lane ongithub.event.pull_request.draft != true. Three green test lanes that had executed nothing. Markingit ready is what got them their first real run.
Related
Defects and coverage gaps the sweep measured but could not fix within a behavior-preserving
remit. This is the part worth filing:
generate-manifests.js. Not "it maps to zero shell suites" — it exports nothing,no module imports it, and no suite names it, so the course-digest vitest lane reaches none of it
despite covering the directory.
affected-tests.shcorrectly calls it UNMAPPED. Closing this needseither a real test, which means exporting
classifyLessonand is a source change beyond abehavior-preserving remit, or an owner decision about the script's coverage. An earlier revision of
this description asserted the vitest lane covered it; that was wrong.
work-items' githublist-items.shskips the gh-version ladder its siblings use.:37requests
--json …,issueType,blockedBy,…unconditionally, whilecommon.sh:229wit_gh_issue_view_json_fields()gates exactly those names behindwit_gh_has_native_surface,citing work-items: create-item is blocked by the gh>=2.94 sub-issue guard even when no gated flag is passed #3598/fix(work-items): gate gh 2.94 on native-surface flags only #3639 and noting that cloud images ship gh 2.45. So on an older gh,
get-itemandcreate-itemdegrade to null/0 whilelist-itemsshould fail outright. Two qualifications:gh issue list --jsonandgh issue view --jsonaccept different field sets, so the 2.94 thresholdmay not transfer exactly, and only a modern gh was available here, so the failing case was not run.
Out of remit either way, since fixing it changes behavior on old gh.
watch/suites leak temp directories on a throwingrmSync(thesplice(0)finding above).Restart-StoppedService.ps1'sShouldProcessgate is untested. Replacing it withif ($true)breaks no test, and under
-WhatIfthe original skipsStart-Servicewhile the mutant actuallyrestarts the service. No test anywhere passes
-WhatIfor-Confirm.provenancefingerprint algorithm is unpinned. Changing the shingle join separator or thewindow bound leaves the suite 40/40 green while altering every fingerprint the plugin has emitted.
Reconfirmed during the merge by two independent negative controls.
check-cross-plugin-source-drift.shcannot see intra-plugin drift. It iteratesfor plugin_dir in plugins/*/and compares across plugins, so five byte-identical file pairsinside
knowledge(.npmrc,tsconfig.json,register-hook.mjs,resolve-hook.mjs,vitest.config.ts) are unprotected. Confirmed withcmpon all five; the gate exits 0.affected-testsmapping lost its redundancy.drive-root-baseline.jsoncmaps to its Pester suite by textual reference; that basename appeared twice in the test file and now
appears once, in a docstring. Still mapped, but a future docstring edit would silently unmap it.
acquire.test.jsrecursively walks the machine's shared/tmpwhile asserting only that theresult is an array. Flaky by construction, and slower the longer a machine lives.
miro's MCP wire protocol is untested: 14.72% statement coverage, and 19 of 31 plantedmutations survive, including every one in
response.ts,stderr.tsandmiro-client.ts.tr -d '\r'fromprovenance'slist-corpus.shconfig reader is invisible to its suite.go-format.test.shskips entirely withoutgoimports, giving an always-on hook zero coveragewhile still reporting success. Confirmed here: the binary is absent, the suite prints
SKIP: no goimports binaryand exits 0.watching/models.jsfansaffected-tests.shout to about 200 suites on a basename match.hook::jq_fieldsfails withjq: Argument list too longon an actionlint run producing ~120findings (
lib/hook-utils.sh:1963). Pre-existing and identical before and after this PR, so nodifferential signal, but a real degradation on large workflows. It lives in the synced
lib/hook-utils.sh, so fixing it is a canonical-plus-17-copies change.plugins/knowledge/vendor/repo-analysis/repo-analysis.test.jshas a real suite and no CI lane.allowScriptsin the rootpackage.jsonis consumed by nothing in the repo. It occurs exactlyonce, with no script, workflow, gate or lavamoat tooling reading it, and it has drifted behind the
pinned
claude-codeversion twice.repo-hygieneships bash 4+ constructs (local -n,local -A,mapfile) whilecheck-shell-portability.shreasons about GNU-vs-BSD userland rather than bash version, so theypass every gate here and would fail on stock macOS bash 3.2.
--helphandlers disagree with their siblings:worktree-claim.shexits 2 rather than 0,and
worktree-create.shdocuments exit codes only up to 4 whileexit 5exists.shfmtis not a CI gate (ci.ymlmarks it optional; gated cases skip rather than fail), so therepo carries a long tail of non-conforming shell including
lib/hook-utils.sh. Worth knowingbefore reading any "brings the tree into conformance" claim. One consequence:
repo-hygiene/scripts/allowed-tools-pairing.test.shis the one copy of five thatda70c871did notreformat, so the bash-format hook will reflow it on the next edit and drag 16 unrelated lines into
whatever diff touches it next.
Deferred items are recorded per group with an explicit ground. Of 273 recovered from the run's
transcripts: HUMAN-DECISION 185, PROTECTED 50, CROSS-GROUP 27, TOO-LARGE 11. HUMAN-DECISION at 68% is
high for a fix-first contract; sampling the rows, most are genuine (paired doc-and-code changes,
documented boilerplate conventions, style calls with no behavior content), but a subset is really
"declined on judgment" wearing a softer label, and a few paired doc-and-code items are CROSS-GROUP
mislabeled.
One structural note for whoever runs the next sweep: agents were given a scoped file list but not
a scoped workspace, so isolation rested on discipline rather than structure. That produced two
near-misses in this run (a
git stashthat swept up two sibling agents' in-flight work, and a sharedscratch directory whose contents a sibling overwrote mid-comparison). Give each agent its own git
worktree.
🤖 Generated with Claude Code
https://claude.ai/code/session_01XsxC7nPL8mhm3JXL1rrjNJ