Conversation
--check auto-corrected drift: it WROTE tests/CLAUDE.md and exited 0. That made a check mode mutate the tree, made count drift structurally unable to fail CI (fail-open gate), and made tests/test_tests_claudemd_drift.py rewrite a tracked file on every test run. New contract: - --check (default) and --strict are READ-ONLY validation, never write. Drift is exit 1 with a "run --regenerate" hint. --strict is an alias reserved for future main-only CI wiring so the current CI contract stays stable. - --regenerate (deprecated alias --fix, still used by auto_merge.py) is the only writing mode, and now applies the same exactly-one assertion before writing so it can no longer launder a duplicated count line into a green tree. Count-line scanning hardened against the refine-r1 adversarial lens evasions: line-anchored and tolerant of spacing/colon-placement variants; labels restricted to exact ASCII Node/Shell/Python so a homoglyph label is MALFORMED instead of invisible; fenced blocks and HTML comments masked out (offset-preserving) so a format example is neither a duplicate nor a substitute for the real line; regeneration rewrites by match span in canonical form. Error text now shows the canonical format the matcher prefers instead of one it rejected. Preserved: exactly-one/dup detection (#679), vacuous zero-file exit 2, which now also guards the writing path. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Folds five more verified defects into the read-only gate fix. Each reproduced as a failing test before the fix. Format-variant evasion (refine-r1 lens C/D): the exact-literal regex missed `**Python (N suites)** :` and `**Python (N suites):**`, so a document could carry two contradictory counts with the gate green. Matching is now line-anchored and tolerant of spacing and both colon placements. Homoglyph evasion (case E): a Cyrillic look-alike in the label was invisible. Labels are restricted to exact ASCII Node/Shell/Python and any other count-line-shaped label is reported MALFORMED instead of skipped. Fence/comment blindness (cases F/G/H): a fenced-only count line satisfied the exactly-one requirement (and auto-correct then rewrote the number inside the documentation example), while a legitimate format example or commented-out line was reported as a duplicate. Fenced blocks and HTML comments are masked out offset-preservingly, so they are neither duplicates nor substitutes for the real line, and regeneration never touches them. Duplicate laundering: the writing path used unbounded re.sub with no exactly-one assertion, rewriting BOTH duplicates and exiting 0. It now runs the same structural validation before writing and rewrites by match span. --repo was accepted and ignored: every git ls-files ran in the process CWD, so --repo at an empty tree reported "[OK] counts match". cwd is threaded into every git call, the target must be a git work tree, and a failed ls-files is exit 2 rather than a silent zero. Vacuous-zero guard was an AND over all three families, so a single-language wipeout was auto-blessed. It is now per family; a deliberate removal is declared by hand-editing that line to 0 suites. Error text now shows the canonical format the matcher prefers instead of one it rejected. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… exit 2)
bin/cli.js propagated child exit codes with `result.status || 0`. spawnSync
reports `status: null` (and leaves `error` undefined) whenever the child was
terminated by a signal rather than exiting on its own -- SIGTERM/SIGKILL from
an operator, an OOM kill, or a CI job cancellation. `null || 0` collapsed that
to 0, so a signal-killed child reported SUCCESS.
This propagator is shared by every `aesop <namespace> <verb>` dispatch (~50
gate/lint/verify subcommands), so a killed `aesop gate secret-scan` was
indistinguishable from a passing secret gate: a fail-OPEN security gate.
Fix: route all three spawnSync sites (Python namespace dispatch, `init`, and
`init`'s python fallback) through a single `exitCodeFromSpawnResult()` that
fails CLOSED -- real numeric status verbatim, but spawn error or a non-numeric
status (null = signal-killed, undefined = unknown) exits 2. The namespace
dispatch also prints why it failed instead of exiting silently.
`init`'s fallback additionally collapsed a signal-killed child to 0 via
`fallback.status || (fallback.error ? 1 : 0)`; same fix applies.
Requiring bin/cli.js as a module now exports the helper instead of running the
scaffolder, which is the seam the tests use.
TDD: tests/cli-dispatch.test.mjs gains 6 assertions -- real codes propagate
unchanged, {status:null,signal:'SIGTERM',error:undefined} must exit nonzero
(2), SIGKILL/undefined status fail closed, spawn errors exit 2, and the
fixture is cross-checked against a real self-SIGTERM child on POSIX so it is
not an invented shape. Verified RED: the old expression yields 0 for that
fixture, the new one yields 2.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Owner
Author
|
Dissolving merge-queue batch: required check(s) absent from rollup: windows |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Merge-queue batch built by tools/merge_queue.py.
Members: #719, #725
Members are closed only after
git merge-base --is-ancestorproves their content landed on main.