Memory, evidence & deletion
How memory is written
After each provider exchange, SPM projects the conversation, removes control scaffolding, and queues an extraction job. Jobs are idempotent—a replayed exchange is a no-op—retried with backoff, and dead-lettered after exhausting attempts. Slow or failed ingestion does not break a live request.
How recall answers
Recall runs lexical and vector searches, fuses their results, and admits candidates through an evidence gate. Before content reaches the prompt, the gate verifies tenancy, namespace, epochs, ACL scope, and signed provenance; it fails closed. When nothing qualifies, the model receives no memory, and the honest answer is:
UNKNOWN — no supporting memory found.
This prevents unsupported memory from encouraging a confident invention.
Provenance ladder
At write time, each memory receives an origin role: user, assistant, or derived (SPM-synthesized state). Conflicts resolve by authority rank: a user's statement outranks an assistant's proposal, and an assistant cannot promote its claims to user authority. Fragments that cannot be attributed to exactly one role are downgraded rather than guessed.
Deletion with a signed receipt
POST /v2/purge removes a source, or an entire tenant scope, from the authoritative store and vector index, completes derived cleanup, and returns a receipt:
{
"status": "purged",
"purge_id": "…",
"receipt": {
"payload": {"typ": "purge-receipt+v1", "kid": "…", "deleted_candidates": 12, "…": "…"},
"signature": "EVhlqoLD3Gky7u…"
}
}
The signature is HMAC-SHA256 over the canonical JSON payload and is stored with the purge record. The payload carries its key id, keeping receipts verifiable after key rotation.
Verify a receipt (operator side):
- Take
receipt.payloadand canonicalize it (sorted keys, UTF-16-ordered, no whitespace). - Compute
HMAC-SHA256(signing_key, canonical_bytes), base64url-encode without padding. - Constant-time compare with
receipt.signature.
Repeated purges are safe: purging the same source again returns the original signed record. Records written before signed receipts existed carry no signature—a documented exception.
Scope note: purge removes data from the online stores. Backups, WAL, and replicas taken before a purge age out on their own rotation schedule; cryptographically enforced erasure (per-tenant keys with key destruction) is on the maturity roadmap.
Tenant isolation
Every memory object—records, candidates, jobs, vectors, and receipts—carries tenant_id. The data path enforces isolation through row-level security in the authoritative store, namespace fences, signed capability tokens with replay protection, and an evidence gate that rechecks all content at render time.