Skip to main content
There is no pluggable storage-driver abstraction. No StorageDriver interface, no storage_provider config key, no YAML adapter format, and no S3/R2/Qdrant provider blocks exist in this codebase. Self-hosting means running the v2-agent-state edge function on your own Supabase project — Postgres and Supabase Storage are the storage layer, not one option among several.If you’ve seen documentation describing swappable storage adapters for this project, that describes a different project’s plugin architecture.

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-v2 in @sovseal/mcp-server, intfloat/multilingual-e5-small in 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 at enterprise@sovseal.com rather than working around with a fork you then have to maintain.