The store slot fills itself
createVendo picks the store at composition time. With VENDO_API_KEY set and
no store passed, the slot takes the hosted store.
app/api/vendo/[...vendo]/route.ts
vendo ready
What lands where
The hosted store speaks the same wire your process would speak to a local database, one hop shorter.
Blobs ride the same store unless you pass a
files adapter. One adapter serves
both writes and the erase cascade, so rows and objects can never drift apart.
ensureSchema() is a no-op against Vendo Cloud. The service owns its own
migrations.
What the store refuses
The store refuses three things outright. Each one shows up in a log rather than as a silent no-op.Audit is append-only
Audit is append-only
Writing
vendo_audit with an id that already exists fails with conflict.
Deleting an audit row is refused with blocked.The erase API below is the only sanctioned way to remove one.Ownership flips are refused
Ownership flips are refused
vendo_apps, vendo_grants, and vendo_threads reject a same-id write
that moves a row to a different subject.To transfer ownership, delete the row and re-seed it under the new subject.Secrets never ride the hosted wire
Secrets never ride the hosted wire
The hosted store has no secrets surface, by construction. Secret values
resolve from your process environment first, and Vendo Cloud’s secrets
provider answers only for names the environment leaves unset.Nothing sends a secret value to the console as store data.
Erasing a user
Erasure is the deletion path for right-to-erasure requests, for tearing down a test app, and for purging old runs. It cascades across every store table, and which call you make depends on which store this deployment composed. A LOCAL store — the default, or your own Postgres — runs the SQL cascade througheraseStore, which takes the files adapter so rows and objects go together:
files — the console cascades its own storage server-side. eraseStore cannot
be handed that store: it throws Unknown VendoStore handle before any request
goes out.
Racing writers
Two ticks, two retries, or two agent runs can land on the same record. The collection handle carries compare-and-set primitives for that case.claim returns true for the single caller whose read of expected still
matched. insertIfAbsent and compareAndSwap return null when another
caller won.
Both are optional on the handle, which is why the calls above are guarded. Your
own collections expose them; Vendo’s internal tables vary.
Where to go next
Vendo Cloud
What the key covers, what it costs, and how to mint a scoped one.
vnd_ + 40 hexAuth
The subject every row above is scoped to, and where it comes from.
principal.subjectDeploying
The eight checks that have to pass before your users arrive.
npx vendo doctor