Stagehand: Narrated State Choreography
Stagehand gives the model a director's baton, not root access.
Chapter 42 - Stagehand: Narrated State Choreography
Part: X - The Presentation Layer
Thesis
The next interface is not chat. It is narrated state: the model speaks, the system routes, the renderer moves, and the validator decides what becomes real. Stagehand is where the whole book’s argument becomes visible in one running system: the model produces narration and typed proposals, and deterministic components — parser, schema, registry, renderer — route, validate, execute, and render them. Nothing becomes real by being said convincingly.
Key Line
Stagehand gives the model a director’s baton, not root access.
The Problem With “The Model Gave An Answer”
Every serious AI system eventually discovers the same thing: model output is not one thing.
A chess model responding to a position produces a move, a strategic rationale, a broadcast line, a confidence signal, and sometimes an illegal action. These are different objects. Treating them as a single “answer” and routing them all to the same sink produces errors, corruptions, and failures.
The first serious fix for this is output routing — the insight from Chapter 6 that mixed model output must be split into trust lanes before anything is acted on. Code goes through a compiler. Facts go through a citation check. Commands go through a schema validator. Claims go through a review gate.
Stagehand is what happens when output routing becomes visible, typed, and synchronized with human-perceivable presentation.
What Stagehand Is
Stagehand is a typed narration protocol for synchronizing speech, visuals, and validated state.
The model writes a narration script. Inside the script, embedded commands direct the renderer:
The Strait of Hormuz is one of the most important chokepoints in global energy.
[map.highlight entity="strait:hormuz"]
Now zoom in and notice its proximity to Iran, Oman, and the shipping lanes.
[map.zoom entity="strait:hormuz" level=6]
The renderer parses the stream. It splits each fragment into lanes:
| Fragment | Lane | Validator |
|---|---|---|
| Spoken sentence | Narration / TTS | Source review, tone review |
map.highlight | Visual command | Command schema |
entity="strait:hormuz" | Entity reference | SQLite entity registry lookup |
| Published claim | Public civic assertion | Source and provenance gate |
The spoken sentence goes to text-to-speech. The visual command goes to the renderer. The entity reference is validated against a live registry. The claim, if it makes it past the provenance gate, becomes a public artifact.
Two more lanes appear once Stagehand drives something more stateful than a globe reading. A state patch — [svs.patch ...], shown in Proof 3 below — is a proposed change to durable state, checked against a state-plane schema before a reducer applies it. A render operation — [svs.render ...] — is a request to compile current state into pixels or audio, checked by the render plan and the renderer itself, not by the narration that asked for it. Every lane shares the same shape: the command schema is an ex ante constraint that shapes what the model can even attempt to say, and the validator behind each lane is the ex post constraint that decides whether the attempt becomes real. A command that parses cleanly has only cleared the first gate.
The model never writes directly to state. The model narrates state that already exists.
Proof 1 — LLM-Chess: Routing Makes The Principle Undeniable
Chess is the cleanest teaching demo because it exposes the lie of “the model gave one answer.”
A chess model responding to a position might produce:
I want to play Nf3 because it develops the knight and pressures the center.
[chess.move san="Nf3"]
[chess.highlight square="f3"]
[chess.arrow from="g1" to="f3"]
These are different objects. The move goes to the chess engine for legality checking. The reasoning goes to benchmark metadata. The highlight and arrow go to the broadcast layer. The commentary goes to TTS.
Chapter 26 established this directly: the proposed move needs legality checking, illegal moves must be caught before corrupting game state, reasoning is benchmark metadata, commentary is broadcast content, and highlights are visual output. Each fragment has a destination. Each destination has a gate.
The key line from LLM-Chess, stated as a Stagehand principle:
Commentary is content. The board is state.
The model can commentate brilliantly on a position. The chess engine still decides whether the move is legal. Stagehand makes this split explicit in the command stream rather than leaving it to the system to infer.
Proof 2 — Clio: Civic Intelligence As Rendered State
Clio is the canonical Stagehand system. Chapter 27 established its architecture: a MapLibre globe backed by a SQLite-WASM entity registry, with narration, TTS, and FFmpeg export. The registry is ground truth. The model narrates from what the database says is true.
The Stagehand command stream for a Clio episode:
The Strait of Hormuz is not just a body of water. It is a pressure valve in the global energy system.
[map.focus entity="strait:hormuz"]
[map.highlight entity="shipping_lane:hormuz_main"]
Now trace the dependency outward.
[map.draw_route from="port:ras_tanura" to="strait:hormuz" to="region:indian_ocean"]
Two things cannot happen in this system:
The command cannot invent geography. If strait:hormuz is not in the entity registry, the command fails. The narration may describe the strait. The renderer cannot move the globe to a location that does not exist in the database.
The route cannot be published without source support. A route that is verified gets a provenance card. An unverified route stays in draft state. The public event log only receives what has crossed the validation boundary.
In civic intelligence, this matters beyond correctness. A false map, false border, or false geopolitical claim does not just mislead technically. In Clio’s domain, civic claims have consequences. Stagehand’s validation gates are not performance. They are the structural guarantee that narration explains civic state rather than creating it.
Narration explains civic state. It does not create civic state.
Proof 3 — Semantic Video Studio: State First, Pixels Second
Semantic Video Studio extends Stagehand from live presentation to generated media.
Chapter 28 established the four-plane state pack: scene_graph.json, asset_manifest.json, timeline.json, and render_plan.json. The MP4 is reproducible because it is compiled from those state planes, not generated in one pass. Pixels are output. State is the product.
Stagehand in SVS becomes a semantic editing language:
The greenhouse rises from the red dust like a sealed ecosystem trying to bargain with Mars.
[svs.camera target="greenhouse" move="slow_push_in" duration=4s]
[svs.highlight object="greenhouse_glass_shell"]
[svs.animate object="drone_01" action="orbit" radius=8 duration=6s]
Each command compiles into a state patch:
[svs.patch plane="timeline" op="add_action" object="drone_01" action="orbit"]
[svs.patch plane="scene_graph" op="set_camera" target="greenhouse"]
[svs.render profile="preview"]
The narration line describes what the viewer sees. The commands construct the state that produces what the viewer sees. The two are synchronized but separate. The narration is never the authoritative source. The state pack is.
This separation enables reproducibility. Given the same state pack and renderer, the video is identical. Given a different narration over the same state, the video changes — but the state remains editable, auditable, and independently correct.
Not everything here is meant to be reproducible, and Stagehand does not pretend otherwise. The wording of the narration, its pacing, and which details the model chooses to mention are allowed to vary between runs — that variation is the model doing what models do, and it stays harmless because it is confined to the narration lane. The four state planes are not allowed to vary. Given the same state pack and the same renderer version, the render must be the same output. If a render needs deliberate randomness — camera shake, particle seed, ambient variation — that randomness is typed: owned by the render plan, seeded, and logged, never left to whatever the model felt like generating this time.
Stagehand is the bridge from narration to editable cinematic state.
The Command Language
Stagehand commands follow a consistent schema:
[namespace.action key="value" key2=value]
Commands are:
- Typed: every namespace and action must be declared in the command schema. Unknown commands fail at parse time, not at render time.
- Validated: entity references are checked against the registry before the command executes.
- Idempotent: running the same command stream twice produces the same state.
- Auditable: every command execution is logged with its inputs and output state.
The narration and command streams are separated at parse time. The TTS system receives narration. The renderer receives commands. Neither receives the other.
Synchronization Is Not Authority
A command sitting next to narration, timed to land exactly when the spoken sentence needs it, looks like it has already happened. It has not.
Timing is a presentation concern. Admission is a validation concern. Stagehand keeps the two separate on purpose: a command can be perfectly synchronized to the narration — right namespace, right timing, right voice — and still fail every check behind it. Synchronization proves the model produced a well-formed proposal at the right moment. It proves nothing about whether the proposal is true, legal, or safe to execute. That question belongs to the validator, asked and answered after the sync, not instead of it.
Every command has a defined failure behavior, because “the command looked right” is not a passing check:
| Failure | Trigger | Behavior |
|---|---|---|
| Unknown command | Namespace or action not in the schema | Rejected at parse time; narration continues without it |
| Unresolved entity | entity= reference not found in the registry | Rejected before render; logged as a failed lookup |
| Unsupported claim | Assertion lacks a source or provenance card | Held in draft; not promoted to the public log |
| Stale state | Command targets state that has changed underneath it | Re-validated against current state or rejected; never applied blind |
| Render failure | Renderer errors while executing an accepted command | Logged to the private trace; narration is not retried automatically |
| Partial completion | Some commands in a stream succeed, others fail | Successful commands commit individually; failures do not roll back what already succeeded |
None of these failures stop the narration. The spoken sentence still plays. What fails is the visual or state-changing side of the pair, and it fails into the trace, not into silence. A viewer might hear a claim that never appears on screen. That gap is not a bug the system is hiding. It is the record of a proposal the validator did not accept.
Public vs. Private Events
A Stagehand session has two event logs: private and public.
The private log captures everything: draft narration, failed commands, rejected entity lookups, unverified claims, reasoning traces, retries. The private log is for the system’s internal audit trail. It is not user-facing.
The public log captures only what has crossed the validation boundary: verified narration, executed visual commands, confirmed entity references, sourced claims, and completed render operations.
The model produces private events. The validator promotes events to public. The public log is the content that can be shared, published, cited, or exported.
This is the same distinction that appears throughout the book: the proposal is cheap; the commit is the meaningful act. In Stagehand, the private event is the proposal. The public event is the commit.
The AI Factory And Stagehand
Chapter 41 described the AI factory pipeline: Extract, Normalize, Validate, Harden, Package, Publish, Observe.
Stagehand is the presentation layer of that pipeline.
The vibe coding session produces raw artifacts: code, notes, screenshots, TTS drafts, visual commands, prototype interactions. The factory processes those artifacts. Stagehand is how the validated, packaged artifacts are presented to an audience.
A book chapter (like the ones in this volume) passes through the factory and becomes:
- A narration script (the prose, cleaned and verified)
- A Stagehand command stream (visual cues, diagram animations, link highlights)
- A TTS audio track (narration, voice-synced to the command stream)
- A visual timeline (compiled by SVS or equivalent renderer)
- A published episode (exportable, shareable, citable)
Two loops are doing this work, and they run at different times. The factory pipeline is a build-time loop: it runs once per chapter, once per episode, converting a session’s proposals into a validated command stream and audio track, with a human able to review every stage before Publish fires. Stagehand’s renderer is a runtime loop: once an episode is live, or a Clio session or an LLM-Chess broadcast is running, the same routing and validation happens per request, at playback speed, with no factory stage standing between a proposal and the screen. The factory builds the schemas and validators. The runtime loop is where they are actually tested, command by command, for as long as the system runs.
The session is the forge. The factory is the refinery. Stagehand is the stage. The audience sees only the produced artifact, not the raw generation that created it.
The One-Line Definition
Stagehand is a typed narration protocol for synchronizing speech, visuals, and validated state.
Longer:
Stagehand lets an LLM write a spoken script with embedded visual commands, while deterministic validators route those commands into safe renderers — a chess board, a civic globe, a semantic video timeline — without letting prose become truth.
The core invariant:
The model narrates from state. The model does not write to state.
Practical Artifact — Stagehand Command Reference
Core namespaces
Each namespace answers to a different source of truth. A command is only as trustworthy as the state the renderer reads before executing it.
| Namespace | Domain | Example | Source of truth |
|---|---|---|---|
map.* | Geographic / civic | [map.highlight entity="strait:hormuz"] | Entity registry (SQLite-WASM) |
chess.* | Chess board and broadcast | [chess.move san="Nf3"] | Rules engine for legality; Stockfish for quality |
svs.* | Semantic video scene | [svs.camera target="greenhouse" move="push_in"] | Four-plane state pack |
stage.* | Generic presentation | [stage.highlight text="key phrase"] | The renderer’s current focus and highlight state |
doc.* | Document / chapter highlight | [doc.highlight section="The Autonomy Ladder"] | The manuscript source file |
Validation pipeline for every command
1. Parse command against schema → unknown commands fail here
2. Validate entity references against registry → unregistered entities fail here
3. Check authorization → commands outside agent scope fail here
4. Execute against renderer → render errors are logged, not surfaced to narration
5. Log to public event log → only on successful execution
The split-lane rule
Model output stream
|
├─ Narrative prose → TTS → audio track
├─ [commands] → schema validator → renderer
├─ Entity refs → registry → confirmed or rejected
├─ Claims → provenance gate → public log or draft
└─ Errors / rejected commands → private audit log
The lanes never cross. Narration does not become command. Command does not become narration. Both become state only after their respective validators confirm them.
Forge, Refinery, Stage
Three words have carried the second half of this book: forge, refinery, stage.
The forge is the session. A human and a model work fast and loose, producing proposals — code, decisions, narration, commands. Nothing from the forge is real yet. It is raw material.
The refinery is the factory from Chapter 41. It takes what the forge produced and runs it through extraction, normalization, validation, and hardening — moving rules out of memory and into specification, out of hope and into verdict — until what remains is typed, tested, and traceable enough to publish. When the shipped product is itself AI-native, the factory’s output includes the schemas and validators that will govern its model at runtime.
The stage is Stagehand. It is where those schemas and validators meet a live model on a live clock. The model narrates. The system parses, routes, and checks. What passes becomes a public event, rendered and citable. What fails stays in the private trace, rejected but not discarded.
The same ideas describe every stop on this journey, under different names. Proposal is what the forge makes, what every model in every chapter of this book makes, every time. Specification is what the refinery writes down and what the stage hands the model before it speaks — the rule, represented, before generation. Verdict is what the factory’s tests apply and what the stage’s validators apply — the rule, enforced, after generation, on a different clock, against the same question: does this belong in trusted state? Commit is Publish in the factory and public-event promotion on the stage — the same boundary, drawn twice. Trace is the handoff file, the ADR, the rejection log, and the private event stream: the record of what was proposed, what was checked, and what happened next.
The model does not get smaller as this architecture grows around it. It stays exactly what it is — fast, fluent, stochastic, useful in every stage and every lane. What changes is what the model is allowed to own. It owns fluency, breadth, and speed. It does not own the schema, the registry, the rules engine, the render plan, or the commit.
The system becomes trustworthy not because the model became reliable. It becomes trustworthy because the model was never handed the laws.
Export
Copy this block into your CLAUDE.md, agent instructions, or project checklist.
Stagehand gives the model a director’s baton, not root access.
vcb_chapter: 42
title: "Stagehand: Narrated State Choreography"
key_line: "Stagehand gives the model a director's baton, not root access."
thesis: "The next interface is narrated state: the model speaks, the system routes, the renderer moves, and the validator decides what becomes real."
checklist:
- item: "Is every command in the stream typed and schema-validated before execution?"
protects: "against untyped commands reaching renderers with unvalidated inputs"
- item: "Are entity references validated against a live registry before commands execute?"
protects: "against narration that names things that do not exist in the ground-truth state"
- item: "Does the model narrate FROM state rather than writing TO state?"
protects: "against the model treating its narration as an authoritative source"
- item: "Are private and public event logs kept separate?"
protects: "against draft, rejected, or unverified events appearing in public output"
- item: "Is the narration lane separated from the command lane at parse time?"
protects: "against prose being treated as executable and commands being spoken as fact"
- Commands are typed and schema-validated before execution — protects against unvalidated renderer inputs
- Entity references checked against registry — protects against narrating nonexistent state
- Model narrates from state, does not write to state — protects against prose-as-truth
- Private events separated from public events — protects against unverified claims in public output
- Narration and command lanes split at parse time — protects against command/prose confusion