RuntimeStore
Exact persistence contract for queues, leases, history, checkpoints, approvals, and the delivery outbox.
RuntimeStore is the durability protocol behind every core turn.
Inbound queue
enqueueInbound(event, conversationKey, runId) inserts once. claimInbound(options) returns one due job and assigns the worker lease atomically. renewInbound, completeInbound, and retryInbound must require the current worker ID.
Conversation history
appendMessage(message) is idempotent by message ID. listMessages(conversationKey, { limit }) returns bounded history in chronological order. Never implement it as an unbounded full-table read.
Checkpoints
getToolStep(key) and saveToolStep(step) implement replay-safe JSON checkpoints. The first successful save wins. The key includes the stable run/tool identity; outputs must be valid Noir JSON values.
Approvals
createApproval inserts a pending record. getApproval reads by ID. decideApproval atomically verifies pending status, expiry, and expected requester before writing approved or denied state. The stored continuation is required to resume without asking the model to reconstruct the effect.
Outbox
enqueueOutbound inserts once. claimOutbound leases one due event. completeOutbound stores the optional provider ID. retryOutbound records the error and next availability. failOutbound terminates non-retryable or exhausted output.
Store invariants
- All insert-once operations are atomic.
- A stale worker cannot settle another worker's lease.
- Conversation ordering is preserved under concurrency.
- List operations are bounded and indexed.
- Times are ISO 8601 strings and compared consistently.
closeis safe to call once during shutdown.
Use the included memory and Postgres stores as executable references. A raw Drizzle or Prisma client does not satisfy this contract until these operations are implemented.