What actually gets stored, and where
Two Postgres tables plus one storage bucket, all inside your own Supabase project:
Row-Level Security scopes every row to its owning account. The schema lives in
supabase/migrations/ — read it directly rather than trusting a transcription, including this one.
The blind-ciphertext contract
Whatever backs your deployment, the invariant holds and is enforced by the client, not the server:- The server receives only encrypted bytes plus non-secret metadata: hashed agent IDs, sequence numbers, byte sizes, hashes, timestamps.
- Encryption and decryption keys never leave client devices. The server has no key material and no code path that would use one.
- Because content arrives already sealed, no storage backend can inspect it — that property comes from the client-side encryption boundary, not from a well-behaved driver.
The embedding vectors never reach the server at all under any configuration — they live only in the local LanceDB store on each device. What replicates is the encrypted
active_context payload, not the vector index.What you can realistically change
Your own Supabase project. This is the supported path, and it is the whole of self-hosting: your Postgres, your storage bucket, your region, your backup policy, your compliance boundary. See Deploy Self-Hosted. Your own Postgres behind Supabase. Supabase projects can be pointed at external Postgres in some configurations — that is a Supabase-level concern, and sovseal neither knows nor cares which Postgres answers. Forking the function.supabase/functions/v2-agent-state/ is open source. If you need a genuinely different storage backend — S3 for payloads, a different database — you can fork and rewrite the persistence calls. There is no adapter seam designed for this, so you take on merge cost against upstream changes. It is a fork, not a configuration.
What you cannot change without forking
- The storage shape — two tables plus a bucket, with the schema in
supabase/migrations/. - The vector store — LanceDB locally, IndexedDB in the extension. Not server-side, not swappable. See Vector Stores.
- The embedder — fixed per surface (
Xenova/all-MiniLM-L6-v2in@sovseal/mcp-server,intfloat/multilingual-e5-smallin the browser extension). See Embedding Model for why this is deliberate.
If you need something different
If a compliance requirement makes the Supabase-backed shape unworkable — a mandated on-premise database, a specific sovereign cloud — that is a real constraint worth raising atenterprise@sovseal.com rather than working around with a fork you then have to maintain.