credential gate: block message still claims a guaranteed audit log (#119 follow-up) - #224
credential gate: block message still claims a guaranteed audit log (#119 follow-up)#224firaen22 wants to merge 3 commits into
Conversation
|
Landed via owner-curated replacement — closing without merge (this repo's consolidation convention). Your current-head wording ( The mechanical gate proved "text corrected, runtime unchanged": AST identical modulo string constants, Thank you — catching that the message an agent reads at block time still overpromised, after the docs were already fixed, is precisely the residual-surface discipline this pack's own doctrine now teaches. |
What
#222 corrected both READMEs: the credential-gate override's audit log is best-effort, not guaranteed. The same overclaim is still live in the hook's own block message.
hooks/gate-credential-destruction.py:224, printed to the agent at block time:_log(lines 108-115) istry: … except Exception: pass— a failed write is dropped silently and never blocks. So the one string an agent actually reads when deciding whether to override still promises the guarantee #222 retracted, and it outranks the README for that decision: nobody consults the README mid-block.This is the same defect class already tracked in-repo as threat-model I6 (
skills-staging/2026-07-30-security-enhancement/UNCERTAINTY.md:111, and skill-vetting-security-invariants §148: "threat-model I6 said a failed write 'is logged' and both READMEs called advisory…"). #222 closed the README half; this closes the hook half.Change
One string, matching #222's wording:
Verified
ast.parseclean.rm ~/.ssh/id_rsa→ exit 2, new text printed.CRED_GATE_APPROVED=1 rm ~/.ssh/id_rsa→ exit 0. Unchanged.python3 .github/checks.py— all checks passed.Not changed
hooks/verify-before-stop.py:20says "the pass is logged for audit" but its own header already qualifies logging as best-effort four lines down, so it does not carry the same defect. Left alone rather than widened into this change.Second commit — the same overclaim in the docstring
Found while stacking a later change: fixing only
BLOCK_MESSAGEleft the identical guarantee in the module docstring, so this PR did not close its own defect class on the first pass._log)".~/.claude/hooks/hooks.log." → states that_logswallows every write error, so a failed or unwritable log is dropped silently and never blocks; the log is friction and telemetry, not a guaranteed audit trail.Left alone: line 43's "with the traceback logged", which describes the same best-effort
_logand is now covered by the corrected line 70.Re-verified after the second commit:
ast.parseclean, block path exit 2, override path exit 0,checks.pyall passed.Third commit — dual review of the second
Both families reviewed the docstring commit; both returned the same MAJOR, and it says my earlier judgment call was wrong.
_log)"._logwrapsos.makedirstoo and catchesException, so a non-write failure is swallowed the same way. Line 70 now says it swallows every exception, directory creation included.Re-verified after this commit:
ast.parseclean, block path exit 2, override path exit 0,checks.pypassed, andgrep -n 'logged\b'over the file now returns nothing — no unqualified logging guarantee remains.