fix(hooks): capability-commit gate no longer false-positives npm overrides keys as new deps - #983
Merged
Merged
Conversation
…es/resolutions keys isNewDepAdded() parsed the package.json diff line-by-line with no JSON-section awareness, so keys added inside an "overrides" block matched the dependency-key regex and flagged the commit as a capability commit. Incident: PR #980 (security overrides for qs/js-yaml/markdown-it) was blocked at pre-push as "new explicit dep in package.json" and needed the escape-hatch trailer. Fix: indent-based block tracking skips keys inside overrides / resolutions / pnpm blocks (they force versions of packages already in the tree — no new capability). Tracking resets at @@ hunk headers; a hunk editing deep inside an existing overrides block without its opening line in context remains a documented accepted residual. CLAUDE.md prose definition updated in sync per its own "prose and hook stay in sync" contract. Tests: 6 new cases (3 skip cases + 3 paired negatives incl. post-block dep, nested braces, hunk-boundary reset), RED observed before fix, 104/104 green.
prior-art.ts is a shipped file — its hash feeds the byte-identical install baselines (8 stacks×modes). SNAPSHOT_MODE=capture regen; each baseline diff is exactly the one prior-art.ts hash line; byte-identical.test.sh 2/0 green.
artyhoo
added a commit
that referenced
this pull request
Jul 11, 2026
… attention-only) (#984) Invited follow-up from the 2026-07-11 reviewer verification: the «prose definition and the hook stay in sync» promise at CLAUDE.md:36 had no enforcement — verified as a `#hope-as-gate` (attention-is-not-a-mechanism.md §1): zero automated checks referenced the capability-commit definition (searched principles/, audit-self/, scripts/, workflows under three phrasings). ## Change `packages/core/hooks/checks/prior-art.test.ts` — new describe block making the overrides-exclusion clause of the sync executable: - parses the `nonDepBlockRe` alternation out of `prior-art.ts` source; asserts every skipped block name is present (backticked) in the CLAUDE.md explicit-dependency bullet; - canonical-trio floor (`overrides`/`resolutions`/`pnpm`) guards against silently narrowing the regex; - paired negatives: stale prose missing a code block name fails containment; a moved/renamed bullet makes the extractor throw (loud, not silent-pass). RED observed before trusting the test: mutating CLAUDE.md (dropping `` `resolutions` ``) → 1 failed; restored → 108/108. Channel: runs inside `test:hooks` → pre-push + CI (audit-self), i.e. the check fires earlier than the human-review channel it replaces. Scope note: the sync is made executable for the block-exclusion clause specifically (the clause added in PR #983). The rest of the prose bullet (semver-prefix list, LOC thresholds) remains attention-synced — extending coverage is possible but was not invited; noted as future candidate. ## §1.7 Self-discipline check (REQUIRED if PR touches discipline-bearing files) ### §1.7 Forward-check applied The rule this PR strengthens («prose and hook stay in sync», CLAUDE.md:36) now fails at the earliest reachable channel instead of relying on reviewer attention: `packages/core/hooks/checks/prior-art.test.ts:180-247` executes on every `test:hooks` run (pre-push step + CI audit-self job). Paired negatives are non-vacuous — RED was observed against a real prose mutation before the test was committed. ### §1.7 Backward-check applied Class of this change = making an attention-only sync promise executable. Sibling surfaces where the same class occurs, swept: CLAUDE.md:38 LOC-thresholds + semver-prefix prose vs `prior-art.ts` `loc()`/dep-regex (GAP-KNOWN — deliberately out of invited scope, recorded above as future candidate); `packages/core/principles/09-doc-authority-hierarchy.test.ts` (doc-structure checks exist but none cover capability-commit definition — confirmed by grep, SWEPT-CLEAN for overlap); `.github/workflows/audit-self.yml` §7 trailer backstop (validates trailers, not the definition text — SWEPT-CLEAN); `packages/core/audit-self/audit-ai-docs.ts` (ai-docs drift scope, no capability-commit references — SWEPT-CLEAN).
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.
Follow-up invited by the maintainer after PR #980: the pre-push capability-commit gate false-positived npm
overridesentries as new explicit dependencies and demanded aPrior-art:trailer on a pure security-maintenance commit.Change
packages/core/hooks/checks/prior-art.ts:76-118—isNewDepAdded()now tracksoverrides/resolutions/pnpmblocks in the package.json diff (indent-based, resets at@@hunk headers) and skips keys inside them: they force versions of packages already in the tree, adding no capability. Documented accepted residual: a hunk editing deep inside an existing overrides block without its opening line in diff context can still false-positive — the existing escape-hatch trailer covers that rare case.packages/core/hooks/checks/prior-art.test.ts— 6 new cases: 3 skip cases (overrides, resolutions, pnpm.overrides) + 3 paired negatives (new dep after the block closes → still detected; nested braces inside overrides don't end the skip early;@@reset → conservative re-arm). RED observed before the fix (4 failed), 104/104 after.CLAUDE.md:38— prose definition updated in the same commit, per its own "the prose definition and the hook stay in sync" contract (CLAUDE.md:36).Incident evidence: PR #980 push was blocked with
reason: new explicit dep in package.jsonon commit whose only package.json additions were theoverridessecurity pins.§1.7 Self-discipline check (REQUIRED if PR touches discipline-bearing files)
§1.7 Forward-check applied
The refinement itself lands as an executable artifact at the earliest reachable channel, not prose: the skip logic is enforced in the pre-push hook path (
packages/core/hooks/checks/prior-art.ts:90-113) and pinned by paired-negative tests (packages/core/hooks/checks/prior-art.test.ts:112-176) that fail if the skip over-reaches (post-block dep still detected, hunk-boundary reset re-arms detection conservatively). The prose (CLAUDE.md:38) changed in the same commit as the hook, honoring the stay-in-sync contract.§1.7 Backward-check applied
Class of this change = capability-commit detection semantics. Surfaces where the class occurs, each swept:
packages/core/hooks/checks/prior-art.ts(the only detection implementation — fixed);.husky/pre-push+packages/core/hooks/shell entry points (grep for a bash duplicate of the dep-detection: none — the bash predecessor was fully ported per prior-art.ts:2-4 header, SWEPT-CLEAN);CLAUDE.md:38prose definition (updated in sync);packages/core/principles/11-build-first-reuse-default.test.ts(principle test consumes the SSOT register, not the dep-detection regex — grep shows noisNewDepAddedimport outside hooks/checks, SWEPT-CLEAN);.github/workflows/audit-self.yml§7 trailer backstop (validates trailer presence on commits, does not re-implement dep detection — SWEPT-CLEAN). No other surface encodes "what counts as a new dependency".