Development record
The implement loop's run-state reader, readStateIn in internal/core/implement/loop/state.go, decodes state.json with DisallowUnknownFields only: a repeated key is read last-wins (encoding/json binds case twins to one field too) and anything after the first JSON document is ignored, so a file that is not the one the loop wrote can pass as the run's state. state.json lives in the primary checkout's .abcd/.work.local/run/<id>/, the directory an implementer is sent to write into, and the loop reads lane status and each lane's awaited receipt path from it. The lane receipt reader was fixed for the same class (iss-2609262123574454) by routing it through jsonstrict.Decode; readStateIn should take the same one primitive, with a repeated key and a trailing document each refused under test.
The implement loop's run-state reader, readStateIn in internal/core/implement/loop/state.go, decodes state.json with DisallowUnknownFields only: a repeated key is read last-wins (encoding/json binds case twins to one field too) and anything after the first JSON document is ignored, so a file that is not the one the loop wrote can pass as the run's state. state.json lives in the primary checkout's .abcd/.work.local/run/<id>/, the directory an implementer is sent to write into, and the loop reads lane status and each lane's awaited receipt path from it. The lane receipt reader was fixed for the same class (iss-2609262123574454) by routing it through jsonstrict.Decode; readStateIn should take the same one primitive, with a repeated key and a trailing document each refused under test.
Grounds
- pursued: a state.json carrying a repeated key or a trailing document is refused rather than read; TestReadStateFailsClosed's three new cases would pass against a last-wins or first-document decode and show it wrong
Frontmatter
| id | iss-2609281204381700 |
|---|---|
| type | issue |
| lifecycle | resolved |
| severity | minor |
.abcd/work/issues/resolved/iss-2609281204381700-the-implement-loop-s-run-state-reader.md
open on GitHub ↗ · commit history ↗
mentions1
- iss-2609262123574454The implement loop's lane receipt reader (internal/core/implement/loop/receipt.go readReceipt) decodes the receipt strictly by hand, refusing an unknown field and a second document, but reads a repeated key last-wins: a receipt carrying "exit_code":1,"exit_code":0 (or a case twin such as EXIT_CODE) verifies as a passing definition of done. Every other trust-boundary JSON reader refuses a repeated key through internal/core/jsonstrict; this one was written before jsonstrict reached its base, so its strict decode is an inline copy that lacks the check.