Development record
Deferring the orphan sweep to the commit path lengthens the window in which an orphan's reading records can be dispositioned before they are deleted. The sweep now runs only when a later ingest validates (iss-2608311517509690), so an orphaned run's reading records sit in the committed ledger for longer, and during that window capture's disposition verb can act on one of them. A later sweep then removes the item record by its id grammar and leaves the disposition record dangling, pointing at an item that no longer exists. The dangling case existed before the move — any orphan could be dispositioned between its crash and the next invocation — but the move widens it from the next invocation to the next one that validates. A future change could have the sweep refuse, or report, an orphan whose records already carry a disposition.
Deferring the orphan sweep to the commit path lengthens the window in which an orphan's reading records can be dispositioned before they are deleted. The sweep now runs only when a later ingest validates (iss-2608311517509690), so an orphaned run's reading records sit in the committed ledger for longer, and during that window capture's disposition verb can act on one of them. A later sweep then removes the item record by its id grammar and leaves the disposition record dangling, pointing at an item that no longer exists. The dangling case existed before the move — any orphan could be dispositioned between its crash and the next invocation — but the move widens it from the next invocation to the next one that validates. A future change could have the sweep refuse, or report, an orphan whose records already carry a disposition.
Remedy grounds (2026-09-29)
- rollbackRun at the base removes an orphan's item records by the id grammar under the ledger lock and never reads dispositions, so the dangling case is real; option (a) is the lane-found writer-side close the deferral names.
- No outside-practice check: the choice is among behaviours of a shipped internal verb.
- Rejected: widening the sweep back to every invocation, which reopens the refused-run delete the commit-path move closed.
Frontmatter
| id | iss-2609012043443066 |
|---|---|
| type | issue |
| lifecycle | open |
| severity | minor |
.abcd/work/issues/open/iss-2609012043443066-deferring-the-orphan-sweep-to-the-commit.md
open on GitHub ↗ · commit history ↗
mentions1
- iss-2608311517509690The orphan sweep silently deletes committed reading records. With an orphaned stage present and its record already in the ledger, an ingest whose payload fails at the type check deleted a committed record from the durable tier and printed only the type error: the rolled-back and cleared-stage fields are dropped on the error path, and the JSON render emits an error object without them, because the surface renders those fields only when a refusal record exists. The code's own comment says this must not happen. It is the worst shape a defect can take here, because the loss is durable, silent, and triggered by a payload that was itself refused: an operator sees a validation error and has no way to learn that a record was destroyed while it was being reported.