diff options
| author | Craig Jennings <c@cjennings.net> | 2026-07-24 11:00:39 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-07-24 11:00:39 -0500 |
| commit | 781fa0786e2096797e630dcb81ffbc62ed98460b (patch) | |
| tree | e47a1662ed9ff8ea1b1744c407873974a6bd0b2b /todo.org | |
| parent | 267d1de7b8a8e7fd22b156433567c88216ec3d0f (diff) | |
| download | rulesets-781fa0786e2096797e630dcb81ffbc62ed98460b.tar.gz rulesets-781fa0786e2096797e630dcb81ffbc62ed98460b.zip | |
chore(inbox): park two hook fail-open fixes from .emacs.d
Diffstat (limited to 'todo.org')
| -rw-r--r-- | todo.org | 32 |
1 files changed, 32 insertions, 0 deletions
@@ -55,6 +55,38 @@ Grading: Minor severity (nothing broken now; the exposure is a future regression Fix: add =claude-templates/bin/*= to the =check_hook= loop, the same shape =languages/*/githooks/*= already uses for extensionless files. A no-op today by design — it passes immediately — which is exactly what a guard should do. +** VERIFY [#A] Parked: the secret-scan pre-commit fails open in ALL FIVE bundles (from .emacs.d) +:PROPERTIES: +:LAST_REVIEWED: 2026-07-24 +:END: +What arrived: .emacs.d found that =languages/elisp/githooks/pre-commit= builds its scan input as =added_lines="$(git diff --cached -U0 ... | grep '^+' | grep -v '^+++' || true)"=. With no pipefail and =|| true= swallowing everything, any git failure yields an empty string, so the scan searches nothing, finds nothing, reports clean, and the commit proceeds with the secret in it. The staged-file list feeding the paren check has the identical hole. + +*Verified independently, and it is worse than reported.* I reproduced the fail-open with a stub git that fails only the staged-diff call: exit 0 with an AWS-shaped key staged. Then I checked the other bundles, which the sender did not: *bash, go, python, and typescript all carry the same pattern and all fail open the same way.* Confirmed live on all five. Two of those (python, typescript) are hooks I wrote on 2026-07-24 by copying the bash one, so I propagated the defect while closing a different gap. + +Graded [#A] on severity alone, per the todo-format security carve-out: a credential-scanning gate that reports clean without having looked is a showstopper regardless of how rarely git fails. + +The sender's fix is correct and I verified all three axes on it: refuses to proceed when the diff cannot be read (exit 1), still blocks a real staged secret (exit 1), still passes a clean commit (exit 0). It splits the git read from the greps so a git failure aborts while "grep matched nothing" stays the ordinary case. + +Decision needed: the fix as sent covers elisp only. It should be applied to all five bundles, which is my scope expansion rather than the sender's proposal — hence a VERIFY rather than a silent apply. Also unresolved: where the two attached bats suites live, since the hooks are rulesets-owned and the tests currently sit in the consuming project. + +Prepared: [[file:working/hook-fail-open/pre-commit.diff]], plus =test-pre-commit-hook.bats= (8 tests) in the same dir. +Say "approve the hook fail-open fix" and it gets applied across all five bundles. + +** VERIFY [#B] Parked: remove the validate-el auto-test cap (from .emacs.d, Craig's call) +:PROPERTIES: +:LAST_REVIEWED: 2026-07-24 +:END: +What arrived: a superseding handoff. The first proposed a loud notice when the test count exceeds =MAX_AUTO_TEST_FILES=20= (above the cap the block was skipped, nothing printed, exit 0 — indistinguishable from a pass). Craig chose in the .emacs.d session to remove the cap instead. + +The reasoning is the valuable part. Measured, a whole family runs in under two seconds (calendar-sync 63 files / 633 tests / 0.9s), so the cap bought nothing. Worse, it was *concealing* a real cross-test pollution bug: calendar-sync exits 1 when its 63 files run in one process, because one test marks a calendar as syncing and never resets it, and a sibling file's test then hits the stale guard. Invisible from both directions — =make test= runs each file in its own Emacs, and the hook skipped the family for being over the cap. + +Verified the superseding file drops the cap entirely (zero references, gate is now =count -ge 1=) and removes the now-unreachable notice helper. + +Since Craig already made this call, the remaining decision is only adoption scope: removing the cap means other consuming projects run every stem-matched test file per edit, and one may go red on first use by surfacing pollution that per-file runs hid. The sender flags that as intended. + +Prepared: [[file:working/hook-fail-open/validate-el.diff]], plus =test-validate-el-hook.bats= (6 tests, two of which stage a deliberately failing test so a quiet pass proves the run happened). +Say "approve the cap removal" and it gets applied. + ** TODO [#B] cj-remove-block still can delete the WRONG cj block :bug: :PROPERTIES: :LAST_REVIEWED: 2026-07-24 |
