fix(gate): the wire-contract search shelled out to grep and read its failure as a finding
gates / gates (push) Successful in 33s
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:
@@ -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 260–262).
|
||||
|
||||
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.
|
||||
|
||||
Reference in New Issue
Block a user