fix(gate): the wire-contract search shelled out to grep and read its failure as a finding
gates / gates (push) Successful in 33s

CI convicted ALL 174 checked tags while the pre-push hook was green. Cause, read from the run log
rather than guessed at the second attempt: the search used `grep -rnE --include=…`, and the CI
runner's image carries python3 and git and deliberately little else — its grep does not support
`--include`, so stdout was empty and the gate read empty as "the tag is absent".

That is a gate silently treating a tool failure as a finding, which is worse than no gate, and it is
exactly the error-swallowing this repo forbids. A green from it would have been just as untrustworthy
as the red.

Fixed by removing the dependency, not by working around it: the search is now pure Python — one
token index per receiving repo, built in a single pass, no subprocess. Faster too (one walk instead
of ~350 greps), and unreadable-file / empty-repo cases now exit 2 INCONCLUSIVE rather than reporting
absence.

THE BEFORE CAPTURE WAS RE-VERIFIED, NOT RE-GENERATED — the stronger claim. All 40 fields recorded in
BEFORE.md were re-tested against the new implementation: agree=40, disagree=0, i.e. exactly the four
this session fixed are now present and the other 36 still absent. The number 40 stands under both
implementations; only the mechanism changed. The whole-token property survives by construction — a
token index treats `healed_at` and `privsep_healed_at` as distinct tokens.

This is the THIRD instrument defect this gate's own controls caught before it was trusted, after the
substring false negative and the dr_recipe over-opacity. The first two were caught by re-finding the
known instances; this one by the CI-versus-hook disagreement the workflow's alarm mail explicitly
says outranks whatever the push was for.
This commit is contained in:
2026-08-08 09:10:59 +02:00
parent 436abf39d5
commit 3bf62b95bb
2 changed files with 75 additions and 17 deletions
@@ -75,3 +75,33 @@ exit=1
SELFTEST OK — the gate convicts a planted unreachable tag and the plant is the only difference.
exit=0
```
---
## ⚠ The search implementation changed AFTER this capture, and the capture was re-verified
The run above used `grep -rnE --include=…` to test whether a tag occurs in the receiving repo. That
**works on a workstation and returns nothing on the CI runner**, whose image carries python3 and git
and deliberately little else — its `grep` does not support `--include`. Empty stdout was then read as
"the tag is absent", so the gate convicted **all 174** checked tags and CI went red while the
pre-push hook was green (runs 260262).
That is the gate silently reading a tool failure as a finding, which is worse than no gate, and it is
the error-swallowing this repo's rules forbid. The search is now **pure Python**: one token index per
receiving repo, no subprocess, no external dependency.
**This capture was NOT re-generated — it is re-verified**, which is the stronger claim. Every one of
the 40 fields recorded above was re-tested against the new implementation:
```
fields recorded in BEFORE.md: 40
agree=40 disagree=0
```
— i.e. the new implementation finds exactly the four this session fixed (`operator_key_configured`,
`wg_handshake_age_s`, `healed_at`, `escrow_stale`) present, and the other 36 still absent. **The
number 40 stands under both implementations**; only the mechanism and its portability changed.
The whole-token property also survives by construction: a token index treats `healed_at` and
`privsep_healed_at` as distinct tokens, so the substring false negative that the control caught
cannot come back.