Watch-tower harvest car. Derives from pruneExpiredOrders in src/types/model.ts and the 27.5 MB registry lesson behind upstream PR #209. Shepherd builds the uid, so it stores valid_to as a field, never parsed from the uid tail.
Bounded GC for rows no chain event will ever clean: expired journal entries, parked watches whose INVALID never comes, and negative-cache entries.
Why
Watch-tower's store grew unbounded until expiry pruning was retrofitted, and it recovered validTo from the uid's trailing bytes, a parse model.ts itself documents as truncation-hazardous. The Rust-native shape is structural: a valid_to: u32 field in SubmittedRow, and a per-tick prefix-scan sweep with a bounded cursor so GC cost is flat regardless of backlog. Teardown is not journal GC: a parked watch is out of the poll rotation, so the INVALID that would remove it never arrives, and orphan rows outlive their watch. Hardening, not launch-blocking, but the first soak month accumulates all of it, so land it early.
Scope
Done when
Blocked by: #654.
Blocked by: #654.
Bounded GC for rows no chain event will ever clean: expired journal entries, parked watches whose INVALID never comes, and negative-cache entries.
Why
Watch-tower's store grew unbounded until expiry pruning was retrofitted, and it recovered
validTofrom the uid's trailing bytes, a parsemodel.tsitself documents as truncation-hazardous. The Rust-native shape is structural: avalid_to: u32field inSubmittedRow, and a per-tick prefix-scan sweep with a bounded cursor so GC cost is flat regardless of backlog. Teardown is not journal GC: a parked watch is out of the poll rotation, so the INVALID that would remove it never arrives, and orphan rows outlive their watch. Hardening, not launch-blocking, but the first soak month accumulates all of it, so land it early.Scope
SubmittedRowgains structuredvalid_to: u32; goldens regenerated (fold into the cow: reorg-aware ingestion and submission-policy pass #654 schema break if it has not merged, else a follow-up migration per cow-venue: use alloy primitives instead of byte-array aliases #546's land-schema-early rule).Done when
valid_tofrom uid bytes.Blocked by: #654.
Blocked by: #654.