Your data never leaves the device.
Inference, embeddings, and search that run on the machine in front of you. Sovereignty is the default — not a setting you harden in later. The egress is zero because there is no outbound call to make.
import { TenantFieldCrypto } from "@caisson/field-crypto" const env = await fc.encryptField(tenant, "record", "notes") // v1 · aes-256-gcm · per-tenant key · AAD-bound ← sealed at rest await fc.decryptField(otherTenant, env, "notes") // cross-tenant key — open refused ← isolation proof
Four pieces. All on the device.
Each piece does its job without a network. Compose them, or take a single module — the data path never widens past the disk.
One interface over on-device and hosted inference. Local is the default you ship; hosted is an opt-in you make on purpose — not a default you discover in a network trace.
A policy boundary every payload crosses before it can leave the process. Default-deny by host: nothing egresses unless you allowed that destination in writing.
Embeddings indexed with sqlite-vec ANN, queried on disk. Semantic recall with zero round-trips to a vector cloud and nothing to leak from one.
License verification that works air-gapped — signature-checked on the device, no phone-home, no remote kill switch. The library keeps running when the network does not.
Semantic recall that never round-trips.
sqlite-vec holds the ANN index next to your rows. A query is a statement against a local file — no API key, no vector vendor, no embeddings shipped off the box to be indexed by someone else. The shape below is illustrative.
-- ANN over the local store; the index lives next to your rows SELECT id, distance FROM cs_cards WHERE embedding MATCH :query_vec ORDER BY distance LIMIT 8; -- index on disk · nothing shipped to a vector cloud
Fail-closed is how the base already behaves.
Default-deny is not a promise — it is how the base substrate behaves today. A cross-tenant read is refused at the database, fail-closed by construction. The privacy gate extends that same posture to network egress: hosts are deny-listed by default, allowed only in a typed config.
-- session scoped to tenant A; reach for tenant B's rows SELECT * FROM records WHERE tenant_id = 'tenant_b'; ERROR: permission denied for table records DETAIL: RLS policy "tenant_isolation" forbids the read
Own the source. Run it on your machine.
Local-first AI is a commercial edition — own the source, ship on-device inference behind the privacy gate, and keep your data on the box. Scaffold the base, then add the edition.
$ npx create-caisson@latest