Skip to main content
sovseal orders an agent’s state checkpoints as a strict, per-agent sequence — not a mutable “latest state” row. Every snapshot the server has ever confirmed for an agent stays retrievable by its sequence number, which is what makes point-in-time recovery and crash-safe replication structural properties of the system rather than special-case code.
This page covers the snapshot/restore/lineage state-replication system. It does not apply to store/recall semantic memory, which has no sequencing or lineage concept — see Memory Model for how the two systems differ.

Sequence numbers, not content hashes, define order

Each agent_id has its own independent sequence starting at 0. The server enforces order at write time: a snapshot() call’s sequence_number must equal latest confirmed sequence for this agent + 1, or it’s rejected with 409 sequence_gap. The very first snapshot for a new agent must be sequence_number: 0 with parent_snapshot: null — this genesis check is what proves a chain has no missing prefix.
Retrying the same (agent_id, sequence_number) with an unchanged client_payload_hash is idempotent — the server returns the original receipt rather than erroring, which is what makes replay-after-crash safe. The same sequence number with a different hash is a real conflict (409 sequence_conflict): two different payloads are trying to claim the same position, and the server refuses to silently pick a winner.

Point-in-time recovery: restoreAt, not rollback

There is no rollback() call that moves a “current state” pointer. Instead:
  • restore({ agentId }) fetches the latest confirmed checkpoint.
  • restoreAt({ agentId, sequence }) fetches the checkpoint at any specific sequence number in that agent’s history — including ones that are no longer the latest.
Because every sequence number is permanently retrievable, “going back to how things looked three checkpoints ago” is just calling restoreAt with that number — nothing is deleted, nothing needs to be un-done. Nothing about calling restoreAt on an old sequence affects what restore() returns afterward; the server’s “latest” pointer only ever moves forward via new snapshot() calls.

”Branching” means a new agent_id

sovseal has no fork() primitive. If you want two independent lines of state descending from the same point, the pattern is: restoreAt the checkpoint you want to branch from, decrypt and verify it (see Verified Semantic Recall), then call snapshot() for that payload as sequence 0 under a new agent_id. The two agent IDs then have fully independent sequence chains — there’s no shared ancestry tracked by the server beyond whatever you encode into the payload yourself.

Every restore is verified, not just fetched

restore/restoreAt return { receipt, ciphertextUrl } — metadata and an encrypted blob, not verified plaintext. The receipt’s client_payload_hash is an anchor you check yourself: decrypt, re-derive sha256(canonicalize(payload)), and compare. A mismatch means either the ciphertext was tampered with (the AES-GCM auth tag catches this) or a different valid record was substituted in its place (the hash comparison catches this, because the hash covers the whole payload including its sequence_number and parent_snapshot). See Verified Semantic Recall for the full two-check pattern and a ready-to-use implementation — this is not automatic, you must run it.

Crash safety and conflicting writers

Local durability and replication crash-safety are properties of the write-behind sync worker, not of the SDK’s snapshot/restore calls themselves — see Replication & Sync for the full mechanics: the local LanceDB write-ahead log, the sync worker’s poll/retry loop, and what happens when two writers collide on the same sequence number (a split-brain halt, not an automatic merge — sovseal refuses to guess which version is correct).

Next steps

Memory Model

The full record shape for both semantic memory and state snapshots, and the complete SDK method table.

Verified Semantic Recall

The tamper/substitution check you run on every restore — with working code.

Replication & Sync

The write-behind worker: batching, retry, idempotent replay, and split-brain handling.

Zero-Knowledge Guarantees

How lineage integrity fits into the broader cryptographic threat model.