Skip to content

fix(hooks): close _hooklib detection gaps + centralize the audit-guard path sets (deep-review HARD-GATE batch A)#132

Merged
SUaDtL merged 1 commit into
mainfrom
fix/hooks-detection-audit-guards
Jun 25, 2026
Merged

fix(hooks): close _hooklib detection gaps + centralize the audit-guard path sets (deep-review HARD-GATE batch A)#132
SUaDtL merged 1 commit into
mainfrom
fix/hooks-detection-audit-guards

Conversation

@SUaDtL

@SUaDtL SUaDtL commented Jun 25, 2026

Copy link
Copy Markdown
Collaborator

Deep-review 2026-06-24-root HARD-GATE batch A (3 of the 9 remaining enforcement fixes). Rides untagged 2.5.2 — no new version bump (CI version-bump guard allows changes on the untagged 2.5.2).

Each change followed the trust-boundary rhythm: RED tests proving the gap, then GREEN.

v2.rev.0016 — detection-regex gaps + de-fork the secret spec (secrets-001/002, architecture-001)

  • CRYPTO_RE: add rc2/blowfish (both forbidden by security-controls.md; a commit adding either previously passed the H-09b gate with no crypto-compliance review).
  • SECRET_RE: drop the leading \b so a secret keyword that is the trailing segment of a compound name (FARM_API_KEY = "...") matches. The \b never fired when the char to the left is a word char (the _). The right-hand quoted-assignment anchor still bounds the match, so a bare token: reference does not fire (verified by existing negatives).
  • De-fork: farm.ts SECRET_LINE (broad outbound redactor) and _hooklib.SECRET_RE (narrow commit gate) are deliberately distinct in shape. New plugins/ca/hooks/secret-detection-corpus.json pins their agreement region — real secret shapes both must flag, benign lines both must pass — asserted against SECRET_RE in test_hooklib.py and against SECRET_LINE (via redactSecrets) in farm.unit.test.ts, so CI fails on divergence. The false "kept in step … never disagree" comment is corrected.

v2.rev.0019 — centralize the audit-guard path sets (architecture-004)

The append-only-log and ADR-decisions path patterns were triplicated inline across pre-write/pre-edit/pre-bash. Lifted into _hooklib: AUDIT_LOG_NAMES / AUDIT_LOG_RE / is_audit_log, DECISIONS_DIR_RE / DECISIONS_PATH_RE / is_decisions_path. The three hooks now import one definition (pre-bash composes its shell LOG_NAMES/DECISIONS from the same constants — byte-identical patterns, verdicts unchanged). Adding an audit artifact now touches one file.

v2.rev.0021 — H-05 hardening + policy-doc alignment (migration-003, appsec-003, observability-005)

  • Block an Edit with an empty old_string on an audit log (new.startswith("") is always True, so the append check was bypassable).
  • Document the variable-indirection residual risk in the pre-bash N-3 note.
  • Mirror the H-05 regex scope gaps (exec N>, >>>, process-substitution) into security-controls.md §Audit trail as accepted residual risk.

Verification

  • Python: test_hooklib 61/0, test_hook_guards 86/0, test_hooks_cold_install PASS (REAL/STUB/NONE), test_migration_backstop 31/0, hooks unittest 525/0.
  • TS: farm typecheck clean, 147 vitest green, npm run buildfarm.js in sync.

The new crypto/secret test fixtures newly trip the H-10b gate (expected); the diff-bound pass was recorded via security-pass.py (AD-008 test-fixture pattern), not an /override.

Defers v2.rev.0020 (farm god-module refactor) to post-release per plan.

…d path sets

Deep-review 2026-06-24-root HARD-GATE batch A (rides untagged 2.5.2).

v2.rev.0016 (secrets-001/002, architecture-001): add rc2|blowfish to CRYPTO_RE
(both forbidden by security-controls.md, previously unmatched); drop SECRET_RE's
leading \b so a secret keyword as the trailing segment of a compound name
(FARM_API_KEY) matches (the right-hand quoted-assignment anchor still bounds it);
de-fork farm.ts SECRET_LINE vs _hooklib SECRET_RE into one CI-checked shared
corpus (secret-detection-corpus.json) asserted against both sides, and correct
the false "kept in step" comment to state they are deliberately distinct.

v2.rev.0019 (architecture-004): lift the append-only-log and ADR-decisions path
sets into _hooklib (AUDIT_LOG_NAMES/AUDIT_LOG_RE/is_audit_log, DECISIONS_DIR_RE/
DECISIONS_PATH_RE/is_decisions_path); pre-write/pre-edit/pre-bash now import one
definition instead of re-encoding the regex inline.

v2.rev.0021 (migration-003, appsec-003, observability-005): block an Edit with an
empty old_string on an audit log (startswith("") was always True); document the
variable-indirection residual risk in pre-bash; mirror the H-05 regex scope gaps
into security-controls.md.

Verify: test_hooklib 61/0, guard 86/0, cold-install PASS, migration 31/0,
hooks unittest 525/0; farm typecheck + 147 vitest green, farm.js in sync.

Claude-Session: https://claude.ai/code/session_01M3e2cHcf864YSxDmCohcET
@SUaDtL
SUaDtL merged commit 715dd6c into main Jun 25, 2026
22 checks passed
@SUaDtL
SUaDtL deleted the fix/hooks-detection-audit-guards branch June 25, 2026 12:56
SUaDtL added a commit that referenced this pull request Jun 26, 2026
* docs(changelog): roll the 2.5.2 HARD-GATE batch into the release notes

