Skip to main content
A screen runs in a sealed VM with no DOM, no network, and no clock. An approved version runs in your page instead, as real modules.

The verdict decides the venue

open() computes the venue on every open. Nothing a stored, imported, or streamed document says about inClient survives to the client.

A stored approval pinning the current content hash is the only way into your page.

The same Maple slot with no stored approval: a contained notice stands where the generated component would be
The same Maple slot once an approval pins the version: the generated component renders natively in the page

Approvals pin a version

An approval records that one named principal approved one exact content hash of one app. The hash covers everything but the app’s id, its fork lineage, and the conversation. Any edit produces a new hash, so every existing approval for that app stops granting.
Review-kind never drops. A remix wrapped in <Remixable review> keeps showing your original component while it waits, so the reader sees the review standing rather than a half-trusted render.

Reviewing what changed

The review artifact is the ship-diff: approvable code diffed against the host baselines vendo sync captured, pinned to the current version. The base side is always your shipped product. So the diff answers how far the app has drifted from what your users run, not what changed since the last approval.
A baseline that has since moved is flagged drifted. The diff still returns and approving is still possible.

Minting an approval

Vendo Cloud’s review console mints approvals in production. On your own server the call is one line, and approvedBy is required because the record names who reviewed.
A review-kind app refuses to be approved by its own owner. Assert a reviewer through the apps.review.reviewer(ctx) hook, or the call comes back blocked with a pointer to it. For local work, one development route pins whatever is running right now.
approvedBy is optional here and defaults to "local-dev". The route is mounted in development compositions only, and it refuses a principal marked ephemeral: true with a 401.

What runs in your page

Approved source is compiled with sucrase and every import is rewritten into a controlled require. That require resolves React, three bundled packages, and the captured sub-sources of this component, and nothing else. Presses do not change venue. A $action still routes through the tree chokepoint, so host tools keep the same policy, grants, approvals, and audit path they have everywhere else.
In-thread previews are never granted. The inClient field is stripped from conversational payloads, so a preview can never become a host-page mount.

The record

Records live in the vendo_inclient_approvals collection, one per approved version. The verdict is only ever “some stored approval pins the current version’s content hash”, so a hand-crafted row can never grant. Deleting an app clears its approvals.

Where to go next

Host components

Register your components, and a generated screen renders your real UI.

Import & fork

How a remix is minted from your component, and what drift does to it.