Skip to content

cow: journal, park, and negative-cache expiry sweep #665

Description

@mfw78

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

  • Expired journal rows are swept within the scan budget, with a test.
  • Removing a watch removes its dependent rows, with a test.
  • No code path derives valid_to from uid bytes.

Blocked by: #654.

Blocked by: #654.

Metadata

Metadata

Assignees

No one assigned

    Labels

    blockedCan't proceed. Waiting on something.component/cow-integrationshepherd:cow / cow-api order submissioncomponent/local-storeredb per-module state + byte quotasdebtCode works but makes future work harder.effort/daysFew days. Needs design.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions