docs: a 2 is a question, not automatically a failure
TOOLS.md said "exit code 2 is never a pass", which is right and was only half the rule. The pre-commit hook read it as "2 is always a refusal" and made every deletion-only commit impossible while reporting a credential that did not exist. Both documents now carry the completed rule: on a 2, ask whether the check could have had anything to look at. The hooks README records the one place the two scripts are treated differently and why.
This commit is contained in:
parent
d7fe58883c
commit
418261b482
|
|
@ -69,6 +69,21 @@ the outside and only one of them is evidence. A hook or a CI step that treats a
|
|||
`2` as success has quietly turned the check off. Each script states its codes at
|
||||
the top; read them there.
|
||||
|
||||
**And a `2` is not automatically a failure either — it is a question.** The
|
||||
pre-commit hook learned this the hard way: `secrets.sh` exits `2` on a commit
|
||||
that only *deletes* files, because a deletion has no added lines to scan, and
|
||||
that is the correct answer. The hook treated every non-zero as a refusal and
|
||||
printed *"possible credential in the staged changes"* over a plain `git rm`, so
|
||||
deletion-only commits were impossible and the reason given was a security
|
||||
problem that did not exist.
|
||||
|
||||
The rule that came out of it: **on a `2`, ask whether the check could have had
|
||||
anything to look at.** The hook now refuses a `2` whenever the staged diff adds
|
||||
lines — because then the scanner did have input and checking nothing is exactly
|
||||
the failure `2` reports — and accepts it, saying so, when the diff only removes
|
||||
content. Both directions are proved with `prove-guard.sh`-style injections
|
||||
before either is believed.
|
||||
|
||||
The hooks are the other place work gets stopped:
|
||||
[`architecture/githooks/README.md`](architecture/githooks/README.md) has the one
|
||||
install command and the table of what each hook runs. Note that **`post-commit`
|
||||
|
|
|
|||
|
|
@ -68,6 +68,12 @@ exactly the failure it claimed to catch.
|
|||
It exits `2` for "nothing was checked", and the hook treats `2` as a refusal.
|
||||
A missing schema directory is not a clean schema.
|
||||
|
||||
**The secret scan's `2` is handled differently, and deliberately.** A commit that
|
||||
only deletes files gives it nothing to scan, which is the right answer rather
|
||||
than a fault — so the hook accepts a `2` when the staged diff adds no lines, and
|
||||
refuses it whenever the diff adds any. Before that distinction existed, `git rm`
|
||||
was impossible and the refusal claimed a credential had been found.
|
||||
|
||||
**`post-commit` pushes.** That is the intent — the commit that first added a
|
||||
pre-commit hook to the project this came from sat unpushed for a day, guarded
|
||||
and invisible — but it is a surprise if you were not expecting it. It never
|
||||
|
|
|
|||
Loading…
Reference in New Issue