Size limits
Cards
Widgets (identical as a result block and as a confirmation view)
Widget Kit asset budgets
Bridge messages
Degradation order
Nothing on the card surface fails loudly, and nothing vanishes without a rule:- An off-schema block is dropped individually; its siblings render.
- Over-budget blocks (4th block, 2nd chart) are dropped in declaration order.
- A Widget-Kit card over the HTML budget sheds content images first
(never the integration mark), then trailing blocks — the header goes
last. (
renderCustomthrows instead, so you find out in your test run.) - A card with zero valid blocks is dropped whole — the spoken answer still happens.
bun verify.ts is how you catch all of this before a user does.
Timing
Security model
- Process isolation. Integration code never runs inside VoiceOS
processes and never sees VoiceOS secrets.
local-mcpservers run as child processes on the user’s machine;remote-mcpruns on your infra. - UI is data. Declarative blocks can’t reach host APIs, and
markdownis sanitized. Anything off-schema degrades to a safe placeholder. - Widgets are sandboxed. Opaque origin, no network egress, validated postMessage only, clamped heights — and no approve leg: only VoiceOS’s own button (or the user’s voice) can approve an action.
- The model never sees your UI, and can never author a widget. Glance
payloads are stripped from tool results before the model reads them, and
the parser refuses
widgetblocks outside integration surfaces. - Secrets stay out of band. Setup values are stored encrypted, injected as env vars, never echoed to the UI, and never enter the agent transcript.
- Consent at the edges. Permissions are declared in the manifest and shown at install; acting tools confirm before running; users hold per-tool “Asks first” overrides.
Stability
Two version gates cover the whole contract:
The promise (the “Minecraft rule”): additive changes never bump them. New
blocks, new fields, and new permissions arrive without breaking existing
manifests, and hosts render unknown future blocks as safe placeholders. An
integration authored today keeps working across years of VoiceOS updates.
Reserved-but-declared surfaces you’ll see in the types —
hosted runtime,
store and webhook permissions, canvas blocks, role: "custom"
actions, brokered oauth2 — exist so that when they ship, nothing you wrote
changes.
