Skip to content

fix(hooks): tail-anchor H-05 audit-log append + reject replace_all; block literal --no-verify (#172 #175)#210

Merged
SUaDtL merged 4 commits into
mainfrom
fix/tribunal-audit-guards
Jul 2, 2026
Merged

fix(hooks): tail-anchor H-05 audit-log append + reject replace_all; block literal --no-verify (#172 #175)#210
SUaDtL merged 4 commits into
mainfrom
fix/tribunal-audit-guards

Conversation

@SUaDtL

@SUaDtL SUaDtL commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator

Lane A2 — two guard-boundary hardenings from the tribunal audit.

What

  • Tail-anchor the H-05 audit-log Edit append check and reject replace_all #172 (security / audit-trail — reliability-003): the H-05 append-only guard (pre-edit.py, via new _hooklib.is_tail_append) now tail-anchors — an audit-log Edit is admitted only as a strict append (new = current + appended tail, old unique), and a replace_all Edit on an audit-log path is rejected outright. Closes the prior new.startswith(old) hole that let a mid-file insertion or multi-site suffix rewrite pass as an "append". Audit-trail integrity is conflict-hierarchy level 1.
  • Bypass both git guard layers via shell-indirected git + --no-verify #175 (security — appsec-002): new H-20 guard blocks a literal --no-verify/-n on git commit and a literal --no-verify on git push — the flag skips the .git/hooks git-enforce backstop, voiding H-01/H-02/H-09b/H-10b/H-14 for that op. Handles bundled/attached short-flag spellings (-nm, -nm=x, -vnm=y) via a char-walk that mirrors git's own cluster parsing; git push -n (=--dry-run) is correctly left alone.

Verification

  • 631 hook tests pass (+20 new across the two issues incl. the full bundled-flag matrix); py_compile clean; LF.
  • security-reviewer: PASS — after two rounds that caught real bypasses (bundled -nm, then attached-value -nm=x), the final adversarial pass drove every literal git commit -n spelling against the actual guard and cross-checked the allowed ones against real git: the entire literal bundled--n class is closed, no over-block regression, only the documented shell-indirection residual remains (out of scope per ADR-0010). The is_tail_append tail-anchor was verified not to over-reject any valid append.

Bumps ca 2.8.4 → 2.8.5. Documents both guards + the accepted residual in security-controls.md §Audit trail.

Closes #172
Closes #175

https://claude.ai/code/session_01PVTCDji6bEuf9SifQ8tfsa

SUaDtL added 4 commits July 2, 2026 14:27
security-reviewer HIGH (first pass): -nm/-vn clusters on git commit weren't
caught by the exact-token check. Add a left-to-right cluster scan that
recognizes -n before any argument-taking short flag (m/c/C/F/t/S/u) consumes
the rest of the token as its value; also stop token scanning at a bare --
(end-of-options) and require is_tail_append's old_string to be unique in the
current file.
…uard

security-reviewer HIGH (second pass): the -[A-Za-z]+ fullmatch gate in
_commit_no_verify_in_cluster skipped any token with a trailing non-letter
byte, so an attached-value cluster (-nm=x, -nm123, -vnm=y) was never even
inspected and let -n/no-verify through live against a real
.git/hooks/pre-commit. Root cause: match on the token's LEADING -+letter
instead of requiring the WHOLE token to be letters, then walk characters
after the dash and stop at the first non-alphabetic byte (an attached value
has begun) in addition to the existing argument-taking-flag stop.
…verify guard)

Version bump + README badge sync for the H-05 tail-anchor (#172) and the H-20
--no-verify guard (#175); documents both plus the accepted shell-indirection
residual in security-controls.md §Audit trail.

Claude-Session: https://claude.ai/code/session_01PVTCDji6bEuf9SifQ8tfsa
@SUaDtL
SUaDtL merged commit a8ea112 into main Jul 2, 2026
23 checks passed
@SUaDtL
SUaDtL deleted the fix/tribunal-audit-guards branch July 24, 2026 21:08
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.

Bypass both git guard layers via shell-indirected git + --no-verify Tail-anchor the H-05 audit-log Edit append check and reject replace_all

1 participant