Development record
gate-hardening nitpicks from the iss-122 reviews, none blocking: (1) the manifest read in receipt_gate uses unbounded os.ReadFile where the sibling convention is fsutil.ReadGuarded (trusted committed file, self-DoS only — but it is the unhardened sibling the bughunt spine says to sweep); (2) receipt.example.json's manifestHash is not test-pinned against manifest.json so a manifest edit silently stales the example; (3) receipt parsing tolerates duplicate JSON keys (Go last-wins) — an audit-legibility gap under the attestation trust model, not an escalation
issueresolvednitpickiss-131
gate-hardening nitpicks from the iss-122 reviews, none blocking: (1) the manifest read in receipt_gate uses unbounded os.ReadFile where the sibling convention is fsutil.ReadGuarded (trusted committed file, self-DoS only — but it is the unhardened sibling the bughunt spine says to sweep); (2) receipt.example.json's manifestHash is not test-pinned against manifest.json so a manifest edit silently stales the example; (3) receipt parsing tolerates duplicate JSON keys (Go last-wins) — an audit-legibility gap under the attestation trust model, not an escalation
Grounds
- pursued: a symlinked manifest fails closed, a receipt with two verificationResult keys is refused by name, and a manifest edit without the example turns the pin test red; any of those passing would show it wrong
Frontmatter
| id | iss-131 |
|---|---|
| type | issue |
| lifecycle | resolved |
| severity | nitpick |
.abcd/work/issues/resolved/iss-131-receipt-gate-hardening-nitpicks.md
open on GitHub ↗ · commit history ↗
mentions2
- iss-122The iss35 crosscheck's scope and depth are unpinned, so the gate is not reproducible: v0.3.0's receipt records zero findings four days ago while a full-depth run (17 brief docs, both directions, 22 checkers) returns 102 discrepancies, and the receipt's own promptHash field is the literal 'no-pinned-prompt' admission. The maintainer choosing briefDocs per run means two honest runs of the same gate can disagree by two orders of magnitude; the gate needs a pinned input manifest and depth so a PROMOTE means the same thing every release.
- iss-2609252145018018internal/core/lint still reads repository content through unbounded os.ReadFile at about fifteen sites (contextcurrency.go, indexdrift.go, persona.go, schema.go's bucket read, speclinks.go, subverbs.go, and lint.go's intent-tree, spec-store, registry and surface reads), where the per-root markdown walk and, since iss-131, receipt_gate read through fsutil.ReadGuarded after containment. A committed symlink to /dev/zero or an oversize file at one of those paths is followed and read unbounded. The sweep is the unhardened-sibling class iss-131 named; it changes symlink handling at each site, so each needs its own containment decision and test.