A reference page can place source and actual renderer output next to each other. The page itself remains read-only. A live example may expose only the interaction the represented node already owns. It never becomes an editor for the source, manifest, or documentation.
Do not treat every rendered object as the same kind of component. Markdown directives become an AUP tree for the document target; native AUP primitives have their own target-specific support; and a Web Device .web component belongs in a page layout, not in a generic Markdown directive. This page proves only the document-target Markdown → AUP path.
Sample contract
| Field | Value |
|---|---|
| Purpose | Unbound document-target input, plus view mode tabs as static UI chrome |
| Boundaries | No bind, session patch, AFS write, exec, multi-field form, or layout-component API |
| Author entry | Content Markdown directives (::input, ::::view) |
| Surface | Web Device document target (static prerender + browser form controls) |
| Public status | released for these two nodes on document |
| Fallback / failure | Missing id → unstable DOM id collision risk; unknown tab children still render as panels without switching JS requirements beyond radio/CSS |
| Verification | arc --version = 2.0.0-beta.28; routes below; narrow viewport still shows controls |
For every published example, record in the same place: the source that produces the node; the data or manifest boundary; the target that renders it; and the exact behavior the reader should observe, including what is deliberately absent.
A document-target text input
This example is an unbound AUP input node. It has no bind, event, action, source path, or write capability. Type in it if useful. The field changes only as a browser form control; no document, manifest, AFS record, or session setting is changed. A browser may restore a form value when it reloads a page, which is browser behavior rather than AUP persistence.
Give every field an explicit id. The content reader promotes that attribute to the node’s top-level id (arc#3321). Without it, multiple inputs on one page can share a broken DOM id.
Source:
::input{id="docs-live-name" type="text" label="Name" placeholder="Type only in this example" value="Ada"}Rendered:
The same Web Device document renderer that reads this page renders the field. This is a real document-target result, but it is not evidence of a bound form, an AUP session patch, or persistence. Use it only as evidence for one unbound field, not as a copyable multi-field live form pattern.
Failure and limits
| Situation | Expected result |
|---|---|
No id on ::input | Field still renders; DOM id is unstable across fields on the same page |
bind / session fields in Markdown here | Not part of this contract; do not invent them on a docs page |
| Narrow viewport | Label, control, and placeholder remain readable; no second layout mode is required |
A document-target view with mode tabs
view is a released cross-device primitive. On the document target, mode="tabs" is static UI: radio inputs and panels, not a separate widget session. Author tabs with a generic container directive so nested panel bodies survive (arc#2598).
Source:
::::view{id="docs-live-tabs" mode="tabs" label="Package manager"}
:::view{label="pnpm"}
Install with `pnpm install`.
:::
:::view{label="npm"}
Install with `npm install`.
:::
::::Rendered:
Install with pnpm install.
Install with npm install.
Switching tabs only changes which panel is visible in the browser. It does not write content, open an AUP session, or run shell commands. The outer fence needs more colons than nested containers, same as other container directives.
Failure and limits
| Situation | Expected result |
|---|---|
Leaf ::view with no body | Empty panel / no body content |
| Outer fence with too few colons | Parser misreads structure; panels may drop |
No label on the tabs container | Tabs still render; accessible name on the tablist is omitted |
Treating tabs as layout .web components | Wrong surface — layout components use layout.aup, not this directive |
What a list must add
An afs-list reference needs a separate contract. Its source must name the list layout and template; its data section must name a read-only fixture or a declared AFS path; and the page must identify the renderer/session that actually resolved it. A static document target can render literal child nodes, but it does not by itself prove that a source-backed list can read an arbitrary path.
The current Showcase list-basic source is useful evidence for that next slice: it binds afs-list to packaged data/items and has no write action on the list itself. Before it becomes an embedded runtime sample, use a dedicated minimal demo origin rather than the full Showcase, keep its fixture data read-only, and verify that the frame has no bridge, write, or exec path. This page does not claim a verified live afs-list sample.
Verification evidence
| Item | Value |
|---|---|
| Baseline | 2026-08-09 · arc --version → 2.0.0-beta.28 |
| Capability row | docs/aup/capability-matrix.md (internal, non-routed) · input, view, ::input |
| Implementation | providers/runtime/web-device/src/content-reader.ts (directive → AUP, id promotion); renderer/primitives/input.ts; renderer/primitives/view.ts (tabs) |
| Tests | content-reader.test.ts (id promotion, nested tabs); renderer/primitives.test.ts (tabs ARIA / radio) |
| Public routes | /en/docs/aup/live-example-contract/ · /zh/docs/aup/live-example-contract/ |
| Local run | arc service start --blocklet blocklets/arcblock --port 4900 then open those routes (desktop + ~390px width) |
| Accept | Source fence matches rendered control; typing stays local; tab switch does not network-write |
For the isolation boundary, read Frames, bridges, and embedded surfaces. For static Web Device versus an interactive AUP session, read AUP on Web Device.