Skip to content

fix(session-store): replace the absorbing fenced-transition receipt lifetime cap #702

Description

@VerifiedOrganic

Refs #696

Downstream: https://github.com/VerifiedOrganic/epdg/issues/181

Problem

At exact SDK main 83b3317dc6bf081b77830129690359b5537e0700 (e9cd3c7746cf092a3311bc5d2eda481aca6a5102), atomic fenced-transition request bindings have a permanent global limit of 4,096 per storage consensus identity.

The receipt table is keyed only by request ID, the capacity count covers every receipt row for the singleton consensus identity, and current compaction only removes response JSON/digests. The request/body binding remains forever; there is no retirement, prune, namespace rollover, or safe reclamation API. Snapshots and recovery preserve the tombstones.

The 4,097th unique request deterministically returns FencedTransitionHistoryFull; it advances replicated logical/applied position but creates no receipt or business-state mutation. New atomic request IDs remain permanently unusable. The cap is per independently routed consensus identity, not per session, key, shard, or voter.

Two atomic transitions for 50,000 sessions require at least 100,000 unique request bindings before headroom or rejected transitions. Reusing an ID with a different body correctly conflicts, so ID reuse is not a solution. A single production identity therefore becomes absorbing far below the declared workload.

Required behavior

  • One consensus identity must support at least 100,000 unique transitions plus documented operational headroom with proven storage/memory/snapshot bounds.
  • Capacity/schema semantics must be protocol-versioned and activated safely for mixed voters; do not silently change the meaning of atomic_fenced_transition_v1.
  • Delayed retries must retain exact replay/conflict, expiry, stable-ID, and OutcomeUnknown guarantees.
  • Long-lived operation must have a durable request namespace/epoch retirement or equivalent irreversible high-watermark design before per-ID tombstones may be reclaimed.
  • Age-only deletion is not acceptable: an old delayed request must never execute twice or lose same-ID/different-body conflict detection.
  • Capacity failure must remain deterministic and must not partially mutate a lease, record, or watch-visible business state.

Acceptance evidence

  • Exact-bound/one-over tests at the new declared capacity.
  • Sustained operation beyond one capacity window using durable retirement/reclamation.
  • Restart, snapshot, recovery, topology-change, and mixed-version activation tests.
  • Delayed old retry and same-ID/different-body conflict tests across retirement boundaries.
  • Failure-injection and independent fix-removal mutations for capacity, retirement, snapshot, and replay invariants.
  • 100,000+ unique-transition qualification with bounded resource evidence.
  • Formatting, warnings-denied Clippy, exact full CI, hosted exact-head checks, and independent review.

This is generic SDK durability behavior required by the production downstream. It must not be replaced by application-local sharding or ID reuse.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions