fix(release-lib): close six doctrine-deletion blind spots in governance rules - #619
Merged
Conversation
…ce rules _GOVERNANCE_RULES in .github/scripts/test_release_lib.py pins load-bearing sentences in the release skill by asserting a set of anchor tokens is present. A rule fires only when ALL its tokens are present, so it could detect its own deletion only if at least one token disappeared entirely when the protected sentence went. Six rules (footer BLOCK / never-auto-fill, publish read-back, immutable-tag hard rule, pre-tag BLOCK-on-nonzero, and two re-run HIGH rules) had every anchor token also occurring elsewhere in the skill, so the guarded sentence could be deleted while the rule stayed green -- the exact inversion of its purpose. Each is now re-anchored on a span unique to its own guarded sentence (verified `text.count(...) == 1` against the source and all three rendered payloads: ca, ca-codex, ca-pi). _KNOWN_WEAK_ANCHORS, the ratchet declaring the six as known-weak, is now empty. Pinned as a permanent RED/GREEN mutation proof (DoctrineDeletionMutationProofTest): each rule's whole guarded sentence (never just the new anchor span, which would make GREEN tautological) is located by marker pair and deleted from a copy of the real source text. The OLD (pre-#571) token tuple stays silent (RED, the reproduced defect); the CURRENT _GOVERNANCE_RULES entry catches it (GREEN, the fix). Version advance: ca -> 2.11.13, ca-codex -> 0.4.12, ca-pi -> 0.2.13. Closes #571 CHANGELOG: Six governance rules that pin load-bearing release-skill doctrine are re-anchored so deleting the sentence they guard is now detected instead of passing silently. Claude-Session: https://claude.ai/code/session_01QjJeSbcwPHwMmd6CEZeagB
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository YAML (base), Organization UI (inherited) Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
Merges origin/main's #620 (fix(hooks): stop a stale git-hook cache from authoring a false H-09b block, ca 2.11.11 -> 2.11.12) into this branch. This PR's diff is .github-only and did not touch core/pysrc/ or any plugins/*/hooks/ files, so #620's core-side changes (_githooks.py, doctor.py, the new AC-4 regression test) merged clean with no conflicts. Conflicts resolved by hand, all version/changelog surfaces: - CHANGELOG.md / plugins/ca-pi/CHANGELOG.md: union -- this branch's 2.11.13 / 0.2.13 sections kept ABOVE main's 2.11.12 / 0.2.12 sections, neither dropped. - plugins/ca/.claude-plugin/plugin.json, plugins/ca-codex/.codex-plugin/ plugin.json, plugins/ca-pi/package.json, README.md badge + ships-line: this branch's higher versions (2.11.13 / 0.4.12 / 0.2.13) win. - Root package.json: regenerated via tools/build-host-packages.py (no-op -- already matched plugins/ca-pi/package.json at 0.2.13). tools/sync-core.py --check and tools/build-surface.py --check both pass clean -- no core source conflict to resolve. H-09b note: the merge commit's raw diff trips the lexical CRYPTO_RE scan on the string "createHash" inside #620's own new test fixture (plugins/ca/hooks/tests/test_git_hooks.py) -- inert test-payload text proving the new heartbeat mechanism, never a real crypto call (no hashlib import or hash/sign/encrypt/TLS-config operation anywhere in the merged diff). auth-crypto-reviewer confirmed PASS against .codearbiter/security-controls.md's existing accepted-adversarial-payload precedent; security-gate-passed marker recorded via hooks/security-pass.py before this commit. Re-verified post-merge: check_badge_consistency.py, test_release_trace.py (29 passed / 34 subtests), payload_version_gate.py for plugins/ca and plugins/ca-codex (both report version advanced against the new origin/main base), build-host-packages.py --check --release-guard-base origin/main, test_release_lib.py (360 passed / 292 subtests, unchanged), and plugins/ca/hooks/tests (1349 passed / 153 subtests, matching #620's own reported count). Claude-Session: https://claude.ai/code/session_01QjJeSbcwPHwMmd6CEZeagB
SUaDtL
added a commit
that referenced
this pull request
Aug 6, 2026
Reconciles with #620 (fix(hooks): stale git-hook cache authoring a false H-09b block) and #619 (fix(release-lib): close six doctrine-deletion blind spots in governance rules), both merged to main ahead of this PR in the version-advance train. - CHANGELOG.md / plugins/ca-pi/CHANGELOG.md: union, this PR's 2.11.14 / 0.2.14 sections placed above main's 2.11.13 / 0.2.13 and 2.11.12 / 0.2.12 sections. - Manifests (plugins/ca/.claude-plugin/plugin.json, plugins/ca-codex/.codex-plugin/plugin.json, plugins/ca-pi/package.json) and README badge/ships-line: this PR's higher versions (2.11.14 / 0.4.13 / 0.2.14) win. - Root package.json: regenerated via tools/build-host-packages.py. - .github/scripts/test_release_lib.py: auto-merged cleanly -- #619's six re-anchored _GOVERNANCE_RULES entries (and its new DoctrineDeletionMutationProofTest class) coexist with this PR's two new --dry-run governance rules. 360 tests pass. - core/pysrc/_githooks.py + doctor.py and their three vendored copies: auto-merged cleanly, no stray conflict markers; sync-core.py --check and build-surface.py --check both confirm the merged core and rendered surface stay byte-identical / in sync. Post-merge verification: plugins/ca/hooks/tests full suite (1369 passed, 153 subtests), .github/scripts/test_release_lib.py + test_check_skill_proof_fresh.py + test_release_trace.py (413 passed, 328 subtests), check_badge_consistency.py, both payload_version_gate.py runs (--base origin/main), and build-host-packages.py --check --release-guard-base origin/main all green. Claude-Session: https://claude.ai/code/session_01QjJeSbcwPHwMmd6CEZeagB
SUaDtL
added a commit
that referenced
this pull request
Aug 6, 2026
Reconciles PR #618 (last wave-2 train slot, ca 2.11.15 / ca-codex 0.4.14 / ca-pi 0.2.15) against #620 (2.11.12), #619 (2.11.13), and #621 (2.11.14), all merged to main since this branch was cut. - CHANGELOG.md / plugins/ca-codex/CHANGELOG.md / plugins/ca-pi/CHANGELOG.md: union, this PR's newest section kept above the three incoming ones; no section dropped. plugins/ca-codex/CHANGELOG.md carries a pre-existing gap (no 0.4.12/0.4.13 headings on main despite the manifest bump) — not backfilled here, out of scope for this merge. - Manifests + README badge/ships-line: this PR's higher versions win (2.11.15 / 0.4.14 / 0.2.15); root package.json regenerated via tools/build-host-packages.py. - #621's core/surface edits (writing-plans, brainstorming, release SKILL.md, new core/pysrc/_intentlib.py) auto-merged with no conflict; #621 did not touch skill-author/SKILL.md, so this PR's Phase 5 citation edit there is the only change to that file. - tools/build-surface.py --check and tools/sync-core.py --check both pass on the merged core sources. - check_routing_index_parity.py re-run on the merged tree: still 4 surfaces / 130 skill-routine-wrapper entries / 84 agents / 146 routing-table rows, zero drift — #621's skill-body edits did not add or remove any skill/agent, so no new INDEX/routing drift appeared. - H-09b false-blocked on the stale cached 2.10.0 git-enforce.py (predates the #279 sensitive-scan exemption), which flagged the literal string "createHash" inside #620's own test fixture (plugins/ca/hooks/tests/test_git_hooks.py) as a crypto change. Cleared via the sanctioned path: auth-crypto-reviewer confirmed PASS (no real crypto/secret content anywhere in the diff), then hooks/security-pass.py was run from both the current worktree plugin and the stale cached 2.10.0 path (its git-enforce.py resolves repo_root() via `git rev-parse --show-toplevel` rather than the newer marker_root() seam, so it reads the worktree-local marker, not the unified main-checkout one). Re-verified post-merge: full hooks test suite (1369 passed, 153 subtests), check_badge_consistency.py, test_release_trace.py, payload_version_gate.py for plugins/ca and plugins/ca-codex, and build-host-packages.py --check --release-guard-base origin/main — all green. Claude-Session: https://claude.ai/code/session_01QjJeSbcwPHwMmd6CEZeagB
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.
Summary
_GOVERNANCE_RULESin.github/scripts/test_release_lib.pypins load-bearing sentences in the release skill by asserting a set of anchor tokens is present. A rule fires only when all its tokens are present, so it could detect its own deletion only if at least one token disappeared entirely when the protected sentence went. Six rules had every anchor token also occurring elsewhere in the file, so the guarded sentence could be deleted while the rule stayed green.Each is now re-anchored on a span unique to its own guarded sentence.
_KNOWN_WEAK_ANCHORS— the ratchet that declared the six as known-weak — is now the empty set.Counts below are re-measured against current
main(32b0992), not the issue's original numbers — the file has moved since #571 was filed (notably #617's run-15${VERSION}rename, which the issue's owngit rev-parse ... MAJOR.MINOR.PATCHquote predates).CHANGELOG:x10,auto-fillx2MUST NOT auto-fill a missinggh release viewx3,non-draftx4MUST verify the published Release by read-backpublished tag is immutablex2Correction means publishing a NEW versionpre-tagx25,non-zero exitx5,BLOCKx15BLOCK on a non-zero exitgit rev-parse ${TAG_PREFIX}${VERSION}x2,peel-tagx3never from a bare `git rev-parsepeel-tagsentences left both old tokens intactlatest-eligible: true`x5,single-targetx3this lane can only ever propose ONE rowlatest-eligible: truementions and two othersingle-targetmentions left both old tokens intactProof
Pinned as a permanent RED/GREEN mutation proof (
DoctrineDeletionMutationProofTest, new class in.github/scripts/test_release_lib.py), run against the realcore/surface/skills/release/SKILL.mdsource text, never a synthetic fixture:(start marker, end marker)pair, not the new anchor span in isolation (an isolated-span proof would be tautological: any unique string added as a token catches its own deletion, and the ratchet test already proves uniqueness) — is deleted from a copy of the source text._GOVERNANCE_RULESentry for that same rule reports it missing — proving the fix, and that the new anchor token actually falls inside the sentence it's meant to guard (asserted directly in the test).Exact counts:
python -m pytest .github/scripts/test_release_lib.py -q-> 360 passed, 292 subtests passed (357 pre-existing + 3 new:test_the_six_rules_are_exactly_the_ones_pinned_here,test_deleting_the_whole_guarded_sentence_is_red_under_the_old_anchor,test_deleting_the_whole_guarded_sentence_is_caught_by_the_current_anchor).GovernanceSurvivalTest.test_every_rule_has_at_least_one_uniquely_occurring_anchornow passes with_KNOWN_WEAK_ANCHORS == set().unittest discover -s plugins/ca/hooks/tests(via pytest) -> 1347 passed, 153 subtests passed - untouched by this change, run as a regression check.tools/sync-core.py --checkandtools/build-surface.py --check-> both OK (nocore/content changed by this PR - only the CI-side test file and version-advance surfaces).Also verified (issue's "verification habit" note)
The issue flags
grep -c(counts matching lines, not occurrences) as an unreliable way to check anchor uniqueness on this file's thousand-character single-line steps. Confirmed no.github/scripts/*.pyfile usesgrep -cfor this purpose - the onlygrep -cstring in the tree is the historical comment describing the defect, insidetest_release_lib.py's own docstring. All new counting in this PR usesstr.count.Version advance (merge-train slot)
ca2.11.11 -> 2.11.13,ca-codex0.4.10 -> 0.4.12,ca-pi0.2.11 -> 0.2.13 - rootpackage.jsonregenerated viatools/build-host-packages.py, rootCHANGELOG.mdandplugins/ca-pi/CHANGELOG.mdboth carry dated2026-08-05sections, README badge and ships-line updated. This PR's diff carries noplugins/ca/**,plugins/ca-codex/**, orplugins/ca-pi/**payload change (CI scripts only), sopayload_version_gate.py --plugin plugins/ca --base origin/mainand--plugin plugins/ca-codexboth reportno shipped payload change - version bump not required(pass), andbuild-host-packages.py --check --release-guard-base origin/mainreportsno Pi payload change - version bump not required(pass) - the version advance here is the merge-train bookkeeping convention this repo's history follows on every merged PR, not something any gate required.All post-commit gates run green:
check_badge_consistency.py,test_release_trace.py(29 passed / 34 subtests),payload_version_gate.py(ca + ca-codex),build-host-packages.py --check --release-guard-base origin/main,check_site_voice.py.Deviations from the task brief
env -u NO_COLOR python -m pytest ...; the sandbox rejected that exact command shape (it can't verifyenv's effect on a wrapped-minvocation), so tests ran instead viaunset NO_COLOR && python -m pytest ...- same effect, different shell spelling.main, not copied from the issue body, which was filed against an earlier revision of the skill.Closes #571
https://claude.ai/code/session_01QjJeSbcwPHwMmd6CEZeagB