The [2.5.2] section existed for the deep-review quick-kills but predated the
HARD-GATE enforcement batch (#132, #133). Append those entries and correct the
section intro, which claimed "no enforcement-behavior change" before the gate
fixes landed. Re-dates the section to the release date (2026-06-25).

Scope: the ca plugin only. Batch C (#134) is ca-sandbox and belongs to the
ca-sandbox-v* series, not this v2.5.2 ca release.

Claude-Session: https://claude.ai/code/session_01M3e2cHcf864YSxDmCohcET

* fix(hooks): list rc2/blowfish in the H-09 advisory crypto reminder

Batch A broadened CRYPTO_RE to match rc2/blowfish but left the human-readable
post-write reminder string listing only MD5/SHA1/DES/RC4, so the advisory under-
described what the commit gate now catches. Align the reminder.

Claude-Session: https://claude.ai/code/session_01M3e2cHcf864YSxDmCohcET

* docs(ca): pre-release prose pass — tighten the core, dedup the lazy-load routers, reconcile to 2.5.2

Always-loaded core (ORCHESTRATOR.md): collapse the softened §0 duplicate of the
§3 hard rules, trim the register, and replace hardcoded `main` with "the default
branch". Lazy-load schema: routing-table.md is declared the single deterministic
trigger-to-route surface, reference-map.md the read-before-a-scope surface, and
skills/INDEX points to routing-table for routing; the redirect repeat-list
regains the dropped sprint/preview/metrics/task. SPRINT.md stops restating the
worker-seam philosophy (it lives once in farm.md). farm.md drops two redundancies.

Accuracy vs the merged HARD-GATE batch: arbiter.md no longer instructs a manual
DEV: exit line that SessionStart now writes itself (was a duplicate-audit-line
bug); auth-crypto-reviewer lists rc2/blowfish; release.md states the ca-only
window scope; checkpoint-aggregator's roster/sections are illustrative (the live
fleet is six reviewers, not four). README aligns the farm worker description with
the root README (OpenAI-compatible, Zen default) and restores the
"Claude still writes the failing tests" guarantee. Skill trims: debug frontmatter,
secret-handling stakes, a commit-gate Phase 4 redundancy.

Claude-Session: https://claude.ai/code/session_01M3e2cHcf864YSxDmCohcET

* docs(governance): reconcile .codearbiter docs to the merged enforcement + roll the docs-pass changelog note

security-controls.md: drop the misleading "(in new code)" qualifier from the
forbidden-crypto list (the CRYPTO_RE gate is line-based, context-free); name the
automated SessionStart `BY: session-cleanup | DEV: exit` write as the one
framework writer of overrides.log (observability-001); fix the dangling
CONFIRM-07 reference to ADR-0007. tech-stack.md: widen the manual secret-sweep
pattern to match SECRET_RE's compound-name and key-prefix shapes, and split the
H-09b (crypto) / H-10b (secret) attribution. coding-standards.md: the LF rule is
now a MUST (a diff that introduces CRLF on tracked text is rejected). CHANGELOG:
a Documentation note for the 2.5.2 docs pass.

Claude-Session: https://claude.ai/code/session_01M3e2cHcf864YSxDmCohcET

* docs(site): enterprise enforcement + hooks reference; fix the gate-catch demo and version pill

Adds a "How it works" sidebar group with two pages: Enforcement & Security (the
activation contract, the blocking commit-time gates H-01/02/03/05/09b/10b/11/14
with the digest-bound TOCTOU close and fail-closed-on-unreadable-diff behavior,
the advisory reminders and why they are advisory, the 2.5.2 hardening, and the
fail-loud + interpreter-dual-registration posture) and a complete Hooks reference
documenting every hook by event, script, controls, and fail posture.

Fixes: the GateCatchTerminal demo cited H-09 (the advisory reminder) for a block
that is actually H-09b, and showed a bare `git commit` going green after a fix;
it now routes the green path through the crypto-compliance gate so it matches the
real digest-bound mechanic. The two-axis diagram's highlighted version pill moves
to v2.5.2 (both the public/ and src/assets/ copies). concepts.md meta description
drops a prose-separator em-dash. Build + link-audit green (79 pages, 6952 links).

Claude-Session: https://claude.ai/code/session_01M3e2cHcf864YSxDmCohcET

* docs(ca): keep "no emojis" on one line in the register (fix test_ux_conversion)

The register trim line-wrapped "no\nemojis", and test_ux_conversion asserts the
literal substring "no emojis" is present. Rewrap so the substring stays intact.
No content change.

Claude-Session: https://claude.ai/code/session_01M3e2cHcf864YSxDmCohcET

---------

Co-authored-by: SUaDtL <SUaDtL@users.noreply.github.com>
SUaDtL added a commit that referenced this pull request Jun 26, 2026
…1.1 release (#136)

Mark the AUTO quick-kills (v2.rev.0001-0013, shipped in #127) and the HARD-GATE
batch (v2.rev.0016-0019, 0021-0025, shipped in #132/#133/#134 and released in
v2.5.2) as done on the board. v2.rev.0020 (farm god-module split) stays open as
the deferred post-release /ca:refactor; 0026/0027 stay open as the DECISION
CONFIRMs.

Adds ca-sandbox.release.0001: Batch C's container-isolation hardening (#134) is
in main on ca-sandbox 0.1.1 but the latest tag is ca-sandbox-v0.1.0, so it is
unreleased; /ca:release is ca-only (ADR-0007), so this needs a ca-sandbox release
path or a manual tag + Release.

Claude-Session: https://claude.ai/code/session_01M3e2cHcf864YSxDmCohcET

Co-authored-by: SUaDtL <SUaDtL@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant