In a repo where 3,000 files define `slug`, scribe_local_dups printed
nothing; with 3 files it printed the duplicate line. Every hook runs under
`set -uo pipefail`, and `hits=$(git grep -l … | head -4) || hits=""` lost
head's four lines whenever git grep was still writing when head exited. That
is a SIGPIPE, the substitution fails, and the outer fallback wipes the result.
So the by-name duplicate arm went silent for exactly the most-duplicated
names. Found while fixing the same trap in the new Stop hook (#4041).
- The fallback moves inside the substitution, `$(… | head -N || true)`, at all
five sites: scribe_defs.sh (local dups), scribe_prior_art.sh (names,
old_first, shapes) and scribe_after_write.sh (names). A real upstream
failure still yields empty output.
- check_plugin gains a known-bad pattern for the shape, so no hook can bring
it back.
- Tests: the real function against a 3,000-file repo (past the pipe buffer),
and the pattern shown to flag the old shape and pass the fix. Plugin
version minted.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>