OptionallegacyMinimum physical grace applied to legacy records that do not carry an
explicit retainUntil. When present, store construction rejects a
larger logical clock-skew window instead of allowing early pruning.
OptionalvalidateValidate backend-specific physical retention against the logical skew.
Atomically install an entry only if no entry exists for scopedKey.
Used as a claim step by the middleware to close the concurrent-miss
race (two parallel requests with the same fresh key both seeing
miss and both executing side effects). Returns true if the
caller "won" the claim and should proceed to run the handler;
false if another request claimed first (the caller should treat
the result as a replay or conflict on re-check). Callers that need to
reclaim a logically expired entry MUST use
replaceIfPayloadHashAndExpired() rather than this primitive or a
read-derived CAS. Treating expiry as absence lets a stale absent read
overwrite a newer generation after its short lease expires.
Atomically replace an entry only when its current payload hash matches.
Atomically replace an entry only when its current payload hash matches and it is logically expired according to backend time. An entry expiring exactly now remains live.
Atomically delete an entry only when its current payload hash matches (used by webhook dedup claims).
Store an entry unconditionally. Middleware publication uses fenced replacement instead.
Delete an entry unconditionally.
OptionalprobeOptional startup probe. Implementations that wrap an external store
(e.g., pgBackend) should implement this to eagerly validate the
connection before the server starts accepting traffic. Called by
probeIdempotencyStore() and by serve() when readinessCheck is
wired. Throws a descriptive error when the backend is unreachable or
the required schema is missing.
OptionalcloseOptional hook for implementations that need to release resources they
created and own (for example internal timers or an internally constructed
client). Called by store.close(). Backends must not close caller-owned
pools or clients that were passed into the backend constructor.
OptionalclearOptional test-harness hook that drops every cached entry without
releasing backend resources. Used by AdcpServer.compliance.reset()
between storyboards so idempotency cache hits from one storyboard
don't replay into the next (shared brand domain, same key prefix).
Production backends that can't cheaply flush everything (e.g., a
shared Postgres cluster) should leave this undefined — the reset
hook refuses to run when this method is missing unless the caller
explicitly opts in with { force: true }.
Storage backend interface. Swap implementations for memory, Postgres, Redis, etc.
Keys are already composed as
{principal}\u001f{key}(or with extra scope segments for per-session tools) before reaching the backend — backends don't need to know about scoping. The separator is U+001F (unit separator) rather than NUL because Postgres TEXT columns reject NUL bytes. The store rejects this separator in principals, keys, and extra-scope segments before backend access; protocol middleware additionally enforces the narrower wire key pattern (^[A-Za-z0-9_.:-]{16,255}$).Object-identity contract. Implementations MUST NOT return the same object reference on subsequent
getcalls — the middleware injects envelope fields (replayed: true, echo-backcontext) onto the returned value, and a shared reference would leak those mutations across requests. Implementations that store values by reference (e.g.,memoryBackend) MUST deep-clone on read; implementations that serialize (e.g.,pgBackendvia JSON) get this for free.