Skip to content

fix(docs): correct a false claim about local git hooks, and log how it got in - #29

Merged
lozit merged 1 commit into
mainfrom
fix/correct-the-hooks-claim
Sep 21, 2026
Merged

lozit merged 1 commit into
mainfrom
fix/correct-the-hooks-claim

Conversation

@lozit

@lozit lozit commented Sep 21, 2026

Copy link
Copy Markdown
Owner

A fact recorded this morning was wrong. It is corrected, the decision it supported is unchanged, and the way it got in is logged.

The correction

A repository pre-commit is dead on this machine — false. Two true things led there: core.hooksPath does redirect globally, and git itself never falls back to .git/hooks. But the occupying script ends with:

_ggshield_local_hook=$(git rev-parse --git-common-dir)/hooks/pre-commit
[ -f "$_ggshield_local_hook" ] && { "$_ggshield_local_hook" "$@" || exit 1; }
ggshield secret scan pre-commit "$@"

It calls the repository's hook and fails the commit if that fails. The slot is chained, not occupied. Verified by reading the file rather than by relaying the correction.

The decision does not move

CI still wins, for the two reasons that were never about the slot: .git/hooks/ is not versioned and does not survive a clone, and --no-verify walks past any local hook — including for whoever merges the PR that introduces the defect, which is how the original omission arrived.

The lesson is sharpened, not removed

Occupancy is not a second question — it answers the first. Whether your control runs is a property of the occupant's code, not of the configuration pointing at it: here the configuration said unreachable and the script said I call it myself. Both halves bite. Read it and you learn your hook is reachable after all. Skip it and you can destroy a working guard while reading as installed — which writing into the ggshield directory itself, where the entries are symlinks into dotfiles beside a .bak- from a previous overwrite, still would have done.

How it got in

Logged in docs/AGENT-EVALS.md. The claim came from a peer with its evidence. The evidence was checked — the redirect, the directory listing, git rev-parse --git-path hooks — and all of it was true. The inference was adopted, and the file it concerned was never opened.

That is a variant of asserts without verifying that survives the usual guard, because verification happened, on the premises. Checking every fact someone measured and adopting their conclusion is agreement with extra steps, and it feels like diligence. The tell: the conclusion concerned the behaviour of a file whose path had been confirmed three ways.

…t got in

The claim that a repository pre-commit is dead on this machine was
wrong. core.hooksPath does redirect and git itself never reads
.git/hooks — both true — but the occupying ggshield script ends by
calling $(git rev-parse --git-common-dir)/hooks/pre-commit and failing
the commit if it fails. The slot is chained, not occupied. Measured by
reading the file, which is what nobody had done.

The decision does not move: CI still wins for the two reasons that were
never about the slot — .git/hooks is not versioned and does not survive
a clone, and --no-verify walks past any local hook including for whoever
merges the PR introducing the defect.

The LEARNINGS lesson is sharpened rather than removed: occupancy is not
a second question, it answers the first. Whether your control runs is a
property of the occupant's code, not of the configuration pointing at
it. Both halves bite — read it and you learn your hook is reachable
after all; skip it and you can destroy a working guard while reading as
installed.

Logged in AGENT-EVALS: the premises were all checked and all true, and
the inference drawn from them was adopted without opening the file it
was about. Verification on the premises is agreement with extra steps.

See CHANGELOG [Unreleased] > Changed.
@lozit
lozit merged commit ec4b73f into main Sep 21, 2026
2 checks passed
@lozit
lozit deleted the fix/correct-the-hooks-claim branch September 21, 2026 12:10
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