DeepBuild Technical Deep Dive
Technical deep dive

DeepBuild, Under the Hood

Where your agents show, not tell.

The design as it stands (draft 6.9.40): the choices, the trade-offs, the use cases, how to extend it, and what’s still open.

Tao Feng · DeepBuildOctober 2026
Needs you · 1checkout-web · claude-code
Taste call · checkout page

Keep the order total above the fold on phones?

Work goes on with “keep” · default in 3 days · undoable

SENT BACK1/3 · receipt shows $18.00 · total.ts:42
PASS3/3 · receipt · journey video
0.1.1Introduction › The idea
Intro: What is DeepBuild, and why build it? › 0.1: What does “vibe visuals” mean?

Vibe Visuals: Describe It, Agents Show You

Like vibe coding, except the result is a picture, a film or a scene, made as data so it can be checked and fixed like code.

VIBE CODING, WHAT YOU KNOW You describe it“add a coupon field” An agent writes codecheckout.ts, 40 lines Tests check itred: fix it, green: done You read a difftext you have to parse VIBE VISUALS, WHAT DEEPBUILD ADDS You describe it“show me why the cartsays $18.01 and thereceipt says $18.00” An agent writes a documentshots, a look, motion,numbers bound to thetest run: data, not pixels The canvas checks itlayout, honest numbers,draw speed, reading time:a miss returns as a fix You watch ita 20-second film: therounding happens beforethe coupon, shown not told “slower on the rounding step” → one patch, not a reroll The canvas is the part of the DeepBuild app that checks and draws: figures, charts, films, 3D scenes, small games and a live map of the agents’ work.
THE LINEWhere your agents show, not tell. DeepBuild is the place agents present their work and ideas as pictures you can trust; it is not an agent itself.2 / 449
0.1.2Introduction › The idea
Intro: What is DeepBuild, and why build it? › 0.1: What does “vibe visuals” mean?

What Vibe Visuals Is, and What It Is Not

The edges of the idea, from the owner’s own corrections during the design.

What it is

Agent-native
agents write documents; the app draws and checks them
A presentation layer
agents present work and ideas as pictures
Checked like code
a miss comes back as a fix, not a reroll
You stay the director
you describe and decide on taste

What the owner ruled out

✕
Not an agent
the presentation layer your agents show their work in
✕
Not proof-first
proof is the trust layer underneath, never the lead
✕
Not AAA games or an MMO
one-minute pieces; small games of 2–8 players
✕
Not a hand-authoring tool
agents make it, you fine-tune what they made (R6), and Blender and Unreal still finish production
✕
Not user controls
agents drive effects by name, as data
✕
Not only video
figures, 3D scenes, games and maps too
✕
Not only coding agents
research, documents, data and services count
BOUNDED BOTH WAYSThe owner also pushed back on cuts: “I think we should have game runtime?” brought sandboxed game rules back a day later.3 / 449
0.2.1Introduction › Why
Intro: What is DeepBuild, and why build it? › 0.2: What did one heavy user’s history show?

One Person, 548 Sessions a Month, No Way to See Them

Before designing, we measured one heavy user’s agent history: 947 sessions in one scan, 548 in a 30-day recheck.

SHARE OF 947 SESSIONS WITH EACH TRUST-GAP PROMPT (OCT 6 SCAN)“is it done / validated?”44%“close the gaps / why stop?”28%“e2e / real stack?”27%UI taste calls25%screenshots asked for21%deploy questions19%
30

sessions at once in one repo (median 28 a day)

72%

of 548 sessions in the recheck had an “is it done?” follow-up

910

stops that ended on a question to you

11%

of your replies were a bare “yes”

409/422

sessions ran in the desktop apps, not terminals

2.4%

of 8,137 prompts were about parallel collisions; in one incident, a pkill took down a sibling’s stack

SOURCEThe owner’s history: 947 sessions, 8,137 prompts (Oct 6); 548 sessions in a 30-day recheck. Not a market study.4 / 449
0.3.1Introduction › An hour
Intro: What is DeepBuild, and why build it? › 0.3: What does an hour with it look like?

An Hour With Three Agents and DeepBuild

Three agents, one hour, read 1 to 6. Each box is what you would see; its last line is what you had to do.

19:04checkout-web · Claude Code
Asks a question only you can answer
Needs you · taste call
Keep the order total above the fold on phones?
KeepMove itgoes on with “keep” meanwhile

It becomes a card in the app. The agent does not stop to wait; it carries on with the default.

You: one tap at 9:26: “keep”
29:19checkout-web · Claude Code
Says it is done. The checks disagree
“Fixed: the receipt now matches the cart.”
SENT BACKthe receipt check failed
receipt shows $18.00, cart $18.01 · total.ts:42

DeepBuild itself runs the tests and a checkout journey in a browser. The failure goes back with the line to fix.

You: nothing; no one pinged you
39:33checkout-web · Claude Code
The second try passes
PASS3 of 3 checks · receipt = cart
▶checkout journey video · 0:12
PR #57 · “Closes #42”

Only check results count as proof, so this PR is allowed to say the issue is closed.

You: nothing; watch the video if you want
49:40docs · Claude Code
Explains the bug as a 20-second film (R6)
Cart$18.01step 2 of 3round()Receipt$18.000:07 / 0:20

The agent writes a short document: three shots, numbers taken from the test run. DeepBuild draws it and checks it.

You: nothing; it waits in the docs session
59:47api · Codex
Tries a command that would hurt the others
$ pkill -f node
✕ denied by a fast rule
kill by name hits other sessions’
servers; stop the PIDs you started

DeepBuild sees every command before it runs. This one is blocked, and the agent is told why.

You: nothing
69:55You · the app
One card left: a push to main
Needs you · 1
Codex wants to push to main in api.
Allow onceNoonly you can grant this

Pushing to main needs your authority, so this is the one thing that waited for you.

You: one tap: “allow once”
WHAT YOU DIDTwo taps in an hour. The failed claim, the pass, the film and the blocked command were settled without you.5 / 449
0.4.1Introduction › The words
Intro: What is DeepBuild, and why build it? › 0.4: Which words does this deck use?

Words You’ll See (1 of 5): How Work Reaches DeepBuild

Follow one session: what it does (left), how it reaches DeepBuild (middle), the log row each step adds (right).

claude · checkout-web · fixing #42› Edit total.ts› Bash npm test› ask: keep the total above the fold?› Stop: “done, total fixed”Agent sessiondeep-hookruns by itself at fixed momentsdeep_askthe agent chooses to call itHookMCP toolRecordrows are only ever added09:12tool.beforeEdit total.tshook09:15tool.beforeBash npm testhook09:16ask.createdkeep the total above the fold?mcp09:20claim.made“done, total fixed”hookthe hub (DeepBuild’s program on your Mac) is the only writer

Agent session

One run of Claude Code or Codex working on one thing.

claude in checkout-web, fixing #42

Hook

A command the agent runs by itself at fixed moments: start, your prompt, before and after a tool, a stop. DeepBuild’s is deep-hook.

PreToolUse → deep-hook

MCP tool

An optional function the agent may call mid-task, over MCP, the usual tool protocol. If it never does, hooks still catch its questions and claims.

deep_ask · deep_show

Record

DeepBuild’s log of everything that happened. Rows are added, never changed.

claim.made · run.finished
THE DIFFERENCEA hook fires whether the agent wants it or not, so nothing depends on the agent choosing to call a tool.6 / 449
0.4.2Introduction › The words
Intro: What is DeepBuild, and why build it? › 0.4: Which words does this deck use?

Words You’ll See (2 of 5): Session, Task, Turn and Stop

A session holds tasks; a task takes turns; a turn ends at a stop. The done gate acts at each stop.

Session
claude · checkout-web · open since Monday, still open
Task
#42 receipt total, 3 turns
#43 docs, 1 turn
Turn
you: fix #42stop
you: yesstop: sent backstop
you: okstop
you: docsstop
idle, waiting for you
grey ticks are tool calls (read, edit, run), many per turn; each  stop  is where the Stop hook fires

Session

One run of Claude Code or Codex. It can stay open for days and carry several tasks.

claude · checkout-web

Task

One request that changes behavior. It gets one definition of done and usually spans several turns.

#42 · #43

Turn

One request and its response: from your message until the agent replies. Not a finished job.

“yes” → … → reply

Stop

The agent ends its response: the Stop hook fires. A send-back makes it go on in the same turn, so a turn can hold two stops.

Stop hook
NOT THE SAMEA turn ends every time the agent replies, finished or not. A task is done only when its checks pass.7 / 449
0.4.3Introduction › The words
Intro: What is DeepBuild, and why build it? › 0.4: Which words does this deck use?

Words You’ll See (3 of 5): How “Done” Is Judged

Read left to right: one bug fix, from what done means to the result. The four yellow labels are the four words.

Definition of doneClaimCheckVerdict#42 · written firstunit tests passcheckout journey worksreceipt = cart totalfixed at the start;agents can’t edit itthe agent works, then stops“Done: the receiptnow matches the cart.”a stop that did work is a claim;its words are not evidenceDeepBuild runs them itself✓unit tests42 passed✓checkout journey0:12, ok✕receipt = cart$18.00 ≠ $18.01tests, commands, browser journeysFAILsent back with total.ts:42 (send-back 1 of 3)PASSevery check passedFAILfailed on every runBLOCKEDoutside need missingINVALIDcould not failINCONCLUSIVEtoo few clean runs

Definition of done

The checks that will judge a task, written down at its start, from your words.

#42: receipt = cart total

Claim

A stop where the agent did work, read as “I did it”.

Stop after editing total.ts

Check

A test, a command or a journey (a scripted run through your app in a browser) that DeepBuild runs itself.

npm test · checkout journey

Verdict

One of five results for a claim, earned from checks only.

PASS · FAIL · and three more
WHY THIS ORDERDone is fixed first so the goalposts can’t move. The agent’s word starts the judging but never counts as evidence.8 / 449
0.4.4Introduction › The words
Intro: What is DeepBuild, and why build it? › 0.4: Which words does this deck use?

Words You’ll See (4 of 5): Asked Once, Then Remembered

Top: you answer a question once, and DeepBuild saves it. Bottom: next week another agent asks the same kind; no ping.

THIS WEEKNEXT WEEKcheckout-web · Codex“Merge my fix PR #57?It unblocks the release.”NEEDS YOU · AUTHORITYMerge PR #57? It unblocks the release.due in 1 day · default “no” · only this step waitsAskyou tapYeskind authority · mergescope checkout-webwhen own fix PR, release blockedsaved by DeepBuild, never by an agentDecisionanswer goes back into the sessioncheckout-web · Claude“Merge my fix PR #61?The release waits on it.”Same kind, same scope?matched by kind and scope,not by the wording✓ Answered for you: mergelogged, undoable; no card, no ping

Ask

A question only you can answer. It has a deadline and a safe default, so no agent waits forever.

push to main? default no, in 1 day

Decision

Your answer, saved and matched by kind and scope, never by exact wording.

merge own fix PR · checkout-web

Six kinds of ask

Authority, taste, choice, unblock, exception, what done means. A repeat taste call asks again until you accept a rule (later).

authority · taste · unblock · …

What agents can’t do

Create, change or widen a decision. Only your answer on a card makes one.

agent edits a decision → denied
A CORE RULEA person sees only what needs a person, and never the same question twice. Decisions keep the second half.9 / 449
0.4.5Introduction › The words
Intro: What is DeepBuild, and why build it? › 0.4: Which words does this deck use?

Words You’ll See (5 of 5): Sharing One Mac, Drawing From Data

Left: two sessions want the same port. Right: an agent sends a few lines of data, the canvas draws them, and a one-value patch changes one bar.

Leaseapi · Codexcheckout · Claudeport 3000held by api✕ refused: held by apiport 3001held by checkoutA lease ends only when its holder has ended and itsprocesses are proven gone. Also: test accounts, GPUs.Documentwhat the agent sendskind: bar-chart@1items:q2: 44q3: 4852patch: items/q3 = 52only that one bar is redrawnwhat the canvas drawsq2444852q3

Lease

A shared thing one session holds so another can’t collide with it.

port 3000, held by api

Why leases

A real pkill once took down a sibling session’s stack, and two worktrees fought over one port.

refused, names the holder

Document

Data the canvas draws: a figure, a film, a scene, a map. Agents send documents, never pixels.

items/q3/params/value: 48

Why documents

Data can be checked, replayed and patched one value at a time. Pixels can’t.

patch: 48 → 52
THAT’S ALL TWELVEMost slides use only these words. Where a slide needs another term, it explains it there.10 / 449
0.5.1Introduction › The map
Intro: What is DeepBuild, and why build it? › 0.5: How is this deck laid out?

Eight Parts, One Map

Parts 1 and 3 say what DeepBuild is; 2 and 4, how it works with you; 5, how it grows; 6 to 8: use, the build, open work.

DeepBuildwhere your agents show, not tell1 · Foundation1.1 four parts, 1.2 four jobs1.3 the rules, 1.4 the hub1.5 extensions, 1.6 ways in1.7 hooks, 1.8 the record1.9 storage, 1.10 processes1.11 platforms2 · See and steer2.1 the app, 2.2 the line2.3 asks, 2.4 matching2.5 answers back, 2.6 a taste call2.7 the app’s toolkit, 2.8 where code runs3 · Make: vibe visuals3.1–3.3 what it makes3.4–3.8 documents, frames3.9–3.12 GPU, light3.13–3.15 modules, checks3.16–3.21 3D, play, sound3.22–3.26 budgets, done bar4 · Trust4.1 a claim, 4.2 what done means4.3 verdicts, 4.4 flaky checks4.5 every stop, 4.6 bug fix #424.7 a UI change, 4.8 the finish line4.9 defenses, 4.10 dodges5 · Extend, compose5.1 extension points, 5.2 agents, hooks5.3 hub slots, 5.4 plug-ins5.5 panels, 5.6 canvas packs5.7 modules, 5.8 composing5.9 safety rules6 · In use6.1 what ships, 6.2 first run6.3 MCP tools, 6.4 the CLI6.5 leases, 6.6 the box6.7 your phone, 6.8 the wiki6.9 learning7 · Build it right7.1 looks right, 7.2 tests first7.3 rules, faults, 7.4 kits7.5 comparisons, 7.6 the gate7.7 borrowed, open, 7.8 budgets7.9 measuring, 7.10 six-week plan7.11 Decision 1, 7.12 routing replay7.13 cuts8 · What’s open8.1 scale, 8.2 issues8.3 R1 path, 8.4 risks8.5 owner calls, 8.6 fleets later8.7 next
HOW TO USE ITEach part opens with this map, its branch highlighted. If a slide feels out of context, its branch tells you which question it answers.11 / 449
0.5.2Introduction › The map
Intro: What is DeepBuild, and why build it? › 0.5: How is this deck laid out?

The Running Index (1 of 4): Introduction to See and Steer

HOW TO USE ITEach part asks one question; each section answers one piece of it. A slide’s number, top left, is part.section.slide: click it to come back here.12 / 449
0.5.3Introduction › The map
Intro: What is DeepBuild, and why build it? › 0.5: How is this deck laid out?

The Running Index (2 of 4): Make

3 · MakeHow do agents show their work as pictures?
3.1What it makesp.95–96What is the canvas for?3.2Who, and whyp.97–100Who uses it, and for what?3.3Primersp.101–103What does a newcomer need to know about rendering?3.4Documentsp.104–130What is a canvas document made of?3.5Inside the canvasp.131–134How do many writers share one picture?3.6A framep.135–153What happens in one frame, and how fast?3.7Computing a framep.154–156Which way of computing a frame, and why?3.8One clockp.157–160How do picture, physics and sound stay in step?3.9Renderingp.161–172How does the GPU draw it?3.10GPU operatorsp.173–191How is new GPU work added safely?3.11Lightp.192–195How is light drawn, and what is kept between frames?3.12Platformsp.196How does one renderer run everywhere?3.13Building blocksp.197–213Which modules make up the canvas?3.14Extendingp.214–225How does the canvas grow without a bigger core?3.15Checksp.226–232How is a picture checked?3.163D scenesp.233–244How is a 3D scene described?3.17Play, physicsp.245–251How do pieces become interactive?3.18Logicp.252–257How do game rules run safely?3.19Shared playp.258–260How do several players share a piece?3.20Soundp.261–262How does sound follow the picture?3.21Exportp.263–265How does a piece leave the app?3.22Budgetsp.266–267How does the canvas stay light on your Mac?3.23The done barp.268–269When does the canvas count as done?3.24An explainerp.270–271How does an agent make an explainer, end to end?3.25The Mapp.272–274How is your project shown as a map?3.26Releasesp.275What arrives in which release?
HOW TO USE ITEach part asks one question; each section answers one piece of it. A slide’s number, top left, is part.section.slide: click it to come back here.13 / 449
0.5.4Introduction › The map
Intro: What is DeepBuild, and why build it? › 0.5: How is this deck laid out?

The Running Index (3 of 4): Trust, Extend, In Use

4 · TrustCan you trust an agent’s “done”?
4.1A claimp.277–287What happens when an agent says “done”?4.2What done meansp.288–298How is “done” fixed before the work?4.3Verdictsp.299–300What verdicts can a claim get?4.4Flaky checksp.301–303What about checks that pass and fail on the same code?4.5Every stopp.304–318Why judge every stop, and how does it stay cheap?4.6Bug fix #42p.319–321How is a bug fix judged, end to end?4.7A UI changep.322–325How is a UI change judged?4.8The finish linep.326–328What must hold before work counts as finished?4.9Defensesp.329–336What stops an agent from cheating?4.10Dodgesp.337–338Which ways of looking done get caught?
5 · Extend and composeHow does it grow without breaking?
5.1Extension pointsp.340–342Where can DeepBuild be extended?5.2Agents, hooksp.343–345How is a new agent added?5.3Hub slotsp.346–349Which hub parts can be swapped?5.4Plug-insp.350–358How does a plug-in do real work?5.5Panelsp.359How does the app change itself?5.6Canvas packsp.360–361How does new GPU work arrive as a pack?5.7Modulesp.362–363How is a new kind added to the canvas?5.8Composingp.364–366How do pieces combine?5.9Safety rulesp.367–368What keeps extensions from breaking things?
6 · In useWhat is it like to use?
6.1What shipsp.370What is on by default?6.2First runp.371–372What happens the first time you run it?6.3MCP toolsp.373–375What can an agent call?6.4The CLIp.376–377What can you do from a terminal?6.5Leasesp.378–383How do sessions share ports, machines and files?6.6The boxp.384–389How do you start and steer sessions from the app?6.7Your phonep.390–391How do you answer away from your desk?6.8The wikip.392–395What does DeepBuild know about you?6.9Learningp.396–403How does it learn from past work?
HOW TO USE ITEach part asks one question; each section answers one piece of it. A slide’s number, top left, is part.section.slide: click it to come back here.14 / 449
0.5.5Introduction › The map
Intro: What is DeepBuild, and why build it? › 0.5: How is this deck laid out?

The Running Index (4 of 4): Build It Right and What’s Open

HOW TO USE ITEach part asks one question; each section answers one piece of it. A slide’s number, top left, is part.section.slide: click it to come back here.15 / 449
1Foundation
Part 1 asks: What is DeepBuild built from? › 11 sections, 1.1 to 1.11, each answering one part of it (running index, slide 12)

Part 1: Foundation

What DeepBuild is built from, the rules every part keeps, and its first trade-offs: logic, storage, processes.

DeepBuildwhere your agents show, not tell1 · Foundation1.1 four parts, 1.2 four jobs1.3 the rules, 1.4 the hub1.5 extensions, 1.6 ways in1.7 hooks, 1.8 the record1.9 storage, 1.10 processes1.11 platforms2 · See and steer2.1 the app, 2.2 the line2.3 asks, 2.4 matching2.5 answers back, 2.6 a taste call2.7 the app’s toolkit, 2.8 where code runs3 · Make: vibe visuals3.1–3.3 what it makes3.4–3.8 documents, frames3.9–3.12 GPU, light3.13–3.15 modules, checks3.16–3.21 3D, play, sound3.22–3.26 budgets, done bar4 · Trust4.1 a claim, 4.2 what done means4.3 verdicts, 4.4 flaky checks4.5 every stop, 4.6 bug fix #424.7 a UI change, 4.8 the finish line4.9 defenses, 4.10 dodges5 · Extend, compose5.1 extension points, 5.2 agents, hooks5.3 hub slots, 5.4 plug-ins5.5 panels, 5.6 canvas packs5.7 modules, 5.8 composing5.9 safety rules6 · In use6.1 what ships, 6.2 first run6.3 MCP tools, 6.4 the CLI6.5 leases, 6.6 the box6.7 your phone, 6.8 the wiki6.9 learning7 · Build it right7.1 looks right, 7.2 tests first7.3 rules, faults, 7.4 kits7.5 comparisons, 7.6 the gate7.7 borrowed, open, 7.8 budgets7.9 measuring, 7.10 six-week plan7.11 Decision 1, 7.12 routing replay7.13 cuts8 · What’s open8.1 scale, 8.2 issues8.3 R1 path, 8.4 risks8.5 owner calls, 8.6 fleets later8.7 next
WHERE WE AREThe highlighted branch is this part; its topics are the slides that follow.16 / 449
1.1.1Foundation › Four partsin the system: DeepBuild
Part 1: What is DeepBuild built from? › 1.1: What are the four running parts?

Four Parts, and One Agent Stop Passing Through Them

Four programs. Follow one agent stop through them, 1 to 5. R1 is the first release (version 0); R2 the next.

Claude Codeor Codex“done, total fixed”deep-hookstarts, stamps the event,passes it on, exitsdeep hubDeepBuild’s background programon your Mac: one per user, always on• appends claim.made• runs the 3 checks• appends the verdictthe recordDeepBuild appcheckout-webSENT BACK1/3 · total.ts:42canvas corethe only part on the GPUCart$18.01round()Receipt$18.00film 0:07 / 0:20drawn from a document, never from pixels1234the reply: one verdict line5
1The agent stops; its Stop hook runs deep-hook.
2deep-hook hands the event to the hub. Hub down? It allows and keeps the event.
3The hub logs the claim, runs the checks itself, logs the verdict.
4The reply puts “sent back” in the chat; the app shows it on the session’s line.
5Another agent explains the bug; the canvas core draws the film (R6).
deep-hookR1
Rust, mostly the rule matcher. Every agent hook runs it. If it fails, the agent goes on.
27 ms to start
<10 MB peak
Deep dive → slide 26
deep hubR1
DeepBuild’s background program on your Mac. The only writer to the record.
1 writer
150 MB memory cap
Deep dive → slide 24
DeepBuild appR1
Native, gpui-kit. Every session by repo, what needs you, each line.
300 MB 30 sessions
4 ms per update
Deep dive → slide 64
Canvas coreR1
Inside the app. Takes documents, never pixels. R1 draws the line, receipts and sheets; R2 adds the GPU layer; films come in R6.
2 ms per frame
256 MB per window
Deep dive → slide 131
NEXTThe same four parts, one level down, then their four jobs. Card numbers are targets; 27 ms is an estimate.17 / 449
1.1.2Foundation › Four partsin the system: DeepBuild
Part 1: What is DeepBuild built from? › 1.1: What are the four running parts?

DeepBuild, Taken Apart: Every Part on One Tree

The four parts from the last slide, opened one level down. Each box names its job and the slide that explains it.

DeepBuildon your Mac, beside your agentsOn the agent’s sideruns inside Claude Code or Codexdeep-hookevery hook moment→ 26deep mcptools an agent may call→ 35deep hubone per user, always onthe corethe record and the rules→ 43trusted ringsupervisor, installer→ 54extensionsdone gate, asks, adapters, wiki→ 33plug-insfenced in, built by agents→ 350DeepBuild appwhat you look atshellwindow, question card→ 91viewssessions, line, Needs you→ 64canvas corethe only part that draws→ 131Around itother ways in and outdeep CLIthe same, in a terminal→ 376channelsyour phone, chat, email→ 390the wikiwhat DeepBuild learns→ 392
HOW TO USE ITEvery slide’s top-left label is its path in this tree; the arrow number is where each part is explained.18 / 449
1.2.1Foundation › Four jobsin the system: DeepBuild
Part 1: What is DeepBuild built from? › 1.2: What four jobs do they do together?

Four Jobs, One Record Under All of Them

What the four parts do for you, as four jobs. Each box’s last line names the parts and the release; all use the record.

The record append-only event log + evidence files, named by hash See every session by repo, as its lineissue → PR · a Map of the projectapp + hub · R1 · 3D Map in R2 Steer only what needs a personanswers back into live sessionshub + app + hook · R1 · your phone R2 Make documents the canvas drawssame document + time = same framecanvas core R1 · GPU R2 · R6 films, 3D Trust checks run by DeepBuildone of five verdicts per claimhub + hook · R1
FRAMINGDeepBuild is not an agent. It is the layer your agents show their work in. Proof is the trust layer underneath, not the pitch.19 / 449
1.2.2Foundation › Four jobsin the system: DeepBuild
Part 1: What is DeepBuild built from? › 1.2: What four jobs do they do together?

Six Releases: What Version 0 Builds, and What Waits

The four jobs don’t all arrive at once. R1, version 0, builds the core; each later release adds to it.

R1version 0Prove done,and see itClaude Code and Codexthe done gate, and itsverdict line in the chatasks with deadlinesyour wikithe app, the CLI andthe MCP toolsleases, commit statusesR2Find, and trustthe numbersstarting sessionspi, paseo and Cursorparallel sessionsplan usage per taskyour phone (channels)Add anythingworkspaces, plansthe 3D MapR3Change withproofyour other machines,over SSHthe infra mapthe app on Linuxlocal models (vLLM)R4Keepguards for failure classeslessons learned once,by every agentspeed and cost ceilingsthat only move downthe feature maptrials of its own partsR5CICI policiesa milestone oftwo issues so farR6Run yourworkflowplaybooks: deep createACP sessionsscheduling insideplan windowsfilms, 3D scenes, gamesthe web playerThe core, from R1:the record, gates, asks and the adapter contract. Everything after R1 lands as an extension on it.
Version 0 is R1: five weeks to build and one of real use, from the repo checkout on the maintainer’s Mac. From R2 the app is a signed download that carries the hub, the hook client and the deep command.
READ IT ASA tag like “(R2)” on a slide means that part arrives in that release. Untagged parts are in version 0.20 / 449
1.3.1Foundation › The rulesin the system: DeepBuild › rules for every part
Part 1: What is DeepBuild built from? › 1.3: Which rules can no part break?

Four Invariants Every Part Must Keep

All four jobs, and every plug-in, keep four rules. Each column: the rule, what it means, and one catch.

1

An agent’s word is never evidence

Only check results count. Why a session stopped is read from hook payloads, never its text.

e.g. “tests pass” in a message
→ changes nothing
2

Nothing missing or unrun passes

A check that ran nothing, couldn’t fail or lost its results never passes. It gets a named non-pass verdict.

e.g. npm test || true
→ INVALID, naming the mask
3

Agents can’t change checks or decisions

Agents can’t edit the checks in .deepbuild/; your decisions live outside every repo.

e.g. agent edits .deepbuild/done.yaml
→ denied; it can only propose
4

Only what needs a person, never twice

Asks sorted by kind; saved decisions answer repeats by kind and scope.

e.g. same merge ask next week
→ decided for you, logged
TESTEvery option in this deck was scored against these four first. Anything that breaks one is cut or kept outside the core.21 / 449
1.3.2Foundation › The rulesin the system: DeepBuild › rules for every part
Part 1: What is DeepBuild built from? › 1.3: Which rules can no part break?

Rule 2 in Practice: Silence Is Never a Pass

Six ways a check can look green while proving nothing. Each row: what happened, the naive reading (struck out), and DeepBuild’s verdict.

What happenedA naive checker saysDeepBuild says, and why
The test command ran zero testsnpm test → exit 0, “0 tests” PASSINVALID ran nothing: a run must count its tests
Its failure is hidden"test": "vitest || true" PASSINVALID exit status masked by || true; it can’t fail
A step was skippeda CI step marked continue-on-error PASSINVALID skipped or masked steps never count
Something outside the code is missinga journey needs a test account nobody granted PASSBLOCKED names the cause, the owner and since when
The power went out mid-runevents after the last disk write are gone PASSINVALID “events lost”: re-run, never assumed
It passed once and failed oncesame commit, two runs, two answers PASSINCONCLUSIVE names how many clean runs are still needed
THE POINTA PASS must be earned by checks that ran and could have failed. Anything else gets a verdict that says what to fix.22 / 449
1.4.1Foundation › The hubin the system: Hub
Part 1: What is DeepBuild built from? › 1.4: What runs inside the hub?

Inside the Hub: The Core, the Ring, Extensions, Plug-ins

The hub, opened one level down. Highlighted: the part the next slides explain first.

deep hubDeepBuild’s background program; one per userThe programone per user, starts at login; the app,CLI and deep mcp reach it by one socket→ 24First-party extensionsdone gate, asks and resolvers, agentadapters, journeys, leases, the wiki→ 33The corethe record (the log of everything),the rules every part keeps, who may do what→ 43Trusted ringthe supervisor (starts and stops programs),the installer (checks code before it loads)→ 54Plug-insbuilt by your agent or others; runfenced in; the hub makes outside calls→ 350Scheduler and leasescheck runs, CPU slots, ports andaccounts one session holds→ 378
WHERE NEXTThe next slides open the hub itself; the core’s record and the extensions follow in this part.23 / 449
1.4.2Foundation › The hubin the system: Hub
Part 1: What is DeepBuild built from? › 1.4: What runs inside the hub?

One Hub per User: The Program That Keeps the Record

The hub is DeepBuild’s one long-running program. Follow 1 to 4: it starts, agents and you connect, it writes the record.

AGENT SESSIONScheckout-web · Claude Codeapi · Codexdocs · Claude Codemore agents join in R2: pi, Cursor, paseo (a runner for agents)deep-hookRust · every hook runs itdeep mcpthe MCP tools, one per sessionhooksMCPdeep hubTypeScript on Node · one per user1Starts at loginlaunchd, systemd or a logon taskListens on one local socket~/.deepbuild/hub.sockmode 0600: only you can open itThe only writerto the record; it stamps eachline with who sent ithook roleappend events, read rulessession credentialits own session only2YOUDeepBuild app · Rust, gpui-kitdeep CLIcontrol token: new each launch; no command line, no env3ledger.dbone SQLite fileevidence/files by sha2564RecordHub
1At login the OS starts one hub for you, and it keeps running: launchd on macOS, a systemd user service or a logon task elsewhere.
2Every agent session reaches it: hook calls through deep-hook, tool calls through deep mcp, each with a narrow key.
3You reach it through the app and the deep CLI, the only two holding the control token, which alone saves no decision.
4Only the hub writes the record: one SQLite log, plus evidence files named by their hash.
ONLY YOUThe socket opens for your user alone. There is no HTTP server and no network port, and any request carrying a browser Origin is refused.24 / 449
1.4.3Foundation › The hubin the system: Hub
Part 1: What is DeepBuild built from? › 1.4: What runs inside the hub?

Why One Hub for All Your Sessions, Always Running

Three jobs no session or short-lived script can do. Each row plays an example; the right box says why.

1Answers come hours latera question waits for you;the session moves onSOOnly a program that staysrunning can hold the ask,deliver your answer later,or apply its default.2It must see every sessiona rule that spans sessionsneeds one place to liveSOLeases, and saved answersto repeat questions, workonly because one hub seesall your sessions.3One writer, one recordtwo writers can disagreeabout what happenedSOOne process holds the lockand appends every line, sothere is one order and onecopy of what happened.checkout-web · Claude Code keeps workingdeep-hook: forwards the ask, exitsthe hub: running the whole time, holding the ask9:04 asks9:26 you tap Keepdelivered into the sessionin 3 days: the defaultapi · Codexcheckout-web · Claude Codehubport 3000api✕ wants 3000: refused,held by api; takes 3001deep-hookdeep mcpappCLIhubledger.dbEach one writing the fileitself?In hermes, an open-sourceagent: 7 corruptions in 4 days
NOT IN THE CLOUDThe hub runs on your Mac and sends nothing by default. Later it can run on a machine you own, still one per person.25 / 449
1.4.4Foundation › The hubin the system: Hub
Part 1: What is DeepBuild built from? › 1.4: What runs inside the hub?

deep-hook: Tiny Because Every Tool Call Runs It

deep-hook carries each hook call to the hub. Top: one call, 1 to 4. Bottom: hub down, and the agent still goes on.

ONE TOOL CALL, HUB RUNNINGclaude · checkout-web› Bash npm testPreToolUse firesdeep-hook startsabout 27 ms (an estimate)under 10 MB peak (target)Rust, mostly the rule matcheradds who, what, when and an ID"agent": "claude-code""event": "PreToolUse""seq": "1760013451123456789""id": "01K74FKZVK8Q…"hub decidesallow, deny or hold(hold: the agent waits)reply in the agent’s formatdeep-hook printsthe reply and exitsthe agent goes on1234Hook clientTHE SAME KIND OF CALLS, HUB DOWNcodex · api› pkill -f nodeclaude · checkout-web› Bash npm testdeep-hookthe hub isn’t there, ordidn’t ack within 50 msso it applies only therules marked fail-closedhub: not running✕rules.jsonno kills by name or portno CI dispatch without approval✕ pkill: deniedfail-closed: this rule denies even with the hub down✓ npm test: allowed, saved to a local spool filewhen the hub starts it replays the spool; eachevent keeps the ID and time it was stamped with
Only two powers

It can append events and read fast rules, the few deny rules kept in a local file. It never holds the control token, so it can’t answer for you.

Why Rust

Estimates until week 1 measures again: on the owner’s Mac a native binary started in about 27 ms, Node 52, Python 75, paid per call.

Budget

Targets: under 10 ms at p95 over process start, except holds. The hub acks each call within 20 ms; no ack by 50 ms counts as down.

WHY TINYHooks fire on every tool call, thousands of times a day, so the thinking lives in the hub; the client stamps, forwards and exits.26 / 449
1.4.5Foundation › The hubin the system: Agent side › deep-hook
Part 1: What is DeepBuild built from? › 1.4: What runs inside the hub?

deep-hook and the Hub on the Wire: Request, Ack, Reply

The last slide’s steps 2 to 4, as the bytes on the socket: a request line, an ack within 20 ms, then the reply.

THE THREE LINES ON THE SOCKET, ONE JSON LINE EACH (VALUES FROM THE DESIGN’S EXAMPLE)REQUESTdeep-hook → hub{ "v": 1, "agent": "claude-code", "event": "PreToolUse", "seq": "1760013451123456789", "id": "01K74FKZVK8Q2X5R7M3N9P4T6W", "pid": 81234, "ppid": 81200, "matched": [ …guard entries it matched… ], "payload": { …the hook’s JSON, unchanged… } }1ACKhub → deep-hook{ "ack": "01K74FKZVK8Q2X5R7M3N9P4T6W", "hold_until_ms": null }within 20 ms of reading the request2REPLYhub → deep-hook{ "exit": 0, "stdout": "{\"hookSpecificOutput\":{…}}", "stderr": "" }in the agent’s own format; printed as is3ONE CALL, THREE WAYS IT GOES (MS AFTER DEEP-HOOK STARTS; TIMES ILLUSTRATIVE)50 msPreToolUse · npm testhub upStop · a held stophub up, checks to runany hook callhub silent123ack at 4 ms, reply at 7 ms: printed; the agent goes on12the ack says hold_until_ms = start + 60 s: it may waitreply by then:31✕ no ack: acts as if the hub is down

Only an acked hold waits

No ack by 50 ms, or no reply by the hold_until_ms the ack set: deep-hook acts as if the hub were down.

Refused counts as down

A request the hub refuses, or a reply that won’t parse: fail-closed rules, allow the rest, spool it.

seq travels as digits

1760013451123456789 as a JavaScript number becomes …768, so it is a string, compared as an exact integer.

NEVER LOSTA reply the hub writes after deep-hook has gone is recorded as not delivered. Next: what the spool keeps.27 / 449
1.4.6Foundation › The hubin the system: Agent side › deep-hook
Part 1: What is DeepBuild built from? › 1.4: What runs inside the hub?

Hub Down: The Spool Keeps Each Event and Replays It Once

The silent-hub row, followed on: what deep-hook writes while the hub is down, and what the hub does at start.

THE SPOOL FILE, WRITTEN WHILE THE HUB WAS DOWN (ILLUSTRATIVE)1deep-hook: one append of one line per call, byte for byte{"id":"01K74G3A…","event":"PreToolUse",…"npm test"…}late{"id":"01K74G4B…","event":"PermissionRequest",…"gh pr create"…}late{"id":"01K74G5C…","event":"PostTocut mid-write{"id":"01K74G6D…","event":"Stop",…}lateeach line keeps the id and seq deep-hook stamped when the hook startedspool10:09 · THE HUB STARTS AND READS IT, LINE BY LINE2the hub appends each line it can read, in order✓log_pos 2311 · tool.before, marked late✓log_pos 2312 · and an ask you see in Needs you✕skipped: recorded as a refused line at offset 1532✓log_pos 2313 · the lines after a cut are keptthe file is removed only once all of it is saved first3log_pos

Old stamps, new numbers

Each line takes the next log_pos, the record’s line number, so a reader that resumes after its last one still gets it.

Each ID once

A hub that crashed mid-replay reads the file again; an ID already in the record is skipped.

Saved first

A commit that waits until it is on the disk itself, so a power cut can’t lose it (more in 48).

NOTHING LOST, NOTHING TWICEA stopped hub never blocks an agent, and every event it missed still lands once, in order.28 / 449
1.4.7Foundation › The hubin the system: Hub
Part 1: What is DeepBuild built from? › 1.4: What runs inside the hub?

Where the Logic Lives: What We Compare, and Why

Before the scores on “Where the Logic Lives”: each row is one column of the next slide’s table, and why it matters.

ColumnWhat it measuresWhy it matters
1Hook cost time added to every tool callhooks fire thousands of times a day
2One writer one process appends to the recordtwo writers disagree on what happened
3Answer later can deliver an answer hours latera taste call may wait 3 days
4Data stays local transcripts and keys stay on the Macnothing is sent by default
5Setup work to install and keep runningsetup is one click
The options on the next slideHooks do all the workA hosted serviceA plugin inside each agentOne hub per user + tiny hook
NEXTEach option scored on these 5 columns, three diamonds for strong.29 / 449
1.4.8Foundation › The hubin the system: Hub
Part 1: What is DeepBuild built from? › 1.4: What runs inside the hub?

Where the Logic Lives: Only a Resident Hub Can Answer Hours Later

Four ways to place DeepBuild’s logic, scored on the columns the previous slide explains.

OptionHook costOne writerAnswer laterData stays localSetup
Hooks do all the workno daemonDropped
A hosted servicecloud hubDropped
A plugin inside each agentone copy per agentDropped
One hub per user + tiny hooklogin serviceChosen
strong weak breaks a hard rulescores: our reading of the gains and costs recorded in the design
COST WE ACCEPTEDA per-user service that starts at login (launchd, systemd user, logon task), survives restarts by replaying the log, and refuses to start twice.30 / 449
1.4.9Foundation › The hubin the system: Hub
Part 1: What is DeepBuild built from? › 1.4: What runs inside the hub?

Which Language Where: What We Compare, and Why

Before the scores on “Which Language Where”: each row is one column of the next slide’s table, and why it matters.

ColumnWhat it measuresWhy it matters
1Agents write it agents produce correct code in itagents will build R1 from its GitHub issues
2Hot-path speed cost on paths that run constantlyhooks have a 10 ms budget
3Ecosystem the libraries we need existJSON Schema, Playwright, MCP SDKs
The options on the next slideTypeScript on NodeRustEffect 4 in hub core
NEXTEach option scored on these 3 columns, three diamonds for strong.31 / 449
1.4.10Foundation › The hubin the system: Hub
Part 1: What is DeepBuild built from? › 1.4: What runs inside the hub?

Rust Where It Runs Often, TypeScript Where It Changes Often

Left: start time per language, paid on every hook call, so deep-hook is Rust. Right: the hub’s language, scored.

PROCESS START, AN ESTIMATE: MEDIAN OF 25, PILOT MAC, OCT 5Bun19 msNative binary (Rust)27 msNode52 msPython 375 ms
Target <10 ms p95 over process startHub-down target <50 msdeep-hook target <10 MB peak
OptionAgents write itHot-path speedEcosystem
TypeScript on Nodehub, CLI, extensionsChosen
Rusthub tooDropped
Effect 4 in hub corea new TS library; a 1-day spike decidesFallback
Hub target <150 MB, 0.5% of a core idleHot path a test fails if the event loop runs git, scans folders, waits on a disk sync or parses a payload
WHY NOT BUNFastest start, but a runtime to ship everywhere. So: TypeScript, and Rust only where a hot path misses its budget.32 / 449
1.5.1Foundation › Extensionsin the system: Hub › extensions
Part 1: What is DeepBuild built from? › 1.5: What is an extension, and who writes one?

What an Extension Is, and Who Writes One

The hub stays small; features on top are extensions. Left: the two parts that never are. Right: who writes them.

The corethe record, the API every part uses, capabilities,two rules (PASS needs real runs; every ask ends)and the trusted path your own answers takesmall, and never an extensionThe trusted ringin the hub: the supervisor, which starts andstops every process DeepBuild runs, and theinstaller; in the app: its shell and canvas coreno extension can replace or extend itnot extensionsEXTENSIONS: EVERY FEATURE BUILT ON TOP, GROUPED BY WHO WROTE ITFirst-partywritten and shipped by DeepBuilddone gatejourneysresolversagent adapterswikiBuilt by your agenta plug-in made from one sentence of yourswatch the receipts inboxCI statusa stocks viewFrom someone elsethird party: installed, pinned, signed by its makera blueprint: a way to close the monthan extension in Python

Extension

Any feature built on top of the core, even DeepBuild’s own; those are pinned and checked before they load.

Done gate · journey

The done gate runs checks a blind job wrote from the old code, and only their results judge a stop. A journey is a scripted browser run of your app.

Resolver · adapter

A resolver answers a repeat ask from your saved decisions. An adapter reads one agent’s hooks and replies.

Wiki · plug-in

The wiki keeps what DeepBuild learns about you. A plug-in is an extension your agent or someone else wrote.

BOTH KINDSDeepBuild’s own features are extensions too. What differs is where each one is allowed to run: the next slide.33 / 449
1.5.2Foundation › Extensionsin the system: Hub › extensions
Part 1: What is DeepBuild built from? › 1.5: What is an extension, and who writes one?

In-Process or Sandboxed: Where Each Extension Runs

Left: DeepBuild’s own extensions, inside the hub. Right: an extension your agent built, in its own fenced program.

IN-PROCESS: INSIDE THE HUB’S OWN PROGRAMdeep hubone program, one memorythe coredone gateresolversA call is a function call: no message, no hop.The done gate runs at every stop, so it can’tafford to wait on another program.only DeepBuild’s own TypeScript, pinned and checkedOUT OF PROCESS, SANDBOXED: ITS OWN FENCED PROGRAMdeep hubstarts it, talks to itmessagesJSON over stdioOS sandboxreceipts watcherbuilt by your agent✕the internet, except hosts you granted✕your files, the hub’s socket, your keys✓asks the hub to read a source or use a keyIf it crashes or misbehaves,the hub keeps runningand the fence holds.

In-process

Loaded into the hub’s own program, like a library. Fast, and fully trusted.

first-party TypeScript only

Out of process

Runs as its own program that the hub starts and talks to by messages. A crash can’t take the hub down.

agent-built · third party

Sandboxed

The operating system fences that program in: only the hosts, folders and keys it was granted.

Seatbelt · bubblewrap · AppContainer

Why split

Putting everything inside would trust agent code fully; putting everything outside would slow the check at every stop.

split by who wrote it
RULEOnly DeepBuild’s own code runs inside the hub. Code your agent wrote, or anyone else did, always runs fenced, on its own.34 / 449
1.6.1Foundation › Ways inin the system: Agent side
Part 1: What is DeepBuild built from? › 1.6: How do agents, apps and you reach the hub?

Five Ways In, All Onto the Same Hub

The hub’s callers from slide 24, plus plug-ins: five ways in. Each card’s last line says where its power stops.

deep-hook · automatic

Hooks

Every agent, at every step. You never call it.

PreToolUseStopSessionStart

limit: can only append events and read fast rules

deep mcp · the agent

MCP tools

When an agent needs something mid-task.

deep_askdeep_showdeep_claim

limit: reaches only its own session; can ask, never decide

deep · you, or a script

CLI

From a terminal, CI or a script.

deep statusdeep inboxdeep doctor

limit: authority or a saved decision counts only after Touch ID

DeepBuild app · you

App

To see every session and answer what needs you.

Needs youthe linethe Map

limit: the question card nothing can cover

deep.* · a plug-in

Plug-in API

To add a check, a source, a view or a channel.

registerCheckregisterSourceregisterView

limit: only what its grant allows, enforced

ONE COREWhichever way a request comes in, the hub records it with the caller’s role, so a hook can’t answer an ask and an agent can’t decide for you.35 / 449
1.6.2Foundation › Ways inin the system: Agent side
Part 1: What is DeepBuild built from? › 1.6: How do agents, apps and you reach the hub?

Which One Is Used When

Start at the top and follow the first yes. Each answer comes with a concrete example of that surface in use.

Is it happening on its own, at every agent step?yesHookClaude runs npm test → PreToolUsedeep-hook checks fast rules firstnoIs it an agent that needs something mid-task?yesMCP tooldeep_ask “delete the old migration?”the ask waits; the agent keeps workingnoIs it you, wanting to see or decide?yesAppNeeds you: one card, answer in a clickor a notification, or your phone (R2)noIs it you in a terminal, or a script?yesCLIdeep status · deep inboxscripts and CI get the same stepsnoIs it new ability: a check, source or view?yesPlug-in API“watch the receipts inbox”your agent writes it; you grant it once
RULE OF THUMBAgents talk through hooks and MCP; you talk through the app and the CLI; plug-ins extend what either can do.36 / 449
1.6.3Foundation › Ways inin the system: Hub
Part 1: What is DeepBuild built from? › 1.6: How do agents, apps and you reach the hub?

How Each Way In Reaches the Hub, and What It Proves

The last slide said which way in is used when. Here: how each reaches the hub’s socket, and who it proves it is.

WAY INWHAT RUNS, FOR EXAMPLEHOW IT REACHES THE HUBWHAT IT PRESENTSTHE HUB STAMPSHooksautomaticClaude Code runs deep-hookPreToolUse · npm testwriter: hookcan’t answer an askone JSON line on hub.sock;deep-hook exits after the replythe hook role: appendevents, read rules.jsonMCP toolsthe agentan agent calls a deep_* tooldeep_ask · keep the total?writer: mcp:<session>its own session onlystdio to deep mcp, whichforwards it on the socketa session credential,bound to one sessionCLIyou, scriptsyou run a deep command$ deep inboxwriter: clia decision needs Touch IDreads control.token (mode0600, new at each hub launch)the control token; the peercheck: run in an agent’stree, it acts as that agentAppyouyou tap Keep on a cardasks/:id/answerwriter: appcounts once this app signs itthe app API: JSON lines onthe same socket; no HTTP, no portthe control token; a requestwith a browser Origin isrefusedPlug-insnew abilitya plug-in calls deep.*the receipts watcherwriter: ext:<id>only what its grant allowsDeepBuild’s own: a functioncall; any other: JSON-RPC onstdio from its sandboxits grant, checked onevery callTHE RULEEvery event’s writer comes from this credential, never from a field the caller fills in. One socket, ~/.deepbuild/hub.sock, mode 0600.writer
WHY IT MATTERSA hook can’t answer an ask and an agent can’t decide for you: who is calling is proven, not claimed.37 / 449
1.7.1Foundation › Hooksin the system: Agent side › deep-hook
Part 1: What is DeepBuild built from? › 1.7: How does an agent tell us what it does?

What a Hook Is: The Agent Calls Us at Five Moments

Slide 6’s hook in full: at five moments of each turn, the agent runs deep-hook, which records it and may answer.

ONE TURN →agent thinksnpm test“done, fixed”SessionStartdeep-hook → hubsend the open asksand what done meansUserPromptSubmitdeep-hook → hubrecord your request;answer “still going?”PreToolUsedeep-hook → hubfast rules first:deny pkill -f nodePostToolUsedeep-hook → hubrecord what ranand how it endedStopdeep-hook → hubjudge the claim;hold it, or let it end
Who sets it up: DeepBuild’s one-click setup writes one line per moment into Claude Code’s and Codex’s hook settings
What it costs: a target of under 10 ms per call on top of starting the program (about 27 ms, an estimate)
If DeepBuild is down or silent: deep-hook lets the agent go on and saves the event, marked late
WHY HOOKSThey work inside the agents’ own apps, with no agent loop of our own. The next slide shows why they can’t be trusted on their own.38 / 449
1.7.2Foundation › Hooksin the system: Agent side › deep-hook
Part 1: What is DeepBuild built from? › 1.7: How does an agent tell us what it does?

Why Hooks Can’t Be Taken Literally: Five Real Cases

A hook says one moment happened, not what the agent is doing now. Read literally, five ordinary cases mislead.

What really happenedTaken literally, you’d be toldWhat DeepBuild does instead
A helper agent (a subagent) finishesits Stop fires while the main agent keeps editing “checkout-web is done”Checks who fired it: the helper stopped, the main agent is still working.
A tool’s result arrives lateits PostToolUse lands after the turn’s Stop “the finished session started again”Orders events by the time deep-hook stamped each one; the late event stays in its own turn.
You type /clearthe session gets a brand-new ID “new session”, and your open question vanishesJoins the old and new IDs into one thread; the question follows it.
The agent waits on a trust promptno hook fires at all “quiet, so it finished”Shows “unknown” and reads the end of the transcript before telling you anything.
The Mac’s clock steps back 2 sa later event carries an earlier time “this happened before the last event”Keeps the order events arrived in, and notes “clock went back”.
Where these rules live: in a data file per agent and version (event names, payload fields, quirks, stop-cause texts), not in DeepBuild’s code. A new agent version no file covers yet gets its events marked unverified, and DeepBuild only watches it, never holding or blocking, until it’s checked.
WHY IT MATTERSDeepBuild sees agents only through hooks. Reading them carefully is what keeps “done”, your questions and the session list honest.39 / 449
1.7.3Foundation › Hooksin the system: Agent side › deep-hook
Part 1: What is DeepBuild built from? › 1.7: How does an agent tell us what it does?

Every Agent’s Events, Mapped Onto the Same Few Shapes

Read carefully, a hook still speaks its agent’s dialect. Its adapter maps it onto shapes that every rule shares.

CLAUDE CODE SAYSCODEX SAYSTHE SHARED SHAPE EVERY RULE READSWHY IT MATTERSEdit · total.tsnames the fileapply_patch*** Update File: total.tstool call · kind: editpaths: [src/total.ts], resolvedkind: shell, read, edit, write,search, fetch, mcp or unknown;unknown counts as a changePermissionRequestone option saves a rulea permission requestallow or deny, this call onlypermission · allow, deny, cancelfrom your answer’s decision onlynever from an option’s label, andnever an option that writes alasting rule into its settingsStopFailurewith its error typerate_limitsin its session logstop · cause: rate limitedone of 11 causes, a closed setread from structure, never text:“usage limit reached” written bythe agent changes nothingtokens per messagefrom the transcripttoken eventsin its session logusage · tokens, cost, modelmissing reads “not captured”never $0 or 0 tokens; the modelthat really answered is named, soa quiet switch away showsadaptereach agent’s adapter does the mapping; its quirks per version live in a facts file
WHY SHAPESRules and gates read only these shapes, so a new agent adds an adapter and its facts, never a core branch.40 / 449
1.7.4Foundation › Hooksin the system: Agent side › deep-hook
Part 1: What is DeepBuild built from? › 1.7: How does an agent tell us what it does?

What If an Agent Never Calls the MCP Tools?

Nothing breaks: the hooks catch every claim and question on their own. The tools are extras an agent may use.

ONE TURN OF CHECKOUT-WEB · CLAUDE CODEa hook can add context or block; it never calls a tool for the agentAGENTHOOKSstarts on issue #42SessionStarttells the agent its open asksand what done means for each;setup already registered deep’sMCP server and a short skillEdit total.tsPreToolUsesees every tool call first, MCPcalls too (mcp__deep__deep_ask):guards it, ties it to this session,names the tool to use on a denialasks: keep the total above the fold?PreToolUsecatches the question card(AskUserQuestion; in Codex,request_user_input): sorted intoan ask, or answered from a decisionstops: “done, total fixed”Stopa stop that did work becomes aclaim, whatever its last messagesays; a question it ends on issorted by kind into an askAutomatic
deep_ask optional, the agent chooses

If called: it asks mid-turn and hears the ask’s deadline and default, with “still waiting” before its tool times out.

If never: a question it stops on, or a question card, still becomes an ask.

deep_claim optional

If called: it records what the agent expects each check to show, so a story made up later shows as a contradiction.

If never: the Stop hook still makes the claim, and the checks still run.

deep_show optional

If called: it draws a figure on the agent’s claim or ask; you see it when you open it.

If never: nothing is drawn and nothing is lost: a picture is never proof.

THE ANSWERHooks never call the tools. They add context, block with a reason that names the tool to use, and catch the rest.41 / 449
1.7.5Foundation › Hooksin the system: Agent side › deep mcp
Part 1: What is DeepBuild built from? › 1.7: How does an agent tell us what it does?

How a deep_ask Call Finds Its Session

When an agent does call a tool, the hub must know which session is asking. Two cases; the hooks settle both.

ONE DEEP MCP PER SESSION, AS CLAUDE CODE RUNS ITClaude Code · checkout-webPID 81200 · started 09:14:02deep-hook, each hookparent: 81200deep mcp, its toolsparent: 81200The hub binds this deep mcp to the sessionwhose hooks come from the same parent: PID 81200,checked by its start time, 09:14:02, never PID alonebindingvalues illustrativeONE PROCESS FOR SEVERAL SESSIONS, AS CODEX’S SHARED DAEMON MAYcheckout-web’s turn calls mcp__deep__deep_ask{ "question": "Keep the total above the fold?" }1PreToolUse fires first; deep-hook stamps the callsession checkout-web · seq …1123456789 · args 9c1e…2the call reaches the shared deep mcp, then the hubthe call itself names no session3the hub matches its tool and argument digest to the onestamp no call has used yet: bound to checkout-web4✕ Two unused stamps match? It binds to none: it may read thewiki, decisions and spec, but never ask, claim, draw or attach evidence

Never by PID alone

The OS reuses PIDs, so a parent is known by its PID and its start time together.

One stamp, one call

Each stamped event binds at most one call. Where the adapter can edit a call’s input, a one-time code added to it does the job.

Ends with its session

At SessionEnd, when the parent exits or the attempt is replaced. A successor never inherits it.

WHYNo agent can ask, claim or draw in another session’s name: each call is tied to the hook that saw it.42 / 449
1.8.1Foundation › The recordin the system: Hub › core › the record
Part 1: What is DeepBuild built from? › 1.8: How is everything written down?

The Record: Write Down What Happened, Never Edit It

What hooks catch goes into the record. Left: an edited table loses the story. Right: DeepBuild’s log keeps it.

A TABLE YOU EDITclaimstatuscheckout-webFAILPASS 3/3overwritten at 09:34After the edit, gone for good:✕ that it failed first✕ which check failed, and where✕ who wrote each change, and whenTHE LOGEventWriter09:20:04claim.madecheckout-web: “done, total fixed”hook09:20:31run.finishedunit test total: failedext:done-gate09:20:31verdictFAILext:done-gate09:33:10claim.madecheckout-web: “fixed the rounding”hook09:34:02run.finishedunit test total: passedext:done-gate09:34:40verdictPASS 3/3ext:done-gate• nothing is edited: the FAIL line stays, as history• each line’s writer comes from its connection, never from what the caller says• a verdict line is saved to disk before it counts, so it survives a power cut
WHY IT MATTERSEvery view in the app, every verdict and every ask is drawn from this one log, so anything you see traces to the lines behind it.43 / 449
1.8.2Foundation › The recordin the system: Hub › core › the record
Part 1: What is DeepBuild built from? › 1.8: How is everything written down?

A Projection: A Table Rebuilt by Replaying the Log

Views need tables, not a list of lines. A projection is a table the hub builds by replaying the log, in order.

THE LOGSource of truth09:20:04claim.made“done, total fixed”09:20:31run.finishedunit test: failed09:20:31verdictFAIL09:33:10claim.made“fixed the rounding”09:34:02run.finishedunit test: passed09:34:40verdictPASS 3/3Replayapply each line,in orderTABLE “CLAIMS”Projectionclaimverdictbuilt fromcheckout-web #1lines 1–3pendingFAILcheckout-web #2lines 4–6pendingPASS 3/3✕ table deletedcheckout-web #1FAILlines 1–3checkout-web #2PASS 3/3lines 4–6✓ replayed from the log: the same table, line for lineEvery table works this way: sessions, claims, asks,decisions, leases and the rest are projections the hubcan rebuild at any time by replaying the log.The app’s views are drawn from these tables.
1The cursor reads the log top to bottom.
2Each line updates the table: a claim appears, then its verdict.
3Delete the table, and nothing is lost.
4Replay the same lines: the same table comes back.
WHY BOTHERA table can’t drift from what happened: delete it and replay. A newer verdict adds a line; it never edits one.44 / 449
1.8.3Foundation › The recordin the system: Hub › core › the record
Part 1: What is DeepBuild built from? › 1.8: How is everything written down?

One Log, Many Tables: Every View Reads the Same Lines

Left: who adds lines, via the hub. Middle: the log; each line’s number is its log_pos. Right: tables rebuilt from it.

WRITERSTHE LOGTABLES, REBUILT FROM ITdeep-hookdeep mcpapp / CLIextensionshubthe only writereach line names its writer,taken from the connection,never from the payload1041session.start1042tool.before1043user.ask1044tool.before1045claim.made1046run.finished1047verdictsaved first1048ask.created1049ask.answeredsaved first1050decisionsaved firstlog_possessionswho works whereclaimswhat each stop claimeddefinitionswhat done means, lockedrunsevery check runverdictsone of five per claimasksquestions for youdecisionsyour saved answersleaseswho holds port 3000evidencefiles by sha256saved first: on disk before it counts, so a power cut can’t lose it
TARGETS5,000 events a second, written in batches · under 1 GB for 30 heavy days, not counting evidence files.45 / 449
1.8.4Foundation › The recordin the system: Hub › core › the record
Part 1: What is DeepBuild built from? › 1.8: How is everything written down?

One Hook Line Into the Record: Read, Parse, Commit, Send

The last slide’s 5,000 lines a second, one line up close: three threads in the hub, then when it is on disk.

THE EVENT LOOPReads, acks, routesreads the hook’s lineacks within 20 msnever waits on a diskor on this line’s commit1A WORKER THREADParses, scrubs, hasheskeeps its kind’s fieldsscrubs secret valueshashes what goesto evidence2THE WRITER THREADAppends in a batchthe one writer connectiongives each line itslog_pos inside thecommit that writes it3LEDGER.DBCommitstool calls: in batchesa verdict, decision,answer or send key:saved first4THE LIVE STREAMSendsthe line with itslog_pos, only afterits commit; readersresume from their last5log_posTHE ROW IT WRITES (ILLUSTRATIVE)id01K74FKZVK8Q2X5R7M3N9P4T6Wminted by deep-hooklog_pos1046given by the hubseq1760013451123456789when the hook startedwriterhookfrom the connectionkindtool.before · data {"command": "npm test"}WHERE A LOG_POS COMES FROM (NUMBERS ILLUSTRATIVE)block 1001–1100saved firstblock 1101–1200after a restartpower cut at 1046Reserved, and saved, before any number in it is used:1047–1100 are skipped, never handed out twice.

Why off the loop

One huge tool output never holds up another session’s hook: parsing and disk waits run elsewhere.

Saved first, or in batches

A cut can lose busy tool-call lines (the claim then can’t PASS), never a verdict or an answer.

Gaps never fill

Positions commit in order, so a gap a reader sees stays empty for good.

NEXTCommitted lines feed the tables. One rule keeps every table equal to its rebuild.46 / 449
1.8.5Foundation › The recordin the system: Hub › core › the record
Part 1: What is DeepBuild built from? › 1.8: How is everything written down?

Every Table Reads Only the Log: No Clock, No Files

Committed lines feed the tables, and one rule keeps each rebuild equal: a table reads events, never the clock.

WRONG: A TABLE THAT READS THE CLOCKthe same lines: a copy of the log from Tuesdaystatus = now > deadline ? "defaulted" : "open"replayed Wednesdayopenreplayed Fridaydefaulted✕ one log, two tables, and a default nobody announcedTHE RULE: TIME ARRIVES AS AN EVENT2201ask.createda taste ask, due Thu 09:20illustrative2388ask.defaultedappended by the core at the deadlineasks · status closed · outcome defaultedbuilt from lines 2201 and 2388, in log_pos order✓ Tuesday’s copy reads open on any day; the full logreads defaulted on any day, and that default was announcedprojectionHOW IT IS HELD: A SEEDED TEST OVER AT LEAST 1,000 GENERATED STREAMSEach table after live appends must equal the same table rebuilt from the log, row by row in key order. The streams mix:ties in seqthe clock stepping backPostToolUse after Stopspool lines replayed late and twiceone kind at two schema versions

Reads nothing else

A projection reads its events in log_pos order: no clock, setting, file or evidence bytes.

Time comes as events

A defaulted ask or a stale lease comes from an event that says so, never from a table reading the time.

Forward only

Each event kind carries a schema version. Migrations only move forward, and every table can be rebuilt.

WHY IT HOLDSA table is a function of its events alone, so delete it, replay the log, and the same rows come back.47 / 449
1.8.6Foundation › The recordin the system: Hub › core › the record
Part 1: What is DeepBuild built from? › 1.8: How is everything written down?

What If the Hub Restarts or the Power Fails?

Left: line numbers let the app pick up exactly where it left off. Right: what a power cut can lose, and can’t.

EACH LINE’S NUMBER IN THE LOG, FROM THE HUBlog_pos10441045104610471048104910501051105210531231The app has read every line up to 1046, and keeps that number.skipped2The power fails and the hub restarts. The app re-reads, learns thenumber its read reaches (1050), and follows on: nothing missed or doubled.3Next comes 1052: the cut skipped 1051. The app checks that gap once,finds it empty and moves on. A skipped number is never filled later.• Numbers only grow, and are never reused.• A reader 10,000 lines behind is cut off, told why, and picks upagain from its own last number.IF THE POWER FAILSSaved first: on disk before it countslines that matterverdictdecisionanswermessage sentSaved in batchesthe busy stream of tool callstool.beforetool.aftertool.beforetool.afterlost in the cutAfter a start with no clean stop recorded:every claim still open becomes INVALID (cause: events lost),never PASS; unless its session ended before the last saved-first write
THE RULEA crash can lose stream lines, never a verdict or an answer, and a lost line can make a claim INVALID, never PASS.48 / 449
1.8.7Foundation › The recordin the system: Hub › core › the record
Part 1: What is DeepBuild built from? › 1.8: How is everything written down?

How the App Reads the Record: Read Once, Then Follow

The last slide’s app, from its first read: each read says where it stands, and the stream picks up from there.

the hubledger.db and the live streamthe app’s record readerthe only one that readsevery viewNeeds you, sidebar, the line1 connect to hub.sock with the control token2 read: inbox, sessions3 rows, as of log_pos 1046 · start ID 74 subscribe after 10465 frames 1047, 1048: each sent after its commit6 one position, 1048, for every view7 hub restarted: start ID 8, so read again from 2Needs youat 1048sidebarat 1048the lineat 1048start IDvalues illustrative

Reads say where they stand

Every read returns the log_pos it reflects, so nothing appended between the read and the stream is missed.

A new start ID: read again

Each hub start gets a new ID. Frames from before a power cut may be gone, so the reader starts over, never resumes.

One reader

A guard in the app’s local preflight fails any other module that subscribes to the stream or calls the reads.

BACK THE SAME WAYYour tap goes to the hub as asks/:id/answer on this socket, and its effect comes back as a frame.49 / 449
1.8.8Foundation › The recordin the system: Hub › core › the record
Part 1: What is DeepBuild built from? › 1.8: How is everything written down?

Evidence: Stored by Its Hash, Checked at the Door

The log says what happened; evidence files prove it. Each is named by its hash and checked when it arrives.

FILES ARRIVING FROM CHECKSreceipt.pnga journey’s screenshotjourney.mp4the recording, cut shorttotal.pngits bytes say JPEGChecked at intakedo its first bytes match thetype its slot declares?is its end there? a PNG’s IEND,a JPEG’s end marker, an MP4’sboxes adding up to the filecapturednamed by its SHA-256evidence/ab/cdef….png✓truncatednever a baselinekept, naming what’s missing✕refusednever capturedits slot reads missing✕WHAT EACH STATE CAN SUPPORTcaptured, completemay support PASSmissing, outside causemakes it BLOCKEDany other gapmakes it INCONCLUSIVEnot requestedthe slot wasn’t asked for

Named by its hash

Stored once under its SHA-256, so a receipt that cites a hash can’t point at a swapped file.

ev:sha256…

Kept 30 days

Except evidence behind a decision or an archived transcript. A verdict whose evidence is gone is never reused: a later claim runs its checks again, and the old verdict stays as recorded.

A pasted image counts

Stored by hash with its message: a bug report becomes a check, a taste remark a decision with that image as its baseline.

Each line names its proof

The agent’s statement, a static check, a test run, a real journey or your decision. A lower one never shows as higher.

WHY BY HASHA cited file can’t be swapped later, and a cut-short screenshot never becomes a baseline.50 / 449
1.8.9Foundation › The recordin the system: Hub › core › the record
Part 1: What is DeepBuild built from? › 1.8: How is everything written down?

Privacy: Secrets Scrubbed by Value, Files Leave by Hash

Before a file is hashed, every secret value DeepBuild knows is scrubbed. Nothing leaves the Mac by default.

A JOURNEY’S OUTPUT (ILLUSTRATIVE)POST /api/payAuthorization: Bearer 9f2c…e71ax-session: OWYyYy4uLmU3MWE=CI=true TZ=UTC PORT=3001scrubbedby value, raw,base64 and URLPOST /api/payAuthorization: Bearer [redacted]x-session: [redacted]CI=true TZ=UTC PORT=3001then hashedinto evidence; short,plain values stayA FILE LEAVING THE MAC GOES BY HASH; ITS ORIGIN DECIDES WHETHER YOU’RE ASKEDmade by DeepBuilda render, a capture, a journey, an exportno askchosen by youa paste, a drop, a file pickerno askput there by an agentor made from such a fileone ask, naming its hash and where it goes

By value, not just pattern

The exact values it injected or holds by handle, and variables named like TOKEN, KEY, SECRET, PASSWORD or AUTH.

Short values stay

CI=true, NODE_ENV=test, TZ=UTC or a leased port are left as they are.

CI=true

Your folder only

A path an agent names outside its working folder is answered as if it didn’t exist.

Content-free mode

Keeps only counts, durations, error signatures and verdicts, never text.

OFF BY DEFAULTNothing leaves unless a syncing extension is on, and each receipt lists every file that went out.51 / 449
1.9.1Foundation › Storagein the system: Hub › core › the record
Part 1: What is DeepBuild built from? › 1.9: Why SQLite, and what else was weighed?

Storage: What We Compare, and Why

Before the scores on “Storage”: each row is one column of the next slide’s table, and why it matters.

ColumnWhat it measuresWhy it matters
1Rebuild after crash state can be recomputed from what was writtena crash must never fake a PASS
2Audit trail every change kept, with who wrote ita verdict must show what it rested on
3Zero setup nothing to run beside the hubone Mac, one click
4Query speed how fast views read their tablesthe inbox loads in under 1 s
5One writer one process owns every writetwo writers race and corrupt state
The options on the next slideMutable tablesJSONL files per sessionA database serverAppend-only SQLite log + projections
NEXTEach option scored on these 5 columns, three diamonds for strong.52 / 449
1.9.2Foundation › Storagein the system: Hub › core › the record
Part 1: What is DeepBuild built from? › 1.9: Why SQLite, and what else was weighed?

Storage: An Append-Only Log Makes Every Verdict Auditable

Four ways to store what happened, scored on the columns the previous slide explains.

OptionRebuild after crashAudit trailZero setupQuery speedOne writer
Mutable tablesupdate rows in placeDropped
JSONL files per sessionwhat agents already writeDropped
A database serverPostgresDropped
Append-only SQLite log + projectionsone file; the hub alone writesChosen
strong weak breaks a hard rulescores: our reading of the gains and costs recorded in the design
COST WE ACCEPTEDEvery table is a projection the hub must keep in step with the log, and migrations only move forward.53 / 449
1.10.1Foundation › Processesin the system: Hub › trusted ring › supervisor
Part 1: What is DeepBuild built from? › 1.10: Who may start and stop a process?

Processes on One Mac: Who Started Each, Who May Stop It

DeepBuild starts checks and test servers for agents, on a Mac many sessions share. Each process has one owner.

STARTED BY THE AGENT ITSELFSTARTED BY DEEPBUILD, FOR AN AGENTSTARTED BY YOUclaude · checkout-web› Bash npm run buildnpm run buildClaude Code’s own process✓ DeepBuild never stops itcodex · api› deep env updeep hub · supervisorstarts, labels, stopsSupervisornode server.jstoken 7f3a · :3000playwrighttoken 7f3a · checklease on port 3000: held until both are goneyou · a terminal$ node server.jsnode server.jsyours: no token✓ DeepBuild never stops it✕ deep-hook, before any agent command runs: a kill by name or port, such as pkill -f node, is refused

Supervisor

The part of the hub that starts every process DeepBuild runs: checks, test servers, sandboxed plug-ins. It stops only what it started.

Run token

A label the supervisor puts in each process it starts, so the hub can later prove the process is its own.

The agent’s own

What Claude Code or Codex starts by itself stays theirs. DeepBuild never stops it; deep-hook only refuses kill-by-name.

Lease, again

Port 3000 stays leased to api until every process the supervisor recorded for it is proven gone.

NEXTThe real pkill from slide 4, replayed: why no agent may kill by name or port.54 / 449
1.10.2Foundation › Processesin the system: Hub › trusted ring › supervisor
Part 1: What is DeepBuild built from? › 1.10: Who may start and stop a process?

Why Never Kill by Name: One pkill, Two Sessions

Codex restarts its server the usual way. Left: what that does on a shared Mac. Right: what deep-hook does.

WITHOUT DEEPBUILDWITH DEEPBUILDcodex · api: “restart my server”$ pkill -f nodenode server.jsapi · Codex · :3000✕ killednode server.jscheckout-web · Claude · :3001✕ killednode server.jsyours, started by hand✕ killedno reply: it just runspkill -f matches every process whose command linesays “node”: the sibling’s stack and yours go down too.Killing by port has the same flaw: a port says who holds it now, not who started it.Kill by namecodex · api: “restart my server”$ pkill -f nodenode server.jsapi · Codex · :3000✓ runningnode server.jscheckout-web · Claude · :3001✓ runningnode server.jsyours, started by hand✓ running✕ denied by a fast rule: kill by name hits other sessions’ servers; stop the processes you startedFast ruledeep-hook checks the command at PreToolUse, beforeit runs, and the rule holds even with the hub down.Instead Codex asks DeepBuild: deep env down stops only what the hub started.
REAL INCIDENTSlide 4’s pkill took down a sibling session’s stack, so deep-hook refuses kills by name or port.55 / 449
1.10.3Foundation › Processesin the system: Hub › trusted ring › supervisor
Part 1: What is DeepBuild built from? › 1.10: Who may start and stop a process?

How a Process Is Known: Run Token, Start Time, Group

The hub’s supervisor labels each process it starts for an agent; each label answers one question.

Run tokenWho started it?Start timeIs it still the same process?Process groupWhat came with it?the hub’ssupervisornode server.jstoken 7f3a, in its envnode server.jsyours or Codex’s own: no token✓ 7f3a: DeepBuild’s ✕ no token: left alonePID 81234 · viteststarted 09:14:30, by DeepBuildexitedPID 81234 · something of yoursstarted 10:02:11, PID reused by the OS✕ 10:02:11 ≠ 09:14:30: not DeepBuild’sONE PROCESS GROUPnode server.jsa helper it spawnedand another✓ one stop reaches the group
Run token

The supervisor puts it in the environment of each process it starts. The start is logged before the process exists, then again with its PID and start time.

Start time

The OS reuses PIDs, so a PID file can point at a stranger. A PID plus its start time names exactly one process.

Process group

Each process it starts gets its own group (a job object on Windows). Before any stop the hub checks the token, the start time and every member. A child that left the group is still known by its token, or by the fork the supervisor saw.

IN SHORTThe token says DeepBuild started it, the start time says it’s still that process, the group says what came with it.56 / 449
1.10.4Foundation › Processesin the system: Hub › trusted ring › supervisor
Part 1: What is DeepBuild built from? › 1.10: Who may start and stop a process?

deep env up, Step by Step: The Lease, Then Each Process

Those labels go on at the start: Codex runs deep env up, and the hub leases the port before it starts anything.

Codex · apithe agentdeep CLIa short-lived commandthe hubenv-local and the coresupervisorin the hub’s trusted ringthe OSprocesses1 deep env up, in its shell2 sent as the api session3 env-local: lease port 3000, exclusive, for api4 core: 3000 is free, no lease can match it: one append5 start node server.js6 records the start, before the process exists7 spawn: token 7f3a, own group8 PID 81290, 09:12:04: recorded9 the health route answers: up on :3000the peer check: it runs in Codex’s treelease09:13, checkout-web asks for 3000 too: refused, naming api as its holder, with the next free port, 3001 (times and PID illustrative)
NO RACEThe lease is decided on the log as read, with no wait before its append. Teardown is the reverse: next slide.57 / 449
1.10.5Foundation › Processesin the system: Hub › trusted ring › supervisor
Part 1: What is DeepBuild built from? › 1.10: Who may start and stop a process?

Cleanup: Stop Exactly What Was Started, Prove It Gone

Codex runs deep env down: the supervisor stops token 7f3a’s processes, leaves the rest, then frees the port.

PROCESSES THE SUPERVISOR KNOWSCHECKEDTHENSupervisor, in the hubcleanup oftoken 7f3a123node server.js(api env up)token 7f3a · started 09:12:04✓ token ✓ start ✓ groupstopped, group and allplaywright(journey check)token 7f3a · started 09:12:09✓ token ✓ start ✓ groupstopped, group and allvitest(unit check)token 91c0 · started 09:14:30✕ token 91c0still runningnode server.js(yours)no token✕ no tokennever touchedLEASEport 3000held by apifree4only once both are proven goneIf the hub crashes mid-wayownership records live in thelog, so the restarted hub reapswhat it left; an unfinishedcleanup lists what’s leftand asks you once, with a defaultThe supervisor alsosandboxes agent-built code:no network but granted hosts,no hub socket, and no weakermode under the same name
1Cleanup names one run token, 7f3a: what DeepBuild started for api, its server and its journey check.
2For each process, the hub checks the token, the start time and every member of its group.
3It stops the two groups that match. vitest (91c0) keeps running; yours is never touched. A process it can’t prove is reported, never stopped.
4Only when both are proven gone does the lease on port 3000 end. Past its expiry, a lease is only stale.
WHOSE IS WHOSEDeepBuild stops only what its supervisor started and can prove. Yours and the agents’ own are never touched.58 / 449
1.10.6Foundation › Processesin the system: Hub › trusted ring › supervisor
Part 1: What is DeepBuild built from? › 1.10: Who may start and stop a process?

Knowing Our Own Processes: What We Compare, and Why

Before the scores on “Knowing Our Own Processes”: each row is one column of the next slide’s table, and why it matters.

ColumnWhat it measuresWhy it matters
1Never kills yours a same-named process of yours survivesother worktrees run the same scripts
2Survives PID reuse a recycled PID can’t be mistakenthe OS reuses PIDs
3Finds children it stops the whole tree it startedservers spawn helpers
The options on the next slideKill by name or portTrack the PIDRun token + start time + group
NEXTEach option scored on these 3 columns, three diamonds for strong.59 / 449
1.10.7Foundation › Processesin the system: Hub › trusted ring › supervisor
Part 1: What is DeepBuild built from? › 1.10: Who may start and stop a process?

How DeepBuild Knows Which Processes Are Its Own

Three ways to clean up after checks and environments, scored on what each column measures and why it matters.

OptionNever kills yoursSurvives PID reuseFinds children
Kill by name or portpkill -f, lsof | killDropped
Track the PIDa PID fileDropped
Run token + start time + groupthe supervisorChosen
strong weak breaks a hard rulescores: our reading of the gains and costs recorded in the design
COST WE ACCEPTEDEvery process DeepBuild runs goes through the supervisor: groups and fork watch, cgroups or job objects.60 / 449
1.11.1Foundation › Platformsin the system: DeepBuild › platform seams
Part 1: What is DeepBuild built from? › 1.11: How does it get beyond macOS?

macOS First, but Every Platform Part Sits Behind One Seam

Each place DeepBuild touches the OS is a seam: one interface, one backend per OS. Rows: seams; columns: backends.

SeammacOS (first)Linux (R2 hub, R3 app)Windows (after R1)
Local socketUnix socket, mode 0600Unix socketnamed pipe, your user
Secret storeKeychainSecret ServiceCredential Manager
Process ownershipprocess groups, fork watcha cgroup per runjob objects
Undoable deletesAPFS copy-on-writebtrfs or XFSReFS
Starts at loginlaunchdsystemd user servicelogon task
SandboxSeatbeltbubblewrap + LandlockAppContainer
Sharing GPU picturesIOSurfaceshared wgpu device or DMA-BUFDXGI shared handle
Audio, captureCoreAudio, ScreenCaptureKitPipeWire, portalWASAPI, Graphics.Capture
RULEA backend ships only once it passes its seam’s own tests, and its name and version are stamped on every result it makes.61 / 449
2See and steer
Part 2 asks: How do you see and steer your agents? › 8 sections, 2.1 to 2.8, each answering one part of it (running index, slide 12)

Part 2: See and Steer

Part 1 built the hub and its record. Part 2: what the app shows you of it, how a question reaches you once, and how your answer gets back.

DeepBuildwhere your agents show, not tell1 · Foundation1.1 four parts, 1.2 four jobs1.3 the rules, 1.4 the hub1.5 extensions, 1.6 ways in1.7 hooks, 1.8 the record1.9 storage, 1.10 processes1.11 platforms2 · See and steer2.1 the app, 2.2 the line2.3 asks, 2.4 matching2.5 answers back, 2.6 a taste call2.7 the app’s toolkit, 2.8 where code runs3 · Make: vibe visuals3.1–3.3 what it makes3.4–3.8 documents, frames3.9–3.12 GPU, light3.13–3.15 modules, checks3.16–3.21 3D, play, sound3.22–3.26 budgets, done bar4 · Trust4.1 a claim, 4.2 what done means4.3 verdicts, 4.4 flaky checks4.5 every stop, 4.6 bug fix #424.7 a UI change, 4.8 the finish line4.9 defenses, 4.10 dodges5 · Extend, compose5.1 extension points, 5.2 agents, hooks5.3 hub slots, 5.4 plug-ins5.5 panels, 5.6 canvas packs5.7 modules, 5.8 composing5.9 safety rules6 · In use6.1 what ships, 6.2 first run6.3 MCP tools, 6.4 the CLI6.5 leases, 6.6 the box6.7 your phone, 6.8 the wiki6.9 learning7 · Build it right7.1 looks right, 7.2 tests first7.3 rules, faults, 7.4 kits7.5 comparisons, 7.6 the gate7.7 borrowed, open, 7.8 budgets7.9 measuring, 7.10 six-week plan7.11 Decision 1, 7.12 routing replay7.13 cuts8 · What’s open8.1 scale, 8.2 issues8.3 R1 path, 8.4 risks8.5 owner calls, 8.6 fleets later8.7 next
WHERE WE AREThe highlighted branch is this part; its topics are the slides that follow.62 / 449
2.1.1See and steer › The appin the system: App › views
Part 2: How do you see and steer your agents? › 2.1: What is the app made of?

Inside the App: Shell, Views, and the Canvas Core

The app, opened one level down. Highlighted: what the next slides show.

DeepBuild appone native window; draws with the GPUViewssessions by repo, each session’s line,Needs you, the Map→ 64Shell (trusted ring)the window, the question card, keyprompts; nothing can draw over it→ 91Panelsviews plug-ins add: they send elementtrees the app builds with its own parts→ 359Canvas coredraws the lines, the Map, charts and agents’pictures; the only part on the GPU→ 131deep CLI and phonethe same asks and status outsidethe window→ 376Setupone button: hub at login, hooks thatonly watch at first, history into the wiki→ 371
WHERE NEXTThis part covers the views and asks; Part 3 opens the canvas core.63 / 449
2.1.2See and steer › The appin the system: App › views
Part 2: How do you see and steer your agents? › 2.1: What is the app made of?

The App: Every Session, What Needs You, and Each Session’s Line

The DeepBuild app draws the hub’s record: sessions by repo, Needs you (the asks waiting on you), one session’s page.

DeepBuild NEEDS YOU · 2 checkout-web claude · #42 coupon1 ask claude · receipt copyPASSapi codex · rate limitsrunning codex · migration1 askdocs claude · guideidle VIEWSMap · Numbers Needs you taste · checkout · keep total visible? authority · api · push to main? THE QUESTION CARD: YOU ANSWER ONE ASK HERE Push api to main?3 commits · checks PASS 5/5 · publicdefault: no, in 22 h · saved for: api YesNo A session’s pageLINE · ASKS · CHECKS · TERMINAL (R2) issuedone =agentclaimchecksyouPR RETURN CARD: WHAT THE LAST TURN DIDchanged: total.ts, receipt.tsx (read from the record)checks: unit 4/4, journey 1/1 · unchecked changes: nonethe agent’s own text, folded the box: tell this agent something…
CHOICESNo Settings page: you ask for changes in words. Every view is a plug-in, but the question card is the app shell’s alone.64 / 449
2.2.1See and steer › The linein the system: App › views › the line
Part 2: How do you see and steer your agents? › 2.2: How does one session look, end to end?

A Session’s Line: Issue #42 to PR #57, Stop by Stop

The line from that page, up close: the app draws Claude Code’s session as a dot that colors each stop it passes.

Issue #42the coupon total is wrongWhat done means3 checks, locked firstAgent worksClaude CodeClaima stop that did workChecksrun by DeepBuildYouone taste callPR #57says Closes #42queuedworkingsays donesent back 1 of 3PASS 3/3needs youStates, one word eachround 1: sent back with total.ts:42, the agent keeps working

Drawn from the record

Every stop links to the events behind it, so the line shows only what happened.

Colors are states

Red: its checks failed. Yellow: it waits on you. It says “says done” until checks back the claim.

On a session’s page

Tabs for its line, its asks and its checks (from R2, a terminal tab when the hub hosts it), plus a box that talks to the agent.

The Map is many lines

Journeys are lines and code parts are stations, so a project reads like a transit map.

WHY A LINEYou open a session to know where it stands. The line answers in one glance, before you read any of the agent’s text.65 / 449
2.2.2See and steer › The linein the system: App › views › the line
Part 2: How do you see and steer your agents? › 2.2: How does one session look, end to end?

The Same Line for Work That Isn’t Code (R2)

From R2 (the release after the first, R1), a weekly report an agent writes runs the same line as code.

CODE: ISSUE #42 (FROM THE LAST SLIDE)Issue #42What done meansAgent worksClaimChecks: tests, journeysYouPR #57A WEEKLY REPORTRequestasked in a chat threador the app’s boxWhat done meansnumbers match sources;sent only on your yessameAgent worksin a workspace,not a reposameClaima stop that did worksameChecksdocument and data:numbers vs sourcesYouyour taste call,then yes to the sendSentdelivered andacknowledgedchanges with the worksame loop as for code

Where it lives

A workspace: a git repo DeepBuild keeps under ~/.deepbuild/workspaces/, so history and undo work as in a repo.

What it is pinned to

A commit plus digests of what its sources read. If a source it read changes, its verdicts go stale and only affected checks rerun.

Writing has no machine proof

So done means the numbers are checked and you made the taste call. A model’s opinion is never a verdict.

NEXTHere only the start, the checks and the end changed. Which parts of any line can change, and from when?66 / 449
2.2.3See and steer › The linein the system: App › views › the line
Part 2: How do you see and steer your agents? › 2.2: How does one session look, end to end?

What You Can Change About a Line, and When

Top: a playbook, a custom line. Below: what each part of a line can be, tagged by release (R1 is the first).

A PLAYBOOK’S LINE (R6), STEPS ILLUSTRATIVEApull the sales numbersApull the costs✓numbers checkAwrite the draft✓document checkYtaste callYyes to the send✓deliveredAthe agent does it✓a check proves itYyou decide

1 · Where it starts

an issue R1a prompt you type R1Linear, Jira, GitLab R2+an email label, a chat thread, a calendar event, a folder, the app’s box R2+

2 · What proves it

commands, journeys, review, numbers R1service, data, document, message R2setting, machine R3playtest R6money laterjudgment: facts checked, then your call

3 · Where it ends

a PR: “Closes” or “Part of” R1a commit status R1a PR comment R2a comment on the issue, a reply in the thread, a tracker status R2+

4 · Its steps

a playbook from your words: deep create R6lanes in parallel R6a blueprint: “close the month” R6
Never changesdone is fixed before work startsonly checks give a verdictevery ask endsno step runs past its checks
SHORT ANSWERYes: where a line starts, what proves it and where it ends follow the work from R2; custom steps come with playbooks in R6.67 / 449
2.3.1See and steer › Asksin the system: Hub › extensions › asks
Part 2: How do you see and steer your agents? › 2.3: How does a question reach you?

An Ask, by Example: One Card, a Deadline, a Safe Default

The You stop on a line is an ask. Up close: Codex asks to push; the hub makes one card, with a deadline and a default.

AGENT (CODEX, API REPO)“Can I push to main?”it ends its turn on the question NEEDS YOU · AUTHORITY Push api to main? 3 commits · checks PASS · public repo DEFAULT: NO, IN 1 DAY Yes No IF YOU ANSWER “YES” (TOUCH ID ON THE CLI) • delivered into the session; it pushes• saved as a decision: kind authority, repo api• the next push from api is answered for you IF NOBODY ANSWERS IN A DAY • the default applies: no push• announced, recorded as “defaulted”• undo it from Needs you; it never passes a claim Meanwhile the agent keeps working on anythingthat doesn’t leave the machine.
NEXTThis was an authority ask. Each of the six kinds waits a different time and has its own safe default.68 / 449
2.3.2See and steer › Asksin the system: Hub › extensions › asks
Part 2: How do you see and steer your agents? › 2.3: How does a question reach you?

Every Ask Ends (1 of 2): Six Kinds, Six Clocks

The hub gives each of the six kinds its own clock. Bar: how long it waits for you; box: what it applies if you never answer.

KINDAN EXAMPLEHow long it waitsIf you don’t answerTaste“Keep the order total above the fold on phones?”3 daysthe recommended option, undoableChoice“Fix the rounding in total.ts or in receipt.tsx?”2 daysthe recommended optionUnblock“Accept the model’s license on its site.”2 daysthe claim stays BLOCKEDException“The agent disputes a drafted check.”2 daysno change, no waiverAuthority“Push api to main?”1 daynoDefinition“Done means the receipt equals the cart, right?”4 hleave it out: PR says “Part of”work goes on with the recommended option meanwhileanything irreversible defaults to no, whatever its kind
Where the values livedrafted at setup, changed in words; a repo’s done.yaml overrides them key by key; a value nobody declared makes what needs it BLOCKED
WHY DEADLINESA public agent repo merged wait-forever approval prompts and reverted them 12 hours later: a question with no answerer hung.69 / 449
2.3.3See and steer › Asksin the system: Hub › extensions › asks
Part 2: How do you see and steer your agents? › 2.3: How does a question reach you?

Every Ask Ends (2 of 2): None Expires Unseen

No default lands unseen: the hub holds each ask for your next visit, or shows it at once if its deadline comes first.

Mon 9:0013:0017:00Tue 9:0013:00YOUR VISITS TO NEEDS YOU (DASHED), ILLUSTRATIVE15:00Tastekeep the total visible?Definitiondone means X, right?Authoritypush api to main?1you answer at 13:00waits for your next visit2due 21:30, before tomorrow’s visit: shows at once3you tapped Later: hidden until Tue 9:00, never past its deadlinedeadline: default no
→

Past the deadline

To the fallback: the owner of the change, then the queue you named. For one person, no one is above you, so the default applies.

0

claims a default can pass

A default is announced, recorded as “defaulted”, and undoable from Needs you.

5

open asks per session

After five, its further asks fold into one: “this session keeps asking”. Answer it in bulk, pause, or leave it.

1

thread per ask

On every channel: the app now, your phone or a chat app from R2. Answer anywhere; it closes everywhere.

WHY ONE THREADPeople answer where they are: Codex’s own question prompts were answered in place only 11 times of 331.70 / 449
2.3.4See and steer › Asksin the system: Hub › extensions › asks
Part 2: How do you see and steer your agents? › 2.3: How does a question reach you?

A Task Only You Can Do, and Why It Closes Itself

Of the six kinds, unblock is a step only you can take. It names the check that proves it, so it closes itself.

ONE CAUSE STOPS THREE SESSIONScheckout-web · Claude Codestop cause: sign-in requireddocs · Claude Codestop cause: sign-in requiredapi · Claude Codestop cause: sign-in requiredTASK · ONLY YOU CAN DO ITSign in to Claude Code againwhere: the sign-in command its facts namewhy: three sessions stopped on itunblocks: all threeproved by: the check the task namesI did itunblockits check runsyour word decides nothing✓checkout-web resumesdocs resumesapi resumesstill fails? the task comes backnaming what’s still missingWHICH STOPS GET ONE AUTOMATIC “CONTINUE”a dropped connectionone continuean overloaded serviceone continuea refusalnevera sign-in problemnever: a taska spent plan windowwaits for its reset

What a task says

What to do and where, why it’s needed, what it unblocks, and the check that will prove it’s done.

Never a link to click

A sign-in names a provider or a secret; the trusted path supplies where to go. Other URLs show as plain text.

One cause, one task

Sessions stopped by one cause share one task, read from the stop’s closed set of causes, never from text.

One automatic continue

Only from the newest stop, under 10 minutes old, and only if nothing you typed has reached it since.

YOUR WORD ISN’T EVIDENCE EITHER“I did it” only re-runs the check, so a claim never passes on your word.71 / 449
2.3.5See and steer › Asksin the system: Hub › extensions › asks
Part 2: How do you see and steer your agents? › 2.3: How does a question reach you?

How One Question Travels (1 of 3): Four Gates, Then You

The hub tries four gates first. Follow a taste call from Claude Code; grey boxes show what each gate settles.

CLAUDE · CHECKOUT-WEB“Keep the ordertotal above the foldon phones?”1Needs a person?by structure, not wordsNo: “proceed”recorded, never an ask“Want me to run e2e?”2A saved decision?same kind and scopeYes: decided for youlogged, with an overrulea push you allowed for api3Could the agent?unblock tasks onlyYes: back to the agentnaming the tool to use“Sign in to staging?”4Already open?same kind, scope, commitYes: joins that askone card for bothCodex asks the same thingyes: taste callno: none yetskip: not an unblocknoNEEDS YOU · TASTE CALLKeep the order totalabove the fold on phones?due in 3 days · default keepwork goes on with “keep”AskYou tap Keep: saved as a decisionor, after 3 days, the default, undoabledelivered by the adapter (DeepBuild’s link to Claude Code), confirmed in its transcript
RULEText that shows up in a session’s own prompt never answers an authority ask and is never saved as a decision: another agent may have typed it.72 / 449
2.3.6See and steer › Asksin the system: Hub › extensions › asks
Part 2: How do you see and steer your agents? › 2.3: How does a question reach you?

How One Question Travels (2 of 3): Reads and Writes

The four gates, then Needs you and delivery, as the hub runs them. A resolver is a plug-in that may answer for you.

READSWRITESthe call it leads to,the open ask-task,the turn’s screen or step1 Needs a person?Stop · PreToolUse hooks“proceed”, a new ask,or back for deep_asksaved decisionsbudgets you approvedwhat you typed here2 Saved decision?deep.registerResolverthe answer and why,“decided for you”its tools, MCP serversyour standing grantsleases, secrets by name3 Could the agent?a resolver, for unblocksback to the agent,naming the toolopen asks: kind,scope, and the commiteach one shows4 Already open?hub corejoins it, orsupersedes an older oneopen asksyour next visiteach deadline5 Needs youview + question cardyour answer: a decisionor “defaulted”what the session hasshown it can do6 Deliverthe agent’s adapterdelivered, stalled,timed out, replacedTHE RECORDevents, only ever added, such asask.createdtables rebuilt from it:asks(kind, key, pinned_to, deadline, default, outcome)decisions(key, scope, answer, by, ask_id, state)
ONE PLACEEvery gate writes to the record, so Needs you, the counts and any audit read the same rows. Nothing is kept aside.73 / 449
2.3.7See and steer › Asksin the system: Hub › extensions › asks
Part 2: How do you see and steer your agents? › 2.3: How does a question reach you?

How One Question Travels (3 of 3): The Resolver Contract

Gate 2 up close: a resolver is one function a plug-in hands the hub; the core checks its reason before answering for you.

deep.registerResolver(resolver) // resolver(ask) → { answer, because } | undefined
The resolver returnsThe core checksWhat happens{ answer: “yes”, because: “decision: push, api” }an active decision of thiskind and scope?✓ Decided for you: logged,shown with an overrule, counted{ answer: “yes”, because: “budget: issue #42” }a budget you approved,with room for this run?✓ The paid run starts; theagent hears what’s left{ answer: “yes”, because: “looks safe” }names nothing it cancheck✕ Refused: the ask goeson to youundefinednothing to checkNot covered: the nextgate takes it

Two answers disagree

Neither applies. You see both, and your answer overrules the other only at that ask’s scope.

Also accepted

A request you typed in that thread. For an unblock: the tool, grant, lease or credential to use.

Rules are scored

Each saved decision acts as a rule. If the work it decided breaks more often than yours, it is revoked.

WHY A REASONThe core can check a decision or a budget, never a plug-in’s opinion. Next: why match by kind and scope.74 / 449
2.3.8See and steer › Asksin the system: Hub › extensions › asks
Part 2: How do you see and steer your agents? › 2.3: How does a question reach you?

What Your Words Authorize: “Create PR” Is Not a Merge

A request you typed can answer an ask, as the last slide said. It covers only what it names, in that thread.

YOU, IN CHECKOUT-WEB’S THREAD“fix #42 and create PR”names: push, PRLATER, THE AGENT’S CALLSgit push origin fix-42✓push: named by “create PR”gh pr create✓the PR: namedgh pr merge 57✕merge: not namedan MCP tool that merges✕the same effect class: mergeNEEDS YOU · AUTHORITYMerge PR #57 in checkout-web?default: no, in 1 day · one card for both callsYesNoNot covered either• a push from the api session: another thread• “merge it” showing up in the session’s own prompt: another agent may have typed it

Exactly what it names

“Create PR” covers the push and the PR. Anything it doesn’t name is still an authority ask.

In that thread only

The request answers asks in the thread you typed it in, never in another session.

By what a call does

The core sorts calls by effect: push, merge, dispatch, send, delete. gh or an MCP tool, same rule.

Typed by you

Text that merely shows up in a session’s prompt never authorizes anything.

DECIDEDA request authorizes exactly what it names. That reopens only if you say a request should cover more, or less.75 / 449
2.3.9See and steer › Asksin the system: Hub › extensions › asks
Part 2: How do you see and steer your agents? › 2.3: How does a question reach you?

Plans Before Acting: Every Step Shown Before Your Yes (R2)

Each authority ask, like that merge card, carries a plan: the steps, what each changes, its undo and cost.

NEEDS YOU · AUTHORITYSend the weekly report to the sales list?THE PLANWHAT IT CHANGESUNDO1 attach report.pdfnothing yet—2 send to the list40 inboxes, illustrativecan’t be undonecosts: nothing · touches: your mail account, through its plug-ina dry run filled in the effects · default: no, in 1 dayYes, run this planNoplanLocked with your yesplan d1:7f3a…its hash, and yourclick’s tokenTHE RUN1 attach report.pdfin the plan✓2 send to the listin the plan✓3 also cc financenot in the plan✕stops before step 3,and asks you again
Every yes with authority works this way: sends, deletions, settings, opening a port, contracts and purchases. Buying is a plan with its price, inside a budget you approved; payment is a task for you, and DeepBuild never sees a card number.
NO DRIFTThe plan’s hash is locked with your answer, and a run that would do anything outside it stops and asks again.76 / 449
2.4.1See and steer › Matchingin the system: Hub › extensions › asks › resolvers
Part 2: How do you see and steer your agents? › 2.4: How is a repeat question recognized?

Matching Questions: What We Compare, and Why

Before the scores on “Matching Questions”: each row is one column of the next slide’s table, and why it matters.

ColumnWhat it measuresWhy it matters
1Asked once a repeat question doesn’t reach youinvariant 4
2No silent wrong answer an automatic answer can’t be wrong unseenan answer can authorize a push
3Auditable you can see why it answeredyou re-answer a sample, blind
4Ends every wait every ask reaches an outcomea hung ask stalls an agent for days
The options on the next slideMatch exact wordingMatch by model similarityKind + scope, confirm near matchesWait forever for youDeadline → fallback → undoable default
NEXTEach option scored on these 4 columns, three diamonds for strong.77 / 449
2.4.2See and steer › Matchingin the system: Hub › extensions › asks › resolvers
Part 2: How do you see and steer your agents? › 2.4: How is a repeat question recognized?

Matching Questions and Ending Waits

Two choices the hub makes: how a saved answer matches a new ask, and what happens when nobody answers.

OptionAsked onceNo silent wrong answerAuditableEnds every wait
Match exact wordingDropped
Match by model similarityDropped
Kind + scope, confirm near matchesthe card says how many asks it closesChosen
Wait forever for youDropped
Deadline → fallback → undoable defaultnever a passChosen
strong weak breaks a hard rulescores: our reading of the gains and costs recorded in the design
CHECKED BYA blind audit after the first week of real use: you re-answer 40 to 60 of its automatic answers, unseen.78 / 449
2.4.3See and steer › Matchingin the system: Hub › extensions › asks › resolvers
Part 2: How do you see and steer your agents? › 2.4: How is a repeat question recognized?

How an Ask Gets Its Key: Fields, Never Words

Kind and scope won. The hub turns them into a key built from the ask’s fields; its wording never enters it.

AS ASKEDFIELDS THE HUB READSWHAT HAPPENSkeyAUTHORITY: THE EFFECT, THE TARGET’S KIND AND OWNER, AND THE BOUNDSCodex · api · Mon“Can I push to main?”push · branch main · owner api · bounds nonek:3f1aYou answer Yes: saved for apiCodex · api · Tue“OK to push these 3 commits to main?”push · branch main · owner api · bounds nonek:3f1aDecided for you, with an overruleClaude Code · checkout-web“Push to main?”push · branch main · owner checkout-webk:8b07Asks you; api’s answer only suggestedTASTE: THE SCREEN OR JOURNEY STEP, AND THE ELEMENT’S STABLE NAMEClaude Code · checkout-web“Keep the order total above the fold?”taste · screen checkout · element order-totalk:c42eAn open ask, one cardCodex · checkout-web“Should the total stay visible?”taste · screen checkout · element order-totalk:c42eJoins it: one card for bothClaude Code · checkout-web“Keep the cart total above the fold?”taste · screen cart · element cart-totalk:5d90A near miss: its own cardkeys illustrative

Choices and definitions

Their key is the requirement or decision point the ask is pinned to, with its options’ IDs.

One canonical form

The fields are hashed as RFC 8785 bytes, so the same fields always give the same key.

Tested on near misses

A fixture file per kind: pairs that must share a key, and near misses (another screen, owner or option) that must not.

WIDENS ONLY WITH YOUSaved for this repo; it covers all your repos only once you confirm a suggested wider match.79 / 449
2.5.1See and steer › Answers backin the system: Hub › extensions › adapters
Part 2: How do you see and steer your agents? › 2.5: How does your answer reach the agent?

Getting Your Answer Back (1 of 4): It Must Find Its Session

You answer on your phone, hours after an agent asked. Your answer still has to reach that one session.

ONE QUESTION, ANSWERED HOURS LATER (TIMES ILLUSTRATIVE)9:20Claude Code asks“Keep the total above the fold?”a card appears in Needs you9:21it carries onwith the default, “keep”it never sits blocked on you9:40its turn endsit waits for your next messageas it does today11:40you tap “Move it”on your phone, at lunchthe hub records your answerSo where does the answer go? DeepBuild can’t type into Claude Code’s window.It waits in the hub until the agent opens a door: a hook, a moment the agent itself calls DeepBuild (Part 1).Which door depends on what the session is doing when your answer lands: stopping, idle, or closed.Your answer is never lost, and DeepBuild never stops a running turn to deliver it.

The hub keeps it

Your answer is recorded the moment you tap, so a closed laptop or a quit app loses nothing.

A hook is the only way in

DeepBuild reaches a session only when the agent calls it: as it stops, through a waiting hook, or with your next message.

Never an interrupt

Stopping a turn to deliver an answer is not allowed. The agent always finishes its step first.

NEXTClaude Code has three such doors. Which one opens depends on the session when you answer.80 / 449
2.5.2See and steer › Answers backin the system: Hub › extensions › adapters
Part 2: How do you see and steer your agents? › 2.5: How does your answer reach the agent?

Getting Your Answer Back (2 of 4): Three Doors Into Claude Code

Which door opens depends on what the session is doing when your answer lands. One row each, with an example.

WHEN YOUR ANSWER LANDS, THE SESSION ISTHE DOORWHAT HAPPENS1It is stopping right nowHold the stopthe agent says “done”; its Stop hook waits up to60 s for checks, or your answerYour answer lands in the wait: the stop is turned back with“you chose: move it”; the same turn goes on2It is idle, waiting for youWake ita waiter, a small hook left running in the background, waitswith the idle session, for hours if need beYour answer lands at 11:40: the waiter exits and the samesession takes a new turn with it3It is closedNext timethe terminal was closed or the session ended; DeepBuild neverstarts a session to deliver itYour answer is kept, and goes in when you reopen that session ornext type in it
NO NEW SESSIONSWaking adds a turn to the session that asked. DeepBuild never opens a session to deliver.81 / 449
2.5.3See and steer › Answers backin the system: Hub › extensions › adapters
Part 2: How do you see and steer your agents? › 2.5: How does your answer reach the agent?

The Waiter: How an Idle Claude Code Session Wakes

Door 2 up close: a waiter is a hook that sleeps beside the idle session and exits to wake it when you answer.

Claude Codecheckout-webthe waitera background hookthe hubyouthe app9:4011:40 (times illustrative)stop1idle, waiting for you, as it does todaywaits: under 5 MB, no CPU, watching its parenta hook entry Claude Code runs in the background (asyncRewake)2waiterrecords it as a wait with a time limitand the process it waits on; never “finished”you tap “Move it”3records your answer, hands itto checkout-web’s waiter4exits with code 2so Claude Code wakes the session5wakes: a new turn with your answer6reads the transcript:delivered and acknowledged7

Its timeout is set long

Claude Code stops a hook at its timeout, 600 s unless set, so setup gives the waiter the longest ask deadline, 3 days.

One per session

A new waiter replaces the old one, which exits without waking. It watches its parent, so it can’t outlive a headless session.

Measured once

1.4 s to wake, from a claude -p script on Oct 4. Waking an interactive session, or the desktop app, is unmeasured.

NEXTCodex’s background hooks can’t start a turn, so not every agent has this door.82 / 449
2.5.4See and steer › Answers backin the system: Hub › extensions › adapters
Part 2: How do you see and steer your agents? › 2.5: How does your answer reach the agent?

Getting Your Answer Back (3 of 4): Each Agent’s Doors

Not every agent lets a hook wake it. Which doors each agent has today: ✓ yes, ✕ no, – not offered.

AgentHold the stopWake when idleSteer mid-turnNext messageWhy
Claude Code
terminal
✓✓✓✓the three doors of the last slide; while it works, its next tool call
Codex CLI
terminal
✓✕✓✓its next tool call while it works; its stop can wait up to 45 min; a background hook can’t start a turn
Codex app
desktop
✕✕–✓watch-only until its hooks are seen firing there; then as the CLI
pi, paseo (R2)
driven
✓✓✓✓steers a running turn, or starts the next one when idle

Picked per session

A door counts only once that session has shown it works, for example its hook seen firing; otherwise the next one down.

Steer, never interrupt

Where an agent allows it, an answer can join a running turn at its next step. DeepBuild never stops a turn to deliver.

NEXTNone of this changes how the agent waits for you. Next: who waits for whom, and on whose clock.83 / 449
2.5.5See and steer › Answers backin the system: Hub › extensions › adapters
Part 2: How do you see and steer your agents? › 2.5: How does your answer reach the agent?

Who Waits for Whom: The Agent’s Clock, Not Ours

DeepBuild waits only inside the agent’s hooks and tools, and the agent stops each after a set time.

THE AGENT: ONE CLAUDE CODE TURNDEEPBUILD: ONLY INSIDE THE AGENT’S OWN HOOKS AND TOOLSworkingtool calls, edits, testssays “done”its Stop hook fireswakesyour answer, or the verdictturn over: it waits for youas it does today; nothing here changes thateach tool call: deep-hookstamps it, checks fast rules, under 10 mslimit: the hook timeoutholds the stop up to 60 sfast checks run; FAIL goes backlimit: Stop hook timeout, 600 sthe waiter waits with ita background hook, ready for your answerlimit: the waiter’s timeoutyour answer arrives:it wakes the agenta question mid-turn: deep_ask returns at once with its default, inside the agent’s MCP tool timeout

The agent still waits for you

When a turn ends, Claude Code waits for your next message, as today. DeepBuild never makes it wait longer.

The time limits are the agent’s

Claude Code and Codex stop a hook or tool call that runs too long. These are their settings, not DeepBuild’s.

So every wait ends early

A hook cut off mid-hold would let “done” through unjudged, so each DeepBuild wait ends before the agent’s limit.

NEXTEach of these waits, with the limit it must fit inside and what happens if it doesn’t.84 / 449
2.5.6See and steer › Answers backin the system: Hub › extensions › adapters
Part 2: How do you see and steer your agents? › 2.5: How does your answer reach the agent?

Getting Your Answer Back (4 of 4): Timing Rules

The agent’s own time limits, one per row: what DeepBuild waits for, the limit it fits inside, and what if not.

RULE AND WHYWHAT MUST FIT INSIDE WHAT (NOT TO SCALE)IF IT BREAKSStop holda cut-off hook lets the stop through unjudgedStop hook timeout: 600 shold: 60 sends ≥ 5 s beforeholds go watch-only; the verdict takes the next routeCodex slow lanechanging it makes Codex re-ask hook trustStop timeout: 45 min, set oncea slow check’s deadlineends ≥ 5 s beforethe claim stays pending until your next messageWaiterClaude Code stops the waiter at its timeoutits own hook entry’s timeoutlongest ask: 3 dayslater answers wait for a hold or your next promptdeep_aska call cut off reads as a failed toolagent’s MCP tool timeout, ≥ 10 sdeep_ask waits“still waiting” 5 s beforereturns at once with ID, deadline and defaultSend-backs per turnpast 8, Claude Code ends the turn12345678≤ 8 a turn; a tool call resets itthat send-back goes by the next prompt
Checkedat hub start, when settings or hook entries change, and by deep doctora broken rule is never silent: its route turns watch-only (record, never hold) or falls back, naming both times
TESTED FIRST409 of 422 replayed sessions ran in desktop apps; week 1 opens with a spike (a quick test) of these hooks.85 / 449
2.6.1See and steer › A taste callin the system: Hub › extensions › asks
Part 2: How do you see and steer your agents? › 2.6: What happens while you decide?

A Taste Call Mid-Turn (1 of 2): The Agent Keeps Working

Asks and delivery in one story. Codex hits a taste call mid-task; deep-hook and the hub tell it to go on. Follow 1 to 7.

Codexmid-task, checkout-webDeepBuildhook and hubYouyour phone (R2)“Keep the total above the fold?”1deep-hook catches itCodex’s question, at PreToolUse2Hub: a taste callno saved decision for checkout-web3“go on with keep”, marked provisional4works on “keep”; undoablea push: waits5only steps that leave the machine waitNEEDS YOU · TASTE CALLKeep the total above the fold?default keep · due in 3 days6Notificationthe question, its defaultand when it applies7

Provisional

Work goes on with the recommended option at once, marked as undoable. Your answer can still change it.

What waits

Only steps that leave the machine, such as a push. Everything local goes ahead.

The notification

Carries the question, its default and when it applies. It opens the card; it answers nothing.

NO WAITINGA taste call or a choice never stops the agent. The deadline and the default still apply if you never answer.86 / 449
2.6.2See and steer › A taste callin the system: Hub › extensions › asks
Part 2: How do you see and steer your agents? › 2.6: What happens while you decide?

A Taste Call Mid-Turn (2 of 2): You Answer Once

You answer later, on your phone. Follow 8 to 13: the hub saves it, and Codex’s adapter steers it into the live turn.

Codexmid-task, checkout-webDeepBuildhook and hubYouyour phone (R2)earlier: asked, went on with “keep”You tap an answer:“move it under the cart”8Saved as a decisiontaste · checkout-web · move it9steered into the running turn10redoes only what the answer changed11Acknowledged in the transcriptdelivery confirmed, not assumed12NEXT WEEKThe same kind of taste call in checkout-web asks you againtaste rules, offered after the same answer three times, come later as an extension13

Saved, matched by kind

A saved answer settles repeats of kinds like a merge. A taste call repeats until you accept a rule (later).

Steer, never interrupt

Your answer joins the running turn and is read at Codex’s next step.

Confirmed

Delivery counts only once the agent’s transcript shows it got the answer.

NEXTCodex never waited and you answered once, on a card nothing may fake. That rule picked the app’s toolkit.87 / 449
2.7.1See and steer › The app’s toolkitin the system: App
Part 2: How do you see and steer your agents? › 2.7: Which UI toolkit, and why?

The App: What We Compare, and Why

Before the scores on “The App”: each row is one column of the next slide’s table, and why it matters.

ColumnWhat it measuresWhy it matters
1Trusted question card a surface nothing can draw over or clickyour yes there authorizes pushes
2GPU canvas in window the canvas draws inside the app window, no copy (from R2)measured Oct 10: a copy cost 6.7 ms a frame; in place, 0.8
3Idle memory memory and CPU while open all day300 MB, 1% of a core budget
4Extension panels plug-ins can add viewsevery view is a plug-in
5Maturity how proven the toolkit isits script host is at its first milestone
The options on the next slideA local web viewTauriSwift, per platformgpui-kit (Rust, GPUI)
NEXTEach option scored on these 5 columns, three diamonds for strong.88 / 449
2.7.2See and steer › The app’s toolkitin the system: App
Part 2: How do you see and steer your agents? › 2.7: Which UI toolkit, and why?

The App: Native and GPU-Drawn, Decided by a Two-Day Spike

Four toolkits that could draw the DeepBuild app, scored. Chosen: gpui-kit, a Rust toolkit that draws on the GPU.

OptionTrusted question cardGPU canvas in windowIdle memoryExtension panelsMaturity
A local web viewPreact on 127.0.0.1Dropped
Tauriweb view UI, Rust coreDropped
Swift, per platformline and count onlyFallback
gpui-kit (Rust, GPUI)behind a two-day spikeChosen
strong weak breaks a hard rulescores: our reading of the gains and costs recorded in the design
The spike must show: a long session list, the menu-bar count, a JS panel agents wrote from the docs alone, a headless render test, one capture frame
WHY THIS ONEOne native window, if a two-day spike passes R1’s list. The GPU handover, timed Oct 10, matters from R2.89 / 449
2.8.1See and steer › Where code runsin the system: DeepBuild › rings of trust
Part 2: How do you see and steer your agents? › 2.8: Where may each piece of code run?

Where Code Runs (1 of 2): Three Rings of Trust

As in Part 1, who wrote a piece of code decides where it runs. The nearer the middle, the more that code may do.

Trusted ringnever a plug-infirst-partyagent-built: sandboxedThe question card, the canvas, the supervisorIn the app: the question card, the canvas (the only code on the GPU), the sound and capture gate.In the hub: the supervisor and the installer.11The done gate, wiki, check drafting, adaptersTypeScript in the hub, first-party: pinned, and checked before they load.22A view DeepBuild ships, such as Needs youJavaScript inside the app, on the UI thread, with no powers of its own: a target of 4 ms per update.33A plug-in your agent wroteIts own process in the OS sandbox: no network but granted hosts, no hub socket.44A view your agent wroteIts own process, JIT compiler off. It sends a tree of elements; the app draws them.55A small game’s logic (Part 3)WebAssembly in DeepBuild’s own sandbox, with a step budget. A crash freezes only that game.66
WHY OUT OF PROCESSThe app’s script host shares the UI thread and turns its JIT on in release builds: it isn’t a sandbox.90 / 449
2.8.2See and steer › Where code runsin the system: DeepBuild › rings of trust
Part 2: How do you see and steer your agents? › 2.8: Where may each piece of code run?

Where Code Runs (2 of 2): Nothing Covers the Question Card

The ring’s most guarded part. Left: a view your agent wrote tries to fake a Yes on the card. Right: who draws what.

DeepBuildCI PANEL · WRITTEN BY YOUR AGENTmain · run 812main · run 811fix-42 · run 810fix-42 · run 809draws only inside its own panelQUESTION CARD · THE APP SHELL’SPush api to main?3 commits · checks PASS 5/5default no, in 22 hYesNoAlways on topfake YesRefused at install: the headless render check failsany panel that draws over the question cardThe app shell owns the top layerThe window frame, the question card, access and keyprompts, notifications.A panel stays in its panelIts toasts show only right after your gesture there.It can’t draw a secret field.An agent’s drawing is its own layerIt can’t hide, move or restyle anything of yours.Status colors mean statusRed, green and yellow appear only when tied to areal verdict, run or ask.
The card itselfcounts as shown only once it’s on screenits buttons work only after a short pauseand pause again if moved, covered or changedrefuses synthetic clicksfails closed if the app dies
WHY IT MATTERSYour yes on that card can authorize a push. If anything could draw over it, an agent could click yes for you.91 / 449
2.8.3See and steer › Where code runsin the system: DeepBuild › rings of trust
Part 2: How do you see and steer your agents? › 2.8: Where may each piece of code run?

Where Plug-in Code Runs: What We Compare, and Why

Before the scores on “Where Plug-in Code Runs”: each row is one column of the next slide’s table, and why it matters.

ColumnWhat it measuresWhy it matters
1Speed for trusted code no process hop for first-party codethe done gate runs on every stop
2Isolation a broken or hostile piece can’t reach the hubagents write plug-ins
3Simple to write a plug-in is a small TypeScript moduleagents build them from one sentence
4Enforced grants limits the OS actually enforcesa grant on paper protects nothing
The options on the next slideEverything in-processEverything out of processGrants without a sandboxSplit by trust
NEXTEach option scored on these 4 columns, three diamonds for strong.92 / 449
2.8.4See and steer › Where code runsin the system: DeepBuild › rings of trust
Part 2: How do you see and steer your agents? › 2.8: Where may each piece of code run?

Where Plug-in Code Runs: Split by Who Wrote It

Four ways the hub could host plug-ins. Chosen: DeepBuild’s own code inside, your agent’s code fenced off.

OptionSpeed for trusted codeIsolationSimple to writeEnforced grants
Everything in-processlike an editor’s extensionsDropped
Everything out of processDropped
Grants without a sandboxDropped
Split by trustfirst-party in, agent-built outChosen
strong weak breaks a hard rulescores: our reading of the gains and costs recorded in the design
LESSONA neighbor project built permission grants, then deleted them 83 days later. Ours exist only where enforced.93 / 449
3Make
Part 3 asks: How do agents show their work as pictures? › 26 sections, 3.1 to 3.26, each answering one part of it (running index, slide 13)

Part 3: Make: Vibe Visuals

Parts 1 and 2: how DeepBuild records agents’ work and asks you only what needs you. Part 3: how agents show that work as pictures made of data, which DeepBuild’s canvas checks and draws.

DeepBuildwhere your agents show, not tell1 · Foundation1.1 four parts, 1.2 four jobs1.3 the rules, 1.4 the hub1.5 extensions, 1.6 ways in1.7 hooks, 1.8 the record1.9 storage, 1.10 processes1.11 platforms2 · See and steer2.1 the app, 2.2 the line2.3 asks, 2.4 matching2.5 answers back, 2.6 a taste call2.7 the app’s toolkit, 2.8 where code runs3 · Make: vibe visuals3.1–3.3 what it makes3.4–3.8 documents, frames3.9–3.12 GPU, light3.13–3.15 modules, checks3.16–3.21 3D, play, sound3.22–3.26 budgets, done bar4 · Trust4.1 a claim, 4.2 what done means4.3 verdicts, 4.4 flaky checks4.5 every stop, 4.6 bug fix #424.7 a UI change, 4.8 the finish line4.9 defenses, 4.10 dodges5 · Extend, compose5.1 extension points, 5.2 agents, hooks5.3 hub slots, 5.4 plug-ins5.5 panels, 5.6 canvas packs5.7 modules, 5.8 composing5.9 safety rules6 · In use6.1 what ships, 6.2 first run6.3 MCP tools, 6.4 the CLI6.5 leases, 6.6 the box6.7 your phone, 6.8 the wiki6.9 learning7 · Build it right7.1 looks right, 7.2 tests first7.3 rules, faults, 7.4 kits7.5 comparisons, 7.6 the gate7.7 borrowed, open, 7.8 budgets7.9 measuring, 7.10 six-week plan7.11 Decision 1, 7.12 routing replay7.13 cuts8 · What’s open8.1 scale, 8.2 issues8.3 R1 path, 8.4 risks8.5 owner calls, 8.6 fleets later8.7 next
WHERE WE AREThe highlighted branch is this part; its topics are the slides that follow.94 / 449
3.1.1Make › What it makesin the system: App › canvas core
Part 3: How do agents show their work as pictures? › 3.1: What is the canvas for?

Primer: The Canvas Is Where Agents Show Their Work

The DeepBuild app, simplified. An agent sends a few lines of data; the canvas draws them inside the app’s window.

DeepBuildCHECKOUT-WEBClaude CodeCodexDOCSClaude CodeCanvas: draws all of thischeckout-web · #42issueagentsays donechecksPRclaude · checkout-webAgent› deep_showprofile: chartq2: 44q3: 48 ← sales.q3title: Sales by quarterDocumentdeep_showis the tool an agentcalls to show you something. Itsends data, never pixels.Claude · its own layer, outlinedSales by quarterq2q34448

What it is

The app’s one drawing surface: every session’s line, the Map, charts, terminals and agents’ figures.

Who draws on it

Only the canvas core, DeepBuild’s trusted drawing code. Agents and plug-ins only send it documents.

What it never does

Push a picture at you, count a picture as proof, or draw over the question card.

Where it runs

Inside the DeepBuild app’s window on your machine, drawn with your own GPU.

IN ONE LINEThe canvas core is the part of DeepBuild’s app that draws. Agents say what to show; the core draws it.95 / 449
3.1.2Make › What it makesin the system: App › canvas core
Part 3: How do agents show their work as pictures? › 3.1: What is the canvas for?

What Agents Make: Ten Kinds of Picture, One Canvas

What agents can ask DeepBuild’s canvas to draw, from a chart to a small game, and the release each lands in.

Figures and chartsevery number boundto its sourceR2Explainer filmsmath, science, how asystem worksR6A film of a changean agent shows itsown bug and fixR63D scenesorbit a product, apaper’s architectureR6The Mapyour repo as a city,live servicesR1 flat · R2 3DLive dashboardsreadings on a view,notices you asked forR2Interactive piecessliders, steps, afigure you play withR6Small games2 to 8 players, rulesas sandboxed logicR6Characters and soundrigged puppets, ascore, narrationR6ExportsMP4, Lottie, PDF, glTF,a web pageR6R1 is version 0, the first release; R2 and R6 come after it. The pill says when each kind first lands.
ONE ENGINEAll ten are documents on one canvas, checked the same way. None of them is pixels an agent drew itself.96 / 449
3.2.1Make › Who, and whyin the system: DeepBuild › who it serves
Part 3: How do agents show their work as pictures? › 3.2: Who uses it, and for what?

Who Would Use It (1 of 2): Engineers to Researchers

Who would have agents draw these in DeepBuild: four kinds of people here, four next. Each picture plays item one.

Engineersa failing test as a 20-secondfilm of the buga before-and-after figure of arefactor, on its PRthe repo as a 3D city, each partwith what it holdsCart$18.01round()Receipt$18.000:07 / 0:20the bug, as a 20-second filmReviewers and leadsan evidence board built from aclaim’s recordevery session as lights over theparts it touchesa clash a trial merge found, drawnas a dashed line#42says done✓tests✓journey✕receiptFAIL · evidence by hashOpsa live map of services, linkrates from metricsa notice when an error ratepasses 2%a Read now button that re-readsevery source; under 2 s old is keptwebapidbapinotice: errors past 2%Researchersa paper’s architecture in 3D thatopens to its sourceformulas written on term by termfrom LaTeXa chart whose every numbertraces backEq. 1sourceopens down to its source
SOURCEEach example comes from the design’s own briefs and acceptance sentences.97 / 449
3.2.2Make › Who, and whyin the system: DeepBuild › who it serves
Part 3: How do agents show their work as pictures? › 3.2: Who uses it, and for what?

Who Would Use It (2 of 2): Teachers to Game Makers

The other four. Again, each picture plays the first thing on that person’s list.

Teacherstwelve math films: a derivative,a Fourier chaina linear map with a slider onthe matrixa Galton board run by realphysicsthe slope, moving: a derivativeProduct and marketinga launch film from a brief, in achosen lookkinetic type on the beat at120 BPMthe 2D motion exported to Lottiefor the siteLAUNCHon the beat · 120 BPMGame makersa 4-player arena prototype overa relayrules in sandboxed logic, replaysby hasha bot that playtests in a copy4 players over a relayNon-code agent worka weekly report whose numbersare re-checkeda data story that stops on anyperioda figure attached to an ask, asevidenceWeekly reportrevenue✓signups✓tickets✓each number re-checked
NO CODE NEEDEDNone of it asks anyone to write code: they describe it, an agent writes the document, DeepBuild draws it.98 / 449
3.2.3Make › Who, and whyin the system: DeepBuild › who it serves
Part 3: How do agents show their work as pictures? › 3.2: Who uses it, and for what?

Use Cases the Owner Asked For (1 of 2): Agents and Plug-ins

Now the owner’s own 24 requests, in four groups. Here: running many agents, and one-sentence plug-ins.

Running many agentsThe owner’s own problem: many agents, one person.Claude CodeCodexa research agentDeepBuildNeeds you · 1PASSyouProve it’s done without asking (“is it done?” was typed 894 times)See every agent, not just the coding onesOne box for any agent; only what needs a person comes backAgents that see what they made, without my screenshotsCost across every vendor, in one placeSet up a GPU box over SSHPlug-ins from one sentenceYou say one sentence; your agent builds the plug-in.“Hang every screenshot I takeon a line under the menu bar.” File Edit Viewyour agent builds it; DeepBuild checks it“Hang every screenshot I take on a line under the menu bar”“Hold ⌥Space: look at my screen and point”“Tell me when a receipt bounces for a real order”“A stocks view: live prices, a chart each, alerts”“Keep my agents’ terminals running when I quit”“Show this repo as a 3D city, my services as a live map”
SOURCEEach line is a request or a yes from the owner in the design sessions, or one of the plug-in API’s seven acceptance sentences.99 / 449
3.2.4Make › Who, and whyin the system: DeepBuild › who it serves
Part 3: How do agents show their work as pictures? › 3.2: Who uses it, and for what?

Use Cases the Owner Asked For (2 of 2): Explain, Make, Play

The other two groups: pictures that explain and teach, and pieces to watch, share and play.

Explain and teachPictures that explain a change, an idea or a paper.Cart$18.01round()Receipt$18.000:07 / 0:20a film of the changeor a figure you play withA change explained as a short film or a figure you can play withMachines and skills drawn natively, on the GPUFigures with sliders, steps and quizzesMath explainers in our own lookA research paper drawn in 3D, down to Eq. 1A launch video from a written briefMake and playPieces to watch, share and play.a live piece, one web pagea slideArt-motion films, in 2D and in 3DOne-minute interactive piecesA live piece shared as one web pageSlides like this deckAn architecture map for readers with no contextSmall games: an arena, a shooter, a 4v4 game (INKWAVE)
SOURCESame as the last slide: the owner’s own requests.100 / 449
3.3.1Make › Primersin the system: App › canvas core
Part 3: How do agents show their work as pictures? › 3.3: What does a newcomer need to know about rendering?

Primer: Rendering Draws Pixels, One Frame at a Time

Three primers before the canvas. First, drawing: a description becomes colored dots; motion is many timed frames.

RenderingA DESCRIPTIONbar q3height 48color: yellowPIXELS: ONE COLOR EACHON SCREENFrameFrame rateframe 1frame 2frame 3frame 4frame 50 s1 s60 frames a second: one every 16.7 msone frame at 60 Hz: 16.7 ms120 Hz: 8.3 msyellow: canvas work, under 2 msA view that isn’t moving draws nothing at all.

Pixel

One dot of color. A 1920 × 1080 picture has 2,073,600 of them.

Rendering

Working out each pixel’s color from a description, such as “a yellow bar, 48 high”.

Frame

One finished still picture. Motion is many frames shown one after another.

Frame rate

Frames per second, written Hz. At 60 Hz, each has 16.7 ms; a 20-second film is 1,200 frames.

WHY IT MATTERSA moving picture is redrawn many times a second, so drawing must be fast; a still view draws nothing.101 / 449
3.3.2Make › Primersin the system: App › canvas core
Part 3: How do agents show their work as pictures? › 3.3: What does a newcomer need to know about rendering?

Primer: The GPU, and Why Only One Part May Touch It

Top: what a GPU is. Below, a writer is any agent, plug-in or view that sends DeepBuild something to draw.

GPUA chip built to work out many pixels at the same time. 3D, effects and smooth motion need it.CPU: a few strong workers, one batch after anothercorecorecorecoreGPU: many small workers, all pixels at onceIf every writer drew its own pixelsPush to main?AllowNoplug-in draws afake Allow on topPASSno checkbehind it✕A plug-in could cover the questioncard and fake your click✕Anyone could paint a green PASSthat no check earned✕One heavy scene could slow themachine your agents are using✕Nothing could check a picturebefore you see itDeepBuild: only the canvas core touches the GPUagentplug-inyoudocumentscanvascoreGPUquestion cardalways on top✓The question card is drawn only by the shell, always on top✓Status colors come only from a verdict, a run or an open ask✓The core slows only the writer that costs too much
THE RULEOnly the canvas core, inside DeepBuild’s app, touches the GPU. Agents and plug-ins only describe scenes.102 / 449
3.3.3Make › Primersin the system: App › canvas core
Part 3: How do agents show their work as pictures? › 3.3: What does a newcomer need to know about rendering?

Primer: Documents Can Be Checked; Pixels Can’t

So writers send DeepBuild documents, not pixels. Why: the same Q3 chart kept two ways, asked five questions.

PixelsDocument2,073,600 colors at 1920 × 1080.Nothing says which dots are Q3.profile: chartitems: q2: bar, 44 q3: bar, 48 source: sales.q3 title: text, “Sales”A few named items,each value with a source.Which shape is Q3?✕only colored dotsthe item with ID q3✓Where does 48 come from?✕nothing sayssource: sales.q3, as of 09:40✓Does the title cover a bar?✕a guess from lookingboxes are known: a layout check✓Make Q3 52.✕draw the whole picture againone patch: items/q3/params/value✓Same picture next time?✕compare two imagessame data, same time: same hash✓
WHY DATAData can be checked, replayed and patched one value at a time. Pixels can’t. So agents send documents, never pixels.103 / 449
3.4.1Make › Documentsin the system: Canvas core › documents
Part 3: How do agents show their work as pictures? › 3.4: What is a canvas document made of?

The Canvas Core, Taken Apart: Five Pieces

The canvas core, opened one level down. Each box is a section of this part; the arrow is where it starts.

Canvas corethe part of the app that draws everythingDocumentswhat agents send: items of known kinds,patches, revisions, writer layers→ 108Compositortakes every writer’s layer, checks it,stacks it in bands, one frame at a time→ 131Evaluationcomputes the picture for time t;one clock for picture, physics, sound→ 154GPU layerpasses and operators on the GPU,our renderer on wgpu→ 16724 canvas modules2D, data, motion and style, 3D,play, sound and export→ 214Checksread the picture’s data, not its pixels,and return issues an agent can fix→ 226
WHERE NEXTDocuments first, since everything else consumes them; then the compositor, evaluation, the GPU and the modules.104 / 449
3.4.2Make › Documentsin the system: Canvas core › documents
Part 3: How do agents show their work as pictures? › 3.4: What is a canvas document made of?

Four Ways an Agent Could Make a Picture

Four ways an agent could hand DeepBuild a picture, each with its main strengths and weaknesses. The scores follow.

1Agent writes HTMLor WebGL codethe result is pixels✓agents write it already✓cheap for us to build✕nothing checks it first✕numbers have no source2Agent drives agame engineUnreal, Blender, Godot✓agents know these tools✓less for us to build✕numbers have no source✕weak check and replay3A renderer thatkeeps historyreuses past frames, like big engines✕jump to 0:07 ≠ play to 0:07✕so exact replay breaks✓familiar to agents✕weak check before show4Documents thecanvas drawskinds, patches, checks✓checked before you see it✓scrub = export, exactly✓fix one value; honest numbers✕agents must learn it✕we build the rendererCHOSENctx.fillStyle = ‘#F2C440’ctx.fillRect(…)code that paints dotsengine projectthe engine owns the picturef5f6f7each frame reuses the last onesplay: frame A≠jump: frame Bq2: 44q3: 48✓patch q3 = 52
NEXTThe scores behind these lines, column by column, with what each column measures and why it matters.105 / 449
3.4.3Make › Documentsin the system: Canvas core › documents
Part 3: How do agents show their work as pictures? › 3.4: What is a canvas document made of?

Making Visual Work: What We Compare, and Why

Before the scores on “Making Visual Work”: each row is one column of the next slide’s table, and why it matters.

ColumnWhat it measuresWhy it matters
1Check before show problems caught before you see ita miss returns as a fix
2Exact scrub = export any frame you scrub is the exported onechecks read what you see
3Fix one frame a change touches only what it namesno reroll of the whole piece
4Honest numbers numbers on screen trace to a sourcea picture must not mislead
5Agent learns it agents write it from the docsagents do the making
6Build cost work for us to builda hobby project’s time
The options on the next slideAgent writes HTML / WebGL codeAgent drives a game engineA renderer that keeps historyDocuments the canvas draws
NEXTEach option scored on these 6 columns, three diamonds for strong.106 / 449
3.4.4Make › Documentsin the system: Canvas core › documents
Part 3: How do agents show their work as pictures? › 3.4: What is a canvas document made of?

Making Visual Work, Scored: Only Documents Check and Fix

Four ways an agent could make a picture, scored on the columns the previous slide explains.

OptionCheck before showExact scrub = exportFix one frameHonest numbersAgent learns itBuild cost
Agent writes HTML / WebGL codeDropped
Agent drives a game engineUnreal, Blender, GodotDropped
A renderer that keeps historyreuses past frames (TAA), like big enginesDropped
Documents the canvas drawskinds, patches, checksChosen
strong weak breaks a hard rulescores: our reading of the gains and costs recorded in the design
COST WE ACCEPTEDAgents learn our language (deep_kinds, docs, engine words mapped to ours); engines stay test references.107 / 449
3.4.5Make › Documentsin the system: Canvas core › documents
Part 3: How do agents show their work as pictures? › 3.4: What is a canvas document made of?

A Document, by Example: The Q3 Chart as Data

Documents won; here is one. Left: what an agent sends. Right: what the canvas core draws. Yellow labels name parts.

Documentthe Q3 chart, simplifiedprofile: chart title: Sales by quarterlook: clean budget: data viewEnvelopeitemsq2kind: bar value: 44q3kind: bar value: 48source: reading:sales.q3titlekind: text“Sales by quarter”ItemStable IDHandleSales by quarter44q248q3sales.q3as of 09:40

Document

One picture’s data, checked whole before it shows.

Envelope

The whole picture: profile (chart, film…), title, size, look (style), seed, cost budget.

Item

Anything with an ID and a kind: a bar, a label, a light.

Stable ID

An item’s name for good: never reused, never a position.

Handle

A link to the record, so a number shows its source.

SIMPLIFIEDA real chart keeps its bars in one table (a mark set), a row per quarter. Still: named items, numbers sourced.108 / 449
3.4.6Make › Documentsin the system: Canvas core › documents
Part 3: How do agents show their work as pictures? › 3.4: What is a canvas document made of?

Items and Kinds: Every Item Follows Its Kind’s Rules

A kind is the rulebook for one sort of item. Watch the canvas core’s check use it on five things an agent writes.

Itemid: q3kind: bar@1layer: Claudeparams: value: 48at: position onlylayer comes from the writerbar@1name @ major versionfor each param:type numberunit nonedefault 0range 0 and uplive yescost transformvalues illustrativeKindWHAT THE AGENT WRITESWHAT THE CHECK SAYSq3 with no value✓takes the default, 0valeu: 52✕unknown_fieldan error that names close fields: valuevalue: -5✕out_of_rangean error; outside the soft range is only a warningkind: sparkle@1!unknown_kindskipped when drawing, kept byte for byte, with a noticekind: bar@3✕kind_too_newrefused; an older version is migrated instead

IDs never point by position

An ID is never reused after a delete. Renaming changes the name, never the ID, and an item never changes kind in place.

Who may add kinds

Canvas modules (DeepBuild’s own built-in code) register kinds backed by code. A pack, a versioned add-on bundle, may add kinds built from a recipe that makes items: data, never code.

WHY KINDSEvery item says what it is, so the check knows each field’s type, unit and range before anything draws.109 / 449
3.4.7Make › Documentsin the system: Canvas core › documents
Part 3: How do agents show their work as pictures? › 3.4: What is a canvas document made of?

Kinds Have Versions, So Old Documents Still Open

Kinds change over time. A chart saved under bar@1 opens in a DeepBuild release that ships bar@2. Follow it, 1 to 5.

Savedthe Q3 chart,with bar@11Migrated at loadbar@1 → bar@2,before the check2A notice, alwaysmigrated: kind,from, to, IDs3Checked and drawnexactly as abar@2 chart4File unchangeduntil its writernext patches it5This release ships bar@2. It reads bar@2 and every older major a release shipped.Two majors back? It still opens, a step at a time.A bar@0 chart migrates to bar@1, then to bar@2,each step with its notice; no release drops one.window: every shipped majorThe corpus: old documents must draw the sameFixture documents for every shipped major are loadedand drawn in every release, and compared.a difference fails the release

Pack kinds migrate as data

A pack’s migration is rename, set and drop. No pack code runs, and no ID ever changes.

A failed comparison names it

It names the kind, the item, the field and the first time that differs.

Only you bless a change

A release that draws an old document differently waits for your decision, once per cause.

NEVER SILENTA migration never changes an ID, never runs a pack’s code, and always leaves a notice.110 / 449
3.4.8Make › Documentsin the system: Canvas core › documents
Part 3: How do agents show their work as pictures? › 3.4: What is a canvas document made of?

Units and Axes: One Measure for Every Kind of Number

A kind gives every param a unit. These are the units: one per kind of quantity, the same in every document.

2D: U, Y POINTS DOWN0, 0xyq2q34448uone logical pixel at zoom 13D: METERS, +Y UP, FRONT FACES +Z+Y+X+Zheight 8 m(illustrative)metersright-handed, as in glTFONE UNIT PER KIND OF NUMBERAnglesdegrees, and deg/sLightlumens, lux (sun), kelvin, EV100Colorlinear BT.709 or a look roleSounddB, LUFS, dBTPPhysicsSI: kg, N, m/sSpringshertz + a damping ratioTimestored as flicks

Literals carry units

"300 mm", "45deg" or "0.6s" are converted at check. A bare number takes the field’s declared unit.

Sizes by the frame

fw and fh are fractions of the frame at design size: "1/300fw" at 1920 px wide is 6.4 u. px keeps a hairline fixed on screen.

One transform order

Subtract the pivot, scale, shear, rotate, add the position, then apply the parent. Euler angles turn about X, then Y, then Z.

Files from other tools

A z-up file converts at import. Exports write each track’s own timescale, never flicks; output color is tagged sRGB.

NO SETTINGA document has no unit setting of its own, so a check and an agent always read one number the same way.111 / 449
3.4.9Make › Documentsin the system: Canvas core › documents
Part 3: How do agents show their work as pictures? › 3.4: What is a canvas document made of?

A Patch Changes One Value, Found by Its Path

Claude changes Q3 from 48 to 52 in rev 7, the chart’s 7th version (revision). The canvas core applies it, 1 to 4.

Patchbase: rev 7writer: from the connectionreason: “Q3 restated”set items/q3/params/value = 52itemssectionq3stable ID/params/valuefield/PathResolved once, at check, to where the value is stored:following it costs nothing per frame.Dry run firstwould update 1 item; nothing else1Checked, then appliedall or nothing: rev 7 → rev 82The result comes backapplied · updated 1 · undo ready3Undo, if wantedset value = 48, by Claude only444q2untouched4852q3only q3 rebuilt
Eight ops: create · set · unset · delete · move · reorder · rows · break_outStale base? It rebases if no ID it touches changed; otherwise it’s a conflict naming both writersAfter # a path names a part that isn’t an item, such as trees#42
WHY PATCHESA fix is one line, not a reroll: only Q3 rebuilds, and undo puts back exactly that value.112 / 449
3.4.10Make › Documentsin the system: Canvas core › documents
Part 3: How do agents show their work as pictures? › 3.4: What is a canvas document made of?

How a Patch Lands: Copied, Checked, Then Recorded Once

The last slide’s patch, opened up: what the canvas core and the hub do with rev 7 → rev 8, step by step.

THE PATCH CLAUDE CODE SENDS{patch: 01J9… doc: q3-chart base: 7 reason: "Q3 restated" ops: [set   items/q3/params/value   = 52]}no writer field: it comesfrom the connection1canvas coreBase check: base 7 is the current revelse a rebase, or a conflict naming both2canvas coreApply the ops to a copy of rev 7one refused op, and nothing applies3canvas coreCheck only what changedq3 and what reads it; issues as data; ≤ 2 ms4canvas coreCanonical bytes, then their sha256that is rev 8’s hash: same content, same hash5the hubCommit: the layer file, by its hash,then the doc.patched row: the commit point6canvas coreReply to Claude Codeoutcome, counts, issues and the undoONE ROW IN THE RECORDkind: doc.patchedlog_pos: 48213, set by the hubwriter: Claude Code’s sessiondata: {doc: q3-chart, rev: 8,  patch: 01J9…,  achieved: {updated: 1}}WHAT CLAUDE CODE GETS BACKoutcome: applied · rev: 8achieved: {updated: 1}issues: [] · cost_delta: {…}undo: [set …/value = 48]ULID, log_pos and hash illustrative

All or nothing

Every op runs on the copy first. If any op is refused, rev 7 stays and not one byte changes.

A stale base

A patch on base 7 that lands after rev 8 rebases if no ID it touches changed; on q3 it’s a conflict.

A crash between writes

The file is written first. If the hub dies before the row lands, rev 8 isn’t current after a restart.

Held by a fuzzer

A dry run matches its commit, a refusal changes no byte, a patch then its undo gives back rev 7’s hash.

ONE EVENTEach agent call is one doc.patched row, so an item’s history shows who changed what, and when.113 / 449
3.4.11Make › Documentsin the system: Canvas core › documents
Part 3: How do agents show their work as pictures? › 3.4: What is a canvas document made of?

Paths Point Inside a Document; Handles Point to the Record

The patch found q3 by its path. A path points inside one document; a handle reaches the record, if you may read it.

A PATH: INSIDE ONE DOCUMENTitemssection/q3stable ID/params/valuefielditems/title/at/rot/1one angle of an item’s transformcontrols/throttle/valuea control’s valuedata/salesa named value a channel may keytrees#42after #: an element, not an itembanner#r0c27a soft body’s particleplank.01#neara builder’s anchorResolved once, at check, to an array and an offset: free each frame.A HANDLE: OUT TO THE RECORD<scheme>:<id>[#<fragment>]task:ask:claim:verdict:run:req:decision:plan:lease:reading:notice:doc:ev:session:reading:sales.q3the source of a bound valueverdict:01J…the source of a status colorreq:<definition>#R2one requirement of a definitiondoc:<id>#row.m14an item in another documentev:01J…a view of the record as of that eventResolves only to what its writer may read; anything else is ref_unresolved.

Paths stay home

A path never reaches another document. Only a handle does, and a handle names a record object or a document.

Dependencies in plain sight

An expression never holds a raw path: a driver names its variables and binds each one to a path.

Who may read it

An agent reads through its session’s credential, a plug-in through its grant. A reply returns a value only to a caller that may read it too.

Closed lists

Sections: items, controls, channels, markers, data, inputs, assemblies. Schemes: the fourteen above, and no others.

ONE GRAMMARPatches, channels, drivers, bound values and status bindings all name what they touch the same two ways.114 / 449
3.4.12Make › Documentsin the system: Canvas core › documents
Part 3: How do agents show their work as pictures? › 3.4: What is a canvas document made of?

Revisions: Nothing Shows Before Its Check Passes

Every patch or whole new chart makes a revision. Top: four from Claude, as they arrive. Bottom: what you see.

WHAT ARRIVES FROM CLAUDEWHAT YOU SEE ON SCREENrev 6the whole chart✓ check passedcurrentrev 7the whole chart, but q2left out by mistake✕ unintended_removal: q2refusedrev 8q3 = 52pending… then rev 9 camesupersededrev 9q3 = 52, title fixed✓ check passedcurrentback to Claude, with the fixone in flight; the newest winsrev 6 stays on screen: the last good onerev 9 is current
A whole revision, as deep_show sends, must list every ID it removesFive states: pending · current · last good · superseded · refusedAn old issue (a problem a check found) the last good revision already had comes back marked carried, and doesn’t blockYour note on an item stays open until a later revision changes it and passes its checks; a writer saying “fixed” closes nothing
WHYA broken revision never replaces a good one on screen, and an agent that lost track of its document can’t drop what it forgot.115 / 449
3.4.13Make › Documentsin the system: Canvas core › documents
Part 3: How do agents show their work as pictures? › 3.4: What is a canvas document made of?

Writer Layers: Several Writers Share One Document

The Q3 chart with three writers: you, Claude and Codex. Each writes only its own layer. Read moments 1 to 4.

Writer layeryoutitle: Sales by quarterClaudebars q2 and q3Codexa note on q3joined by ID into one pictureSales by quarterClaudenoteClaude patches q3✓ Applied: q3 lives in Claude’s layer, so only Claude’s patches change it.1Codex patches your title✕ Refused, not_your_layer. It’s filed as a suggestion on the title:never an ask, never a ping; only your gesture applies it.2You change q3 in the editorIf no lease covers it, your patch takes q3 into your layer.Claude’s later patches to q3 become suggestions.3Codex leases the prefix notes.*Every ID it creates starts with notes. and a patch outside its leaseis refused with lease_held, routed to the lease’s holder.4
Who changed what: every change is a doc.patched event in the record, so an item’s history shows who made what, and a merge by stable ID never loses a writer’s change. “Layer” alone means only this: one writer’s layer.
WHY LAYERSTwo agents and you can edit one picture without clobbering each other, and undo is by writer.116 / 449
3.4.14Make › Documentsin the system: Canvas core › documents
Part 3: How do agents show their work as pictures? › 3.4: What is a canvas document made of?

Order Keys: Two Writers Insert at Once, Nothing Collides

Writer layers join items by ID, and a map keeps no order. Where order matters, each item carries a key that sorts.

A MAP KEYED BY ID HAS NO ORDERq3titleq2legendTwo writers merge by ID, so nothinghere says which legend row comes first.THE LEGEND, SORTED BY ORDER KEYq2order: a0targetorder: a0Fnoteorder: a0kq3order: a1keys illustrativeClaude inserts “target”between a0 and a1Codex inserts “note”at the same momentjitter seeded by(Claude, patch ID) → a0Fjitter seeded by(Codex, patch ID) → a0k✓no collision, nothing renumbereda replay makes the same keysorder key

A key between neighbours

order is a fractional index, a base-62 string. A new key falls between the two around it, so nothing else moves.

Seeded, so it repeats

Jitter seeded from (writer, patch ID) keeps two inserts at once apart, and a replay gives the same keys. Ties break by ID.

What draws on top, in 2D

First the writer layer’s band, then the layer’s own order, then the item’s order key.

And in 3D

By depth. A document’s writer layers share one depth pass and one light, so their 3D items hide and shadow one another.

NO Z FIELDA writer layer has no z or opacity of its own: order keys and a group’s opacity cover both.117 / 449
3.4.15Make › Documentsin the system: Canvas core › documents
Part 3: How do agents show their work as pictures? › 3.4: What is a canvas document made of?

Every Frame Is a Pure Function of the Document and the Time

From document to motion: the canvas core computes each frame from the document and a time t. Reach 0:07 three ways.

Pure functionframe(t) = eval(doc, t, inputs ≤ t, view)the film’s dataa moment, like 0:07what was pressed, recordedthe camera you move0:000:201 play from 0:002 jump straight to 0:073 export frame 168 (7 s × 24)0:07Cart$18.01round()Receipt$18.000:07 / 0:20same frame, same hash, all three waysRandom effects use a seed from the document, so they repeat too.No plug-in code runs per frame.

Document input

Recorded on the document’s input track and replayed, like a figure’s throttle.

View setting

A setting the document declares, like a chart’s pan. Kept per viewer; pinned for replay checks.

Viewer input

Orbit, zoom and hover. Kept per viewer, never saved, and left out of replay checks.

WHY IT MATTERSScrubbing, replay and export match exactly, so a check that reads frame 168 reads what you saw at 0:07.118 / 449
3.4.16Make › Documentsin the system: Canvas core › documents
Part 3: How do agents show their work as pictures? › 3.4: What is a canvas document made of?

Point and Ask: Click What Is Wrong; the Agent Gets Its Name

A frame is a function of its time, so pointing at 0:07 tells the agent exactly what you saw. Follow 1 to 4.

the explainer at 0:07 · rev 3YOU POINT AND TYPEWHAT THE AGENT GETSCart$18.01round()Receipt$18.00you: “why does this round down?”1selectionbeside your words, as datahandles:[doc:explainer#receipt]t:0:07doc_rev:3precision:idquote:"$18.00"render-back at 0:07, rev 3 shows what you saw2ON A WORK PRODUCT (R6)agent patches the title✕ outside_selection3option Areceiptoption Breceiptoption Creceiptyour pick: one patch, as you, one undo4 · a preview, or up to three options

Your selection is yours

Session state: never saved in a document or the record, and no agent can set it. The highlight is an outline, never a fill.

How exactly it hit

id names items; geometry a place on one; region alone, as on a captured screen, can be asked about but never patched.

If the item is gone

Its handle comes back detached, with who removed it, and your ask-task stays open.

When it lands

R1 click to select; R2 point and ask everywhere; R6 the lease on the selected IDs, the preview and the options.

YOUR WORDS STAY YOURSText under the pointer goes as a quote, apart from what you typed, so the agent reads it as data.119 / 449
3.4.17Make › Documentsin the system: Canvas core › documents
Part 3: How do agents show their work as pictures? › 3.4: What is a canvas document made of?

Notes and Suggestions: Feedback That Stays on the Item

A return card is the card an agent’s stop leaves you. On it, three ways to answer a picture without an editor.

A NOTE ON THE RECEIPT, REVISION BY REVISIONrev 3you leave a note at 0:07“say why it rounds”note: openrev 4Claude changes the receipta check finds an issuenote: still openrev 5Claude changes it againevery check passesnote: closed by checkClaude says “fixed” in the chat:the note stays open. Only a passing revision that changes the item, or you, closes it.noteA SUGGESTIONCodex patches your title✕ not_your_layerfiled on the title, with a preview; only your gesture applies itsuggestionPUT BACK AS BEFORE THIS STOPOne action on the return card, shown first as a dry run:each item the turn changed gets its old values back,deleted ones return, created ones go; they become yours.

Only you write a note

On a return card, or in the editor panel with your input’s serial. No agent or plug-in can write, edit or close one.

It travels as data

The writer gets {note, doc, item, rev, t, region, text} as one send-back item, never inside a prompt of yours.

Never an ask

A note never opens or answers an ask; a suggestion never notifies you. Neither counts in Needs you.

Put back, honestly

An item another writer changed since is left out (undo_conflict), one under a live lease too (lease_held), each listed.

When it lands

Notes on a return card in R2; in the editor panel in R6. Put back acts on each document the turn changed.

FIXED MEANS CHECKEDA writer saying “fixed” closes nothing. A note closes on a passing revision that changes its item, or by you.120 / 449
3.4.18Make › Documentsin the system: Canvas core › documents
Part 3: How do agents show their work as pictures? › 3.4: What is a canvas document made of?

The Canvas Reads the Record: Views Built From Events

Not every document comes from an agent: the app’s session line is rebuilt from the hub’s record, as of any moment.

EventProjectionView of the record09:12tool.after · edit total.tssession_files09:20claim.madeclaims09:21run.finished · 1 of 3 failedruns09:21verdict.made · FAILverdicts09:40doc.patched · film rev 3documentscheckout-web · #42: the linesays done1 check failedverdict✕ FAILthe Mapa return cardthe film, rev 3,drawn by Claudethe record, oldest to newestnowas of nowas of 09:21: every view shows that moment
The event list is closed: each event type has a schemaA view binds only to fields that events feedA view has no revisions; an agent’s patch to it is refused: record_viewStatus colors come only from a verdict, a run or an ask
WHYA view can only show what the record says, and you can scrub any view back to any moment.121 / 449
3.4.19Make › Documentsin the system: Canvas core › documents
Part 3: How do agents show their work as pictures? › 3.4: What is a canvas document made of?

Timeline From the Record: A Claim’s Film Builds Itself

Views come from events. So does a claim’s film: half an hour on issue #42 becomes 20 seconds, nothing reordered.

THE RECORD, BY CLOCK: ISSUE #42 (TIMES ILLUSTRATIVE)09:1009:2009:3009:40edit total.tsclaim.maderun: 1 of 3 failedverdict FAILsent backclaim.madeverdict PASS16 minutes with no eventsTHE FILM, FIT TO 20 Sworkingsays donechecks 1/3FAILsent back16 min latersays donechecksPASSholddwell: verdict 1.2 s · send-back 0.8 s · each beat ≥ 0.36 s · gaps ≤ 1.1 s, labelled past 2 minevery marker keeps its event IDs

The agent writes little

Only event shots, the title and the narration script. Keys and markers come from the events.

Compress, never reorder

Events within 2 s merge; fit_to rescales gaps, never the order of what happened.

Captions set the pace

A line too long for its beat lengthens the film, or the film audit fails it.

The same builder, live

It appends as events arrive, so a session’s line is drawn the same way. It lands in R1.

HELD TO THE RECORDThe record-replay check holds it to the projections: no state they lack, no event out of order.122 / 449
3.4.20Make › Documentsin the system: Canvas core › documents
Part 3: How do agents show their work as pictures? › 3.4: What is a canvas document made of?

Salience: Show About Nine, Fold the Rest Into a Count

A level of the Map can hold dozens of parts. Salience ranks them by what the record says and shows only the top few.

23 ITEMS AT ONE LEVEL OF CHECKOUT-WEBneeds yousent back, failinglacks proofunchangedranked bythe record1total.tsneeds you: a taste call is open2receiptsent back, round 1 of 33cartfailing: the journey check4coupon.tsfailing: the receipt test5api/orderslacks proof6authlacks proof7sign-uplacks proof8checkoutlacks proof9ui/totallacks proof14 more: 2 lack proof, 12 unchangedfoldnames illustrative

Rank by facts, no model

Needs you, sent back, failing, lacks proof, touched by this work, changed since you last looked, then priority. Ties by ID.

It holds still

The set changes when the level opens, or when a needs-you or a verdict changes. Other arrivals wait as “N new”.

About nine

Fewer if nine won’t fit at the minimum readable size. Ranks also set each item’s level of detail and label priority.

Where you meet it

Levels of views such as the Map, and each return card’s turn view: at most nine parts, files only as evidence. R1.

NO LAUNDRY LISTA needs-you item is never folded: if more need you than fit, all of them show and everything else folds.123 / 449
3.4.21Make › Documentsin the system: Canvas core › documents
Part 3: How do agents show their work as pictures? › 3.4: What is a canvas document made of?

One Document Language: A Chart Grows Into a Film

DeepBuild has one document language. The same items take three profiles; a profile picks the sections and checks.

Profilethe same itemsq2q3titlenothing rewrittenprofile: chart+ values bound to their sourcesprofile: figure+ a card, an isometric cameraand an auditaudit ✓profile: film+ a timeline (shots, markers),a script and sound0:07 / 0:20
Nine profiles, a closed list: figure · film · scene · world · view · board · sheet · chart · cellsBuilt from the record: the Map, a board and a part’s inside are scenesExamples: the bug as boxes and arrows · a 54-second explainer · a rocket landing you can play · a bar race that stops on any yearOne word per idea: a shot is part of a film, a scene is a document; a clip is animation, a strip is media on a track
CHOICEOne language, not five formats: learned once, checked and patched one way, and a figure grows into a film.124 / 449
3.4.22Make › Documentsin the system: Canvas core › documents
Part 3: How do agents show their work as pictures? › 3.4: What is a canvas document made of?

From Words to a Film (1 of 4): One Sentence, One Recipe

The chart grew into a film; now a whole film from one sentence: the 20-second explainer of the receipt bug, 1 to 3.

1 · YOU, ON PR #57“Make a 20-second film: whydoes the cart say $18.01 andthe receipt $18.00?”2 · THE AGENT CALLSdeep_kinds: film recipes?3 · explain@1: ten film recipesdark_mathkeynote_uichart_storyinfographicevidence_boardwhiteboardstorytimekinetic_typepresenterlinear_mapeach is explain.<name>Recipeexplain.evidence_board@1: its inputscues{at, kind, text, sub, data}4 rowsstage2d | 3d2dlooka lookcleanpalettea palettethe look’sthe brief fills the rest by default:1920 × 1080 · 24 fps · captions on · narration onlength: 20 s, from your ask (the default is 30 to 60 s)

explain@1

Ten film recipes. Each turns a short cue list into shots, items, camera moves and sound cues, at check.

under 20 ms, the largest

Cue

One row of the film: when, which verb (write, fade_in, indicate), which words, which data.

{at: 1.2 s, kind: fade_in, …}

Grammar as checks

One entrance at a time, text still once landed, exits faster than entrances, a section at most 8 s. A cue that breaks one is refused, by name.

refused, naming the rule

Film brief

The plan fixed before work: goal, moments, reading holds, cue list. It becomes the checks; the working agent can’t change it.

a definition of done
A FILM IS A DOCUMENT TOOThe same envelope and items as the Q3 chart, plus a timeline, a script and sound. One recipe writes most of it.125 / 449
3.4.23Make › Documentsin the system: Canvas core › documents
Part 3: How do agents show their work as pictures? › 3.4: What is a canvas document made of?

From Words to a Film (2 of 4): Each Line, and What It Shows

Left: the film’s document. Right: its frame at 0:07; each numbered line leads to the part of the picture it makes.

receipt-film.json · what the agent writesvalues illustrativeprofile: film · look: clean · 1920 × 1080 · 24 fpsspan: 20 s · packs: [explain@1]look: cleanWhy the receipt says $18.00Cart$18.01step 2 of 3round()Receipt$18.00The cart says $18.01, the receipt $18.00.s1 holds2 push0:07 / 0:201boardexplain.evidence_board@1 · stage: 2d12c1cue · 0 s · write "Why the receipt says {receipt}"23c2cue · 1.2 s · fade_in "Cart {cart}"34cartbound value · run: receipt-test → $18.0145c3cue · 2.2 s · indicate "round()"56c4cue · 3.7 s · fade_in "Receipt {receipt}"67receiptbound value · run: receipt-test → $18.0078l1narration "The cart says {cart}, …"89shotss1 hold 0–9 s · s2 push 9–20 s9then: deep_show(film) → issues, audit, snapshots
Every number is bound, not typed. {cart} and {receipt} are filled from the test run in the record, in the title, the boxes and the narration alike; a rerun that changes them changes every place at once.
NINE LINESThe recipe, four cues, two bound values, one narration line and two shots: a whole 20-second film, all data.126 / 449
3.4.24Make › Documentsin the system: Canvas core › documents
Part 3: How do agents show their work as pictures? › 3.4: What is a canvas document made of?

From Words to a Film (3 of 4): Three Checks Before It Plays

Three checks the film runs before it plays. Left to right: where text sits, where numbers come from, how long text holds.

film.layoutboxes and strokes, never pixelshonest_numbersevery number needs a sourcereading timelong enough to read, standing stilllook: cleanWhy the receipt says $18.00Cart$18.01step 2 of 3round()Receipt$18.00The cart says $18.01, the receipt $18.00.Glyph boxtwo texts share ≤ 5% of a box✓strokes stay ≥ 4 u from text✓no text past the frame’s edge✓$18.01run: receipt-test✓$18.00run: receipt-test✓“One cent goes missing.”no source✕a line the agent added; “one” is a number wordfix: compute itlost = cart − receipt → $0.01“$0.01 goes missing.” ✓ traces to the runstep 2 of 3round()“step 2 of 3”: 8 characters,spaces not counted1.5 s + 8 ÷ 15 a second = 2.0 s2 s4 s6 s8 s10 spulsingneeds 2.0 sstill 5.8 s ✓the clock starts once it stops movingcaptions: their own limit, ≤ 20 a second
All three read the document, not pixels, so they give the same answer on every Mac and run before anything shows. A failing one comes back as an issue with a fix, as the 30-second explainer later shows step by step.
CHECKED BEFORE YOU SEE ITLayout, numbers and reading time are measured, not judged by eye, so a miss is named and fixed with one patch.127 / 449
3.4.25Make › Documentsin the system: Canvas core › documents
Part 3: How do agents show their work as pictures? › 3.4: What is a canvas document made of?

From Words to a Film (4 of 4): One Clock, 480 Frames, One MP4

Top: the film’s tracks on one clock. Middle: the frames that clock asks for. Bottom: what happens to each frame.

0 s2 s4 s6 s8 s10 s12 s14 s16 s18 s20 sshotss1 holds2 pushcuesc1c2c3c4voicel1captionscap 1Clockt = 7 s → frame 7 × 24 = 168frames156157158159160161162163164165166167168169170171172173174175176177178179zoomed to 6.5–7.5 s: one frame every 1/24 s = 29,400,000 flicks · 20 s = 480 frames, each at its exact timeevaluatethe document at tdrawon the GPUhashBLAKE3, on the GPUhand overas a GPU surfaceencodeH.264, in hardwareMP4+ captions + sound

Virtual clock

Export draws frame k at exactly k ÷ 24 s, however fast the Mac is, so the file equals what you scrubbed.

frame 168 = 0:07.000

Stays on the GPU

Hashed where it’s drawn: 32 bytes come back, not the frame’s 8.3 MB. A held frame is drawn and hashed once.

BLAKE3, before encoding

All or nothing

A failure at any frame stops the export, names the frame, and leaves no half-written file.

no partial MP4

Receipt

Size, frame rate, duration, every frame’s hash, loudness and captions, kept with the file.

target: 2× real time or faster
ONE CLOCKShots, cues, voice and captions sit on one timeline, so every frame, and the file, is the document at its own time.128 / 449
3.4.26Make › Documentsin the system: Canvas core › documents
Part 3: How do agents show their work as pictures? › 3.4: What is a canvas document made of?

Changing a Film: Say It, Point at It, or Fine-Tune It

You change a film the way you made it: in words. Or point at one item, or fine-tune it by hand.

Nothing is prerendered. The film is a document: the app draws each frame live from it and the clock,and export draws the same frames again, offline, into the MP4. So any change is one edit to the document, then a fresh draw.1Say it“Warmer look, and orbit slower round the rocket”look: look.clean@1 → look.warm@1orbit.azimuth: 45° → 20°the agent sends patches; checks run again2Point at it (R2)click the receipt line, then say “hold it longer”items/receipt_linehold: 2.0 s → 3.0 sthe agent gets the item’s name, not a guess3Fine-tune it by hand (R6)drag a key on the timeline, or type a valueshot 2 · dolly end: 1.2 m → 0.9 mwritten as you, on your layereach gesture is one patch; the agent sees itpatch values illustrative · looks are look@major assets, and a pack can add new ones; camera moves are shots on camera@1

Style is data

A look is an asset the film names, so “warmer” swaps one line. The numbers and checks underneath stay the same.

The camera is data too

A camera move is a shot: it goes a set amount, then lands. Slower, closer or a different angle is one value.

Nothing is lost

Every change is a patch in the record, so it can be undone, and the agent sees what you changed by hand.

NEXTBefore going inside the canvas: the few words it uses in one sense only.129 / 449
3.4.27Make › Documentsin the system: Canvas core › documents
Part 3: How do agents show their work as pictures? › 3.4: What is a canvas document made of?

Words That Mean One Thing Here

One language for every picture needs one meaning per word. These pairs are the ones newcomers mix up most.

writer layer

One writer’s own layer of a document, and nothing else.

never: a graph’s rank, a collision group, a proof

clip · strip

A clip is animation that drives slots. A strip is media placed on a track.

never: a clip of video

mask · matte

A mask clips by shape, alpha or luma. A matte’s coverage comes from another item’s pixels, each frame.

shot · scene

A shot is a film segment with its camera move. A scene is a whole 2D or 3D document.

event · occurrence · moment

A line in the record; a baked contact, word or beat; a checked instant in a film.

step · stages

One physics, logic or match step. Stages is the control that steps through states.

a slider’s move per key is its increment

snapshot · checkpoint

A snapshot is a rendered image. A checkpoint is saved simulation state.

selection · named parts

What you selected, as session state. Named parts are a builder’s top, side and rim.

recipe · collection · group

Generates items; a set of items by list or rule; a container with a transform.

flick

The time unit, 1/705,600,000 s, kept as a whole number.

never: tick

Why it matters

Fields, issues and tool replies use these words exactly, so a code like not_your_layer means one thing.

Where the list lives

The canvas reference’s first table: about 170 words, each with what it means, what never to call it, and why.

When words collide

Where an outside tool uses a word differently, its meaning here wins inside DeepBuild’s documents.

WHYReferences use “layer” five different ways. Here a layer is one writer’s layer, and every other sense has its own word.130 / 449
3.5.1Make › Inside the canvasin the system: Canvas core › compositor
Part 3: How do agents show their work as pictures? › 3.5: How do many writers share one picture?

Inside the Canvas (1 of 2): Five Writers, One Compositor

Now the part that draws documents: the canvas core. Five kinds of writer send it data; it stacks them in order.

WriterAgentsdeep_show, patchesPlug-insviews, map layersThe app’s viewsthe line, Needs youYouthe editor panel (R6)The recordtimelines, the MapCanvas corethe only part that draws or touches the GPUCompositorAn account per writera quota on size, rate and GPU memoryOne revision in flightper document; the newest winsA ladder for the costly oneit slows only the writer that costs too muchrecordthe line, the Mapworkwhat you or agents editagentagents’ layers, outlinedplug-in overlayplug-ins on top of viewsshellwindow frame, promptscardthe question card, always lastBandbottom to top: the order they stack in

Compositor

What the canvas core is: the part that combines every writer’s layer into one picture, in a fixed order.

Band

A layer’s place in that order, set by what sort of writer it is, never by the writer.

Identity

A writer is known by its connection, never by what a message claims.

In a window

Nested in the app’s window: other apps can cover it, or capture it with permission.

WHY ONE COMPOSITORNo writer draws its own pixels, so one part can check every picture, replay it exactly and keep the card on top.131 / 449
3.5.2Make › Inside the canvasin the system: Canvas core › compositor
Part 3: How do agents show their work as pictures? › 3.5: How do many writers share one picture?

Inside the Canvas (2 of 2): Take In, Draw, Guard

The canvas core’s nine jobs, in three groups. Follow Claude’s Q3 patch; after the scores, a frame step by step.

TAKE INwhen a writer sends somethingAdmissionsize, rate, a quota per writer1Document checkon another thread; issues as data2Render-backissues and snapshots back to the writer3DRAWon every frame while the view movesEvaluate at tthe document at the frame’s time4Build dirty itemsonly what changed: here, q35Render workera thread that draws on the GPU6Compose by bandthe question card last7GUARDall the timeDegrade ladderslows only the costly writer8Input routerkeys go only to the focused panel9The windowshows the frame at vsync, the momentthe screen refreshes; still: draws nothingClaude’s Q3 patch: admitted and checked (1, 2), q3 alone rebuilt (5), composed under the card (7), shown at the next refresh. Claude hears back (3).
WHO SEES WHATTake in answers the writer; draw serves you; guard keeps one writer from hurting another or reaching the card.132 / 449
3.5.3Make › Inside the canvasin the system: Canvas core › compositor
Part 3: How do agents show their work as pictures? › 3.5: How do many writers share one picture?

Who Draws the Pixels: What We Compare, and Why

Before the scores on “Who Draws the Pixels”: each row is one column of the next slide’s table, and why it matters.

ColumnWhat it measuresWhy it matters
1Check before show can refuse a bad picture before you see ita miss returns as a fix
2Exact replay same frame every time for the same inputscrub equals export
3Card stays on top nothing can draw over the question cardyour yes must be yours
4Many writers agents, plug-ins and you share one viewthe Map has many layers
5Cost to build work to make itwe build the compositor
The options on the next slideEach writer draws its own pixelsA web view per writerA render server fed documents
NEXTEach option scored on these 5 columns, three diamonds for strong.133 / 449
3.5.4Make › Inside the canvasin the system: Canvas core › compositor
Part 3: How do agents show their work as pictures? › 3.5: How do many writers share one picture?

Who Draws the Pixels, Scored: One Trusted Compositor

Three ways a canvas can be shared by many writers, scored on the columns the previous slide explains.

OptionCheck before showExact replayCard stays on topMany writersCost to build
Each writer draws its own pixelslike a window systemDropped
A web view per writerHTML and JavaScriptDropped
A render server fed documentsone trusted compositorChosen
strong weak breaks a hard rulescores: our reading of the gains and costs recorded in the design
COST WE ACCEPTEDEach new kind of picture needs a new kind or built-in canvas code, never a plug-in’s own drawing code.134 / 449
3.6.1Make › A framein the system: Canvas core › compositor › one frame
Part 3: How do agents show their work as pictures? › 3.6: What happens in one frame, and how fast?

A Frame, and the Budget for Drawing One

Back to frames (slide 101), now with deadlines. At 120 Hz: pictures, ticks, and the canvas core’s share.

Frameone still pictureVsyncthe tick when the screentakes the next pictureFrame budgethow much of one frameone job may useframe 10 msframe 28.33 msframe 316.67 msframe 425.00 msframe 533.33 mscanvas: under 2 mseverything else the app does: your typing, scrolling, the session listthe UI thread, during one 8.33 ms frame

Frame

One still picture, as in the rendering primer. Here each one gets a deadline.

120 a second at 120 Hz

Vsync

The tick at which the display takes the next frame. A frame not ready by then waits a whole tick: a stutter.

every 8.33 ms at 120 Hz

Frame budget

How much of one frame a job may spend. The canvas gets a small slice so the rest of the app stays smooth.

canvas: under 2 ms of 8.33

UI thread

The one thread that takes your clicks and keys and lays out the app. If it waits, the whole app freezes.

never waits for the GPU
THE RULECanvas work on the UI thread stays under 2 ms of each 8.33 ms frame and never waits for the GPU.135 / 449
3.6.2Make › A framein the system: Canvas core › compositor › one frame
Part 3: How do agents show their work as pictures? › 3.6: What happens in one frame, and how fast?

Damage: Redraw What Changed, and Nothing When Still

How the core draws nothing when still: ten ticks, q3 changes at tick 5. Top: redraw all. Bottom: only the change.

tick 1tick 2tick 3tick 4tick 5tick 6tick 7tick 8tick 9tick 10Redraw every tickthe simple wayRedraw what changedDeepBuildpatch: q3 48 → 52Damageticks 6 to 10: nothing changed,so nothing is drawndashed: the same picturestays up, not redrawn10full redraws1bar rebuilt

Damage

The part of a picture that changed since the last frame. Only that part needs new work.

q3: 48 → 52

Still view

Nothing changed, so nothing is drawn. The display link, the vsync timer, stops; the last picture stays up.

target: 0 frames, 0 wakeups

Why it matters

The canvas is open all day on the Mac your agents are using. Idle redraws would cost that machine.

every kind of view: 0 when still

How it is tracked

By item, then by layer, never by pixel. Step 7, a few slides on, shows how.

item, then layer
RULEEvery kind of canvas view draws nothing while still. Work happens only when something changed, and only for what changed.136 / 449
3.6.3Make › A framein the system: Canvas core › compositor › one frame
Part 3: How do agents show their work as pictures? › 3.6: What happens in one frame, and how fast?

One Frame in 13 Steps, Grouped Into Four Stages

The whole path one change takes through the canvas core: q3: 48 → 52, from Claude Code to your screen.

Claude Codea writerq3: 48 → 52A · Arrive1send a patch2admission3check4held as pendingwhenever a writer sendsB · Take and compute5latch6evaluate at t7build what changedeach frame with a changeC · Draw and show8record GPU commands9hand over by fence10stack in bands11presentworker, GPU, then the windowD · Report back12shown or discarded13render-backto every writerq2q352your screensteps 12 and 13 go back to the writer

Writer

Anyone who sends the canvas something to draw: an agent, a plug-in, the app’s own views, you, or the record.

Claude Code, writing the Q3 chart

Revision and patch

A revision is a whole new version of a document. A patch changes a few values in one.

patch: items/q3 = 52

Document session

One document in one place on screen, for one writer. In these steps, “session” means this.

Q3 chart · its panel · Claude Code

Compositor

The trusted part of DeepBuild’s app that draws every writer’s layer and stacks them in the window.

the canvas core
READ IT ASStage A runs whenever something arrives; stages B to D run only on frames where something changed.137 / 449
3.6.4Make › A framein the system: Canvas core › compositor › one frame
Part 3: How do agents show their work as pictures? › 3.6: What happens in one frame, and how fast?

Steps 1 and 2: Who Sent It, and Is It Too Much?

Two writers send to the canvas core at once: Claude Code one patch, a plug-in a flood. Read each row left to right.

WRITERWHAT IT SENDSSTEP 1 · WHO IS IT?STEP 2 · TOO MUCH?RESULTClaude Codean agentpatch: q3 → 52writer: "you"read from the connection:agent · Claude Codesize ✓ rate ✓within its own quotaon to the checknot slowed by the floodMap plug-ina plug-inread from the connection:plug-in · Maprate over its quotalimited → coalesced → frozenone coalesced update,or frozen with a badgeWriter connectionAdmissionQuota

Who is writing

Read from the connection: you, the app’s shell, the record, an agent or a plug-in. A message can’t name itself.

writer: "you" → ignored

Quota

Each writer has its own: documents, items, message size, patches per second, GPU memory. It can’t share or raise it.

one quota per writer

Admission

Size and rate are checked first. A flood is rate-limited, then coalesced, then frozen.

never delays another writer

A broken writer

A protocol error closes only that connection. Its documents freeze at their last good revision, with a badge.

the others keep drawing
WHYOne writer’s flood can’t slow another, and no message can claim to be you. Both follow from one connection per writer.138 / 449
3.6.5Make › A framein the system: Canvas core › compositor › one frame
Part 3: How do agents show their work as pictures? › 3.6: What happens in one frame, and how fast?

Steps 3 and 4: Checked to One Side, Then Held as Pending

Two revisions arrive. Top: a good patch passes and waits. Bottom: a bad one is refused. Right: the document session.

rev 8 · from Claude Codepatch q3: 48 → 52rev 9 · from Claude Codea whole revision with no q2off the UI thread≤ 50 ms per 10,000 itemsre-checks only changeditems and what needs themfair between writersCheck✓ PASSpendingrev 8Pendingwaits for the latch(step 5)✕ REFUSEDunintended_removalit dropped q2 without naming it;the issues go back to the writerDocument sessionthe Q3 chart, for Claude Codestatelivecurrentrev 7pendinglast goodrev 7—rev 8Last goodrev 9 refused: the screenkeeps showing rev 7

Check

Runs on another thread, so a big document can’t stall the app. Problems come back as data, with fixes.

issues, not a crash

Pending

A checked revision waiting for the next latch. One revision is in flight per document; the newest wins.

pending: rev 8

Last good

What stays on screen when a revision is refused. Nothing unchecked is ever shown.

rev 9 refused → rev 7 stays

Hidden

A hidden document session is neither evaluated nor called back: it costs nothing until it shows again.

state: hidden
THE RULEA revision becomes current only after its check passes. A refusal keeps the last good one on screen.139 / 449
3.6.6Make › A framein the system: Canvas core › compositor › one frame
Part 3: How do agents show their work as pictures? › 3.6: What happens in one frame, and how fast?

Step 5: The Latch Takes the Newest Revision Before Vsync

One frame, zoomed in. Three checked revisions reach the core at different times; the latch takes only the newest.

FRAME N, ON SCREENq2q348vsync: frame Nvsync: frame N+1rev 8 · q3 50rev 9 · q3 51rev 10 · q3 52skippedskippedtakenleadLatchpending:rev 8rev 9rev 10Newest winsFRAME N+1q2q352

Latch

The moment each session takes its newest checked revision: vsync minus a lead, which leaves time to draw.

latch = vsync − lead

Never mid-frame

A revision applies only at the latch, so one frame never mixes two revisions.

q3 is 48 or 52, never both

Newest wins

In-between revisions are skipped and their writers hear superseded_by. A coalesce key keeps only the latest value.

rev 8, 9 → superseded_by rev 10

Budget

A patch shows within 1 frame of the latch.

1 frame
WHY A LATCHWriters send whenever they like; the screen changes only at one known moment per frame, with whole revisions.140 / 449
3.6.7Make › A framein the system: Canvas core › compositor › one frame
Part 3: How do agents show their work as pictures? › 3.6: What happens in one frame, and how fast?

Step 6: Compute the Picture for the Moment It Will Show

Left: the only reasons the canvas draws at all. Right: a landing rocket, computed for the moment the frame is seen.

WHAT CAN WAKE A FRAMEFrame clockA writer’s new revisionA reading that changed: a live numberYour input: a click, a key, a dragThe GPU finishing a frameA document’s valid_until: the time it next changesA number going stale, or an age ticking onNone of these? The display link stops:0 frames and 0 wakeups.frame(t) = eval( document, t, inputs up to t, view )groundat the latchwhen this frame reaches the glassthe clock predicts it, and t is that momentPredicted presentation time

frame(t)

As on slide 118: the document at one time t, with inputs up to t and the view.

same t, same frame

Predicted presentation time

The picture is computed for when you will see it, so a moving thing lands where it should.

not “now”, but when it’s seen

Paced per display

Each window follows its own display. Inactive windows cap at 30 Hz, a hot Mac at 60, a hidden window at 0.

caps: 30 · 60 · 0 Hz

Hidden costs nothing

A hidden session is never evaluated. Wakeups are counted and reported, so idle work shows.

0 frames while hidden
FRAMES ON DEMANDThe clock arms a frame only for a reason on the left, then evaluates every visible session for the same predicted moment.141 / 449
3.6.8Make › A framein the system: Canvas core › compositor › one frame
Part 3: How do agents show their work as pictures? › 3.6: What happens in one frame, and how fast?

How the Frame Clock Decides: Arm, Latch, Draw, Sleep

Step 6’s clock across a few seconds of one window: the rocket landing beside the Q3 chart. Values illustrative.

rocket pieceQ3 chartthe windowvsync ticks, compressedpausedfalling: valid_until = the next framelanded, still: valid_until = nonestill: valid_until = 09:41:00, when its “as of” age ticksnext: 09:42rev 8, then stillasleep: 0 framesyou press playinputit landsvalid_until: nonethe age ticksa timera patch commitsfrom Claude Codeframes drawn: 33 + 1 + 1 of 82 vsyncs · illustrativeAT EACH ARMED VSYNC, THE CANVAS CORE’S FRAME CLOCK1 Latchat vsync minus the lead:newest checked revisions2 Evaluateevery visible session atthe predicted present time3 Compose onceevery layer, by band;then the window presents4 Ask each sessionwhen do you next change?it returns valid_until5 Arm or sleepearliest valid_until armsthe next; none: sleepProof: a fixture runs twice on a virtual display clock, evaluating only on armed frames, then on every vsync.At every vsync, the shown frame’s evaluated data must match byte for byte.
NO REASON, NO FRAMEEach frame says when it next changes; with nothing due, the window sleeps: 0 frames, 0 wakeups.142 / 449
3.6.9Make › A framein the system: Canvas core › compositor › one frame
Part 3: How do agents show their work as pictures? › 3.6: What happens in one frame, and how fast?

Step 7: A Change Marks Only the Kinds of Thing It Touched

A change is marked with the class of thing it touched, its dirty class (yellow dot). Right: the work that follows.

Dirty classseven kinds of changeA CHANGE TO THE CHARTWHAT RUNS AGAINtransformgeometryshadingpresencetexta readingtimeMove the titleUploads one 32–64 byte entry. No shape is rebuilt.Round the corners of bar q3Rebuilds that bar and records its GPU commands again.Recolor bar q2Rewrites one buffer; keeps last frame’s commands.Hide bar q1Records that batch’s GPU commands again.Rename the title to RevenueShapes only the title’s text again.A new sales.q3 reading arrivesAlways reruns whatever reads that reading.The film moves on one frameOnly steps that read the time run again.

Epoch

A counter per item and per kind of change. Each step remembers the count it last ran at and reruns only if it moved.

nothing is cleared per frame

By item, then by layer

A changed item rebuilds only itself. An unchanged layer re-composites from its cache, kept after 3 still frames.

≤ 3 new layer caches per frame

Never by pixel

The app redraws the whole window on every present, and a moving camera changes every pixel anyway.

pixels: no saving to find

What it costs

CPU time grows with what changed, not with the size of the picture.

upload 32–64 B per changed item
WHY EPOCHSCounters are kept, never cleared, so a hidden session or a look at an old revision still knows exactly what changed since.143 / 449
3.6.10Make › A framein the system: Canvas core › compositor › one frame
Part 3: How do agents show their work as pictures? › 3.6: What happens in one frame, and how fast?

Content Keys: The Same Inputs Always Reuse One Result

Two edit paths, one chart: epochs differ (left), the key doesn’t (middle), so cached work is reused (right).

PATH A · ONE PATCHPATH B · TWO PATCHESrev 7 · q3 48q3 52epoch 8 (example)rev 7 · q3 48q3 60q3 52epoch 9 (example)Epochdiffers: 8 vs 9, though the chart is the samecontent key = hash@1 of• the step and its code’s version• its params• the content keys of what it reads• the view inputs it reads• the seedContent keyno epoch in the list✓ one key for both pathsthe cached bar is reusedWrong: an epoch in the key8 ≠ 9: two keys for one picture,so a clean rebuild couldn’t match

Epoch says when

A counter that changed means: run this step again. It never decides what the result is.

when to recompute

Key says what

A fingerprint of everything a step read. Same content, by any edit history, gives the same key.

what can be reused

What a read adds

An array a step wrote enters by its writer’s key and step; only data from outside, such as a reading, by a hash of its values.

nothing read is left out

Proved, not assumed

Each canvas module’s fixtures prove a cached result equals a clean rebuild, and after a restart for what it keeps on disk.

cache = clean rebuild
RULENo counter or epoch ever goes into a content key, so a cached result always equals a clean rebuild.144 / 449
3.6.11Make › A framein the system: Canvas core › compositor › one frame
Part 3: How do agents show their work as pictures? › 3.6: What happens in one frame, and how fast?

Reuse or Rebuild: Each Step Asks Two Questions

The last slide’s rule as a decision every step makes. Three moments of the Q3 chart go through it.

a step, in aframe that changed1 · Did anything it readschange since it last ran?its reads’ epochs vs its last_runyes2 · Compute its keyhash@1 of all it read:params, keys, view, seedno epoch in it3 · Same key as theresult it holds, or ashared one?yesreuse itnorun it, keep by keynokeep its result: no key, no workTHE Q3 CHART, THREE CASESepochs and keys illustrativeWHAT CHANGEDTHE STEP1 · EPOCHS2 · KEY3 · RESULTClaude Code: q3 48 → 52the title’s shapingtitle: no changenot computedkept, no workthe same patchq3’s bar buildq3: 9 > last_run 87c1e…held a03f…: rebuilt48 → 52 → 48 before one latchq3’s bar buildq3: moved twicea03f…same as held: kept

Epochs are cheap

A counter per item and kind of change, 4 B each. Comparing two costs nothing.

Keys are exact

Equal keys always give byte-identical results; fixtures change each read alone to prove it.

Kept by key

An item’s result; a layer after 3 still frames; pipelines and tables shared across documents.

On disk (R6)

Read after a restart only if its key, its build and its sha256 all match; else rebuilt.

WHEN, THEN WHATThe epoch only says a step must look again; the key alone decides whether its work is redone.145 / 449
3.6.12Make › A framein the system: Canvas core › compositor › one frame
Part 3: How do agents show their work as pictures? › 3.6: What happens in one frame, and how fast?

Steps 8 and 9: Drawn Off the UI Thread, Passed On by a Fence

Three lanes: the UI thread, a render worker (the core’s drawing thread) and the GPU. The window shows a slot.

UI threadRender workerGPUvsyncvsynclatchevaluate the GPU layer, then encodeEncodedraws into slot 3Fenceshow newestfree for the rest of the app; it never waits for the GPUSLOTS: 2 OR 3 IMAGESslot 1on screenslot 2readyslot 3renderingnone free? that frame isskipped, never waited for

GPU

A separate processor that colors millions of pixels at once. The CPU writes it a list of commands, which it runs later.

the 3D and effects layer

Encode

Writing that command list, on the render worker. An unchanged batch replays last frame’s list instead.

worker: ≤ 4 ms CPU, ≤ 2 ms GPU

Fence

A signal the GPU raises when it finishes. Nothing sits and waits; the next step starts when it sees the signal.

never a CPU wait

Slot

One of 2 or 3 images the GPU draws into. The window shows the newest ready one and holds it while it’s on screen.

free, rendering, ready, shown
WHYThe UI thread only latches and composes, so a heavy 3D frame can’t freeze the app. A late frame is skipped, not waited for.146 / 449
3.6.13Make › A framein the system: Canvas core › compositor › one frame
Part 3: How do agents show their work as pictures? › 3.6: What happens in one frame, and how fast?

Step 10: Layers Stack in Bands, the Question Card Last

Left: the compositor’s six bands, bottom to top. Right: the same layers composed in the window, the card last.

recordviews of the record: the line, the Mapworkthe document you work on: the chartagentClaude Code’s note, outlined with its nameplugin_overlaya plug-in’s overlay: a target lineshellthe app itself: frame, menus, toastscardthe question card: always lastBOTTOM TO TOP; THE CORE PICKSDeepBuildthe line: checkout-web · 3 sessionsq2q352Q3 salestargetClaude Codeq3: 52,up from 48NEEDS YOU · TASTEKeep the order totalabove the fold?KeepMove itBandQuestion card

Band from the writer

The core gives each layer its band from what sort of writer drew it. No layer picks its own.

agent → agent band

Clipped to its panel

Every layer is cut to its panel. An agent’s layer is outlined with its name, so you know who drew it.

outline: Claude Code

Clicks only where it draws

A layer catches input only where it visibly draws, never through its see-through pixels.

no invisible click traps

Nothing above the card

No layer can sit above the shell or the card. Each layer costs one cut and one composite.

about 0.02 ms per quad (rectangle)
WHY BANDSYour answer on the card must be yours: nothing an agent or plug-in draws can cover it or catch the click meant for it.147 / 449
3.6.14Make › A framein the system: Canvas core › compositor › one frame
Part 3: How do agents show their work as pictures? › 3.6: What happens in one frame, and how fast?

Steps 11 and 12: The Window Shows It, Each Writer Hears

The window shows frame 1042; the core tells each writer what happened. Each row: its message, and what it means.

The windowpresents at vsyncframe 1042(an example number)Presentation feedbackpresented · rev 8 · frame 1042 · zero_copyClaude Code, Q3 chartgets its credit back and sends its next patchdiscarded · rev 11Map plug-ina newer frame replaced it: never reported as shownno callback · its panel is hiddenCodex, via deep_showhears “not presented: hidden” within 2 sCredit

Presented

One message per frame that actually reached the screen, sent only while the writer is visible. About 40 bytes.

rev, frame, time, copied or not

Discarded

A frame that never reached the screen is reported as discarded. Nothing is reported as shown that wasn’t.

no false “shown”

Credit

A writer may hold one update in flight. It sends the next after its message, so it can’t run ahead of the screen.

credit: 0 or 1

The deep_show reply

An agent hears presented, or not presented with a reason (hidden, refused, timed out), within 2 s.

never blocked by a hidden panel
WHYAn agent learns whether you could actually have seen its picture, from the screen itself, never from its own guess.148 / 449
3.6.15Make › A framein the system: Canvas core › compositor › one frame
Part 3: How do agents show their work as pictures? › 3.6: What happens in one frame, and how fast?

Step 13: An Agent Sees What It Made, Never Your Screen

Two ways DeepBuild lets an agent see its work. Left: one document, rendered aside. Right: an app copy it drives.

Render-backwhat one document looks likeREQUESTdoc: the Q3 chart, rev 8t: 0 · size: 800 × 500include: issues, pixelsA headless canvas workersame core; works with the app closedrenders only a settled frameabout 4 ms at 1936 × 1584REPLYrev 8 · issues: nonesnapshot: by sha256 hash, kept as evidencevisible items: q2, q3, title, each with its boxIt can’t read other writers’ layers, the card,other apps or your screen.It never counts as proof.Replicaa whole copy of the app: deep_drive1launchfrom a fixture (a saved setup), on a virtual clock, ≤ 2 s2locateby role and name, or a canvas item3actclick, type, drag; each waits for a still target4wait_foruntil the app has settled5seea text tree, or a screenshot by hash6recordvideo at 30 fps, each action timedIts input is synthetic: no gesture serial (next slide), so it can’tanswer your asks. A screenshot proves nothing;only a run with assertions is a check.
LIMITSA replica is a separate app with its own hub copy: at most 2 per machine, under a lease, each ≤ 500 MB.149 / 449
3.6.16Make › A framein the system: Canvas core › compositor › one frame
Part 3: How do agents show their work as pictures? › 3.6: What happens in one frame, and how fast?

deep_show, End to End: Who Carries Each Step

Steps 1 to 13 from outside the canvas core: the programs between Claude Code and your screen, and the reply.

Claude Codethe agentdeep mcpMCP server, on stdiothe hubTypeScript; keeps the recordcanvas corein the app, Rust1 deep_show: the whole Q3 chart, q3 now 52, removes: []2 passes it on with this session’s credential3 writer: this session, from the connection, not the bytes4 the revision, on Claude Code’s writer connection5 admit: size and rate inside Claude Code’s own quota6 checked off the UI thread, kinds migrated first7 passed: layer file by its hash, then doc.patched8 latched at the next frame, drawn, presented9 the reply, back through the hub and deep mcp, within 2 sCommit pointthe reply Claude Code reads: presented · rev 8 · issues: [] · changed: [q3] · unchanged: [q2, title] · snapshot sha256 9be2… 800×500rev, hash and size illustrative
NEVER PUSHEDYou see the chart when you open its card. A hidden panel answers “not presented: hidden” in 2 s.150 / 449
3.6.17Make › A framein the system: Canvas core › compositor › one frame
Part 3: How do agents show their work as pictures? › 3.6: What happens in one frame, and how fast?

Only Your Input Moves Focus or Answers the Card

Beyond the 13 steps, the compositor guards input. Left: a real input’s serial unlocks focus. Right: the card arms.

Gesture serialyour clickon the trackpadinput routerhit-tests its own shapesfocused panelserial 311Only a fresh serial unlocks:focusa pop-outsoundthe clipboardraw inputpointer lockClaude Code“focus my panel”✕ refused: agents never hold a serialno focus, sound or clipboard of its ownArmingNEEDS YOU · AUTHORITYCodex wants to push to mainin api.Allow onceNoAllow onceNooptions startunarmed: a clickchanges nothing andsays to hold stillshownwindow moved: start over≈ 500 ms still: armedyour click answersVoice Control, Switch Control or a synthetic clickanswers only after Touch ID or your password.An agent’s computer use can’t pass that.
BUDGETSA hit test takes ≤ 0.1 ms per pointer move at 10,000 items, and a drag shows on screen within 2 frames.151 / 449
3.6.18Make › A framein the system: Canvas core › compositor › one frame
Part 3: How do agents show their work as pictures? › 3.6: What happens in one frame, and how fast?

Cost: Estimated Before It Shows, Metered While It Runs

The compositor guards cost too. Left: a 3D castle scene, costed before it shows. Right: the costly layer steps down.

Budget classestimated before it showsper item: ns per item, vertex, glyph, draw; 32–64 B per instanceper pixel: ns per pixel × render scale² × overdraw × lightsTHE CASTLE, ESTIMATED: ABOUT 10 MS OF GPU PER FRAME≈ 10 msfigure cap: 2 msshowpiece cap: 10 ms✕ AS A FIGURErefused, naming its top three costs✓ AS A SHOWPIECEfull screen, at half scale while movingCosts come from benchmarks on the reference Mac, so a refusal is the same on every machine.Degrade laddermetered while it runsfull qualityeffects offlevel of detail downrender scale down30 Hzfreezeplaceholderchartrocketdown after 30 slow frames,back up after 120 good onesnever touches numbers,status colors, the shellor the cardexports and checks run attheir class’s fixed quality

Budget class

Six: core view, data view, figure, work product, showpiece, export. A document may only tighten its caps.

figure: 2 ms GPU, 4 ms CPU

Meter

Measures each writer’s layer every frame, from GPU timestamps, over a 120-frame ring.

per writer, per layer

Degrade ladder

Steps down only the costly writer’s layer, and tells that writer why at every rung.

one writer never slows another
WHY CLASSESThe prototype’s castle took about 10 ms; one 2 ms rule for all would refuse it, so each class has a budget.152 / 449
3.6.19Make › A framein the system: Canvas core › compositor › one frame
Part 3: How do agents show their work as pictures? › 3.6: What happens in one frame, and how fast?

Four More Jobs: Recovery, Hit Tests, Panels, Windows

Besides drawing frames, the compositor keeps writers alive and apart. One job per box; the picture shows the idea.

frozen

Liveness and recovery

A writer that stops answering freezes with a badge. A crashing step freezes only its session, at its last good revision. A lost GPU is rebuilt from documents; after a crash, documents and asks survive.

ping every 2 s · frozen after 5 s

Spatial index

Each 2D view keeps a tree of item boxes, updated only where items changed. It answers what to draw and what you clicked. 3D clicks read an image of item IDs, so they land only where an item draws.

≤ 0.1 ms per move at 10,000 items
apppanelhostelement trees

Panel host

Panels that agents or plug-ins built run in a separate process and send trees of components, never pixels. They can’t reach the GPU, the network or a program, or draw over the card.

shipped panels: ≤ 4 ms per update
card follows you

Window placement

Only the app places windows, and a pop-out needs your input’s serial. Each window follows its own display; the question card opens on the display you last touched.

a pop-out in under 300 ms
ONE OWNERScreen, input, windows and recovery all belong to the compositor, so no writer can take any of them over.153 / 449
3.7.1Make › Computing a framein the system: Canvas core › evaluation
Part 3: How do agents show their work as pictures? › 3.7: Which way of computing a frame, and why?

Three Ways to Compute a Frame, and the One We Chose

Step 6 computed a frame at t. Three ways to do that, scored on what the canvas core must guarantee; yellow wins.

Redraw everythingevery frame, from scratchEdit a scene in placea scene graph you changePure evaluationplus keyed cacheswork at every tick← changed in placeframe = f(document, t)Cost when stillwork when nothing movesdraws at every tickdraws only what changedsleeps until valid_untilSeek = playjumping to t equals playing to talways computed fresha jump skips the edits betweenthe frame depends only on tCache is correcta cached result equals a rebuildnothing cached to go staleold state can lingerkeys from what was readCost of an editwork after one small changerebuilds everythingchange one nodereruns what read the changeOutcomeDROPPEDDROPPEDCHOSEN
COST WE ACCEPTEDEvery step declares what it reads and keeps no state between frames unless declared (two slides on).154 / 449
3.7.2Make › Computing a framein the system: Canvas core › evaluation
Part 3: How do agents show their work as pictures? › 3.7: Which way of computing a frame, and why?

The Fixed Order of One Evaluation

Top: the core’s 11 phases per frame, the same path as steps 5 to 13. Below: one evaluation (step 6), in order.

THE 11 FRAME PHASES: A CLOSED LIST; CANVAS MODULES (BUILT-IN FEATURES) PLUG IN, NEVER ADD OR REORDER ONElatchtimeinputssimulateitemsviewssourcesextractrendercomposefeedbackONE EVALUATION, IN ORDERPHASETHE ROCKET-LANDING PIECE AT t = 0:07 (EXAMPLE)1Placements and time remapstimeWhich clips play now: the descent shot is on2Controls, read from the input trackinputsYour throttle, as recorded up to 0:073Physics, one step at a time up to tsimulate120 Hz steps up to 0:07; each first reads its inputs4Each item: animated values, position, shape, textitemsThe rocket takes its physics pose; its altitude label reads it5Masks and mattessourcesA matte shapes the exhaust6Compositor: looks, tone map, transitions, statuscomposeThe flame is tone-mapped into screen colors; status colors go last7valid_until: when anything visible next changesreturnedFalling: the next frame. Landed and still: nothing until you act
WHY FIXEDPhysics reads controls; the rocket reads physics; the compositor reads the rocket. One order means one answer, on every run.155 / 449
3.7.3Make › Computing a framein the system: Canvas core › evaluation
Part 3: How do agents show their work as pictures? › 3.7: Which way of computing a frame, and why?

Three Rules That Keep a Frame a Pure Function of Time

Three rules the core enforces, or a frame would depend on its past. An array: one value per item, such as position.

Read setOne writer per arrayCarried staterocket posetfont tablealtitudelabelits ownarray✕ the clockGets only what it declared:nothing else is reachable.Its cache key and change testcome from that same list.No clock, no thread randomnumbers, no previous value.motionthe ownerphysicscontributes_toarray: transform✕ 2nd writerstartup refusedEach array has one owner.Others add through contributes_to;the owner applies them in afixed order. A second writerstops the app at startup, beforeany document is drawn.checkpoints along the timelinebake: kept by keytail: pre-rolledlive view only: frame history, rebuilt on a jumpOnly declared state outlives a frame:bakes, tails, checkpoints and thegame logic’s world pages, eachwith a key and a byte budget.Frame history is for display only:never checked, never exported.
SAME ON EVERY MACChecked math runs in f64 through one pinned libm; a lint refuses clocks, thread random numbers and SIMD floats.156 / 449
3.8.1Make › One clockin the system: Canvas core › evaluation › one clock
Part 3: How do agents show their work as pictures? › 3.8: How do picture, physics and sound stay in step?

Why One Clock: Picture, Physics and Sound Tick Differently

The core’s frames depend on t, so t must be exact. Top: three clocks over 0.1 s. Bottom: per-frame rounding drifts.

Picture30 frames a secondPhysics120 steps a secondSound48,000 samples a second4,800 samples in 0.1 s0 ms50 ms100 ms29.97 fps video with 48 kHz sound: 1,601.6 samples per frame, never a whole number.Round each frame alone (1,602)pictureDriftsound: 12,000 samples late= 0.25 s, after 30,000 framesCount in flicks: frame f owns thesamples from its start to the next one✓ 0 samples off, ever
WHY WHOLE NUMBERSA float can’t hold 1/30 s exactly, so errors pile up. Whole ticks (flicks, next) never drift.157 / 449
3.8.2Make › One clockin the system: Canvas core › evaluation › one clock
Part 3: How do agents show their work as pictures? › 3.8: How do picture, physics and sound stay in step?

The Flick: One Tick That Every Common Rate Divides

DeepBuild’s time unit. Left: the flick, and a time written in it. Right: flicks per frame or sample, by rate.

Flick1 flick= 1/705,600,000 of a secondStored as a whole number (i64): lasts about 414 years.Every common frame, sample and step rate divides it,so each frame, sample or step is a whole count.A DOCUMENT WRITES “195f” AT 30 FPS= 195 × 23,520,000= 4,586,400,000 flicks, exactlyRATEFLICKS PER FRAME OR SAMPLEValid rate24 fps29,400,000WHOLE23.976 fps (24000/1001)29,429,400WHOLE30 fps23,520,000WHOLE60 fps11,760,000WHOLE120 Hz physics step5,880,000WHOLE48 kHz sound14,700WHOLE44.1 kHz sound16,000WHOLE8 fps, drawings held on threes88,200,000WHOLE165 Hz display4,276,363.6…NOT WHOLE128 kHz sound5,512.5NOT WHOLENot whole: nothing is authored at that rate. A 165 Hz display samples thedocument and rounds to the nearest flick.
FILESExports write normal timescales (24000, 30000, 48000), since a 32-bit MP4 duration counted in flicks overflows after 6.09 s.158 / 449
3.8.3Make › One clockin the system: Canvas core › evaluation › one clock
Part 3: How do agents show their work as pictures? › 3.8: How do picture, physics and sound stay in step?

Seek Equals Play, and One Clock Leads at a Time

How the core keeps seek = play with physics: restore a checkpoint, then step. Bottom: which clock moves t.

SeekPlay0:000:010:020:030:040:050:060:070:080:090:10Checkpointevery 0.5 splay: every step from 0:00seek: restore the 0:06.5 checkpointthen 60 steps✓ the same framesame pixels, same samples, same hashSeek = playA seek only moves the playhead: your recorded inputs stay. A new input after seeking back forks the track there.WHICH CLOCK LEADSMaster clockSound is playingThe audio device leads. Each frame shows thesample you hear as it reaches the glass.SilentThe display leads, moved on by the time thatpassed, never capped: a cap would slow timedown.ExportA virtual clock pulls each frame and itsexact span of samples in lockstep.
LIVE ONLYEffects that blend in past frames, like TAA, are for the live view only; checks and exports never use them.159 / 449
3.8.4Make › One clockin the system: Canvas core › evaluation › one clock
Part 3: How do agents show their work as pictures? › 3.8: How do picture, physics and sound stay in step?

Inside a Seek: Restore the Whole World, Step, Compare

The last slide’s seek to 0:07, opened up: what a checkpoint holds, the 60 steps, and the test that proves it.

THE ROCKET PIECE’S CHECKPOINT RING: AN ENTRY EVERY 60 STEPS OF 120 HZ, 16 MIB AT MOST0601201802403003604204805406006607207808400:06.50:07not yetyou have played to 0:06.8; past 16 MiB, the spacing doubles to 120WHAT ENTRY 780 HOLDSstep: 780deep_hash: 0x5c1f… (64 bits)state: the physics backend’s whole world:  bodies, colliders, joints, soft bodies,  both collision phases, warm-start impulses✕ poses and velocities alonelose the contacts and warm starts, and driftYOU DRAG THE PLAYHEAD TO 0:07, STEP 840UI thread1 moves the playhead; your recorded inputs stayrender worker2 restores entry 780, the last at or before 840render worker3 steps 781 to 840: inputs up to each step’s time,then the channels physics reads, then the steprender worker4 then items, render, compose: the frame at 0:07THE TEST: A SEEK, THEN PLAY, EQUALS A STRAIGHT RUN, HASH BY STEPstraight runh781h782h783…h839h840seek from 780h781h782h783…h839h840✓ all 60 equalhashes illustrativeA newer seek winsit cancels the old one’s steps; checkpoints stay
LONGER THAN A FRAMEA long seek steps over several frames, its view marked stale meanwhile; exports and checks wait.160 / 449
3.9.1Make › Renderingin the system: Canvas core › GPU layer
Part 3: How do agents show their work as pictures? › 3.9: How does the GPU draw it?

Primer: Why a GPU? Two Million Pixels, One Small Job Each

The clock says which frame to draw. Six primers now show how a GPU draws it, starting with why a GPU at all.

One worker: one pixel after anothereach pixel waits for the one before it…16.7 ms ÷ 2,073,600 pixels = 8 ns a pixelone frame at 60 a second, done one pixel at a timeA GPU: one small program, many pixels at onceeach run reads only its own inputs, so none waitsthe same program, 2,073,600 runs a frameeach run: its own pixel in, its own color outGPU
2,073,600

pixels in one 1920 × 1080 frame

124,416,000

pixel runs a second at 60 frames a second

≈ 83 million

math operations a frame to light it once, at about 40 a pixel (an estimate)

≈ 10 ms

the castle: 3024 × 2180, 6.6 million pixels, on an M3 Pro, CPU and GPU together

What stays on the CPU. Working out the document at time t, physics and a piece’s logic: steps that depend on the step before and must replay the same on every machine. Shaders only draw.
WHY IT FITSDrawing is the same tiny job for every pixel, and no pixel needs another’s answer. That is exactly what a GPU is built for.161 / 449
3.9.2Make › Renderingin the system: Canvas core › GPU layer
Part 3: How do agents show their work as pictures? › 3.9: How does the GPU draw it?

Primer: How a 3D Model Becomes Pixels, in Five Steps

Follow the rocket from numbers to a picture, 1 to 5. The GPU repeats steps 3 to 5 for every frame it draws.

Pointscorners in 3D, in meters1a builder makes themfrom a few numbersTrianglesevery 3 points, a face2a rocket: a few hundred(illustrative)The camera projects3D points onto the screen3farther away, smallerand nearer the middlePixels coveredeach one runs the shader42,073,600 at 1080pone color eachDepththe nearest surface wins5each pixel keeps thedistance of what is in front(x, y, z)onetrianglescreenpadthis pixel:rocket 18.2 mpad 19.5 m→ rocket showsillustrative distances

Vertex

One corner point of a shape: where it is, which way the surface faces there, and where it reads its image.

position · normal · uv0

Triangle

Three vertices. Every 3D surface, curved ones too, is drawn as many flat triangles.

indices: 0 1 2, 2 1 3, …

Projection

The camera maps each 3D point to a screen point: farther things land smaller and nearer the middle.

the camera’s lens or flat view

Depth

A hidden image holding, per pixel, the distance of the nearest surface drawn so far. A farther one is dropped.

the depth target
WHO DOES WHATA builder makes the points and triangles once, from a few numbers; the GPU projects, covers and shades them every frame.162 / 449
3.9.3Make › Renderingin the system: Canvas core › GPU layer
Part 3: How do agents show their work as pictures? › 3.9: How does the GPU draw it?

Primer: Mesh, Material, Texture: Shape, Surface, Picture

One idea each, with a tiny picture. These three words come back on every 3D slide that follows.

Meshthe shape, as trianglesMaterialhow its surface takes lightTexturean image laid on the surfacea 32-sided cylinder:64 triangles around,plus its two capseach vertex keepsposition · normal · uv0(16 sides drawn here)roughness 0.1sharp highlightroughness 0.6soft highlightmetallic 1tinted reflectionsu →vthe imageuv0wrapped by uv0

Mesh

Vertices plus the list of triangles. A builder makes one from a few numbers; it is built once, uploaded once, 32 B a vertex, at most 262,144 vertices a build.

positions · normals · uv0 · indices

Material

Base color, metallic and roughness, plus glass, glow and more. Values sit in a buffer, so changing one never recompiles. studio@1 names about 40 measured presets.

from: brushed_aluminium

Texture

An image in GPU memory that a surface reads at its uv0. DeepBuild’s patterns (wood, stone, roof tiles) are computed, so a built scene needs no image files; a glTF model brings its own.

pattern: wood · maps: base_color
THREE WORDSThe mesh says where the surface is, the material how it takes light, a texture what is painted on it. The next primer adds the light.163 / 449
3.9.4Make › Renderingin the system: Canvas core › GPU layer
Part 3: How do agents show their work as pictures? › 3.9: How does the GPU draw it?

Primer: Light and Shadow: Facing the Sun, and What Blocks It

Two sums each lit pixel runs. Left: which way it faces the light. Right: whether something blocks it.

1 · How much light a point getsthe rocket’s body seen from above; the sun is to the rightl: toward the sun, the same for every pointABCmax(dot(n, l), 0)A 1.0fullB 0.5halfC −1.0 → 0darkFacing2 · Is the point in shadow? A shadow mapfirst draw distances from the sun, then compareShadow mapP: 15.0 m from the sun,map saw 12.0 m: shadowPQ: 15.0 = 15.0: litillustrative distances

Normal, n

Which way the surface faces at a point. A builder computes it with every vertex.

A faces the sun; C faces away

Light direction, l

From the point toward the light. A sun is so far away that l is the same everywhere.

dot(n, l): 1 facing, 0 edge-on

Shadow map

The scene drawn from the light, keeping only distances. A point farther than the map says has something in front of it.

one depth pass per map

In DeepBuild

Up to 32 lights shaded in a view; shadows from 1 sun (its map split near to far, up to 4 parts) and 2 spots. Soft shadows harden where things touch.

≤ 32 lit · 3 cast shadows
TWO QUESTIONS PER PIXELWhich way does it face the light, and is anything in between? Brightness and shadow answer them; the shader adds color.164 / 449
3.9.5Make › Renderingin the system: Canvas core › GPU layer
Part 3: How do agents show their work as pictures? › 3.9: How does the GPU draw it?

Primer: A Shader Is One Small Program, Run Once per Pixel

What the GPU runs for each frame: shaders, one small program per pixel. Follow pixels A, B and C through one.

One frame of the rocket piece84 pixels here; a 1080p frame has 2,073,600ABCPixelfor each pixel p, at time t:d = distance(p, flame)glow = 1 − smoothstep(0, 3, d)color = mix(sky, flame, glow)illustrative: a glow around the flameShaderpixeldglowcolorA0.50.93B2.00.26C5.00Outputthe GPU makes all 84 runs side by side,60 to 120 times a second

Shader

A small program the GPU runs once for every pixel, vertex or item. Each run sees only its own inputs.

one program, millions of runs

Inputs

What a run reads: its own position, plus values shared by the whole frame, such as the time.

p per pixel · t per frame

Output

What a run returns: here, one color for its own pixel.

A: 0.93 glow → flame yellow

In DeepBuild

Agents never send shader text. New GPU work comes as an operator, a graph the core checks and then turns into a shader.

operator → check → shader
WHY IT MATTERSEvery glow, blur and material is a shader. GPU operators, ahead: who may write one, and how it is checked.165 / 449
3.9.6Make › Renderingin the system: Canvas core › GPU layer
Part 3: How do agents show their work as pictures? › 3.9: How does the GPU draw it?

Primer: A Frame Is Drawn in Passes, Each Writing a Texture

A frame runs its shaders in passes. The rocket piece, pass by pass: each reads earlier images and writes a new one.

Shadowswrites: depth seen from the sunreads: the shapesSkywrites: colorreads: the sun’s angleGeometrywrites: color, depth, IDsreads: the shadow mapEffectswrites: colorreads: color, depthBloom, tone mapwrites: screen colorsreads: colorlanding burnText, statuswrites: the final framedrawn last, exactTextureRender passDrawn last

Texture

An image kept in GPU memory. A pass writes one, and later passes read it: color, depth, normals, object IDs.

color · depth · object_id

Render pass

One sweep of drawing into a texture, called its target. A frame runs its passes in a fixed order.

shadows → sky → geometry → …

Linear light

3D adds light up in plain physical values that can go far past white. Tone mapping turns them into screen colors.

shade linear, then tone-map

Drawn last

Status colors, text and overlays draw after every effect, unlit, so no effect or look can change them.

status colors after tone mapping
WHY PASSESEach pass does one job and hands on an image. That lets DeepBuild say exactly where new GPU work may plug in, and what it may read.166 / 449
3.9.7Make › Renderingin the system: Canvas core › GPU layer
Part 3: How do agents show their work as pictures? › 3.9: How does the GPU draw it?

Two Draw Paths in One Window: GPUI and Our GPU Renderer

Who runs those passes? The app’s window has two draw paths: GPUI for the app and flat marks, our renderer for 3D.

The window you seecheckoutapidocsq2q3pulled apartGPUIGPU layerGPUI’s paththe app’s chrome, panels and text,and flat 2D marks: rects, paths, glyphsdrawn by GPUI with Metal · R1the 3D view is left clearThe GPU layerour own renderer on wgpu: 3D scenes,effects, insets and GPU operatorsMetal on macOS · R2handed over as one GPU surface; GPUI shows it in placeHandoff

GPUI

The Rust UI toolkit the app is built on, through gpui-kit. It draws the app with Metal on macOS.

R1: the app and 2D marks

GPU layer

Our own renderer for what GPUI can’t draw. It draws into a GPU texture, never straight to the screen.

R2: 3D, effects, operators

wgpu

A Rust library that speaks each platform’s GPU interface: Metal, Vulkan, Direct3D 12 and WebGPU.

wgpu 30 on Metal

Handoff

Getting the GPU layer’s texture into GPUI’s window, ideally by sharing memory, not copying.

an IOSurface on macOS
WHY TWOGPUI draws the app well but has no way to run our own shaders. So the GPU layer draws what GPUI can’t, and GPUI shows the result in place.167 / 449
3.9.8Make › Renderingin the system: Canvas core › GPU layer
Part 3: How do agents show their work as pictures? › 3.9: How does the GPU draw it?

Which Path Draws a Layer: The Cheapest That Draws It Exactly

A writer layer stays with GPUI unless an item in it needs the GPU layer; then it all moves and pays a handoff.

the session lineDeepBuilda caption’s textone shaperQ3 bar chartClaudea video in a receiptevidencethe rocket landing, 3DCodexGPUI draws it exactlyrounded quads, borders, box shadows,paths cut into triangles on the CPU,glyph sprites, underlines, video,rect masks, two-stop gradients, opacityR1The GPU layer draws it3D scenes, effects, insets, operators,and any 2D layer with an item thatuses an operatorR2+ glow on q3+ glow: the whole chart layer moves to the GPU layer and pays one handoff, counted in its budgetVello GPU, R2, behind a spikeshape masks, group opacity, multi-stopgradients, if a second handoff is under 1 msGoldens: Vello CPU2D snapshots render on the CPU, so a GPU-onlyeffect in a 2D view is display only thereText: one shaper, bundled fontsparley + skrifa shape it; GPUI draws the glyphsfrom our atlas; never the system’s fontsDraw path

Writer layer

Each writer’s own layer in a document. A layer changes path whole, never item by item.

Claude’s chart layer

Vello

A Rust 2D vector renderer. Its CPU version draws reference snapshots; its GPU version may take masks in R2.

Vello CPU · Vello GPU

Golden

A stored reference frame that a check compares a new render against.

2D goldens: Vello CPU

Display only

Shown on screen, but never read by a check.

a GPU effect in a 2D golden
THE RULEGPUI keeps drawing everything it can. Moving a layer GPUI could draw onto the GPU must be explained in that layer’s cost report.168 / 449
3.9.9Make › Renderingin the system: Canvas core › GPU layer
Part 3: How do agents show their work as pictures? › 3.9: How does the GPU draw it?

The GPU Layer: What We Compare, and Why

Before the scores on “The GPU Layer”: each row is one column of the next slide’s table, and why it matters.

ColumnWhat it measuresWhy it matters
1Look of big engines lighting, materials, effectsshowpieces must look like top games
2Checkable output frames we can hash and comparechecks read the frames
3Fits the app window draws inside GPUI, zero copyone app, no second window
4Platforms Mac now; Linux, Windows, web laterevery part behind a seam
5Cost to build work for usa hobby project’s time
The options on the next slideEmbed a game engineRaw MetalVello onlyOur renderer on wgpu
NEXTEach option scored on these 5 columns, three diamonds for strong.169 / 449
3.9.10Make › Renderingin the system: Canvas core › GPU layer
Part 3: How do agents show their work as pictures? › 3.9: How does the GPU draw it?

The GPU Layer, Scored: Our Own Renderer on wgpu

Four ways to put 3D into the app, scored against what the canvas needs. Each row is one option.

OptionLook of big enginesCheckable outputFits the app windowPlatformsCost to build
Embed a game engineBevy or similarDropped
Raw MetalApple’s GPU interface, directlyDropped
Vello onlya 2D vector rendererDropped
Our renderer on wgpuport shaders, not enginesChosen
strong weak breaks a hard rulescores: our reading of the gains and costs recorded in the design
COST WE ACCEPTEDFar more work now than embedding an engine, which “costs far more” later. We port engines’ shaders, not engines.170 / 449
3.9.11Make › Renderingin the system: Canvas core › GPU layer
Part 3: How do agents show their work as pictures? › 3.9: How does the GPU draw it?

How the Handoff Works: Three Slots, Two Fences

The chosen renderer draws into a texture; GPUI’s window must show it. One rocket frame, slot by slot.

vsync nvsync n+1vsync n+2slot 1IOSurface, BGRAon screen: 1041heldfree1rendering 1044ready: 1044slot 2IOSurface, BGRAready: 1042on screen: 10424heldfreeslot 3IOSurface, BGRArendering 10432ready: 10433on screen: 1043on screenreadyrenderingheld until GPUI is donefreea fence: gpu_done or released1The render worker takes a free slot; wgpu draws the rocket into it.2The GPU finishes and raises gpu_done: the slot is ready. No thread waits.3At vsync the UI thread paints the newest ready slot via GPUI’s BGRA path.4The replaced slot is held until GPUI’s command buffer is done, then freed.feedback: presented · frame_seq 1043 · zero_copy. The altitude label, 2D and anchored to the rocket, draws from frame 1043’s data.

Same memory

wgpu renders into the IOSurface that GPUI draws from, so nothing is copied.

Premultiplied

GPUI blends one × source plus (1 − source alpha) × what is below; alpha is never divided out.

No free slot?

That frame is skipped, never waited for; the last one stays up.

A lost GPU

Every module’s GPU resources are rebuilt from documents and assets, by hash.

NEXTThe spike that timed this shared path against a copy through CPU memory.171 / 449
3.9.12Make › Renderingin the system: Canvas core › GPU layer
Part 3: How do agents show their work as pictures? › 3.9: How does the GPU draw it?

Handing Over the Picture: A Tenth of a Frame, Not Four Fifths

Two ways to hand the GPU layer’s picture to GPUI’s window, timed in a spike (a short test build): share or copy.

MS PER FRAME · M3 PRO · 1936×1584 · 3 RUNS OF 600 FRAMES · THE MAP’S 3D CITY · OCT 10wgpu draws intoan IOSurfaceGPUI’s windowshows it in placesame memoryZero copywgpu drawsa textureCPU memoryGPUI uploadsit againread backupload0123456789one 120 Hz frame: 8.33 ms0.7–0.9 msabout a tenth of a frame1.5draw3.6–3.8read back1.5–1.6upload6.6–6.8 ms: four fifths of a frame
Our GPUI change. GPUI’s paint_surface takes only 4:2:0 video frames with no alpha, so we added a BGRA path: 46 lines in its Metal renderer and a 7-line shader.
Same pixels. Both paths give pixel-identical frames, and a still frame is shown again without drawing. Copying stays the fallback, at 30 fps and half scale.
Bug found. core-video 0.5.2’s get_io_surface() released the IOSurface once too often, so the code takes the raw pointer.
NEXTGPU operators: with the picture handed over, how new GPU work, such as a glow, gets into the GPU layer.172 / 449
3.10.1Make › GPU operatorsin the system: Canvas core › GPU layer › operators
Part 3: How do agents show their work as pictures? › 3.10: How is new GPU work added safely?

A GPU Operator: New GPU Work, Written as Data

Where GPUI can’t draw, new GPU work comes as an operator. The rocket’s flame glow, as data: inputs, steps, an output.

the frame so farwhat the glow adds to itrocket.flame_glowkind: pass · chain: effectsinputsscenetexturethe frame so fartf32, secondsthe timeseedu32a fixed numberstrengthf32, 0..2a paramheatf32a channel over timeInputsteps, from a closed listsample(scene)luminancesmoothstepnoise(p, seed)mul × 3compose colorStepresolution: halffallback: lookcost: declareddeterminism: computedoutputcolorvec4: red, green,blue, coverageblend: addOutput

Operator

New GPU work as a graph: inputs, steps, outputs. The core checks it and turns it into a shader.

rocket.flame_glow

Input

The only way data gets in. Values live in a buffer, so moving strength from 1.0 to 1.4 never recompiles.

f32: a decimal · u32: a whole number

Step

One operation from the core’s fixed list, such as luminance or noise. No loops without a count, no code.

next: all six, built up

Output

What it hands back. A pass’s color is blended into the frame at its place; add only brightens.

vec4: four numbers
NOT CODENo shader text, no callbacks, no loop without a fixed count, nothing from an earlier frame: only named steps the core can check.173 / 449
3.10.2Make › GPU operatorsin the system: Canvas core › GPU layer › operators
Part 3: How do agents show their work as pictures? › 3.10: How is new GPU work added safely?

Building the Flame Glow (1 of 2): Read, Measure, Keep

The flame glow, built one step at a time. Each panel: the step, the drawer it comes from, the pixels after it.

1c = sample(scene, screen_uv)TexturesPQpixel Pbright yellowpixel Qdusk blueRead the frame’s color at this pixel.Every pixel runs this same line.2b = luminance(c)ColorPQpixel P0.96pixel Q0.30One number: how bright the pixel is,0 for black, 1 for white.3hot = smoothstep(0.75, 0.95, b)MathPQpixel P1.00pixel Q0.000 below 0.75, 1 above 0.95, a smoothramp between: only the flame stays.

Textures

Steps that read an image: sample at a place, load one exact pixel, a size.

sample · load · size

Color

Steps about color: brightness, a look’s named colors, blend modes, saturation.

luminance · role · blend

Math

The same list drivers use on the CPU, so a step means the same on both.

smoothstep · mix · sin · dot

Each run

Pixel P sits in the flame, Q in the sky. Every pixel runs the same steps on its own values.

values illustrative
ONE STEP AT A TIMEEach line is one named step from the list, and each picture is what the pixels hold after it. Three more steps follow.174 / 449
3.10.3Make › GPU operatorsin the system: Canvas core › GPU layer › operators
Part 3: How do agents show their work as pictures? › 3.10: How is new GPU work added safely?

Building the Flame Glow (2 of 2): Flicker, Scale, Color

Steps 4 to 6, then the output: the flicker, the strength, the color, and the frame with the glow added.

4n = noise(p, seed)SeededPQP: 0.46 · Q: 0.33A smooth random pattern. The sameseed gives the same pattern, always.5glow = hot · n · strength · heatArithmeticPQP: 0.69 · Q: 0.00Three mul steps: flicker inside theflame, scaled by two inputs.6color = compose(tint·glow, glow)ValuesPQP: orange · Q: nothingFour numbers out: red, green, blue,coverage. tint is a const.→blend: addOutputPQP: brighter · Q: unchangedAdded to the frame at its place,before tone mapping.

Seeded

Randomness from a hash of the seed and the place, never a stream, so every machine and every replay sees the same flicker.

hash · rand · noise · fbm

Arithmetic

add, sub, mul, div and the bit steps. Whole-number steps give the same bits on every GPU.

mul · add · and · shl

Values

Constants, the inputs, explicit conversions, and putting numbers together or apart.

const · input · compose

Where t comes in

p mixes the pixel’s place with the input t, the frame’s own time: a scrub to 0:07 flickers as playing does.

never a clock
SIX STEPS, SIX DRAWERSA real effect from named steps only. Next: what happens when an agent reaches for something not in the box.175 / 449
3.10.4Make › GPU operatorsin the system: Canvas core › GPU layer › operators
Part 3: How do agents show their work as pictures? › 3.10: How is new GPU work added safely?

What an Agent Can’t Write, and the Reason It Gets Back

Three lines an agent might reach for. Each is refused before the GPU sees it, with a code, a reason and a way that works.

repeat {until: glow < 0.1, …}✕operator_unboundeda repeat with no fixed count:might never end, so its cost can’t be computedthe fixrepeat {count: 8} + stop_if(glow < 0.1)wave = sin(clock())✕operator_unknown_op: clockno step reads a clock:a scrub to 0:07 would differ from playing to itthe fixsin(mul(t, 12)): t, the frame’s own timeold = last_frame(scene)✕operator_unknown_op: last_framenothing from an earlier frame:a frame would depend on how you got to itthe fixnone: only the live view keeps framesIssue
Left out of the list on purpose, so no one can write them
✕ shader text, or strings spliced into one
✕ JavaScript callbacks
✕ frame counters and time added up frame by frame
✕ anything read from the previous frame
✕ randomness from GPU math tricks or creation order
✕ subgroups: lanes of the GPU sharing values
✕ a whole scene rendered inside a graph
✕ lights, shadows, environment maps, tone mapping: the core’s own
✕ debug and inspector hooks
A CLOSED LISTLeaving these out is what lets the check promise an operator ends, costs what it says, and draws the same frame on a replay.176 / 449
3.10.5Make › GPU operatorsin the system: Canvas core › GPU layer › operators
Part 3: How do agents show their work as pictures? › 3.10: How is new GPU work added safely?

The Whole Toolbox: Every Step Has a Drawer

The op table as drawers. Yellow: the flame glow’s steps. “exact”: same bits on every GPU, at least for integers.

Valuesconst input convertcompose splitcomposeArithmetic, bitsadd sub mul div remand or xor shl shrmulCompare, selecteq ne lt le gt geselect · switch ≤ 8exactMaththe drivers’ list:floor sqrt mix sin …smoothstepSeededhash rand dithernoise cells fbm ≤ 8noiseGeometryposition normal uv0attribute columnexactViewcamera screen_uv pixeldepth object_idscreen_uvTime and seedt · phase(period)seedexactTexturessample sample_gradload size triplanarsampleStorageread write storeatomic_add … barrierexactRepeatrepeat {count ≤ 64}stop_if; the only loopColorluminance roleblend(mode) adjustluminanceSpline, warpspline ≤ 16 pointshomographyDerivativesddx ddy fwidth(material, pass)Discarddiscard_if(material)exactUseuse(name@major)inlined, ≤ 4 deepStructural (R6)iterate · sort_by_keyscan compactexactNot in the boxsee the slide before:clocks, last frame, text …
256

steps a graph at most; 2,048 once every use is inlined

64

a repeat’s count at most; nested ≤ 2, ≤ 256 trips a run

16

texture reads a pixel (32 in showpiece and export); a read is a fetch

8

textures, 4 storage outputs, 1,048,576 elements a dispatch

WHY CLOSEDEach step comes with a cost weight, an exactness flag and the kinds it may run in, so a graph’s cost, end and exactness are computed.177 / 449
3.10.6Make › GPU operatorsin the system: Canvas core › GPU layer › operators
Part 3: How do agents show their work as pictures? › 3.10: How is new GPU work added safely?

Three Kinds of Operator: a Surface, a Picture, an Array

Same steps, three places to use them. Left: on a surface. Middle: on the whole frame. Right: on lists of numbers.

Material operatorshades one surfacePass operatorworks on a whole pictureCompute operatorfills arrays, draws nothingplugs in at: geometryattached by: material.opwrites: base color,roughness, emission,normal, and a vertexoffset with a caprocket.cel: three flat bandsplugs ina chain: effects or finishwritescolor and coverageblendsover · add · multiply · screenrocket.flame_glow; a grade, a ripplesparks: each one’s placefrom its age and indexpos[0], pos[1], … for later stepswrites storage, textures or instance columnssparks at their age; a sort

Material

Runs for the pixels of one surface, as the surface is shaded. Its vertex offset is capped, so the shape checks still read the true shape.

material.op: rocket.cel

Pass

Runs once for every pixel of a whole image, at its place in a chain, and blends its color over what is there.

chain: effects | finish

Compute

Runs once per element, up to 1,048,576 a dispatch, and fills arrays that later steps or an instancer read.

workgroups of 64 to 256
THREE SHAPES OF WORKEvery operator is one of these three. Its kind fixes where it may run, what it may read and what it may write.178 / 449
3.10.7Make › GPU operatorsin the system: Canvas core › GPU layer › operators
Part 3: How do agents show their work as pictures? › 3.10: How is new GPU work added safely?

A Material Operator, by Example: Toon Bands From the Sun

An agent wants a cel-shaded rocket. Left: the result. Middle: the steps for one pixel. Right: what stays the core’s job.

core.light@1smooth: the defaultrocket.celthree flat bandsthe same sun, two light responsesone pixel, once per lamp (illustrative)ndl = dot(n, l)0.62faces the sun at an anglelit = max(ndl, 0)0.62never below zerosh = mul(lit, shadow)0.62shadow 1.0: nothing in the wayx3 = floor(mul(sh, 3))10.62 × 3 = 1.86, down to 1band = div(x3, 3)0.33so 0, 0.33, 0.67 or 1out = mul(radiance, band)×0.33the light it returnsStepthe light loop stays the core’spicks the lights (≤ 32) and their shadowscalls rocket.cel’s light once per lightsums them, adds ambient and glowit never sees a light the policy cut,casts no shadow, adds no light

Light response

A material’s own `light` step, written with public steps. The core calls it for each light that shades the pixel.

default: core.light@1

ALU

One basic math operation on the GPU, such as an add or a multiply. The usual way to count a shader’s cost.

cel ≈ 12 a light · default ≈ 40

What it can’t do

See a light the policy cut, cast a shadow, change a light’s count or brightness. Its pixels pass the status guard.

estimates, until measured

Finals

Path-traced finals refuse a part with a light response, naming the part, since rays shade it differently.

R6, with composed graphs
WHY THIS SHAPEToon, cel and hatched looks use the scene’s own lights through public steps, so their cost and exactness stay computed.179 / 449
3.10.8Make › GPU operatorsin the system: Canvas core › GPU layer › operators
Part 3: How do agents show their work as pictures? › 3.10: How is new GPU work added safely?

Where Operators Run: Fixed Places in One Frame

One frame, left to right, the same order every time. Each kind of operator plugs in only at its own places.

linear light: plain amounts of light that add up and can pass whitedisplay colors: what the screen shows1compute2shadows3sky4geometry+ materials5effectschain6bloom7tonemapping8finishchain9statusguard10upscale orhistory11status colors,overlaysComputesparksMaterialrocket.celPassrocket.flame_glowPassgrain, vignetteno operator runs here:the core has the last word

No free edges

A pass reads only what was drawn earlier in this order, and says what it reads and writes.

declared reads and writes

Still costs nothing

A compute operator whose inputs didn’t change keeps its last output, so a still view does no work.

kept by content key

Fusion (R6)

Neighbouring pixel-by-pixel passes in one chain compile into one, so grain, vignette, tint and grade cost one pass; warm-up compiles each variant’s chain.

saves k − 1 passes

Last word

After the status guard come only the upscale or history, then status colors and overlays.

nothing paints over status
WHY FIXEDA place, an order and declared reads and writes are all an operator gets, so the core can order, cache and cost every pass.180 / 449
3.10.9Make › GPU operatorsin the system: Canvas core › GPU layer › operators
Part 3: How do agents show their work as pictures? › 3.10: How is new GPU work added safely?

WGSL, in Plain Words: One Glow, Written Two Ways

First what WGSL is. Then the shader primer’s glow written in it, beside the same glow as steps from the list.

WGSL, in plain wordsThe small language that GPUprograms, shaders, are writtenin for WebGPU.wgpu, the GPU library DeepBuilddraws with, reads WGSL and runsit on Metal, Vulkan or Direct3D 12.In DeepBuild only the core writesthe WGSL a GPU runs.the glow from the shader primer, in WGSL1fn pass(i: In) -> Out {2 let d = distance(i.p, i.flame);3 let glow = 1.0 - smoothstep(0.0, 3.0, d);4 return Out(vec4(i.tint * glow, glow));5}WGSLthe same glow as public stepsdistanceMathconst 1.0ValuessmoothstepMathsubArithmeticmulArithmeticcomposeValues

Shader language

A small programming language for code that runs on the GPU, once per pixel or vertex. WGSL is WebGPU’s.

fn, let, return, vec4

Line → steps

Each WGSL line maps onto steps from the public list: distance, smoothstep, sub, mul, compose.

same meaning, two spellings

Who writes it

Agents and packs write steps, or WGSL the core turns into steps. The GPU runs only WGSL the core wrote from checked steps.

never the agent’s text
ONE GLOW, TWO SPELLINGSWGSL is the usual way to write GPU programs. DeepBuild reads it as steps; the GPU never runs it as written.181 / 449
3.10.10Make › GPU operatorsin the system: Canvas core › GPU layer › operators
Part 3: How do agents show their work as pictures? › 3.10: How is new GPU work added safely?

Checked, Then Compiled: Nine Gates Before the GPU

Two operators meet nine checks. One gets a cached pipeline; one is stopped, with the reason named.

the check, in order1schemafields there2closed opsevery step listed3typesright kinds of value4DAGsteps feed forward5fixed repeatsevery count known6kind rulessteps fit the kind7exactnessclass computed8limitssteps, reads9costvs declaredrocket.flame_glow✓a home-made glow✕operator_unbounded: a repeat with no countthen compiled, off the UI threadthe core writes WGSLfrom the checked stepsnaga validates itno optional featureswgpu adds runtime checksbounds, loops, divisionpipeline, cachedby the graph’s hash

naga

The checker inside wgpu. It reads every program the core writes and proves it well formed, with no optional GPU features turned on.

no 64-bit floats, no subgroups

Runtime checks

wgpu’s guards in the compiled program: an index out of range is clamped, no loop runs forever, no divide by zero crashes.

on by default

Pipeline

The compiled program plus its settings, ready to draw. Kept by the graph’s hash, so equal graphs share one.

≤ 32 a document session

Warm-up

At check, every variant an item can reach in the film is compiled, so turning one on mid-film compiles nothing.

no stall on first use
WHILE IT COMPILES1 to a few ms a module, off the UI thread (estimate). Until then the item draws its fallback; the frame says settling.182 / 449
3.10.11Make › GPU operatorsin the system: Canvas core › GPU layer › operators
Part 3: How do agents show their work as pictures? › 3.10: How is new GPU work added safely?

An Agent’s WGSL: Each Line Becomes Steps, or Is Refused

An agent writes a ripple in WGSL. naga’s parser reads it, and each line becomes public steps or is refused by its number.

an agent’s ripple, in WGSL (illustrative)what the check makes of each line1fn pass(i: In) -> Out {the entry for a pass2 var a = 0.0;a value in the graph3 for (var k = 0; k < 4; k++) {repeat {count: 4}4 a += sin(i.d * 8.0 - i.t + f32(k));sin · mul · sub · add · convert5 }6 if (i.d > 1.0) { a = 0.0; }select7 while (a > 2.0) { a -= 1.0; }✕ operator_source {line: 7, construct: while}8 return Out(vec4(a, a, a, 1.0));compose9}f32(k): turn the whole number k into a decimalthe agent fixes line 7 and sends againLowered

Lowered

A for loop with a fixed count (or an input with max ≤ 64) becomes repeat; if and else become select; switch up to 8 cases; calls are inlined.

discard → discard_if

Refused, by line

loop and while, its own globals or bindings, recursion, pointers past its locals, any builtin the list lacks. Nothing is guessed.

operator_source {line, construct}

Keyed by its steps

WGSL and a hand-written graph that lower alike share one pipeline. deep_query shows the steps beside the source, line by line.

the text never reaches the GPU
WHY LOWER ITOnly the core writes the WGSL a GPU runs, so cost, ending and exactness stay computed, and no plug-in ever ships a shader.183 / 449
3.10.12Make › GPU operatorsin the system: Canvas core › GPU layer › operators
Part 3: How do agents show their work as pictures? › 3.10: How is new GPU work added safely?

How a Checked Operator Becomes a Pipeline

Steps written by hand or lowered from WGSL, once past the nine gates. The flame glow, from first show to reuse.

THE FLAME GLOW, FIRST SHOWN · ALL IN THE CANVAS CORE, OFF THE UI THREAD1 Keyhash of the stepsand args, op tableand core versions,kind, targets, MSAA→ 9c41…, 128 bits2 Look upthe session’s cache:wgsl, naga module,pipeline, by keymiss: first show3 Emitthe core writesthe WGSL; bindgroups fixed: frame,inputs, storage@group 0 · 1 · 24 Validatenaga, every flag,no optionalcapabilitiesno f64, no subgroups5 Builda wgpu pipelinewith runtime checks:bounds, loops,divisionon by default6 Storeunder its key;the session holds32 at mostnext show: a hitUntil step 6 is done, the glow’s item draws its fallback, the look’s, and the frame says settling: about 1 to a few ms a module (estimate).A LATER CHANGEITS KEYWHAT COMPILESstrength 1.0 → 1.4, an inputsame: inputs are buffer valuesnothing; one buffer writesmoothstep’s 0.75 → 0.80, a literalnew: it is part of the stepsonce, off the UI threada second film uses the same glowthe samenothing: one shared pipelinea control turns the glow on mid-filmknown at check: warm-upnothing on that first framekey and timings illustrative
HELD TO THE GRAPHTests run 10,000 random graphs on the GPU and an f64 interpreter; each output lands within its bound.184 / 449
3.10.13Make › GPU operatorsin the system: Canvas core › GPU layer › operators
Part 3: How do agents show their work as pictures? › 3.10: How is new GPU work added safely?

Who Brings Operators: the App, Packs and Agents

Three sources, one check, one way in. Left: shipped with the app. Middle: packs. Right: agents writing their own.

Shipped with the appR2, with the GPU layerreviewed and benchmarked with the app;may use internal steps and reviewed WGSLeffects: glow, ink, dof, flare, wave_field,plume, arc, airflow, sparks, blur, particlesthe look’s passes: bloom, tone map, finishesthe core’s: shadow, sky, object ID, pixel hashPacksR6, once costs are calibratedfx@1, first party: about 70 named operators:levels, curves, twirl, ripple, corner_pin,turbulent_displace, luma_key …three new steps: spline, homography, HSLstep functions: use(pack.name@major)pinned and signed; never a shipped nameAgentsR6, composed graphscompose graphs from the public steps,or write the WGSL subsetcost declared, estimated, then metereda good graph joins the shipped libraryonly by review with the app, neverthrough a documentone operator check for every pack and agent graph: nine gates, then compileda document uses any of them the same way, by name and params:op: fx.levels@1 · op: rocket.flame_glow · op: blur
Internal steps are the reviewed extras only shipped operators may use, such as mip chains and multi-pass chains. A composed graph never gets them, a pack can’t take a shipped name, and no operator loads from the network.
ONE GATENo plug-in ever brings shader text. Whoever writes an operator, it reaches a document only by name, after the same check.185 / 449
3.10.14Make › GPU operatorsin the system: Canvas core › GPU layer › operators
Part 3: How do agents show their work as pictures? › 3.10: How is new GPU work added safely?

Group Passes: Effects on One Part of a Picture

The Q3 chart again. One group wraps the Q3 bar and its label, runs two passes on them alone, then blends back in.

in the Q3 chart’s document (illustrative)group: q3_highlight children: [bar q3, label q3] passes: - op: fx.levels@1 - op: blur blend: screenGroup passes48its own target: only itschildren48after fx.levels@148after blur4448blended back with screenitems drawn after the group stay untouched

Own target

The group’s children draw into an image of their own first, so the passes see only them.

children: [bar q3, label q3]

Up to 8 passes

Run in order on that image: shipped, pack or agent operators, by name.

fx.levels@1, then blur

28 blend modes

Then the result blends in at the group’s place in the draw order: over, screen, multiply and the rest.

blend: screen

Backdrop

Run the passes on what is beneath the group instead, for a frosted panel or a blurred background.

a frosted panel
LOCAL EFFECTSOne bar can glow without touching the rest of the chart, and the same named operators work here as on a whole frame.186 / 449
3.10.15Make › GPU operatorsin the system: Canvas core › GPU layer › operators
Part 3: How do agents show their work as pictures? › 3.10: How is new GPU work added safely?

Same Pixels on Every Mac? Three Determinism Classes

One operator, two Macs. Its determinism class says how alike its pixels come out, and where they may count.

CLASSEXAMPLEON AN M3ON AN M1MAY FEEDExactthe pixel hash:whole-number steps only9f3c…e19f3c…e1=any check, on any Mac,through a readbackSame machinea blur:decimal (f32) steps41aa…07c2d9…5b≠checks marked “machines: same”;elsewhere INCONCLUSIVELive onlyframe history, HDR,the live upscalescreen onlyscreen onlynothing: exports and checksdraw its fallback insteadhashes illustrative · f32: a number with a decimal point, 32 bits · readback: copying a GPU result to the CPU, a frame late

Why decimals differ

WGSL lets a GPU flush tiny numbers to zero, ignore the sign of zero and assume no NaN or infinity; Metal’s fast default math adds more.

same program, other bits

Exact allows

Whole-number and true/false steps, select on them, bit casts, whole-number loads, order-free atomics whose result isn’t read. No f32 step.

integers travel as bits

Fingerprint

A same-machine result carries the GPU and core count, OS build, wgpu and naga versions. A golden hash from another reads INCONCLUSIVE.

golden: a hash kept to compare

Computed, not claimed

The check computes each operator’s class from its steps. It may declare a weaker class, never a stronger one.

determinism: computed
WHAT IT MAY FEEDThe class decides where an operator’s pixels may count: in any check, in this Mac’s checks only, or on screen only.187 / 449
3.10.16Make › GPU operatorsin the system: Canvas core › GPU layer › operators
Part 3: How do agents show their work as pictures? › 3.10: How is new GPU work added safely?

The Status Guard: An Effect Can’t Paint a Verdict Color

The checkout film from the explainer. Left: a glow too close to FAIL’s red. Middle: the guard’s test. Right: the order.

checkout film · 0:07 / 0:20Cart$18.01round()Receipt$18.00an agent’s glow drifts toward FAIL’s red✕ FAIL 1/3the guard compares colorsglow pixelFAIL’s color0.06 apart in OKLab: closerthan the look’s 0.10moved to the nearestallowed colorStatus guardcolors illustrativeoperators drawfinish chainstatus guardstatus colors, on topunlit and exact, each with a glyph and a word

OKLab

A way to measure color so that equal distances look equally different to people. The look sets how close to a status color is too close.

status.min_distance = 0.10

Can’t reach status

Operators run before status colors, can’t read that layer and can’t write to a slot a status binding owns.

drawn last, unlit

Always on

No document, look or operator can turn the guard off where status can show. Other documents run none.

where status can show

Cost

One full-screen pass of about 30 ALU a touched pixel (estimate), skipped when no operator drew.

R2 with the GPU layer
WHYA status color means a verdict. If an effect could paint one, a picture could show a pass no check gave.188 / 449
3.10.17Make › GPU operatorsin the system: Canvas core › GPU layer › operators
Part 3: How do agents show their work as pictures? › 3.10: How is new GPU work added safely?

Inside the Status Guard: Four Pixels, One Rule

The last slide’s guard, one pixel at a time: which pixels it reads, the test it runs, what it never touches.

checkout film · 0:07 / 0:20Cart$18.01round()Receipt$18.00✕ FAIL 1/3P1P2P3P4the film binds a status (FAIL 1/3), so the guard runs;an art film played on its own runs nonePIXELDRAWN BYNEAREST STATUS COLORWHAT THE GUARD DOESP1the glowan operatorFAIL, 0.06 apartunder 0.10: moved to thenearest allowed colorP2the glowan operatorFAIL, 0.24 apart0.10 or more: kept as drawnP3the backgroundno operator—not read: it reads onlypixels an operator wroteP4the FAIL chipa status binding—not drawn yet: status colorsdraw after it, unlitdistances in OKLab, illustrative1 Maskpixels an operatorwrote this frame2 TestOKLab distance toeach status color3 Moveunder 0.10: to thenearest allowed4 Then statuscolors draw on top,glyph and word tooback to the glow’s writer, sampled: status_guard {op: glow, pixels_moved: 1840} · no operator drew? the pass is skipped
ONLY OPERATOR PIXELSThe guard reads what effects drew and nothing else, and status colors always draw after it.189 / 449
3.10.18Make › GPU operatorsin the system: Canvas core › GPU layer › operators
Part 3: How do agents show their work as pictures? › 3.10: How is new GPU work added safely?

An Operator’s Cost: Declared, Estimated, Then Metered

One number, checked three times. Top: the three gates. Bottom: the flame glow’s cost against its class.

1 · Declaredthe operator states itcost: {ns_per_px: 0.4}per pixel for materials and passes,per element for computeillustrative value2 · Estimated at checkfrom its stepsΣ weight × trips + texture reads × pixels × scale² × overdrawadd ≈ 1 · divide ≈ 4 · sin ≈ 8 ·noise ≈ 16 an octave (estimates)over the declaration by 25%+: refused3 · Metered while it runsGPU timestampsover 2× its declaration:its own writer’s layer steps down,half → quarter → off, and is told whyGPU time: the time at least one passis running, never a sumThe flame glow, per frame, at 1080p:half resolution: 960 × 540 = 518,400 pixels × 0.4 ns = 0.21 ms4 ms*: the class’s limitthe showpiece class: all its operators, a frame0.21 ms

Same verdict anywhere

Step weights come from tiny timing tests on the reference Mac, an M3 Pro, with its fingerprint, so a refusal is the same on any machine.

micro-benchmarks

cost_understated

The estimate beats the declaration by more than 25%: refused before it runs, with both numbers.

declare honestly

Over the class

The declared costs of a document’s operators add up; over its class, refused, naming the top three.

* proposals

Words

scale: the share of full size a pass draws at. overdraw: how many times a pixel is drawn over.

half → 0.25 of the pixels
THREE LOOKS AT ONE NUMBERThe agent states a cost, the check verifies it from the steps, and the meter keeps it honest while it runs.190 / 449
3.10.19Make › GPU operatorsin the system: Canvas core › GPU layer › operators
Part 3: How do agents show their work as pictures? › 3.10: How is new GPU work added safely?

Operator Budgets: Each Class Gets a Share of Its Frame

What packs and agents may add, by kind of view. Column meanings first; the yellow row is the rocket’s.

Budget classthe kind of view, from the budget slides
Kindsoperators packs and agents may add
GPU timeall its operators in one frame, inside the class’s frame time
Resolutionthe size a pass draws at
Elementsthe most one compute dispatch may run
StorageGPU memory for operator outputs
Budget classKinds packs and agents may addOperator GPU timePass resolutionCompute elementsOperator storage
core viewnone: shipped only0.2 ms*n/an/a8 MB*
data viewpass, compute0.5 ms*half1,048,57664 MB*
figurematerial, pass, compute1 ms*half262,144*32 MB*
work productmaterial, pass, compute1 ms*half262,144*64 MB*
showpieceall three kinds4 ms at full screen*full1,048,576128 MB*
exportall three kindsno frame capfull1,048,576128 MB*
The rocket piece is a showpiece, so its flame glow’s 0.21 ms counts inside 4 ms for all its operators. Numbers marked * are proposals within each class’s frame and memory caps; a document may only tighten them.
INSIDE, NOT BESIDEOperator time counts toward its class’s frame GPU time, never on top of it, so effects can’t slow the Mac the agents use.191 / 449
3.11.1Make › Lightin the system: Canvas core › modules › look, raytrace
Part 3: How do agents show their work as pictures? › 3.11: How is light drawn, and what is kept between frames?

Frame History: The Live View’s Only Memory, Rebuilt on a Jump

Operators add GPU work; light is DeepBuild’s own. First, its one memory: the live 3D view’s window of recent frames.

While it playsthe window slides alongwindow: 8 framesolder frames are never usedeach moved to t, then checkedAfter a jump to 0:07the window renders firstwindow: 8 framesseek: render these 8 first, then show 0:07At resthistory drops and theframe settles, sampleby sample, to thecanonical frame: theone an export drawsscrubbing drawswithout historyFrame historySeek = play

Window

A fixed number of the view’s own recent frames, on a grid at its frame cap. Nothing older reaches a frame.

8 by default, 2 to 16

Moved to t

Each older frame is moved to t through poses worked out at both times, then dropped where uncovered or changing.

depth, clamp, reactive mask

Upscale

It can also render smaller and rebuild full size from the window’s jittered frames.

render scale 0.67 by default

Cost

About 12 B a pixel per window frame: about 90 MB for 8 frames at 1080p, at 0.67 (estimate).

work product and showpiece only
NEVER CANONICALExports, render-back, goldens, checks and content keys never read the window; rays denoise through it only while moving.192 / 449
3.11.2Make › Lightin the system: Canvas core › modules › raytrace
Part 3: How do agents show their work as pictures? › 3.11: How is light drawn, and what is kept between frames?

Ray-Traced Light, Where the GPU Has Rays

The GPU layer traces rays from each pixel for shadows, reflections and bounce light, if the GPU’s ray class allows.

glossy floorarea lampcamerapixel P1✕2345Bounce lightSoft shadow1a ray per pixel finds what it sees2rays to points on the lamp: some blocked,so the shadow’s softness follows the lamp3a reflection, even of what’s off screen4short rays darken corners (occlusion)5probes, traced whole when what they see changesOn by the GPU’s ray class, never its namehardwareApple9 and newer: the M3 and every later chipemulatedApple7, Apple8: the M1 and M2unknownkeeps today’s lightwgpu 30 ray queries on Metal, macOS 15+; no ray pipelines
Without rays: light without history. Soft and contact shadows, cached point and spot shadows, Hillaire’s sky, light probes, light shafts; each cache equals a clean rebuild.
Live vs export: the live view denoises rays through its frame history; exports take many samples a frame. A frame’s key names which light drew it.
R6, behind a spike on an M1 and an M3. Proposed budgets: shadows, reflections and occlusion under 4 ms together; a 16³ probe grid under 2 ms.
NO CARRY-OVERRay structures are built from the frame’s own data at t, never refit from an earlier frame, so seeking still equals playing.193 / 449
3.11.3Make › Lightin the system: Canvas core › modules › look, raytrace
Part 3: How do agents show their work as pictures? › 3.11: How is light drawn, and what is kept between frames?

From Light to Screen Colors: Bloom, Tone Mapping, HDR

The GPU layer adds light up in values far past white; the finish turns them into screen colors, in this order.

linear lightbloomtone mappinggradefinishstatus guardstatus colors
0.010.18116.31: paper white2: this XDR displayHDR, R6: ends at the headroomAgX on a normal displayscene light (log scale) →headroom 2: illustrativeTone mapping
Bloom. Bright pixels spill into their neighbors through a mip chain. With no threshold it follows exposure; lens dirt shows only where bloom is bright.
Tone mapping. None, filmic, AgX or neutral, as analytic curves with no lookup image. AgX rolls a bright lamp off without a hue shift.
Grade. White balance and ASC CDL, keyed per shot. The check refuses a grade that moves a data color too near a status color.
HDR (R6). On an XDR display a live 3D view may glow brighter than paper white. The shell, card, text and status stay SDR, and so do checks and exports.
DEFAULTSstudio@1 picks Neutral for products, toys and paper, AgX for night, lamps and fire, and none for drawings. Status colors always draw last.194 / 449
3.11.4Make › Lightin the system: Canvas core › modules › look, raytrace
Part 3: How do agents show their work as pictures? › 3.11: How is light drawn, and what is kept between frames?

Light Inside Things, and Path-Traced Finals

Fog, skin and hair need light that travels inside matter. Film finals can be path traced: many rays a pixel, offline.

VolumesR6fog, clouds, smoke, scansfog fills a grid over the view:160 × 90 cells, 64 depth slices,lit through the shadow maps;clouds at a fixed step countnever reprojected from an earlier frameSubsurfaceR6skin, wax, jade, marblelight enters and leaves nearby,spread at 16 fixed taps, onlywithin the same material; thinparts like ears let light throughnever adds energy or bleeds onto othersHairR6a licensed character’sthree lobes: reflection (R),through (TT), and in, bounce,out (TRT); up to 100,000 strandsride the skinned scalpnever simulated; rigid in its root’s framePath-traced finalsR6a film’s final rendereach path seeded by its ownframe index; 1,024 samples bydefault; an optional denoiserruns on each frame alonemust match the real-time frame (final.match)inoutRTTTRTframe 40seed 40frame 41seed 41frame 42seed 42final.match: IoU 0.99, ±0.33 EV
When volumes are off, mist, puffs and smoke flipbooks stand in. Figures and data views refuse volumes.
When the subsurface pass is off, wrap translucency stands in, and the fallback is reported; hair cards keep an anisotropic highlight.
Finals run as a runner job under the GPU lease, sharded by frame range: a 10 s film at 30 fps is 300 frames, a job of hours (estimate).
NO HISTORYVolumes jitter by cell and sample, never by frame; a final frame depends only on its own index, so any frame renders alone.195 / 449
3.12.1Make › Platformsin the system: Canvas core › GPU layer › seams
Part 3: How do agents show their work as pictures? › 3.12: How does one renderer run everywhere?

One Renderer on Every Platform: Seams and Backends

So far, macOS. Slide 61’s seams, for the renderer: one interface each, one backend per platform.

macOSR2LinuxR3Windowsafter version 0web playerR6GPUwgpu on Metalwgpu on Vulkanwgpu on Direct3D 12wgpu on WebGPUHandoffIOSurface into GPUIGPUI’s wgpu device, DMA-BUFDXGI handle into D3D11the page’s canvasDisplay timingdisplay link via GPUIWayland frame callbacksDXGI frame statisticsthe page’s frame callbackFontsbundled onlybundled onlybundled onlybundled onlyColorsRGB-tagged; HDR in R6Wayland color managementDXGI’s sRGB spacean sRGB canvasHeadlesswgpu offscreen + Vello CPU+ lavapipe if no GPU+ WARP if no GPU—SeamBackend
Feature table at startup: pass timestamps, depth-clip control, ray queries and ray class, MSAA counts, limits. Each gated path runs its fixtures with the feature on and off.
Never mixed: a backend’s name and version enter every content key it feeds. A platform ships a seam only once its backend passes the seam’s suite.
Other seams: accessibility, input (with pen, touch, motion and MIDI device classes), codecs, audio, capture, CPU and network.
NO SILENT FALLBACKA missing backend means module_missing, never a quiet switch to one that changes results. No document names a platform.196 / 449
3.13.1Make › Building blocksin the system: Canvas core › modules › 2D, data, motion
Part 3: How do agents show their work as pictures? › 3.13: Which modules make up the canvas?

Twenty-Four Canvas Modules in Six Families

The modules grouped by what they make. Each family is a section ahead; the arrow is where it starts.

24 canvas modulescompiled into the app; each registers its kinds and checks2Dtext, marks2d (shapes, paths, masks),vector (SVG, formulas), cells→ 198Datadata (mark sets, scales, axes), graph,sheet, record (timelines, salience)→ 199Motion and stylemotion (keys, drivers, shots), look,effects, input (controls)→ 2043Dscene3d, skin, voxels, building,raytrace, loop (scene checks)→ 233Playphysics, sandbox and logic(game rules), net (shared play)→ 245Sound and exportmedia (tracks, narration, captions),export (MP4, Lottie, glTF, web)→ 261
WHERE NEXTThe 2D, data and motion blocks agents write with come first; how a module plugs into the canvas follows them.197 / 449
3.13.2Make › Building blocksin the system: Canvas core › modules › 2D, data, motion
Part 3: How do agents show their work as pictures? › 3.13: Which modules make up the canvas?

The Building Blocks an Agent Writes With

From how the canvas draws to what agents write: one explainer frame in blocks. The next five slides open them.

look: cleanWhy the receipt says $18.00textCart$18.01bound valuepathstep 2 of 3round()Receipt$18.00✕ FAILstatus bindingthe rounding happens before the couponoverlaylookwritefade_inindicatefade_inmove_along0:07 / 0:20cue listchannel and keyMarkstext · rect · circle · star · path · image · mask · frame · groupDatamark set · scale · axis · legend · seriesDiagramsgraph · layout · route · label · sheet · cell grid · formulaMotionkeys · drivers · constraints · clips · shots · transitions · cue listsHonestybound value · status binding · salienceStyle and viewlook · camera · overlay3D partsbuilder · recipe · attribute and field · modifierInteractioncontrol · input track · transport
ONE LANGUAGEAll of these are fields in one document. An agent never draws; it writes blocks, and the canvas draws, checks and replays them.198 / 449
3.13.3Make › Building blocksin the system: Canvas core › modules › data
Part 3: How do agents show their work as pictures? › 3.13: Which modules make up the canvas?

A Q3 Chart, Piece by Piece: Marks, Scales, Bound Values

Group 1, marks and data: the Q3 chart of slide 108 as an agent writes it (left) and the canvas draws it (right).

data:  sales: q2 44 · q3 48 · with its sourceitems:  bars:   marks@1 · mark: bar · key: quarter1          columns: quarter, value  y:      scale@1 · linear · zero: true2  y_axis: axis@1 · scale: y3  note:   text@1 · at.place beside bars#q34bound_values:  note ← reading:sales#q3 · as of 09:205values and names illustrative01020304050q244q348q3 48as of 09:20stale: 2 h old12345mark set

Many rows, one item

A mark set draws one mark per row of its typed columns: 100,000 rows map in under 1 ms and draw as one batch.

Rules a chart keeps

Bars start at zero; a log scale refuses values ≤ 0; color-only categories stay apart for color-blind viewers.

Generated, not drawn

A scale maps values to positions or colors. Ticks fall on 1, 2 and 5 × 10k; axes and legends come from scales.

Live numbers

A bound value shows its source and as-of time. Past its freshness it grays out and shows its age.

NO CODE PER ROWScales map whole columns in one pass. A chart can’t run code per row, map a column to a status color, or start a bar above zero.199 / 449
3.13.4Make › Building blocksin the system: Canvas core › modules › 2D, data, motion
Part 3: How do agents show their work as pictures? › 3.13: Which modules make up the canvas?

Data Over Time: Bars That Glide, Lines That Reveal

A mark set holds the rows. When rows share a week or a year, the chart plays from one period to the next as time runs.

SESSIONS PER REPO, BY WEEK (ILLUSTRATIVE)api1211checkout-web915docs56W1W2atstandingA LINE THAT REVEALS; ONE SERIES IN EMPHASIScostsq1q2q348revealemphasissales: q2 44, q3 48 · q1 and costs illustrative

Periods

Rows that share a value of one column, such as a week, form a period. Between two, each key mixes from the one before to the one after.

Standing

Each period’s rows are ranked at check, ties by key, then mixed like any value, so bars glide past each other.

Reveal and emphasis

A reveal draws rows up to a point, its head carrying the value. Emphasis dims the rows it doesn’t name to 0.3.

Honest in between

A key missing from a period enters or leaves at opacity 0; a mixed number shows no more precision than its source.

SEEK = PLAYWhere the playhead rests on a period, every number equals that period’s own. A stage can stop on any period.200 / 449
3.13.5Make › Building blocksin the system: Canvas core › modules › graph
Part 3: How do agents show their work as pictures? › 3.13: Which modules make up the canvas?

Diagrams: Graphs That Remember, Paths That Reshape

Group 2, diagrams: the repo map gains a node and the rest stays put; salience folds the least urgent into a count.

checkout-webcarttotal.tsreceiptapiuicoupon.tsnew nodelayout memory+14 more: 2 lack proof, 12 unchangedsaliencetrim {start, end}round_corners {radius}zigzag {size, ridges}repeater {copies: 3}

Route

Edges route around labels and boxes; in a layered layout they get slots between ranks.

Label

Labels move aside, fold to a dot or hide, by priority, and stay reachable by keyboard.

Sheet

Cells at exact pixels, such as a taste call’s options. A click preselects; only the question card answers.

Formula

SVG from the typeset job (LaTeX or Typst). Its source text is kept as the accessible name.

SAME BYTESThe same graph, layout memory and seed give the same picture. A path holds up to 8 ops, and its size is known before it is built.201 / 449
3.13.6Make › Building blocksin the system: Canvas core › modules › 2D, data, motion
Part 3: How do agents show their work as pictures? › 3.13: Which modules make up the canvas?

A Sheet: Options Side by Side; Only the Card Answers

Diagrams show structure. A sheet shows choices: here a taste call’s two layouts, side by side, ready for your call.

A SHEET: TWO CANDIDATE LAYOUTS, AT EXACT PIXELStotal $18.00option: keeptotal $18.00option: move itpreselected:beside the cell,never on ita clickpreselectsNEEDS YOU · TASTEKeep the order total above the foldon phones?KeepMove itNone of theseOnly a click here answers. “None of these” sendsthe work back with your note.question card

Exact pixels

Each cell renders once at its exact device size, never scaled, and is cached; then one quad a frame.

Ways to look

A cell can show its option plain, in mono, reversed, blurred or mirrored, with highlights beside it.

Near twins drop

Two candidates under ΔE 0.1 apart at the 90th percentile of pixels count as one; the later is dropped and named.

Other sheets

A contact sheet of times, a variant sheet; in R6 a rig’s model sheet and a moment strip around a moment.

R1Sheets ship in version 0. A click on a cell preselects an option; only the question card’s own click answers it.202 / 449
3.13.7Make › Building blocksin the system: Canvas core › modules › 2D, data, motion
Part 3: How do agents show their work as pictures? › 3.13: Which modules make up the canvas?

Formulas and Code: Written Term by Term, Quoted Exactly

Diagrams also hold formulas and code. Each keeps its parts by name, and a quote must match its source exactly.

A FORMULAA = \pi r^2LaTeX sourcetypeset joboutside the coreA#A=#eqπ#pir²#r2term by termSVG in, one id per term; it writes on term by term,its source text kept as the accessible name.quote: paper.tex, line 12alt bytes = source bytes✓one byte differs✕ quote_mismatch: line 12, byte 9file, line and byte illustrativeCODE: TOTAL.TS, AS THE AGENT’S CHANGE41function total(subtotal, coupon) {42  return round(subtotal) - coupon;43}text diff: kept tokens move42  return round(subtotal - coupon);code illustrative, after total.ts:42 in the deck’s bugquote: {commit, total.ts, lines 41–43}✓raw bytes

Nothing typesets in the core

Formulas arrive as SVG, from the typeset job (pinned Typst and mitex) or the agent’s own renderer.

Terms keep their ids

So a step’s match morph moves the terms two lines share into their new places, and the rest fade.

Code takes the look’s roles

Tokens come from the agent’s own highlighter; lines number; a highlight dims the rest to 40%.

Quoted digits aren’t numbers

A quote’s digits are quotation, which honest numbers lists but never counts. A terminal recording plays in a cell grid.

QUOTED MEANS EQUALA quote is checked byte for byte against its source; the check proves the source text, not the drawing of it.203 / 449
3.13.8Make › Building blocksin the system: Canvas core › modules › motion
Part 3: How do agents show their work as pictures? › 3.13: Which modules make up the canvas?

Motion Without Code: Keys, Drivers, Constraints, Cues

Group 3, motion: the agent writes five seconds as a cue list (left); the check compiles it into keys (right).

cue listwritetitlespan 1sfade_incart {shift: up}after · gap 0.2sindicateround_stepafterwaitspan 0.5sfade_inreceiptafterat checktitlecartround_stepreceiptmarkers0s1s2s3s4s5schannel and keymarkerEach cue starts where the last left off, so one edit re-times everything after it.

Channel and key

A channel is a property that changes over time; a key sets its value at one time. Each segment moves by hold, linear, Bézier, an ease or a spring.

Driver

An expression over time, inputs and other values. At most 64 ops, no loops, no clock; a fallback for a divide by zero.

Constraint

A rule that places an item from others: child of, follow a path, look at, two-bone reach, keep a distance. Nothing iterates; a cycle is refused.

Cue list

Plays and waits in order. Any pack may add a verb, once it passes the verb tests (the cue kit).

ALSO ON THE CLOCKClips are reusable animations placed on items; shots and transitions (cut, wipe, morph …) cut a film.204 / 449
3.13.9Make › Building blocksin the system: Canvas core › modules › 2D, data, motion
Part 3: How do agents show their work as pictures? › 3.13: Which modules make up the canvas?

Shots: Each Camera Move Goes a Set Amount, Then Lands

Cues time the motion; shots cut the film. Each shot names one camera move, sized by a default that reads well.

SHOT 1 · PUSHby: 0.15 (default)SHOT 2 · ORBITby: 30° (default)SHOT 3 · SHAKE0.5° at 2 Hz (default)start: 1.15× the distancelands on the framingframingthe barge, seen from above30° about the targettouchdown; noise seeded by the shot

Moves with sizes

Push and pull 15% of the distance, pan 15°, orbit 30°, slam from 1.7×; also log zoom, follow a path, follow forward.

Framing, solved once

From the kept items’ bounds over the whole shot, so parts that fly apart stay in frame at every instant.

Cut or glide

A shot joins by a cut, or glides in over 0.8 s from the pose shown; a stage’s shot glides by default.

Reduced motion

A move cuts to its final framing at its midpoint with a 200 ms dissolve, unless marked essential; shake and slam drop.

ONE WRITERWhile a shot is active it alone moves its camera; a channel on the same pose is refused unless the shot is keyed.205 / 449
3.13.10Make › Building blocksin the system: Canvas core › modules › 2D, data, motion
Part 3: How do agents show their work as pictures? › 3.13: Which modules make up the canvas?

Transitions: Joins Between Shots That Land on the Beat

Shots meet at a transition. Here a wipe joins two shots of the explainer, timed so its reveal falls on a beat.

A WIPE AT 120 BPM: THE REVEAL LANDS ON THE BEAT2.0s2.5s3.0s3.5s4.0s4.5s5.0s5.5s6.0sshot 1: the cartshot 2: the receiptwipe · span 0.8 s · align: revealreveal, on beat 5cart✕ FAIL0%cart✕ FAIL25%receiptcart✕ FAIL50% · revealreceipt✕ FAIL75%receipt✕ FAIL100%

Kinds

Cut, cross-fade, dip, wipe, push, iris, zoom-through, match morph, text diff, or a pack’s operator such as a page turn.

Both sides live

Each side evaluates at its own local time, draws offscreen, then blends: about twice a frame’s cost inside the window.

What it may not hold

A reading hold or a checked moment; it never hides a cut a check needs. At most two strips overlap on a track.

Reduced motion

Anything but a cut, a cross-fade or a dip becomes a cross-fade of the same span. Cut lands in R1; the rest in R6.

STATUS NEVER BLENDSInside a transition, status colors draw once, after the blend: outgoing side until the reveal, incoming after.206 / 449
3.13.11Make › Building blocksin the system: Canvas core › modules › 2D, data, motion
Part 3: How do agents show their work as pictures? › 3.13: Which modules make up the canvas?

Mattes, Animated Type and Counters

Keys move items; three more kinds move or reveal type. Each is still computed from the time alone.

MATTERECEIPTRECEIPTRECEIPT← source: the title, hidden,still evaluated each framemode: alphaTEXT ANIMATORLAUNCHrange selector sweeps by graphemeprops: y, scale, opacityunits: graphemeCOUNTERchecks14151617of 29bound to run: the check runas of 09:21 · tabular figuresreformats only when its string changesbound value

Matte

Coverage from another item’s evaluated pixels, frame by frame, by alpha or luma. It applies before status colors and never hides one.

Text animator

Up to four selectors (range, noise, field) over graphemes, words or lines. Text shapes only when it changes; per frame, glyphs just move.

Counter (R1)

A bound value or a driver, formatted as it changes, in tabular figures. A ticking counter never counts toward a reading hold.

NUMBERS STAY HONESTA counter always has a source, and an animator may never shift a glyph inside a number.207 / 449
3.13.12Make › Building blocksin the system: Canvas core › modules › look
Part 3: How do agents show their work as pictures? › 3.13: Which modules make up the canvas?

Looks, Cameras and Overlays: Style That Never Touches Data

Group 4, style and view: the same curve and dot in the four looks that ship first. Only the look changed.

cleanchalkdark mathnotebooklook

A look is one asset

palette and rolesstatus map + its legendline styles: exact to chalkfills and paperbundled fontsfinishing effectstime feela signature transitiontone map: none, filmic, AgX, neutral

Four ship first. Then whiteboard, blueprint, shadow play, pixel, comic, ink map, flat motion graphics, picture book and isometric 2.5D, each proven by a test film.

Camera

Shots, framing that keeps the subject clear of the overlay, a focus pull, and a loop that yields to you and eases back.

Overlay

Anchored type and controls in safe areas. A callout’s leader stays on its part as things move. It never mimics the app or the question card.

STATUS STAYS PUTA shot can name its own look, but the status map and legend stay the document’s, so a verdict reads the same in every look.208 / 449
3.13.13Make › Building blocksin the system: Canvas core › modules › 2D, data, motion
Part 3: How do agents show their work as pictures? › 3.13: Which modules make up the canvas?

Controls: A Figure You Play With Writes One Input Track

Looks style a picture; controls let you play with it. Each gesture becomes one entry on one input track.

A PROJECTILE LAB (VALUES ILLUSTRATIVE)angle45°speed12 m/sLaunchlanded: 14.7 mONE INPUT TRACK0:000:010:020:030:040:050:06angle 45speed 12launch{t, control, value}seek to 0:02.5Scrub or seek alone:the track replays; “launch” at 0:03.1 still comes. Its future is kept.A new drag at 0:02.5:the track forks there; later entries drop, and the new one is recorded.

Three classes

Document: on the track, replayed, in goldens. View: a setting kept per viewer, pinned for goldens. Viewer: orbit, zoom, hover.

Kinds

Slider, toggle, choice, stages, transport, drag along, turn, press, text, hover, scroll; for games, point and actions.

A quiz with no code

A choice reads as its option’s number, so a driver can check an answer and count a score. A hotspot click picks an option.

Your hand only

No entry without your gesture, and no control answers an ask. A tour plays while you’re idle and yields to your first gesture.

PLAY THAT REPLAYSA control’s value is its last entry at or before t, so play, scrub, replay and export agree.209 / 449
3.13.14Make › Building blocksin the system: Canvas core › modules › 2D, data, motion
Part 3: How do agents show their work as pictures? › 3.13: Which modules make up the canvas?

Present Mode: Stages Hold While the Music Plays On

Controls let a viewer play; present mode lets you show a piece to a room, stepping it stage by stage.

THE CLOCK RUNS; THE POSITION HOLDS AT STAGESclockposition(what thefilm reads)stage 2stage 3stage 4→→music bed: plays on through every holdholdTWO DISPLAYSthe piece, full screenthe roomstage 2 of 4 · 03:12nextnotes:“pause onthe coupon”presenter viewAn ask while you present:its card opens on another display, or, with one display,waits with its deadline not started, counted in the menu bar.The presenter view never shows an ask.

Step and branch

→, Space or a remote advance; ← goes back on the path taken. A stage can wait for a choice and go on where it says.

Each step is an entry

Advances, backs, jumps and blanks go on the input track, so seeking equals playing. Paths only go forward, 64 at most.

Holds keep the beat

With a tempo map a hold lasts whole bars; beds marked to play on run through. A stage may loop a span while it holds.

Out of the room

An export takes one path; a PDF handout has a page per stage, with its settled frame.

TWO TIMESThe clock stamps every entry and drives the music; the position, which the film reads, holds and jumps.210 / 449
3.13.15Make › Building blocksin the system: Canvas core › packs and builders
Part 3: How do agents show their work as pictures? › 3.13: Which modules make up the canvas?

Recipes and Builders: Agents Start From Strong Defaults

Last, recipes: rather than write every block, an agent names a recipe. One item and four inputs make a data story.

storypiece.data_story@1subject: sales (table + source)form:    barspoints:  “Q3 up on Q2”length:  45 sRecipecheckderived itemsstory.titlestory.barsstory.axisshots · narration · captionsnames illustrativeIt brings the checks its kind of piece needs:honest_numbers · the color-blind check · film.auditChange an inputstory · length: 45 s → 30 sre-expands; only items whose values changed rebuildPatchChange one item the recipe madebreak_out {instance: story, item: story.title}then set its textthe title is now yours; everything else stays the recipe’s

piece@1 pack

Twelve piece recipes: a product reveal, a physics lab, a walkthrough, a data story, a film of an agent’s change …

explain@1 pack

Film recipes written as a cue list: a proof, a chart’s story, an evidence board, kinetic type on the beat.

studio@1 pack

Lighting rigs, about 40 measured materials, looks and lenses, so 3D needs no tuning by hand.

Builders

Pure functions from numbers to 3D parts (slab, lathe, extrude, tube, ball …) with named parts and true shapes.

TWO LEVELSFirst a recipe: one item turns a subject and a few inputs into a whole piece. Then the primitives, only to change one thing.211 / 449
3.13.16Make › Building blocksin the system: Canvas core › modules › 2D, data, motion
Part 3: How do agents show their work as pictures? › 3.13: Which modules make up the canvas?

The Editor Panel (R6): Fine-Tune What an Agent Made

Agents start from recipes. When one thing needs your hand, the editor panel shows the document’s timeline and fields.

Editor · explainer film · rev 9units: seconds · snap: on0:000:050:100:150:20shotsmarkerscart · at/posreceipt · opacityshot 1 · cartshot 2 · receiptshot 3snaps to a beatplayhead 0:07timelinedragging the cue marker retimes what is anchored to itcart · text@1 · Claude’s layersize32 u8 to 200rolelabelat.pos[120, 340] uhistory: rev 3 Claude · rev 9 younote · open · 0:07“say why it rounds”suggestion · from Codexpreview · Applyinspectorvalues illustrative

What it shows

Shots, markers and channels with their keys on the one clock; the selected item’s fields from its kind’s schema, with units and ranges.

Snapping, on

To frames, beats, markers, shot edges and other keys. A time written relative to a marker keeps its offset when the marker moves.

Read-only, with the reason

A derived item (with Break out), a generated marker, a baked channel, a view of the record, or an item under another’s live lease.

Same limits as agents

Outside a soft range warns; outside a hard range is refused, out_of_range. The playhead is session state.

A PLUG-IN, NOT RING CODEThe app ships it and you can replace it; a replacement writes as you only with the edit_as_you grant.212 / 449
3.13.17Make › Building blocksin the system: Canvas core › modules › 2D, data, motion
Part 3: How do agents show their work as pictures? › 3.13: Which modules make up the canvas?

One Gesture, One Patch: The Editor Writes as You

Every change in the editor is a patch, like an agent’s. Follow one drag, 1 to 5, from your trackpad to Claude.

youeditor panelcanvas coreClaude1dragdry run each frame, ≤ 20 ms;preview = last passing state2releasecommit · gesture: serial 3113✓your input in this panel,unspent: writer = youelse gesture_required4same check and latchrev 10 · doc.patchedone undo step5sees rev 10 by you inits next render-backClaude’s later patch to the cart: ✕ not_your_layer, filed as a suggestion on your item

Not your hand, no commit

A panel script, a timer, an agent’s computer use or a replica’s synthetic input has no serial: gesture_required.

The cart becomes yours

Changing an item an agent made takes it into your layer, unless that agent’s live lease covers it.

Undo by writer

Undo sends your last patch’s inverse as your next patch, so it removes your change and nothing of Claude’s.

NO BACK DOORThe panel can’t skip a check, write what a patch couldn’t, or edit a check, a verdict or the record.213 / 449
3.14.1Make › Extendingin the system: Canvas core › modules
Part 3: How do agents show their work as pictures? › 3.14: How does the canvas grow without a bigger core?

Growing the Canvas Without Growing Its Core

Who may add new blocks? Five rings, from DeepBuild’s core out; the right column says who writes each ring.

Claude Code · Codex · plug-ins · they send documents and patchesClientsa piece’s logic · a pack’s program · a library · a generatorSandboxed programsrecipes · kinds made of recipes · looks · presets · eases · cue verbsPackstext · marks2d · data · motion · scene3d · …24 canvas modulesCoredocument contract · registry and seal · scheduler · cachescompositor · time and seeded randomness · camera · core checksRing pieces, never modules:question card · bands · input router · status colorsmeter · device gate · decode workerAgents and plug-ins send documents and patches;the canvas draws for all of them. No client draws pixels.Outside code runs only here: WebAssembly undersandbox@1, with budgets for work (fuel), memory and stack.A pack is versioned data, such as piece@1. Anyonemay write one; each version is checked once, then frozen.DeepBuild’s own Rust, compiled into the app. Each registersits parts, then the whole set is checked and sealed.Owns the rules and the screen. No module adds aphase or touches the question card or status colors.How it grows. A new extension point is one moduledeclaring a registry: a list others may fill, each entrytested first by its kit, a set of test cases. Core unchanged.
THE RULEOutside code never compiles into the canvas. It arrives as documents, as data in packs, or as sandboxed programs.214 / 449
3.14.2Make › Extendingin the system: Canvas core › modules
Part 3: How do agents show their work as pictures? › 3.14: How does the canvas grow without a bigger core?

A Canvas Module: One Crate, One Manifest, One Register Call

The modules ring up close: each module is one Rust crate (package). Left: its manifest; right: what it registers.

Manifestnamephysicsdepends_onmotion (required) · input (required)featurea Cargo feature: in this build, or notimplementsphysics@1 · its interface: what others seeimplementationRapier, a Rust physics engine · pinned cratesREGISTERSkindsphysics.world@1 · body@1 · joint@1 · soft@1breakable@1stepsrun in phase simulatecarriedcheckpoints and bakes, each a key + byte budgetchecksphysics.determinism · physics.auditphysics.query · nav.reachalsoits own arrays · tables · tool entriescost terms · fixturesOne register callkind@1 registry← kindsarrays, one owner each← its arraysthe phase plan← steps, operatorscarried state← checkpoints, bakescheck catalogue← check kindsagent tools← tool entriescost model← cost termsconformance kit← fixtures: test cases
It can never be loaded at run time or built outside DeepBuild’s repository · write another module’s array · add a phase, a place in the frame or a tool · touch the question card, bands, input routing, status colors or the meter.
OPTIONAL TOOIf an optional dependency is missing, the seal drops only what reads it and refuses documents that need it.215 / 449
3.14.3Make › Extendingin the system: Canvas core › modules
Part 3: How do agents show their work as pictures? › 3.14: How does the canvas grow without a bigger core?

The 24 Canvas Modules and What Each Builds On

From one module to all 24 DeepBuild ships. A line joins each to what it builds on; the fill: its first release.

corevectordatagraphrecordsheetexportnetmarks2dcellsloopraytracebuildingvoxelsskinphysicslogictextlookmediaeffectsscene3dmotioninputsandboxOptionalBuilds on
first lands in R1R2R6line: builds on the lower boxdashed: optionalevery module sits on the core

Packs are not modules

studio@1, explain@1, piece@1 and the rest are data. Each names the modules its kinds need.

Leave one out

Build sets core, r1, r2 and full each hold more modules; a document that needs a missing one gets module_missing.

When it lands

R1’s canvas code needn’t be split into modules yet. The registry and its seal land in R2.

No loops

No module may depend back on one that depends on it; the seal refuses a loop at startup.

WHY SO MANYEach capability is its own module, so a build can leave one out and a backend can be swapped, without touching the rest.216 / 449
3.14.4Make › Extendingin the system: Canvas core › modules
Part 3: How do agents show their work as pictures? › 3.14: How does the canvas grow without a bigger core?

Phases: One Fixed Order Every Module Plugs Into

How modules take turns: slide 155’s frame phases plus a check’s eight, owned by the core; modules plug in below.

EVERY CHECK, IN THIS ORDERloadexpandresolvevalidateplanbuildestimatecheckEVERY FRAME, IN THIS ORDERlatchtimeinputssimulateitemsviewssourcesextractrendercomposefeedbackPhasephysicslogicmotionmarks2dscene3deffectsWHILE SOUND PLAYSblockmediaStepPasssteps, in time order; at one timeby who reads whom: logic firstper-item operators: a graphof (item, operator) nodespasses, only into the frame’snamed placesprocessors, peraudio block

Closed lists

The core owns both lists. No module adds, removes or reorders a phase.

Order from data

An operator is one unit of a module’s work. In a phase, one runs before another only if it writes what the other reads.

Ties by name

Module name, then operator name; items by depth, order key, then ID.

Never

Registration order, thread timing, a shared singleton, a hook, an observer or a message handler.

WHY CLOSEDOne order for every module’s work, in a check and in a frame, so the same document gives the same result every time.217 / 449
3.14.5Make › Extendingin the system: Canvas core › modules
Part 3: How do agents show their work as pictures? › 3.14: How does the canvas grow without a bigger core?

One Writer per Array: Modules Contribute, Never Overwrite

Slide 156’s rule: an array (one value per item, like its place) has one owner. Three modules place one caption.

The documentcap.3 · at.posset by the item’s writermotion modulekeys: slides in at 0:04→ contributes_to the transformmarks2d moduleat.place beside chart.1→ a constraint@1 entrythe transform · one ownerat, plus motion channels(and physics poses, in 3D)motion.constrainedmotion’s array; constraints write itOne writer✕ marks2d writes the transform itself:a second writer, refused at the sealthe frame at 0:05chart.1Q3 up on Q2cap.3gap 16beside

Read set

Each operator lists every array it reads. The core builds its inputs from that list, so nothing else is reachable.

Same list, two more uses

The list is also the operator’s cache key and its change test, so a cache can’t miss a change.

Leave a module out

Its contribution is simply absent. The owner never names who contributes to it.

Never

Read what it didn’t declare, write another’s array, read a later phase, keep last frame’s value, read a clock.

WHYOne writer per array means a cached result always equals a clean rebuild, and no module can overwrite another’s result.218 / 449
3.14.6Make › Extendingin the system: Canvas core › modules
Part 3: How do agents show their work as pictures? › 3.14: How does the canvas grow without a bigger core?

The Seal: Every Module Checked Together at Startup

At startup the core checks all modules together: the seal. Three states, left to right; one failure stops the app.

registeringbuildingcellsdataeffectsexportgraphinputlogiclookloopmarks2dmediamotionnetphysicsraytracerecordsandboxscene3dsheetskintextvectorvoxelsin sorted name orderthe seal checks the whole set✓dependency ranges hold✓one owner per array✓every read resolves✓no read of a later phase✓no cycle✓passes in legal places only✓one implementation per interface✓shapes match the interface digest✓kits refuse planted wrong entries✓no entry in another’s registrysealed✕ Any check fails: startup is refused and the build’s tests fail,naming the reason. No warning level, no accept list.readyplan published atdeep://schedule/<core version>and compared with a committed snapshotregistries published atdeep://registries/<core version>then the first document opensunder 50 ms, once (an estimate);nothing per frame

Optional module missing

The seal leaves out only the operators that read it; a document that needs them is refused with module_missing.

Required module missing

The seal refuses. The app doesn’t start with that set of modules.

After the seal

Nothing in the sealed set changes until the next start. A pack’s entries resolve per document, outside it.

WHY NAME ORDERNothing is ordered by when it registered, so every build of the same modules seals the same plan or refuses for the same reason.219 / 449
3.14.7Make › Extendingin the system: Canvas core › modules
Part 3: How do agents show their work as pictures? › 3.14: How does the canvas grow without a bigger core?

Registries: Every List Says Who May Add to It

Every canvas list is a registry others fill, closed with a reason, or open. One real list of each, then the rules.

RegistryClosedOpengraph.layout@1declared by graph; filled by graph,first-party packs and any packgraph: layered tree treemap grid pinneda pack: circular force stress …kit: the same bytes twice, pinned nodes kept,finite positions. A planted bad layout must fail.layered✓ pin keptplanted✕ refusedphasesreason: determinismone order, with the status guardafter every operatorreopens if a case needs compositionthe phases can’t expressalso closed: bands and status colors(reason: ring; they reopen never)Each closed list states its reason, whatreopens it, and exhaustive or extensible.occurrence kinds from logicevents each logic item declares for itselfe.g. the rocket piece’s rules:landed · fuel_out(illustrative)rows carry numbers onlyalso open: pack programs andpack dependencies, declared per packOpen means each user declares itsown list, so no shared list grows.

The preflight

The local check before each release fails any list with no closure, and any registry missing its kit, its planted wrong entry or since, its first release.

Opening a closed list

Its owner declares a registry whose first entries are the old values, keeping their digests, so no document or golden changes.

The hub follows it too

Plug-in slots (deep.register…) obey the same rule; their fills are code that installs and replaces, never entries.

THE CLOSURE RULEEvery list is a registry, closed with a reason, or open. A kit that admits its planted wrong entry never ships.220 / 449
3.14.8Make › Extendingin the system: Canvas core › modules
Part 3: How do agents show their work as pictures? › 3.14: How does the canvas grow without a bigger core?

Inside the Seal: 24 Register Calls Become One Plan

Registries and the seal, run once at app start: what modules hand in, each check in order, what comes out.

IN: 2 OF THE 24 REGISTER CALLSlogicdepends_onsandbox · motion · inputstepin phase simulatereadsinput entries; arrays asearlier steps left themwritesits items’ own arraysphysicsdepends_onmotion · inputstepin phase simulatereadslogic’s arrays and firedinputs, at its own timewritesposes · occurrences+ 22 more: cells, data, effects, export …THE SEAL, IN ORDER: THE CANVAS CORE, AT STARTUP1Registers all 24 by name, never by arrival order2Dependencies hold; a missing optional drops its readers3Each array has one owner; others only contribute4Every read resolves; none reads a later phase5Orders each phase from reads: logic, then physics6No cycle; ties break by module, then operator name7One implementation per interface, digest matching8Every registry’s kit runs; planted wrong entries failOUT, PUBLISHEDthe plan for simulatelogic’s step → physics’ stepfrom what each reads, never namesdeep://schedule/<core version>equal to the committed snapshot ✓deep://registries/<core version>every list, its entries, kit resultsready: the first document opensunder 50 ms, once (an estimate)✕ A cycle: if logic also read physics at the same instant, the seal refuses, naming both modules.The app doesn’t start and the build’s tests fail. There is no warning level and no accept list.
WHY AT STARTUPA bad set of modules never draws a frame: it fails once, by name, before any document opens.221 / 449
3.14.9Make › Extendingin the system: Canvas core › modules
Part 3: How do agents show their work as pictures? › 3.14: How does the canvas grow without a bigger core?

Who May Add What to the Canvas

The rings as one table. Rows: what the canvas lets others add, with its list; a diamond: that author may add it.

What others can add, and its listModulePackPlug-inWhat every new entry must pass first
Item kinds made of code kind@1––the module’s own fixtures
Item kinds made of a recipe kind@1––the kind kit, with a planted twin per rule
Recipes, looks, materials, presets pack lists––the pack check, once per version
Eases ease@1––the core’s own, then packs’: 0 at 0, 1 at 1, monotone or a stated overshoot
Cue verbs cue.kind@1––the cue kit (motion declares the list)
Graph layouts graph.layout@1–the layout kit (graph fills its own five)
Constraint kinds constraint@1––the constraint kit: no loops; they run every frame
Control kinds control@1––replay, a keyboard path, no agent input
Export targets (MP4, glTF …) export.target@1––a fidelity check whose reader isn’t the writer
Check kinds check.kind.doc@1–a planted twin per code; plug-ins via deep.registerCheck
Device classes device.class@1–the class kit; a plug-in adds only its own ext. classes
Canvas modules themselves closed: ring––from DeepBuild’s repository only, each proved by its kit
THE PATTERNNative code that runs every frame stays first-party; lists of pure data open to any pack. Every entry passes a kit first.222 / 449
3.14.10Make › Extendingin the system: Canvas core › modules
Part 3: How do agents show their work as pictures? › 3.14: How does the canvas grow without a bigger core?

Growing the Canvas: What We Compare, and Why

Before the scores on “Growing the Canvas”: each row is one column of the next slide’s table, and why it matters.

ColumnWhat it measuresWhy it matters
1Grows without redesign a new extension point is one changenew cases keep arriving
2Checked before it runs the seal can verify every parta refusal beats a wrong frame
3Replays exactly the same order and bits every runseeking must equal playing
4Outside code off the ring nothing foreign beside the question cardthe card must stay trusted
5Open to others others can add capabilitypacks, plug-ins and agents extend it
The options on the next slideOne renderer, closed listsThird-party compiled modulesEvery list openFirst-party modules + registries
NEXTEach option scored on these 5 columns, three diamonds for strong.223 / 449
3.14.11Make › Extendingin the system: Canvas core › modules
Part 3: How do agents show their work as pictures? › 3.14: How does the canvas grow without a bigger core?

Why Outside Code Never Compiles Into the Canvas

Four ways to let the canvas grow, scored on those columns. A seal can’t check outside code that registers itself.

OptionGrows without redesignChecked before it runsReplays exactlyOutside code off the ringOpen to others
One renderer, closed listsevery addition is a redesignDropped
Third-party compiled modulesas in the Bevy game engine’s plug-insDropped
Every list openno kits, so no proofsDropped
First-party modules + registriesothers add data and sandboxed programsChosen
strong weak breaks a hard rulescores: our reading of the gains and costs recorded in the design
COST WE ACCEPTEDNew native code waits for a first-party module; everything else arrives as data, packs or sandboxed logic.224 / 449
3.14.12Make › Extendingin the system: Canvas core › modules
Part 3: How do agents show their work as pictures? › 3.14: How does the canvas grow without a bigger core?

How an Agent Extends the Canvas, Rung by Rung

What can an agent add itself? Four rungs, least new material to most, all checked; none draws its own pixels.

NEVER, ON ANY RUNG: COMPILE CODE INTO THE CANVAS · DRAW ITS OWN PIXELS1rungWrite in words it knowsfamiliar-names packs: a web 3D library,Unreal, Blender, Godot, math-film wordsFadeIn(shift) → fade_in {shift}next_to → at.place besidethe math@1 pack: a parameter it can’thonor is refused with a fix, never dropped2rungStart from a recipepiece@1’s twelve and explain@1’s filmrecipes; a subject and a few inputspiece.data_story{subject: sales, form: bars}checked: each recipe brings the checksits kind of piece needs3rungAdd a pack, as datakinds, recipes, cue verbs, eases orlayouts, written from one sentencedeep try pack@2checked: kits at pack check; it judges onlyits own claims until you approve it4rungWrite logicWebAssembly under sandbox@1 at a fixedstep; it writes only its own arrayslogic@1 · fuel · memory · stackchecked: seeking equals playing, by hash;it never draws by itself
COMPOSE FIRSTAn agent first composes what exists. More power comes from recipes with strong defaults, not from more tools.225 / 449
3.15.1Make › Checksin the system: Canvas core › checks
Part 3: How do agents show their work as pictures? › 3.15: How is a picture checked?

Every Check Returns Issues an Agent Can Act On

Every rung meets the same checks, which return issues as data. Follow one caption, 1 to 5; below, who owns which.

Agent’s documentcap.3 · chart.11film.layoutat every cue end2{ "check": "film.layout",  "code": "layout.covered",  "severity": "error",  "ids": ["cap.3", "chart.1"],  "t": "12.4s",  "actual": 0.42,  "what": "chart.1 covers 42% of cap.3",  "fix": "draw chart.1 below cap.3" }Issue3Agent patcheschart.1 order ↓4check again✓ passes, then it shows5

The core’s checks

validate, budget, frame time, layout, determinism, geometry audit, film audit, flicker, film layout, honest numbers, kind rules. They read only the core’s arrays.

Modules’ checks

record replay (record), input replay (input), export (export), physics.* and nav.reach (physics), logic.* (logic), net.* (net).

Plug-ins’ checks

Playtest, asset, rig and lip-sync checks through deep.registerCheck, reading evaluated data through deep.canvas.

Long lists

A reply inlines issues up to the read cap, errors first, and adds truncated with each code’s count; the whole list is evidence.

RULESAgents branch on the code, never the message; each code has a page at deep://codes, and an unlisted one is INVALID.226 / 449
3.15.2Make › Checksin the system: Canvas core › checks
Part 3: How do agents show their work as pictures? › 3.15: How is a picture checked?

Inside One Check: From deep_show to the Issues It Returns

The last slide showed one issue. Here is its whole trip: who runs each step, and which rule decides what shows.

Claude Codethe agentdeep mcp → hubforwards for one sessioncanvas coreadmits and checksdocument sessionrev 4 on screen1 deep_show: the explainer, whole, as rev 52 forwards; the writer comes from the connection3 admits it by size and rate; newest pending wins4 cheap kinds before every show; the rest when asked5 diff by ID with rev 4: a dropped ID must be in removes6 each issue vs rev 4’s, by code and IDs: new or carried7 a new error: refused; rev 4 stays on screen8 issues inline to 8,192 chars, errors first9 branch on the code, never the messagereplyrefused · rev 4 stays currentvalues illustrativenewlayout.coverederrorcap.3, chart.1fix: draw chart.1 below cap.3carriedlayout.crossingwarningnote.2rev 4 had it too, so it can’t refuse
RULESOnly issues the last good revision lacked can refuse a new one; a code the catalog doesn’t list is INVALID.227 / 449
3.15.3Make › Checksin the system: Canvas core › checks
Part 3: How do agents show their work as pictures? › 3.15: How is a picture checked?

Film Layout, by Example: Boxes and Strokes, Never Pixels

One core check, film.layout: four problems found from glyph boxes and strokes, each with its patch.

Receipt $18.00q2 44q3 48totalnotenoteglyph boxstrokelayout.cuttext past the frame’s edgefix: move in by the overshoot + 2.7 ulayout.overlaptwo texts share > 5% of a boxfix: move the later text the leastlayout.crossinga stroke within 4 u of a textfix: a 4 px halo in the paper rolelayout.covereda fill covers > 30% of a textfix: draw that fill below the text

Reads data, not pixels

Text boxes come from glyph outlines and strokes from the core’s flattened lines, so the answer is the same on every machine.

When it runs

At the end of every cue, hold and shot, and at the brief’s moments. Frames equal in data are checked once.

Whose thresholds

Overlap 5%, covered 30%, touch 4 u (1 u: a pixel at zoom 1) by default. A brief may tighten them; the working agent never sets them.

ONE ISSUE PER PAIRA pair seen at many times is one issue listing every time, so an agent fixes the cause once, not each frame.228 / 449
3.15.4Make › Checksin the system: Canvas core › checks › honest numbers
Part 3: How do agents show their work as pictures? › 3.15: How is a picture checked?

Honest Numbers: Every Number on Screen Has a Source

The honest-numbers check scans all text on screen: each number traces to a source or computation, or is a name.

$18.01the cart total in the filmbound value · run: the test run · as of 09:19✓traces to a run48the Q3 bar’s labela data constant with its source✓traces to the table9%Q3 over Q2driver: q3 ÷ q2 − 1, over sourced constants✓computed; no more precision than the sourceM3 Proa chip’s namemarked as a name✓skipped: a name, not a numberscore 3–1a story’s own numbersource: story✓passes only where nothing binds a statusone taste calla number wordno source✕counts as a number: it needs a source too52typed by the agentno source✕fails: bind it, compute it, or mark it a name$18,0…cut short to fitno source✕fails: a number is never ellipsizedHonest numbers
WHYA picture of a result must not mislead. Numbers show no more precision than their source, in tabular figures, and are never cut short.229 / 449
3.15.5Make › Checksin the system: Canvas core › checks › status colors
Part 3: How do agents show their work as pictures? › 3.15: How is a picture checked?

Status Colors Come Only From a Verdict

Slide 188 for data: left, four ways a mark might take the fail color, and what the check does; right, the rules.

status bindingverdict: claim #42 · FAILthresholdq3 < 50 → the fail colordata palettea series 0.04 from faildry-merge conflicta trial merge clashed; no verdict✕ FAIL✕ = FAIL✓glyph, word, legendrefused: no binding✕names the itemrefused: closer than 0.10✕names both colors⚠✓ink and a glyphStatus colorAttention

The legend appears whenever status shows

PASSFAILBLOCKEDINVALIDINCONCLUSIVE

plus running, needs you, stale and idle, each with its own glyph

Drawn last, exact

Unlit, after tone mapping and effects. No mask, effect or other writer’s layer can cover it.

Never color alone

Each status mark carries its glyph or word: the mark at 3:1 contrast, the glyph or word at 4.5:1.

One verdict, one color

A document shown inside another takes its host’s status map, distance and legend.

Art may differ

A film played on its own may use any palette, but it still can’t draw a status color.

WHYA red bar must mean a check failed, every time. If a threshold could paint it, a chart could look like a verdict without one.230 / 449
3.15.6Make › Checksin the system: Canvas core › checks › render-back
Part 3: How do agents show their work as pictures? › 3.15: How is a picture checked?

Render-Back: The Agent Sees, but a Picture Never Proves

Slide 149’s render-back, as an agent uses it. Left: what deep_show returns; right, views for finding a fault.

deep_showdoc · rev · tinclude: issues,audit · timing ·pixelsRender-backheadless canvasworker, same coreworks with the app closedabout 4 ms per snapshotrevissues · audit · timingpresented | not, with whysnapshots, by sha256visible IDs + boxes(at most 200 rows)A snapshot waits until its frame settles; past thetimeout it says why, and a check that needed it is BLOCKED.DIAGNOSTIC MODES, ONE SNAPSHOT EACHlighting onlyoverdrawnormalscascade splitsshadow atlasluminance, false colorlights per clusterdetail level per itemreceivers and castersskeletonlights and camerasboundsphysics shapesUV checker

A picture never proves

Snapshots and modes help the agent see. A document check passes a claim only when the document is itself the deliverable.

Provenance

Every change is a doc.patched event. A by-writer lens shows who made what, and a merge never loses a writer’s change.

Second opinions

Blender, Unreal and Godot run locally from your installs as test oracles. Without one, that check is BLOCKED with one ask.

LIMITSRender-back reads only the agent’s own layer, never the question card, other apps or your screen, and it never touches the live session.231 / 449
3.15.7Make › Checksin the system: Canvas core › checks › render-back
Part 3: How do agents show their work as pictures? › 3.15: How is a picture checked?

Inside Render-Back: How the Agent Gets Its Picture

What the last slide’s deep_show returns, step by step: who draws the snapshot, when it waits, how the agent sees it.

1Claude Codeasks deep_show forthe Q3 chart at rev 8,t = 0, issues + pixels2deep mcp → hubforwards it as thissession’s writer, neveranother session’s3headless workerthe same canvas core;evaluates rev 8 at t;the app may be closed4settle gatewaits until the frameis settled; only thenis a snapshot taken5render, read backoffscreen; 2D throughVello CPU; about 4 msat 1936 × 15846evidence storethe snapshot, storedby its sha256 hash,kept as evidence✓ no fallback pipelines✓ rebuild queue empty✓ assets decodedpast its timeout:not presented, with the reason;a check that needed it is BLOCKEDOnly its own layernever the question card,other apps or your screenActions, on a copyclick, hover and type runoffscreen and mint no serials7REPLY TO THE AGENT (VALUES ILLUSTRATIVE)rev8issuesnonepresentedyes · degraded: nosnapshotsha256 9f2c…e1 · 800 × 500VISIBLE ITEMS BY ID, AT MOST 200 ROWSq2box 92, 310, 120 × 160q3box 252, 290, 120 × 180titlebox 40, 24, 300 × 308The agent opens the picture byits handle, ev:9f2c…e1, and findseach item by ID and box.It explains; it never proves.
WAITS, NEVER GUESSESOnly a settled frame is snapshotted; one that can’t settle in time says why, and its check is BLOCKED.232 / 449
3.16.1Make › 3D scenesin the system: Canvas core › modules › 3D › scene3d
Part 3: How do agents show their work as pictures? › 3.16: How is a 3D scene described?

A 3D Scene Is Data: Shape, Material, Light, Camera

3D is a document too: one rocket on a pad. Each line the agent writes (left) adds a layer to what the app draws.

what the agent writes: one scene, as datarocket: cylinder + conebuilders return a mesh: triangles, named partsShapelook: metal, roughphysically based, so no textures neededMaterialsun: warm, casts shadowspoint, sun, spot or area; sky and fogLightcamera: orbit 30°a default move that reads wellCamerawhat the app drawsorbit 30°a still scene costs nothing to keep on screen

Shape

Made by a builder from a few settings: cube, sphere, cylinder, cone, torus, roofs, tubes; or loaded from a glTF file, the standard 3D file format.

cylinder · cone · glTF

Material

How a surface meets light: base color, metal, roughness, glass, glow. Cloth, skin, car paint and water too.

metal · stone · glass

Light

Point, sun, spot and area lights with color and power, plus sky and fog. Lamps are real lights, up to 32 a scene.

sun · spot · area

Camera

Where we look from: a lens or a flat view, depth of field, and moves such as push, orbit and follow.

push · orbit · follow
WHY DATAThe agent never writes drawing code. It names items and their settings; the app builds, lights and draws them, so checks can read every one.233 / 449
3.16.2Make › 3D scenesin the system: Canvas core › modules › 3D › scene3d
Part 3: How do agents show their work as pictures? › 3.16: How is a 3D scene described?

From Words to a 3D Scene (1 of 4): One Sentence, One Recipe

Now the rocket from one sentence: you ask, deep_kinds lists what to start from, and the agent picks, saying why.

1 · YOU, TO CLAUDE CODE“Show our rocket on its landingpad at golden hour, lit, so Ican orbit it.”2 · THE AGENT CALLSdeep_kinds: what can I start from?3 · deep_kinds lists recipes firstpiece@1whole pieces, 12 of thempiece.product_reveal · piece.machine · …studio@1quality defaultsrigs: studio.sun_and_sky studio.three_point · studio.turntablelooks: physical_filmmaterials (about 40): brushed_aluminiumlenses: normal_50 · wide_24 · …Recipestudio.sun_and_skya low sun and a sky; golden hour is time 18:40physical_filmAgX tone mapping and bloom, made for lamps and firebrushed_aluminiuma measured metal, each value with its sourcenot piece.product_reveala whole film on a turntable; you asked for a scene

deep_kinds

An MCP tool listing what a document can hold: kinds, recipes, packs, presets. Piece recipes first.

one example each

piece@1

Twelve recipes for a whole piece: a subject and a few inputs give shots, narration and music.

product_reveal · flyover · …

studio@1

Lighting rigs, about 40 measured materials, looks and lenses: names instead of numbers.

studio.sun_and_sky

Recipe

Expands at check into ordinary items, so nothing is hidden: deep_query lists each one.

never per frame
START FROM DEFAULTSThe agent never starts from a blank page: it names a rig, a look and a material that are known to look right.234 / 449
3.16.3Make › 3D scenesin the system: Canvas core › modules › 3D › scene3d
Part 3: How do agents show their work as pictures? › 3.16: How is a 3D scene described?

From Words to a 3D Scene (2 of 4): The Document, Line by Line

Left: the document the agent writes. Right: what each numbered line puts in the picture. It ends by calling deep_show.

rocket.json · what the agent writesprofile: scene · title: Rocket on its padpacks: [studio@1] · look: physical_filmitems:1camcamera {orbit: {elevation: 30, distance: 18}}2nosecone {radius: 0.5, height: 1.5} · steel3bodycylinder {radius: 0.5, height: 6} · steel4steelmaterial {from: brushed_aluminium}5lightstudio.sun_and_sky {time_of_day: 18:40}6flamecone, flipped · emission_strength: 87padslab {size: [8, 0.4, 8]}8s1shot {move: orbit, by: 30}then: deep_show(rocket) → issues, audit, snapshotsvalues illustrative12345678
Read it as data. Each line names a kind and a few numbers; the app builds, lights and draws them. The look and the rig come from studio@1, so no line sets a light’s color or a tone curve by hand.
EIGHT LINESA whole lit, framed scene is eight named items. Nothing in it is code, so every value can be checked and patched.235 / 449
3.16.4Make › 3D scenesin the system: Canvas core › modules › 3D › scene3d
Part 3: How do agents show their work as pictures? › 3.16: How is a 3D scene described?

From Words to a 3D Scene (3 of 4): One Miss, One Patch

Read left to right: what deep_show sends back, the one-value patch, and the snapshot before and after.

deep_show answers: rev 1✓scene.scalesizes in range✓render.exposurethe subject is lit✓render.contrastit stands out✓geometry.shadingno bad faces✕camera.framingthe flame is cutcut at the bottom edge · fix:pull the camera back 1.4 mIssueone patchitems/cam/params/orbit/distance18 → 19.4Patchcheck again: all ✓then it showsrev 1 · the flame runs off the framecutrev 2 · all of it inside the safe area✓

Loop checks

Each measures the scene and names a fix as patch ops: pull the camera back 1.4 m, raise exposure 0.7 EV.

scale · framing · exposure · …

Same on any Mac?

Scale, framing and shading read the scene’s data, so they hold everywhere. Exposure and contrast read pixels, so they hold on this Mac only.

else INCONCLUSIVE

Patch

One value at its path. The scene isn’t made again from scratch; only what the value touches rebuilds.

items/cam/params/…

Not a picture’s word

A model looking at the snapshot gives only a reading or a taste ask, never a pass.

render.review: a reading
A MISS COSTS ONE PATCHThe check names the item, the edge and the fix, so the agent changes one number instead of rolling the dice again.236 / 449
3.16.5Make › 3D scenesin the system: Canvas core › modules › 3D › scene3d
Part 3: How do agents show their work as pictures? › 3.16: How is a 3D scene described?

From Words to a 3D Scene (4 of 4): What Each Line Becomes

Top: four kinds of line and what the app makes of each. Bottom: the passes that turn them into one frame.

cylinder + cone {radius, height}a buildera mesh: points, triangles,named parts (top, side), uv0material {from: brushed_aluminium}the presetbase color, metallic androughness, from measurementsstudio.sun_and_sky {18:40}expands at checka sun, a sky and an exposure,scaled to the scene’s sizecamera + shot {orbit, by: 30}a formula of ta pose at every moment:15° before to 15° aftertopsidesun: low and warmsky + exposure−15°45°+15°seen from above: it sweeps 30°Then the GPU draws one frame:shadow map→sky→meshes + materials→bloom→tone map (AgX)
Built once, drawn every frame. The mesh and the rig are made once and kept by their inputs; while the orbit runs, only the camera’s pose changes, so each new frame is just steps 3 to 5 of the 3D primer: project, cover, shade.
NO DRAWING CODEEvery line turns into data the core knows how to draw. The agent chose names and numbers; the app did the rest.237 / 449
3.16.6Make › 3D scenesin the system: Canvas core › modules › 3D › scene3d
Part 3: How do agents show their work as pictures? › 3.16: How is a 3D scene described?

Shapes From Builders, Changed by a Stack of Modifiers

Builders (slide 211) in 3D: a cube becomes a row of blocks that builds itself as modifiers run in order.

StackbuildercubeBuildermodifier 1bevelModifiermodifier 2array ×4modifier 3build, by timeruns top to bottom, at build time1 · a cubefrom its settings only2 · + beveledges rounded3 · + array ×4four copies in a row4 · + buildrevealed over timet

Builder

Turns a few settings into a mesh with named parts and texture coordinates: cube, sphere, cone, torus, roofs, tubes, or a surface from a formula.

cube · torus · surface

Modifier

Changes the mesh above it: array, mirror, subdivide, bevel, solidify, displace with seeded noise, deform along a curve, build. A doubtful order is flagged, never silently fixed.

bevel · array · build

Recipe

A versioned group with typed inputs and defaults that calls builders and modifiers, so a new kind of shape needs no new code.

inputs · defaults · steps

Buildings

Walls, doors and windows cut as holes, eight roof types, stairs from the rise. Switching the prototype house to cutaway rebuilt 10 of its 91 nodes.

wall · roof · stair
BUILT ONCEEach step is a pure function of shape, settings and time, so anything still is built once and cached.238 / 449
3.16.7Make › 3D scenesin the system: Canvas core › modules › 3D › motion, skin
Part 3: How do agents show their work as pictures? › 3.16: How is a 3D scene described?

Moving Without Simulating: Motion Computed From the Time

Four kinds of motion, no physics: the canvas computes each frame from the time alone, so a seek equals play.

time0:000:050:100:150:20Skinned clipa walk clip, sampled at tParticlesMesh sequenceone wingbeat, each at its own phasePuppet righeld drawings for each mouth shapeposition = f(age, index, seed)a declared planetarget

Skinned clip

A character’s own glTF skin (a mesh bent by bones) and clips, sampled at the time. A walk can slow and stop on its mark; mouth shapes let a face speak a line.

up to 256 bones

Particles

Worked out fresh each frame from age, index and seed, never stepped. Bursts start from events; bounces only on planes the piece declares.

1,048,576 in a showpiece

Mesh sequence

An asset’s shape for each frame, played by the time. A flock shares one wingbeat; 100,000 walkers each play it at their own phase.

mesh.sequence@1

Puppet rig

puppet@1: parts, held expressions, mouth shapes, two-bone reach. A new rig is shown to you once as a model sheet; rig checks catch pops and sliding feet.

puppet@1
THE RULENone of these carries anything from one frame to the next, so a check, a scrub and an export all see the same frame at the same time.239 / 449
3.16.8Make › 3D scenesin the system: Canvas core › modules › 3D › scene3d
Part 3: How do agents show their work as pictures? › 3.16: How is a 3D scene described?

A Character Is a Rig, Shown Once as a Model Sheet

The puppet rig on the last slide, opened up: a character as data, approved once from its sheet, checked from then on.

MODEL SHEET: VIEWS × EXPRESSIONSfrontthree-quartersideneutralhappyworriedNEEDS YOU · TASTE · rig “Pip”, by its hashTHE RIG, AS DATAtargetsilhouette markpartchain: two-bone reachmouth: held drawings, A to H and Xantenna spring: baked at checkRIG CHECKS ON EVALUATED DATA✕pops✕missing in-betweens✕shoulders in the wrong order✕props outside the palms✕brows that read wrong✕unreachable targets✕sliding feet✕missing views✕lost silhouette marks✕lip syncname “Pip” illustrative

Held drawings

Expressions and views are drawings: one shows until the next key, never a blend. Parts draw in the shot’s look.

Shown once

A new rig’s model sheet is one taste ask keyed by its hash. Until you answer, a shot that shows it is BLOCKED.

Anything that acts

An object with a face that acts, such as a mug that frowns, is a rig too, held to the same checks.

Never a copy

No living artist’s, studio’s or trademarked character. Caps of 64 parts and 8 chains are proposed.

DATA, NOT CODEA rig expands at check into groups, flips, constraints and clips that already exist; nothing runs per frame.240 / 449
3.16.9Make › 3D scenesin the system: Canvas core › modules › 3D › scene3d
Part 3: How do agents show their work as pictures? › 3.16: How is a 3D scene described?

Skinned Playback: A 3D Character Plays Its Own Clips

A drawn rig is one kind of character; the other is a 3D asset with its own skin. Both play from the time alone.

A PRESENTER WALKS TO ITS MARK AND WAVESmarkroot: along the curveonly: arm_rPLACEMENTS ON ONE ITEMwalkroot: along curvestopidlewave · addonly: arm_rvisemesfrom narration line 20s2s4s6s8s10sEach frame: sample the clips at t, mix, skinonce in a compute pre-skin every pass reads.

Its own skin

A licensed or generated glTF character’s skin and clips, sampled at t. At most 4 influences and 256 bones; a bone is item#bone.

Mixed, never stepped

Placements mix by weight in a fixed order; an add placement lets a wave ride on a walk; only limits it to bones.

Feet that don’t slide

Travel follows the clip’s own feet along a curve; a walk, a stop and a turn chain with no jump. A contacts check reports slides.

Faces and props

Morph targets take weights as channels, so a face speaks a line’s visemes. A file with no skin moves its parts rigidly: a lid opens.

NO RIGGING HEREThe canvas never authors weights, rigs or morph targets, or solves IK by iteration; a job retargets clips.241 / 449
3.16.10Make › 3D scenesin the system: Canvas core › modules › 3D › voxels
Part 3: How do agents show their work as pictures? › 3.16: How is a 3D scene described?

Worlds Too Big to Draw Whole: Chunks and Voxels

When a world is too big to draw whole, the canvas splits it. Left: terrain chunks, finer near you. Right: voxels.

Chunk tree?near you: finest chunksthey load firstfarther: coarsererror stays under a pixelfar: coarsestone not loaded yet:a final waits; missing = BLOCKEDa block world that a game’s logic editsVoxelslogic writes: grid[x, y] = 0only this brickis meshed again;every other brick stays

Chunk tree

A terrain, a huge mesh, a point cloud (PLY, PCD, LAS) or a 3D Tiles region, cut into chunks; each child is finer than its parent.

chunks@1

Under a pixel

A view draws the coarsest chunks whose error would show smaller than a pixel. Live, the nearest load first within a byte budget.

Never coarser

Final frames, exports and checks wait for every chunk they need. One that is missing makes them BLOCKED, never drawn coarser.

BLOCKED, not blurry

Voxels

3D pixels: a grid of palette colors from an asset or a game’s logic, meshed brick by brick on the CPU; only bricks a step changed are meshed again.

voxels@1 · 256³ from logic
LOGIC WRITES, THE CORE DRAWSA game’s logic writes numbers, voxels or a mesh’s triangles; the core draws them as meshes checks can read.242 / 449
3.16.11Make › 3D scenesin the system: Canvas core › modules › 3D › look, raytrace
Part 3: How do agents show their work as pictures? › 3.16: How is a 3D scene described?

From Scene to Pixels: Passes, Live Extras, Final Frames

How the app draws a 3D scene, in the passes of slide 166. Bottom: live-only extras, and what checks use.

PassShadow mapseen from the key light1Sky and meshesmultisampled, high range2Blooma glow from what’s bright3Ink edgeswhere depth jumps4Tone mapinto what the app shows5The prototype’s castle-town above the clouds draws in about 10 ms a frame at 3024×2180 on an M3 Pro, by wall clock, CPU and GPU together.
Live view only, while it moves
  • Smoothing, upscaling and ray denoising keep a fixed window of recent frames; a jump draws that window again.
  • HDR on XDR displays.
  • Budgets bend: 256 MB of GPU memory a window; a big 3D view drops to 0.5 internal scale, then a 2-frame history.
Checks, exports and finals
  • sRGB and no history: each frame stands on its own, at full scale.
  • Light without history, or rays at many samples a frame.
  • Path-traced finals render offline, each seeded by its own frame number, and replay exactly on one machine.
LandsBuilders and meshesR2Materials and lightR2–R6Camera and shotsR1–R6Ray-traced lightR6Path-traced finalsR6
CHOICERays switch on by the GPU’s ray class (hardware from Apple’s M3 on, emulated on M1 and M2), never by its name. Path tracing never runs live.243 / 449
3.16.12Make › 3D scenesin the system: Canvas core › modules › 3D › loop checks
Part 3: How do agents show their work as pictures? › 3.16: How is a 3D scene described?

First Try, Then Checks: One-Shot Scenes and Machine Figures

An agent names presets; the canvas checks. Left: a one-shot scene fixed by one patch. Right: an audited machine.

One-shot scene1 · names, not numbersstudio@1rig: productlook: Neutral2 · render3 · loop checks✓scale✕framing✓exposure✓contrast✓floating parts✓noise✓budgetfix: frame the subject4 · one patch, render again:the miss is named, not rerolledAn AI model’s view of the frame,tied to an object-ID view, is onlya reading or a taste ask.Machine figureFig. 1 · Dial gauge43 parts, one modeltaken apartalong each part’sapart vectorthe audit, from true shapes✓nothing passes into anything✓at rest, apart, every frame✓every part is held✓every wire and tube end lands✓display text fits✓declared ranges holdbroken fixture: its 5 faults, exactly

studio@1

Lighting rigs, measured materials, looks and lens presets an agent names instead of numbers: Neutral for products, AgX for night and fire.

rig · look · lens

Loop checks

Scale, framing, exposure, contrast, shading defects, overlaps, floating parts, missing assets, noise and budget, each naming its fix.

measured on a render

Machine figure

Explains an idea by building a working object: assemblies from 18 part kinds, eased take-apart, a card with a live readout.

about 4–5 ms a frame

The audit

Checks every part’s true shape. The 43-part dial gauge passes with zero failures; each failure names parts, check, time and fix.

JSON report
FIRST TRYStrong defaults aim for a good scene on the first try; the checks take a miss the rest of the way, one named fix at a time.244 / 449
3.17.1Make › Play, physicsin the system: Canvas core › modules › play › physics
Part 3: How do agents show their work as pictures? › 3.17: How do pieces become interactive?

Interactive Pieces: On the Canvas, or in a Game Engine

From watching to playing: a bounded piece runs on the canvas; a whole game goes to an engine project.

An interactive idea“a rocket landing at sea,playable, for two”pieces of a minute or so: a lab, a quiz,a small game for two to eight playersphysicslogicnetmediaCanvas piecea complete game in a pinned engine project;DeepBuild creates, builds, launches and drives itGodot firstmacOS, then the webEngine projectThe same proof on both routes✕game code never touches checks or decisions✕it can’t grant itself permissions✕it can’t imitate the question card✓bots play seeded runs of it, headless✓a tour, a video or a still never counts as playPlaytest

Canvas piece

Interactive visual work and bounded games: rules, rooms and things that fit the arrays and bodies the piece declares, with saves.

physics · logic · net

Engine project

A complete game goes to a pinned engine, Godot first. A first-party blueprint creates, builds, launches and drives it through journeys.

game project blueprint

Playtest

The check that needs live play. Bots play seeded runs; a run fails when stuck, short of a goal, trapped or over budget. Each run replays.

deep.registerCheck

Genre kit

One genre’s tested core as libraries a piece links; the grid core comes first. pixel@1 draws tiles and sprites in at most 32 colors.

grid core · pixel@1
THE BARA presentation, not a complete game: pieces of a minute or so, as close to the best real-time engines as your GPU allows.245 / 449
3.17.2Make › Play, physicsin the system: Canvas core › modules › play › physics
Part 3: How do agents show their work as pictures? › 3.17: How do pieces become interactive?

Interactive Pieces, Taken Apart: Physics, Logic, Shared Play

Three canvas modules make a piece playable. Each splits into the parts the next slides explain.

Playwhat makes a piece something you can playphysics: the worldshapes, bodies, contact materials,collision groups, gravity→ 248physics: special bodiescharacter bodies, vehicle bodies,joints and forces, soft bodies, breakables→ 249physics: prooffixed steps, checkpoints, bakes,goldens, behavior kits, navigation→ 251logicgame rules as WebAssembly: arrays,turns, saves, sounds, libraries→ 252sandboxchecks agent code, adds fuel so arunaway loop stops the same everywhere→ 253net2 to 8 players: only inputs travel;roll back, or wait in lockstep→ 258
HOW THEY STACKLogic decides the rules, physics moves the world, net shares the inputs; all three step on the one clock.246 / 449
3.17.3Make › Play, physicsin the system: Canvas core › modules › play › physics
Part 3: How do agents show their work as pictures? › 3.17: How do pieces become interactive?

Physics Primer: Fixed Steps Make a Replay Land the Same

Play needs physics: the physics module steps the rocket at a fixed rate, stamps each press, and keeps checkpoints.

the rocket-landing piece2Fixed stepstep 01 step = 1/120 s3Input trackthrust onthrust offdragCheckpoint1worldthe rocket’s height, step by step4Seek = playrestore checkpoint, then step forward
1The world is built from the document: shapes, bodies, gravity and a seed.
2It moves in fixed steps of 1/120 s. A force such as wind depends only on time and place.
3Your drags, throws and key presses are kept on an input track, each stamped with its step.
4A seek restores the nearest checkpoint and steps forward. Scrubbing back keeps later inputs; a new drag forks there.
SEEK = PLAYA frame is a function of the document, the time and the input track, so scrubbing, replay, checks and export agree.247 / 449
3.17.4Make › Play, physicsin the system: Canvas core › modules › play › physics › world, bodies, joints
Part 3: How do agents show their work as pictures? › 3.17: How do pieces become interactive?

What a Physics World Holds: Shapes, Bodies, Joints, Forces

The rocket as a world document an agent writes. Each yellow label is one kind of item; touchdown is an occurrence.

Static bodyDynamic bodyJointwindForceOccurrencephysics.world@1step120 Hz · gravity · seedrocketdynamic · convexbargestatic · boxlegshinge · limit · motorwinda force of time and placesteelfriction · bounce · tagcontact · step kspeed, point, tagsa thud, from steel’s taga chart row: landing speed

Shapes

Sphere, box, capsule, cylinder, convex, static mesh, height field and compound; segments and polygons in 2D.

box · capsule · convex

Bodies

Static, kinematic (follows a channel), dynamic, character or vehicle. None is created mid-run: declare it inactive, then wake it.

static · dynamic

Joints and forces

Hinge, ball, slider, spring, rope, gear and more, with limits, motors and a break point; a break is an event. Wind, drag, buoyancy.

hinge · rope · wind

Occurrences

Events the world records: contact, sensor, break, rest and crossing, sorted per step and baked, so sounds, drivers and charts read them by time.

contact · break
RAPIER, BEHIND AN INTERFACEPinned to 0.36.1, determinism on, no fast math; physics@1 absorbs its API changes.248 / 449
3.17.5Make › Play, physicsin the system: Canvas core › modules › play › physics › character, vehicle
Part 3: How do agents show their work as pictures? › 3.17: How do pieces become interactive?

Heroes, Cars and Paths: Character and Vehicle Bodies

Three game features from the physics module, none in the core: a hero, a car on sprung wheels, a path.

Character bodyVehicle bodyNavigationsteps under its step height✕too steep:past its limitjumpbodysprings: hertz, dampingwheels: rays downstartgoal✓nav.reach

One capsule that the backend’s character controller moves, with a slope limit, a step height, snap to ground and a jump. Only its inputs, its controller and gravity move it.

A chassis on up to 8 ray-cast wheels with sprung suspension. Drive, steer and brake are held inputs; steering follows Ackermann’s rule; a wheel touching down writes an event.

An asset job bakes a graph from the level’s fixed shapes, and the piece’s own logic finds paths on it. nav.reach proves every goal can be reached.

SAME RULESEach body’s state joins every checkpoint and hash, so a jump replays exactly. A rig draws on top; the body only moves.249 / 449
3.17.6Make › Play, physicsin the system: Canvas core › modules › play › physics
Part 3: How do agents show their work as pictures? › 3.17: How do pieces become interactive?

One Physics Step, in Order, and How a Seek Lands on It

The bodies of the last slides, moving: the order inside one 1/120 s step, then how a frame and a seek (160) read it.

INSIDE STEP k, ALWAYS IN THIS ORDER (THE PHYSICS MODULE, ON RAPIER)1Apply the inputs stamped for step kordered by kind, then target ID · e.g. thrust, fired by logic2Move kinematic, character and vehicle bodieskinematic targets from channels at t(k+1) · none here3Add forces from the state at t(k)wind: a force of time and place, so it replays exactly4Rapier steps onceits 4 substeps are solver iterations, not extra steps5Read the occurrences and sort themby (step, kind, a, b) · e.g. contact_begin: rocket, barge6Write the state into a two-step ring; hash ita cheap step hash: about 52 B per body, 10 µs for 200ONE FRAME AT t = 7.31 s876877878879αk = ⌊7.31 × 120⌋ = 877α = 877.2 − 877 = 0.2the pose mixes steps 877 and 878: positions lerp, rotations nlerpONE SEEK TO 7.31 sa checkpoint every 60 steps (0.5 s)7808409008781 restore 8402 step 841 → 878: 38 steps, each in the order at left3 the same per-step hashes as a straight run from 0 ✓Baked? The seek reads the bake’s outputs; only a fork re-simulates.“A seek across a checkpoint followed by play equals a straight run, by per-step hash.” The rule the physics module is held to.
WHY THE ORDER IS FIXEDSame inputs, same order, pinned Rapier: the same bits each run, so replay, seek and goldens agree.250 / 449
3.17.7Make › Play, physicsin the system: Canvas core › modules › play › physics › bakes, goldens
Part 3: How do agents show their work as pictures? › 3.17: How do pieces become interactive?

Physics Proves Itself: Hashes, Goldens, a Behavior Kit

The physics module proves it replays: play vs seek on one Mac, a golden across two, and a behavior kit.

Same Macplay vs seekTwo Macsa goldenBehavior kitanswers from first principlesplayseekrestored here✓full-statehashes equalMac ArecordedMac Bfirst difference, e.g.step k · velocityfree fallprojectilependulumslidejumpSoft bodya rope bridgebanner#r0c27a particle’s stable nameNot yet run on Rapier here: proven only oncerope and banner goldens pass on two machines

Bake

Kept by the document, the input track and the backend’s version. It holds checkpoint hashes, events and outputs, so playback never re-simulates.

Golden

Hashes recorded on one machine and checked on another. A mismatch names the first step and field that differ.

same backend, two Macs

Behavior kit

Fixtures with answers worked out on paper: free fall, a projectile’s range, a pendulum’s period, a slide, a jump. Any backend must pass.

tolerances are ours

Soft body

Ropes, cloth, balloons and a jelly cube, each particle with a stable name. Heavier cloth and fluid bake offline and play back exactly.

soft@1
HONEST STATUSThe prototype lab’s own small solver matched a straight run step for step after a fork. Rapier’s soft bodies haven’t run here yet.251 / 449
3.18.1Make › Logicin the system: Canvas core › modules › play › sandbox, logic
Part 3: How do agents show their work as pictures? › 3.18: How do game rules run safely?

Game Rules as Code: Logic in a WebAssembly Sandbox

Physics moves the rocket; its rules (burn fuel, landed or not) are logic, a small program. One step, in to out.

Read regioninputsthrust pressed, player 1readingsas last recordedarraysas earlier steps left themseeddoc seed + item + stepstep(k)fuel − 1; landed?no imports, so nothing to reachLogicSandbox✕ network   ✕ files   ✕ clock✕ threads   ✕ devicesArraysfuellandedfalsefiresthrust force → physicsthe core draws them: a gauge, a flame;the program never draws by itselfFixed step60 steps a second by default, beside physics

WebAssembly

A compact program format that runs the same in the app and in a browser. The agent builds it in its own repo; the app takes it by hash.

logic@1

Reads only what it declares

Its controls’ entries, recorded readings, other arrays as earlier steps left them, and a seed from the document.

reads: […]

Writes only its own arrays

Never checks, verdicts, the record, status colors or the question card. It never draws: the core draws what it writes.

writes: {…}

Whole state saved

Memory and globals are its whole state, checkpointed like a world’s, so seeking equals playing, proved by full-state hashes.

checkpoint · bake
WHY A SANDBOXAgent code runs inside your app. With no imports it can reach nothing, and its whole state can be saved and compared.252 / 449
3.18.2Make › Logicin the system: Canvas core › modules › play › sandbox › fuel
Part 3: How do agents show their work as pictures? › 3.18: How do game rules run safely?

Fuel: A Runaway Loop Stops at the Same Spot Everywhere

The sandbox module rewrites each program to count its work, so a runaway step traps at one spot everywhere.

at check, the program is rewritten oncebeforeloop:x = x + 1go to loopafterloop:fuel −= 2if fuel < 0: trapx = x + 1go to loopalso: NaNs made canonical,stack depth counted, and memorythat can never growfuel for one step1,000,000 by default0a loop thatnever endsTRAPThe app, on this Mactraps at the same instruction, same step✓Another Mactraps at the same instruction, same step✓A browser, in the web playertraps at the same instruction, same step✓Only that item freezes, its arrays at their last values;the rest plays on. In a match, a trap ends it as faulted.

Budgets

Per step by default: 1,000,000 fuel, 4 MiB of memory, 64 KiB of stack. A piece may raise them to 10,000,000, 64 MiB and 256 KiB.

budget: {fuel, memory, stack}

One subset

WebAssembly 2.0 without vector instructions, one memory of fixed size, tables that never change, no imports. The app runs it in wasmtime, pinned.

sandbox@1

Step ceiling

Heavy work such as an AI’s turn is split across steps. deep_kinds publishes how much fuel a step may use within a live frame.

logic.budget

Reported

A trap is reported with its step, the inputs that step read, and where it stopped. A run that trapped can never pass.

logic.trap
WHY FUELA budget counted in instructions, not seconds, runs out at the same place on every machine, so replays, goldens and the web player agree.253 / 449
3.18.3Make › Logicin the system: Canvas core › modules › play › logic
Part 3: How do agents show their work as pictures? › 3.18: How do game rules run safely?

Logic and Physics on One Clock: Who Steps First

With fuel bounding each step, here is how a logic step meets physics on the clock, from one press of thrust.

input trackyour presseslogic · 60 Hzthe rocket’s rulesphysics · 120 Hzthe rocket worldframewhat you see3.100 s3.110 s3.120 s3.130 s186187188372373374375376thrust: on · player 112read at the next logic stepstep(187): burn, fire thrust34same instant: logic runs firstapplies thrust5logic as 187 left it; pose k = 3756times and step numbers illustrative

Logic reads the past

Its read region holds the entries since its last step, arrays as earlier steps left them, and a seed, hash(doc seed, logic ID, k).

Physics reads the present

At its own step’s time it reads logic’s arrays and the inputs logic fired, so at one instant logic runs first.

A frame reads both

Logic’s arrays as the last step at or before t left them; poses mixed between two physics steps.

THE ORDER IS DATANobody writes “logic first”: the seal derives it from what each step reads, the same on every run.254 / 449
3.18.4Make › Logicin the system: Canvas core › modules › play › logic
Part 3: How do agents show their work as pictures? › 3.18: How do game rules run safely?

What Logic Gives a Game: Sounds, Saves, Turns, Libraries

Six things a game needs from its rules. Each is a small, checked addition to the logic module, shown in action.

scorehitdoor

Occurrences

A step can write events (a score, a hit, a door opening); sounds, bursts and clips play at their steps. A step past its cap traps instead of dropping one.

writingnewestone before✓reads backwhole

Saves

Stop and go on later. Written whole or not at all; each slot keeps its newest and the one before. A fix that keeps the layout keeps every save.

input → stepidle: the app sleeps

Turn clock

With clock: on_input, a step runs only when input arrives, so an idle turn-based game runs nothing and lets the app sleep.

10 Hz steps, drawn smoothly

Smooth drawing

A write marked linear is drawn blended between the last two steps, so a 10 Hz simulation still moves smoothly on screen.

hover: a pathand a forecast

Preview

On hover, a throwaway copy works out the path to a hex or a fight’s forecast. Never saved, sent, hashed or exported.

grid core kityour rulesone program✓tests

Libraries

Pinned libraries, such as a genre kit’s grid search, are linked in at check, only once their own tests pass. The running program still imports nothing.

FOR BIG WORLDSA world can page past memory, up to 4 GiB in 64 KiB pages, and a step can split into blocks run on several threads with the same bits.255 / 449
3.18.5Make › Logicin the system: Canvas core › modules › play › sandbox
Part 3: How do agents show their work as pictures? › 3.18: How do game rules run safely?

Agent Code in a Piece: What We Compare, and Why

Before the scores on “Agent Code in a Piece”: each row is one column of the next slide’s table, and why it matters.

ColumnWhat it measuresWhy it matters
1Same steps everywhere same result on every machinereplays and goldens must match
2Can’t escape no files, network or devicesagent code runs inside your app
3Budgets trap alike too-long code stops the same waya runaway loop can’t freeze the view
4Expressive can express game rules and AIsmall games need it
5Seek = play jumping to t equals playing to tscrub, checks and export agree
The options on the next slideData only, no codeJavaScript expressionsNative plug-in code per frameWebAssembly logic, fixed step
NEXTEach option scored on these 5 columns, three diamonds for strong.256 / 449
3.18.6Make › Logicin the system: Canvas core › modules › play › sandbox
Part 3: How do agents show their work as pictures? › 3.18: How do game rules run safely?

Agent Code in a Piece: Sandboxed WebAssembly at a Fixed Step (R6)

When a piece needs real rules (a game, a bot), what code may it hold?

OptionSame steps everywhereCan’t escapeBudgets trap alikeExpressiveSeek = play
Data only, no codedrivers and expressionsDropped
JavaScript expressionsmotion-graphics styleDropped
Native plug-in code per frameDropped
WebAssembly logic, fixed stepsandbox@1, fuel by our rewriteChosen
strong weak breaks a hard rulescores: our reading of the gains and costs recorded in the design
WHYOnly WebAssembly that imports nothing, writes only its own arrays and runs on counted fuel scores strong on every column.257 / 449
3.19.1Make › Shared playin the system: Canvas core › modules › play › net
Part 3: How do agents show their work as pictures? › 3.19: How do several players share a piece?

Shared Play: Only Inputs Travel Between Players

Two players, in the app and a browser: the net module runs the whole game on each copy, and only presses travel.

your app · player 1Copysame worldinput track298299300301302303a browser, web player · player 2Copysame worldinput track298299300301302303p1p2p1p2or straight between copies, when both platforms allowJoinnames the relay hostJoinrelay you declareforwards, holds nothingRelayp1 · thrust · 300p2 · steer · 300Input entryevery 60 steps: full-state hashes compared✓equal on every copy

Every copy runs everything

Same document, input track and modules, by hash, at one match step (60 Hz by default). Two to eight players.

net@1

Only inputs travel

Each copy sends its player’s entries for each step; every copy orders them by step, player and seq, never by arrival. No state, no pixels.

about 32 B + 32 B an entry

A relay that holds nothing

A relay only forwards messages. Copies meet through the one a piece declares; DeepBuild ships a small relay you run, and runs no service itself.

relay@1

Join

Nothing opens until a person clicks Join on a prompt the app or player draws, naming the relay. No cookie, credential or anything about you.

NOT IN SCOPEAuthoritative servers, matchmaking, anti-cheat, voice and large player counts. Peers are equals: every copy holds the full state.258 / 449
3.19.2Make › Shared playin the system: Canvas core › modules › play › net
Part 3: How do agents show their work as pictures? › 3.19: How do several players share a piece?

A Late Input: Roll Back and Replay, or Wait in Lockstep

An input arrives late: the net module rolls back and replays (top, light pieces) or waits in lockstep (bottom).

Rollbacklight pieces:your input shows at once294295296p2?297p2?298p2?299p2?300301302303checkpointnowp2’s entry for step 297 arrives late, at step 300restore the checkpoint, step 297 to now againp2 ✓p2 ✓p2 ✓p2 ✓window: 8 stepsdelay: 2 stepsLockstepheavy pieces:a factory, a strategy gamewaitsA copy steps only once it holds every player’s entries: nothing predicted, nothing rolled back.At 20 Hz, 4 steps of delay hide 200 ms; after 0.25 s the app, never the piece, names the late player.

Desync

Copies compare full-state hashes every 60 steps. A mismatch stops the match and names the first step and field. It is a defect, never retried away.

net.desync

Fair rolls

After an attack is confirmed, every copy adds 64 secret random bits, committed before revealed, so nobody reads a roll ahead or picks it.

draw_after

Courtesy fog

Each copy may hide what its player can’t see, but every copy holds everything. The Join prompt says so in plain words.

match.me

Replay

Every match keeps its merged input track, so it replays exactly and exports like any piece. An export never shows a predicted frame.

WHICH ONEAction games pick a rollback window from the net.budget check, or play lockstep; net.feel bounds felt lag.259 / 449
3.19.3Make › Shared playin the system: Canvas core › modules › play › net
Part 3: How do agents show their work as pictures? › 3.19: How do several players share a piece?

One Match Step on Every Copy: Send, Predict, Confirm

Under the rollback: what each copy sends every step, what it assumes until it hears, and when a step is final.

your app · player 1a whole copy of the piecerelayforwards, holds nothinga browser · player 2another whole copy298299300301302303304305298299300301 · p1?302 · p1?3033043051thrust at 300 is stamped for 302: delay 2{match, player: 1, step: 302, entries: [thrust]}23p1? = player 1’s last input, assumed until heard; no entry is added302 · p1 ✓4heard at 303: lands at 302, rerun5confirmed moves to 302: both players heardsteps and the message illustrative

One message a step

Each copy sends one per match step, empty or not, and repeats any not yet confirmed; a receiver keeps the first copy.

By step, never by arrival

Entries go on every track by (step, player, seq), so every copy applies the same entries at the same steps.

Final once confirmed

A copy runs at most 8 steps past confirmed. Saves wait for it; a full-state hash every 60 confirmed steps.

NO AUTHORITYEvery copy runs everything and holds the full state; none is the referee, and no state crosses the wire.260 / 449
3.20.1Make › Soundin the system: Canvas core › modules › out › media
Part 3: How do agents show their work as pictures? › 3.20: How does sound follow the picture?

Sound on the Picture’s Clock: Five Tracks, One Playhead

Sound runs on the picture’s clock: five tracks, one playhead (black line). When line 2 moves, its motion follows.

TrackPictureshots on the timelineshot 1shot 2shot 3Narrationa speech job, heard backline 1line 3Musicscore@1, rendered to stemsa score with a tempo mapSound effectsfoley@1 presets, by hashCaptionsalways on, timed for readingcap 1cap 3whooshclickline 2cap 2the chart’s motion is anchored to the start of line 2StripCaptionStemline 2 moved later: the motion followed

Track and strip

A strip places a sound, a video, an image or a job’s output on a track, with in and out points, fades and gain. Cuts fade over at least 5 ms, so no edit clicks.

strip · track

Narration sets the pace

A line can start a set gap after another; motion can anchor to a line’s start or end. Overlapping lines are refused.

anchor · gap

Captions, always on

Designed by the look and timed by a caption profile (reading-speed rules); burned into the frames, or carried as .srt and .vtt files.

.srt · .vtt

Never by surprise

Sound starts only after your gesture, with an indicator naming its owner, and a true-peak limiter caps the output.

device gate
ONE CLOCKSound lives on the picture’s clock, so a seek lands both together, and re-timing a line moves the motion tied to it.261 / 449
3.20.2Make › Soundin the system: Canvas core › modules › out › media
Part 3: How do agents show their work as pictures? › 3.20: How does sound follow the picture?

Narration, Music and Effects: Made by Jobs, Then Checked

Each sound is made once, offline, by a pinned job (a fixed tool version), kept by hash. Follow one narration line.

script line“Light bends near the hole.”speech jobKokoro speech engine, countedheard backtranscribed, matched to scriptwords bakeeach word’s start and endcaptions + mouthtiming and lip syncNarrationscore@1notes on a beat gridscore.render@1a pinned jobstems, one per partby hash, same on every exportnote onsetsas events motion can followloop regiona bed that loops, no seamScorefoley@1(material, action) presetsfoley.render@1a pinned job3 levels × 4 variantsround robins, by hashspawned by eventsa contact plays a thudheard where it isin 3D, from the cameraFoley✓
Checked after the codec: R 128 at −23 LUFS ±0.2 LU, peaks at or under −1 dBTP; streaming at −14 ±1 LU; adult captions at up to 20 characters a second.
The audio thread is our own code with pinned math: it allocates nothing and takes no locks. Libraries are CC0 or CC BY only, each credited.
WHY OFFLINE JOBSStems rendered once and kept by hash sound the same on every export; no plug-in code runs in the audio thread.262 / 449
3.21.1Make › Exportin the system: Canvas core › modules › out › export
Part 3: How do agents show their work as pictures? › 3.21: How does a piece leave the app?

Export: One Canonical Render, Seven Ways Out

Out of the app: each export redraws the frames you scrubbed, offline on a virtual clock, for seven targets.

One canonical renderframe k = the frame at start + k×ΔVirtual clock012345the frames you scrubbed, drawn again offlinehashed on the GPU before anything is encodeddraft: frame guards only, stays in the appMP4 / ProResalpha on macOS; captions burned in or .srtPNG framesa range, or one still at a frame or markerLottie2D motion for a web page or an appPDF handouta page per stage, its settled frameglTF3D at a time, for any enginePlayable pagestages and choices, any browser, no networkWeb playerthe piece live in a browser, on WebGPU

Virtual clock

Rendered offline: frame k is the frame at exactly start + k×Δ, so the file never depends on how fast the machine drew it.

Kept by hash

Each frame is hashed on the GPU, never read back, and each sample on the CPU. A held frame is drawn and hashed once, however long it holds.

frame_hashes · pcm_hashes

Draft or delivery

A draft runs the frame guards only, stays in the app’s store, and can never be shared, attached or sent.

purpose: draft
SCRUB = EXPORTThe file holds the frames the live view settled to. An export never differs from them, except a path-traced final, which is held to them.263 / 449
3.21.2Make › Exportin the system: Canvas core › modules › out › export
Part 3: How do agents show their work as pictures? › 3.21: How does a piece leave the app?

An Export Proves Itself Before It Leaves the App

The export module’s five guards, left to right: any failure stops a delivery, names the frame, leaves no file.

Raw frameshashed on the GPU,never read backNo broken framesblank or non-finiteframes stop it1Encodethe platform’s ownencoder first2Decode it backand draw again:each frame once3Tags, loudnesscolor tags; loudnessafter the codec4Licensesevery one its jobsused, credited5Deliveredwritten whole,then renamed✓a blank frame: it stops, names the frame, leaves no partial file1 shard or 3: identical hasheseach file read by a reader its writer doesn’t control

glTF

Checked by the Khronos validator and a round trip. One file per engine profile: plain glTF, Unity, Unreal, Godot, Blender, Roblox.

asset.validate

Lottie

2D motion for the web. It lists what Lottie can’t hold instead of dropping it, and is read back by a pinned reference renderer.

export.fidelity

Playable page

Stages, choices and variants as rendered stills and clips. No network, no code from the document; up to 64 states and 256 transitions.

page

Web player

The canvas core built for the browser, with physics and logic live. It won’t play until every file matches its hash.

<deep-player>
NEVER EVIDENCEA film can ride beside a claim as an explanation, never as evidence. A tour, a video or a still never counts as play for a playtest.264 / 449
3.21.3Make › Exportin the system: Canvas core › modules › out › export
Part 3: How do agents show their work as pictures? › 3.21: How does a piece leave the app?

Inside an Export: Who Draws, Who Encodes, Who Reads It Back

The five guards, by who runs them: the encoder never judges its own file. One frame of the explainer, 1 to 9.

export modulecanvas core, on the GPUencode jobVideoToolbox, own processdecode workerfresh, apart from the toolthe deliveryone file1 draw frame k at start + k×Δ, on the virtual clock2 BLAKE3 on the GPU; only the 32-byte digest comes back3 an exact pass makes NV12: fixed point, never floats4 a surface slot: its index and time5 encodes; writes under a temporary name6 its own bytes, tags and edit list7 decoded frames, back as GPU surfaces8 draw k again: its hash must equal the receipt’s9 nearer its own raw frame than a neighbor; PSNR-Y ≥ 40 dB✕ Say the encoder dropped frame 913: decoded frame 913 matches raw frame 914 better.export.fidelity fails, naming frame 913, and nothing partial is left. All pass: renamed, receipt kept.frame number illustrative
A READER IT DOESN’T CONTROLAn encoder’s exit code or report never proves a delivery; its file, decoded apart, does.265 / 449
3.22.1Make › Budgetsin the system: Canvas core › compositor › cost
Part 3: How do agents show their work as pictures? › 3.22: How does the canvas stay light on your Mac?

Budget Classes: The Canvas Must Not Slow the Agents’ Mac

The caps the canvas holds each view to: slide 152’s six classes in full; next, how the meter holds them live. * proposal.

CLASSMS PER FRAMEGPU MEMORYSCALE MOVINGIDLE LOOP120 Hz frame: 8.33core viewthe line, Needs you, receipts, sheets64 MB*1none1 ms*2 msdata viewcharts, graphs, flat maps, terminals128 MB*1none2 ms2 msfigurefigures and film previews in a panel256 MB a window130 fps2 ms4 mswork productscenes you or an agent edit256 MB a window0.75*30 fps2 ms4 msshowpiecefull-screen 3D, such as the castle256 MB a window0.530 fps10 ms at 30 fps4 msexportheadless renders, no frame capdraft ≥ 4× real time at 1080p60; delivery ≥ 2×met by each speed fixture on its own300 MB a filmGPUCPU
0

frames drawn while nothing moves, in every class

0

heap allocations a frame after warm-up

256MB

of GPU memory a window; a big 3D view first renders at half scale, then keeps 2 history frames

2frames

for a drag to show on screen; a patch within 1 frame of the latch; cold opens and edit loops are timed as readings

TARGETS, TIMED ONthe reference Mac: 16-inch MacBook Pro, M3 Pro, 36 GB, on mains. Elsewhere a timing is only a reading.266 / 449
3.22.2Make › Budgetsin the system: Canvas core › compositor › cost
Part 3: How do agents show their work as pictures? › 3.22: How does the canvas stay light on your Mac?

How the Meter Steps One Layer Down, Frame by Frame

Those caps, held live: the meter times each layer every frame; 30 slow frames in a row drop it one rung.

CLAUDE’S ROCKET FIGURE · GPU TIME PER PRESENTED FRAME (ILLUSTRATIVE)1 ms2 ms3 mslimit: 2 ms (figure class)1 frame over: nothing moves30 frames over in a roweffects offcount restartsThe chart beside it, another writer’s layer, stays at full quality: one writer never degrades another.THE LADDER, TOP TO BOTTOMat check: refuse, if over its classeffects offlevel of detail downrender scale down30 Hzfreezeplaceholdereffects off← now, for frame healthUp again after 120 good frames, but a rungdropped for frame health holds until the viewchanges or you raise it.GPU TIME = TIME COVERED BY ANY PASS, NEVER THE SUMshadow mapmeshesbloomcovered: 2.5 ms ✓sum: 2.9 ms, never usedWHAT CLAUDE HEARS, ON THE FRAME’S CALLBACK{rev: 9, frame_seq: 51, presented_at, flags: degraded(effects_off)}The meter shows why the rung holds: frame health.Exports, checks and goldens never step: they run at their class’s fixed quality.
ONE WRITER PAYSOnly the costly layer steps down; numbers, bound values, status colors, the shell and the card never do.267 / 449
3.23.1Make › The done barin the system: Canvas core › the goal
Part 3: How do agents show their work as pictures? › 3.23: When does the canvas count as done?

When the Canvas Counts as Done: Six Shorts, Made Twice

When is the canvas done? Six short films from briefs, made in 2D and again in 3D, must be easy to make and good.

12 looks

1 · A look speedrun

one room through twelve looks in about 15 s

2D3D

2 · A long scroll

a walker crossing six worlds, each edge on a downbeat

2D3D

3 · A painting that stays alive

the sky drifts, lamps pulse, leaves sway

2D3D
ONTHEBEAT120 BPM

4 · Kinetic type on the beat

words that slam in at 120 BPM

2D3D
$18.01$18.00total.ts:42

5 · An evidence board

built from a claim’s record

2D3D
4448

6 · A 54-second explainer

one object throughout, and one chart

2D3D

Each short must

✓pass its brief’s checks
✓play live within the canvas budget
✓scrub exactly
✓get your yes on its final taste ask
✓pass in at most three rounds: ease is measured
The 3D version keeps the 2D brief, cues, timing and sound. Only the stage and the look change.

An outside film gate, run locally on our exports, is a reading beside your yes, never a pass. First to ship polished: film recipes (explain@1), painterly looks (art@1) and examples.

THE BAR“The canvas counts as done when making a film is easy and the film is good, not when its primitives exist.”268 / 449
3.23.2Make › The done barin the system: Canvas core › the goal
Part 3: How do agents show their work as pictures? › 3.23: When does the canvas count as done?

The Done Bar, Continued: One Interactive Piece, Twelve Films

The rest of the bar: one interactive piece, through an interruption, seek, fork and reload (left); twelve films.

One frozen interactive brief, judged as one piece

60s
1080p
24fps
48kHz

Six to nine shots, one recurring subject, a rigged character, two choices and a slider, a camera move, a look change, an exploded view, narration and an impact.

shotsthe tourchoice 1choice 2interruptionseekforkreload
60 s × 24 = 1,440 frames, exactly
60 s × 48,000 = 2,880,000 samples per channel

Any runner its proof needs that is missing leaves it BLOCKED, never PASS.

Twelve math and science films, each from a one-line brief

A circle’s area
A rearrangement proof
A derivative
A Taylor series
A linear map
A complex map
A Fourier chain drawing a glyph
A surface morph
Chaos from an agent bake
A spinning top from tables
A Galton board from an agent bake
Oscillators that sync, from an agent bake

Each passes its brief, film.audit and film.layout within three rounds, and gets your yes on its final taste ask.

TARGET, NOT RESULTUntil these run, one-shot quality is a target, not a result. Its look is your taste call beside a matched reference of the same shots.269 / 449
3.24.1Make › An explainerin the system: Canvas core › end to end
Part 3: How do agents show their work as pictures? › 3.24: How does an agent make an explainer, end to end?

An Agent Makes a 30-Second Explainer (1 of 2): Checked First

All of Part 3 in one task, 1 to 6: recipes, a document, checks before anything shows; one fails, naming its fix.

The ask1Start from recipes2A document3Show and check4One check fails5A one-field patch6“A 30-secondexplainer: how ablack hole bendslight.”the agent sets outto make a short filmdeep_kindsexplain@1film recipespiece@1piece recipesrecipes come first,each with one exampleRecipekind: filmlook: dark mathshots: 3cues: writenarration: 3 linescaptions: ondata, not code: shots,looks, cues, narrationDocument$ deep_show--check --snapthe canvas checks itbefore anything showsa snapshot comes backwith the resultscap.3film.layout FAILt = 12.4 sfix: at.fit cap.3inside the safe areaCheckpatch:cap.3 at.fit✓checks pass✓snapshot = liveframeone field, not a rerollPatch
WHAT A MISS COSTSA one-field patch, not a reroll. The failure came back as data the agent can act on: the check, the item, the time and a fix.270 / 449
3.24.2Make › An explainerin the system: Canvas core › end to end
Part 3: How do agents show their work as pictures? › 3.24: How does an agent make an explainer, end to end?

An Agent Makes a 30-Second Explainer (2 of 2): Out the Door

Read 7 to 11: the checked film renders on the virtual clock, its narration is heard back, and you make one taste call.

Render, offline7Sound and reading8A film card for you9One taste call10Explains, never proves11frame k atstart + k×Δon the virtual clock,each frame hashedCanonical render✓narration.transcript✓text holds to read✓film.flickereach line heard backagainst its scriptframes by hash, sowhat you scrub is the fileNEEDS YOU · TASTE CALLSlower orbit?SlowerKeepone click; if you don’t,its default appliesTaste calla film is not evidencethe math it showsneeds a check of itsown: decided, notyet filed (Part 8)
WHAT YOU DIDOne click on one taste call. The failed check, the patch, the render and the sound checks were settled without you.271 / 449
3.25.1Make › The Mapin the system: App › views › the Map
Part 3: How do agents show their work as pictures? › 3.25: How is your project shown as a map?

Your Project as a Map: From Transit Lines to a 3D City

The canvas also draws DeepBuild’s own record: version 0’s flat Map (left) and, from R2, a 3D city (right).

lens:proofcostmoving workcartcheckoutapi/ordersreceiptsign-upauthnothing proves itClaude · #42LineStationcheckout-webapipageshopfrontcodeglass towerAPItower, gatedatatank farmoutsidemastSession lightBuilding

A picture of the record

Parts by folder and route, proof by what each check covers, sessions by the files they touch, costs from bills. Nothing is drawn by hand.

Lenses

Proof, cost and moving work: sessions by repo, conflicts a trial (dry) merge found, who holds which lease, and the disk each session uses.

proof · cost · work

Buildings by kind

Page: shopfront. Code: a glass tower as tall as its code. API: a tower with a gate. Data: a tank farm. Docs: a library. Machine: a server hall.

R2

Or tiers

Instead of a city, parts and services as nodes on tiers of glass and stone, linked by conduits; a time slider replays the day.

NO CODE PER FRAMEThe Map is a scene built from the record. Proof color comes only from checks, cost from bills, sessions from the files they touch.272 / 449
3.25.2Make › The Mapin the system: App › views › the Map
Part 3: How do agents show their work as pictures? › 3.25: How is your project shown as a map?

How the Map Gets Its Data: Files, Hooks and Checks, No Model

The Map is built from the record, not drawn: four sources place checkout-web’s parts, sessions and proof.

1The repo’s own structurepackages, top folders, a tree-sitter map: the partssrc/cart · src/receipt · api/orders · src/auth2Hook events → the session mapeach tool call names its file, so a session sits thereClaude #42: Edit src/cart/total.ts → cart3Checks and journeysthe paths each one covers, lit by its latest verdictreceipt.test.ts covers src/receipt/**4Issues, PRs and billsissues and PRs by branch and files; costs from bills#42 on fix/rounding → cartprojectionrebuilt fromthe record,no modelTHE MAP OF CHECKOUT-WEB (NAMES ILLUSTRATIVE)cartreceiptapi/ordersauthClaude · #42 at work✓ PASS receipt.test✓ PASS checkout runnothing proves it: a gapLenses for proof, cost and moving work recolor the same parts.R2 · LAYERS FROM PLUG-INS, OPENED ON THE NEXT SLIDEA layer’s row must cite what names it: a record entry, a file lineat a commit, or a reading keyed by its name. Else: layer.unsupported.Each answer is a layer.rows event, so the scrubber shows rows as they were.
NO GUESSESA level nothing describes reads “not known”; no model places a part, and only checks color proof.273 / 449
3.25.3Make › The Mapin the system: App › views › the Map
Part 3: How do agents show their work as pictures? › 3.25: How is your project shown as a map?

Flying Into a Part, and Live Readings on the Map (R2)

Click a part and the Map’s camera flies in. Map layers from plug-ins add live rows, each citing a source.

1 · a part2 · its nine tables3 · one tablethe data storea write lands, and glowsa tableidtotalstatusindex on totale.g. total 18.01Checkout opens into the steps a request takes,then a step’s function and checks, then its runs.a live layer from a plug-inMap layerwebapipostgrespaymentsstale: greyrequest rateRead nowre-reads every source;a 2 s old answer is keptnotice: error rate past 2%one you asked fora row citing nothinglayer.unsupported

What a part holds

Items, links, plain facts and this week’s changes. Each fact cites its file and line: tables from schemas, endpoints from routes.

repo.facts@1

Map layers from plug-ins

A map layer returns rows anchored to names the map knows. A row that cites nothing that names it is refused.

map.layer@1

Live traffic

An edge with a request-rate reading draws particles at that rate and greys when stale. No source, no traffic.

reading

Read now, and notices

Read now re-reads each source through its own quota. A notice exists only because you asked for it.

deep.readNow
STILL THE RECORDThe hub records each map layer’s answer, so the scrubber shows rows as they were; none restyles another.274 / 449
3.26.1Make › Releasesin the system: Canvas core › by release
Part 3: How do agents show their work as pictures? › 3.26: What arrives in which release?

The Canvas by Release: What You See in R1, R2 and R6

Part 3 by release, left to right: each column is what a person using that release can actually see on the canvas.

R1version 0✓the line and Needs you✓receipts and sheets✓the flat Map✓one document format✓a basic clock and layoutR2the canvas core✓the full document language✓data views and charts✓the Map’s 3D city, live layers✓shipped effects, Vello on the GPU✓modules, registries, seamsR6films, figures, 3D✓films with sound and narration✓looks, recipes, characters✓physics, logic, 2–8 players✓rays, HDR, path-traced finals✓exports and the web playerSENT BACKa receiptq2q32–8 players
ORDERVersion 0 ships only what the line and receipts need. The engine comes in R2; films and 3D pieces in R6, judged by the done bar.275 / 449
4Trust
Part 4 asks: Can you trust an agent’s “done”? › 10 sections, 4.1 to 4.10, each answering one part of it (running index, slide 14)

Part 4: Trust

Under See, Steer and Make: can you trust an agent’s “done”? Done is fixed first, and only checks earn a verdict.

DeepBuildwhere your agents show, not tell1 · Foundation1.1 four parts, 1.2 four jobs1.3 the rules, 1.4 the hub1.5 extensions, 1.6 ways in1.7 hooks, 1.8 the record1.9 storage, 1.10 processes1.11 platforms2 · See and steer2.1 the app, 2.2 the line2.3 asks, 2.4 matching2.5 answers back, 2.6 a taste call2.7 the app’s toolkit, 2.8 where code runs3 · Make: vibe visuals3.1–3.3 what it makes3.4–3.8 documents, frames3.9–3.12 GPU, light3.13–3.15 modules, checks3.16–3.21 3D, play, sound3.22–3.26 budgets, done bar4 · Trust4.1 a claim, 4.2 what done means4.3 verdicts, 4.4 flaky checks4.5 every stop, 4.6 bug fix #424.7 a UI change, 4.8 the finish line4.9 defenses, 4.10 dodges5 · Extend, compose5.1 extension points, 5.2 agents, hooks5.3 hub slots, 5.4 plug-ins5.5 panels, 5.6 canvas packs5.7 modules, 5.8 composing5.9 safety rules6 · In use6.1 what ships, 6.2 first run6.3 MCP tools, 6.4 the CLI6.5 leases, 6.6 the box6.7 your phone, 6.8 the wiki6.9 learning7 · Build it right7.1 looks right, 7.2 tests first7.3 rules, faults, 7.4 kits7.5 comparisons, 7.6 the gate7.7 borrowed, open, 7.8 budgets7.9 measuring, 7.10 six-week plan7.11 Decision 1, 7.12 routing replay7.13 cuts8 · What’s open8.1 scale, 8.2 issues8.3 R1 path, 8.4 risks8.5 owner calls, 8.6 fleets later8.7 next
WHERE WE AREThe highlighted branch is this part; its topics are the slides that follow.276 / 449
4.1.1Trust › A claimin the system: Hub › extensions › done gate
Part 4: Can you trust an agent’s “done”? › 4.1: What happens when an agent says “done”?

Trust, Taken Apart: The Done Gate and Its Defenses

Trust is the done gate, a hub extension, plus defenses around it. Each box is a section; the arrow is where it starts.

Trustthe done gate (a hub extension) and the defenses around itDefinition of donedrafted blind from the issue,proven on the old code, then locked→ 288VerdictsPASS, FAIL, BLOCKED, INVALID,INCONCLUSIVE; the worst one wins→ 299Checkstests, commands, browser journeys,run by DeepBuild itself; flaky ones too→ 301Claimsevery stop that did work, whateverthe agent’s message says→ 307Deliverythe verdict line in the agent’s chat;a send-back names what to fix→ 315Defensesrules, guards, roles, you, a sandboxand the record stop the dodges→ 329
WHERE IT LIVESThe done gate is a first-party extension inside the hub; it writes every claim and verdict to the record.277 / 449
4.1.2Trust › A claimin the system: Hub › extensions › done gate
Part 4: Can you trust an agent’s “done”? › 4.1: What happens when an agent says “done”?

Who Writes What, for a New Feature

Four pieces are DeepBuild’s own code. Only the tests are new for each feature, and an agent writes them.

PieceWritten byWhenNew per feature?
The hook (deep-hook)DeepBuild, in the appinstalled once, at setupNo
The done gate, the judgeDeepBuildships with the appNo
The validity gateDeepBuildships with the appNo
The browser runner and screen compareDeepBuildships with the appNo
This feature’s teststhe drafting job: your own agent, headlesswhen the task starts, from your requestYes
Your repo’s own tests and CIyou, already in the repobefore DeepBuildNo, reused if there
“Does it look right?”youat the end, if it’s tasteYes, one tap

What the drafting agent needs

Needs: your requestAn issue or a prompt. For a new feature, done comes from your words.

Uses, if thereThe repo as it is now, tests it can reuse, your usual proof bar from the wiki.

No history?Fine: it writes every test new from your request.

Too vague to test?“Make it nicer” becomes one early question, or a taste call at the end.

Written once

The hook and both gates are DeepBuild’s own code, the same for every task. Nobody writes them per feature.

Written per feature

Only the tests. An agent has to read your request to write them, so the drafting job does.

Decided by code

Once written and locked, the tests run as plain code. No agent judges a stop.

NEXTOne claim, taken through these pieces, step by step.278 / 449
4.1.3Trust › A claimin the system: Hub › extensions › done gate
Part 4: Can you trust an agent’s “done”? › 4.1: What happens when an agent says “done”?

Issue #61 (1 of 7): You Point an Agent at It

One real path, filed to merged, with what you actually see at each step. It starts with an issue and three words.

GitHub · checkout-webillustrative

#61 · area:view · opened by you
Keep the order total above the fold on phones
On a phone the total sits below the fold, so people scroll to find it. Screenshot attached.On a 390×844 screen the total is fully visible without scrollingNothing outside the checkout panel movesThe cart’s unit tests still pass

Your sessionillustrative

10:00, your terminal, in checkout-web > fix #61 DeepBuild task #61 opened · its checks are being written ● Read src/checkout/Checkout.tsx ● Read src/checkout/checkout.css … the agent works; nothing is checked yet

How DeepBuild knows

The prompt names #61. A branch named for it, or the agent running gh issue view 61, works too.

Nothing to set up

No command and no form: the prompt hook sees the issue and opens a task for it.

Done comes from here

The three checkboxes are what done means. Your words, not the agent’s plan.

NEXTBefore the agent’s work can count, someone else writes the tests: a separate run of your agent.279 / 449
4.1.4Trust › A claimin the system: Hub › extensions › done gate
Part 4: Can you trust an agent’s “done”? › 4.1: What happens when an agent says “done”?

Issue #61 (2 of 7): A Separate Run Writes the Tests First

At 10:00, beside the working agent, a headless run of your agent turns the three checkboxes into checks.

.deepbuild/ · the definition for #61illustrative

task: "#61" base: a1b2c3 locked: 10:01 r1 total fully visible on 390×844 check: journey checkout-total # new expect: total.bottom <= 844 r2 nothing outside the checkout panel moves check: compare screens with base # proof bar r3 the cart’s unit tests still pass check: npm test -- cart # reused hash: 9f2e…

Tried once on the old code, a1b2c3

r1 fails at its own check: bottom 1,092 px > 844. It can see the bug.r2 passes: the old page compared with itselfr3 passes: 14 tests

Locked. In Needs you: “Definition for #61 · decided for you” with an Overrule button.

Who wrote them

Your own agent, run headless by DeepBuild beside the working one. It saw the issue and its screenshot, the old code and your wiki, never the work.

Why it can’t cheat

The working agent can dispute a check with you, never edit it. Its hash is checked at every stop.

When you’re asked

Only if a criterion can’t become a check, such as “looks clean”. Here all three could.

NEXTMeanwhile the agent has been editing. Its first stop.280 / 449
4.1.5Trust › A claimin the system: Hub › extensions › done gate
Part 4: Can you trust an agent’s “done”? › 4.1: What happens when an agent says “done”?

Issue #61 (3 of 7): The First Stop Is Checked in Seconds

The agent says it’s done. Quick checks answer in the chat; the browser test starts only because the turn ended green.

Your session, 10:08illustrative

● Edit src/checkout/checkout.css ● Bash npm test -- cart 14 passed Moved the total above the item list. Done. DeepBuild quick checks 3/3 · journey running · about 1 min 10:08 · the stop waited 4 s; the turn ends; you see the reply
Inside the turn, nothing ranThe hooks only wrote down each read, edit and command.
At the stop: 4 secondslint, typecheck and the cart’s tests, the checks whose files changed, inside the 10 s budget. All green.
The turn ended green, so the journey startsIn the background, on snapshot 4d2a: the code exactly as it was at the stop, on a warm stack. The agent is free.
NEXTA minute later the journey lands, and it fails.281 / 449
4.1.6Trust › A claimin the system: Hub › extensions › done gate
Part 4: Can you trust an agent’s “done”? › 4.1: What happens when an agent says “done”?

Issue #61 (4 of 7): The Journey Fails and Wakes the Agent

A minute later the browser test lands on 4d2a: the total moved up, but not enough. The agent hears it, not you.

OLD CODE a1b2c3foldTotal $18.01SNAPSHOT 4d2afoldTotal $18.01

Your session, 10:09, a new turn nobody typedillustrative

10:09 · the session was idle; a waiter hook wakes it DeepBuild journey FAIL on 4d2a · step cart: total ends at 902 px > 844 · checkout.css:40 ● Edit src/checkout/checkout.css Cut the header’s top padding; the total now ends at 780 px. DeepBuild quick checks 3/3 · journey running · about 1 min

A fact, so it goes to the agent

902 > 844 is not a matter of taste. You aren’t asked anything.

It names where

The failing step, the measured box and the file behind it, from the evidence, with no model.

No message from you

Claude Code was idle, so a small waiter hook woke the same session with the failure.

NEXTThe second journey passes. What’s left is a question only you can answer.282 / 449
4.1.7Trust › A claimin the system: Hub › extensions › done gate
Part 4: Can you trust an agent’s “done”? › 4.1: What happens when an agent says “done”?

Issue #61 (5 of 7): Facts Pass; the Look Is Your Call

At 10:12 the journey on snapshot 7be1 passes. Every fact is green, so one question goes to you: do you like it?

BEFOREfoldTotal $18.01AFTER 7be1foldTotal $18.01

Needs you · on your phoneillustrative

#61 · taste · default Keep in 4 h
Keep the new checkout layout on phones?
r1 total ends at 780 px, within 844r2 only the header and the total moved, both inside the panelr3 14 tests passKeepMove it

10:31: you tap Keep, on your phone.

Code checked the facts

Where the total ends and what else moved are measured from the page, on both versions.

You judge the look

No model decides whether it looks right. The before and after reach you side by side, the change marked.

It doesn’t block

The card waited while you asked for the PR and its checks ran. Unanswered, Keep applies at its deadline.

NEXTYou ask for the PR. One more check: the change merged with main.283 / 449
4.1.8Trust › A claimin the system: Hub › extensions › done gate
Part 4: Can you trust an agent’s “done”? › 4.1: What happens when an agent says “done”?

Issue #61 (6 of 7): The PR Is Checked Merged With Main

At 10:13 you ask for the PR. Its last checks run merged with main; PASS lands once you make the call.

Your session, 10:13illustrative

> ok, open the PR ● Bash gh pr create Opened PR #63. DeepBuild release checks on #63 merged with main · running 10:20 · release checks green; one call is still yours DeepBuild 10:31 · you tapped Keep: PASS 4/4 · Closes #61

GitHub · PR #63illustrative

Keep the order total above the fold on phones
Closes #61 · deepbuild/done ✓r1 journey: before and after, the change markedr2 compared with the base, step by stepr3 14 tests, in the full suiterelease checks on the merge with mainyour call: Keep, 10:31

Merged, not just branched

Your repo’s release checks run on the PR merged with main, so it works where it lands.

Only PASS closes

Had anything been left, the PR would say “Part of #61” and list it.

The agent can’t fake it

Closing #61 by hand is refused while its definition hasn’t passed.

NEXTWhat you read at the end, and what stays behind.284 / 449
4.1.9Trust › A claimin the system: Hub › extensions › done gate
Part 4: Can you trust an agent’s “done”? › 4.1: What happens when an agent says “done”?

Issue #61 (7 of 7): One Card, and What Stays

You read one card with the evidence, not the agent’s summary. The checks it earned stay with the repo.

The return card · DeepBuild appillustrative

CHECKOUT-WEB · #61 · 10:00 to 10:31
PASS 4/4 · Closes #61 · PR #63
total above the fold: journey, before and afternothing else moved: compared with the basethe cart’s tests: 14 passedrelease checks on main: green

Your call: Keep, 10:31 · 3 turns, one started by DeepBuild · one send-back · 0 open items

the agent’s own summary, folded below

The checks stayThey’re kept under .deepbuild/ and protected, so no later agent can weaken them.
The journey becomes a regression testSaved as a plain script, it reruns whenever a later change touches checkout.
Your answer is on the recordWith the evidence it was given. A saved decision, such as “merge my own fix PR”, covers its kind next time; a taste call is asked again.
WHO DID WHATYou wrote three checkboxes and tapped Keep. One agent wrote the tests, another the code; programs judged.285 / 449
4.1.10Trust › A claimin the system: Hub › extensions › done gate
Part 4: Can you trust an agent’s “done”? › 4.1: What happens when an agent says “done”?

A Claim Becomes a Verdict, by Example

Claim, check and verdict from the glossary, on one stop: the done gate, the hub’s judge, runs the checks itself.

THE AGENT SAYS“Fixed: the total nowincludes the coupon. Done!”counts for nothing yet claim THE HUB’S DONE GATE RUNS THE CHECKS ITSELF unit: total(18.00, coupon) = 16.20PASS journey: checkout shows the receiptPASS numbers: receipt equals cart totalFAIL FAIL · sent back, round 1 of 3receipt shows $18.00 · total.ts:42 the agent keeps working after its fix unitPASSjourneyPASSnumbersPASS PASS 3/3pinned to this commit
THE RULEOnly check results decide. Which checks run was fixed from the old code, by a separate job that never saw the agent’s work.286 / 449
4.1.11Trust › A claimin the system: Hub › extensions › done gate
Part 4: Can you trust an agent’s “done”? › 4.1: What happens when an agent says “done”?

Every Ask Gets Its Own Definition, Not Every Session

Sessions run for days, so done is per ask: an issue, or a prompt asking for a change, opens its own task.

checkout-web · Claude Codeone session, Monday to Tuesday: five messages arriveYOU“Fix #42”a link to the issuetask 1 · #42its own definition,drafted from the issueand the base commitYOU“Why does the cartsay $18.01?”no taska question: the stopthat answers it isan answer, not judgedYOU, MID-TURN“Also make couponcodes case-insensitive”task 2read from the queue atthe next hook; the agentacknowledges it in a lineYOU“Rename totalto orderTotal”spec onlyno behavior changes:judged by the repo’sspec aloneA SCHEDULED TASKa prompt arrives,typed by no oneno askrecorded with itsorigin; it opens notask and no askask-task

Ask-task

Something you asked for, with its own definition of done. A long session holds many.

task_ref: #42

Typed by a person

Only a prompt a person typed opens one; a scheduled task, a subagent’s report, a continuation or a prompt that can’t be placed (unknown) never does.

Every attempt shares it

Each attempt on the task is judged against the same locked definition, in any session.

Sent again after /compact

After a compaction or a resume, the session hears its open asks’ requirement IDs again.

WHY PER ASKA stop that did work is a claim for each open ask it touched, each judged by its own locked definition.287 / 449
4.2.1Trust › What done meansin the system: Hub › extensions › done gate › definitions
Part 4: Can you trust an agent’s “done”? › 4.2: How is “done” fixed before the work?

Done Is Written Down From the Old Code, Not the Work

Where those checks come from: as Claude Code starts #42, the hub has a separate job turn the issue into checks.

THE ASKA SEPARATE JOBWHAT IT WRITES DOWNissue #42 · checkout-webReceipt shows $18.00,cart says $18.01unit tests passcheckout shows $18.01receipt = cart totalbase committhe code before any changeBase committhe hub starts your own agent, headlessreads only the issue + the base committurns each requirement into a check:• one of the repo’s approved checks,• or else a new oneDrafting jobthe agent’s work never crosses this lineagent session: editing total.ts …✕Definition of doneunit tests passrepo’s approved check, reusedcheckout shows $18.01new check, drafted nowreceipt = cart totalnew check, drafted nownext: each new check is tried on the old code
Definition of doneThe checks that will judge one task, written down before the agent’s work counts.
Drafting jobA separate run of your own Claude Code or Codex: headless (no chat window), on your plan. DeepBuild has no model of its own.
Tested blindA test plants a marker in the agent’s diff and proves it never reaches the drafting job.
WHY BLINDA job that never sees the work can’t write checks shaped to it, so done can’t drift toward the work.288 / 449
4.2.2Trust › What done meansin the system: Hub › extensions › done gate › definitions
Part 4: Can you trust an agent’s “done”? › 4.2: How is “done” fixed before the work?

Inside the Drafting Job: It Holds the Base, Never the Work

That separate job, up close: its folder holds only the base commit, and tests prove it can’t look further.

WHAT THE HUB HANDS ITissue #42its text, criteria and screenshotthe repo at the base commita1b2c3, before any changethe approved spec and feature mapwhat the repo already checksyour wiki, as of the session’s startyour proof bar becomes requirementsDRAFTING JOBthe hub’s job runner starts your own agent, headless~/.deepbuild/jobs/5e2d/its folder: a checkout of the base commit, base objects only--strict-mcp-configonly the MCP servers it needs--setting-sources usernone of the repo’s own settings-s read-only (Codex)read-only, and no bypass flagenvironmentan allowlist; your own sign-inprompt on stdin · no credential file in its folderFROM INSIDE THE JOB, EACH OF THESE FAILSread the session’s worktreethe agent’s live files✕read its transcript filewhat the agent said and did✕connect to the hub’s socketso it can’t ask the record✕git cat-file the working headnot in a base-only checkout✕THE MARKER TESTplant MARK-7f3 in the agent’s diff → search everything the job read → not found✓blind

Started like any job

The job runner records the job first, then its process ID and start time, before it writes the prompt.

Only the base is there

Its folder holds the base commit’s files and objects, so the agent’s diff has no way in.

Two proofs, both tested

A marker shows what it did read; failed reads from inside show what it can’t.

NEXTBlind by construction, not by a prompt. Each check it drafts is then tried once on the old code.289 / 449
4.2.3Trust › What done meansin the system: Hub › extensions › done gate › definitions
Part 4: Can you trust an agent’s “done”? › 4.2: How is “done” fixed before the work?

What the Drafting Job Writes: Tests From the Outside

Acceptance tests through what exists today: a page, a route, a command. Unit tests of new code are the agent’s.

Your request is aboutThe drafting job writesExample
A bug in code that existsa repro of your steps, with the value from the issueopen the receipt for a 3-item cart; expect “$18.01”
A new featurean acceptance test through a page, route or command that exists todayclick Export, pick SVG; expect a file starting <svg
What must not changeyour repo’s own tests, “no visible change” and the neighbors’ journeys, reusedthe cart’s 14 unit tests; checkout looks the same
A function that already existsa unit test, only when the issue is about that unitroundCents(18.005) is 18.01
Something no test can saynothing: one early question, or your taste call at the end“make it feel faster”

Unit tests of the new code

Written by the working agentThey can’t exist in advance: nobody knows the new functions yet.

They count one wayA failing one sends the claim back. They never pass it alone.

Covered only by them?That requirement stays INCONCLUSIVE, and you’re asked whether to approve one.

Which files? Doesn’t matter

The tests drive a page, a route or a command. The agent can put the code anywhere; only behavior is seen.

Tied to your words

Each test names the requirement it covers, at the depth it needs: a unit test can’t close a journey.

Hard to game

It must fail today at its own check, each journey has a negative case, and hidden fixture variants catch a fit to the visible test.

OUTSIDE INWritten in advance because they test what you asked for, through doors that already exist, not how it gets built.290 / 449
4.2.4Trust › What done meansin the system: Hub › extensions › done gate › definitions
Part 4: Can you trust an agent’s “done”? › 4.2: How is “done” fixed before the work?

When a Step Is a Goal: A Model Drives Once, Then It Replays

Some tests need an agent to click through. A model finds the path once, an assertion judges it, and the path replays.

A journey with one goal stepillustrative

// drafted from issue #70 at base a1b2c3 // no test IDs; the Pro screen doesn’t exist yet test("a member upgrades to Pro", async ({ page, goal }) => { await page.goto("/settings/billing"); await goal("upgrade the workspace to the Pro plan"); await expect(page.getByText("Plan: Pro")).toBeVisible(); });
1First runAn acting model drives the goal: it picks from the page’s elements and the driver’s actions only. No selectors, URLs or code.
2Code decidesThe assertion after the goal runs whatever the model says. Its “I upgraded it” never counts.
3Saved only on a passThe clicks are kept only when that assertion passed, by hash beside the locked definition.
4Then no modelLater runs replay the clicks as plain Playwright. Only a replay that breaks runs the goal live again.

Why

For a screen that doesn’t exist yet, or a repo with no test IDs, the drafting job can’t know the buttons in advance.

In the background

A goal run live is slow, so its journey runs only when a turn ends green, like any heavy test.

Only if it helps

Built in R1 (#581) only if the week-1 spike shows more drafted journeys then fail on the old code and pass on the fix.

THE MODEL DRIVES, CODE JUDGESA model may find the way through the app, but only the step’s own assertion can pass or fail it.291 / 449
4.2.5Trust › What done meansin the system: Hub › extensions › done gate › definitions
Part 4: Can you trust an agent’s “done”? › 4.2: How is “done” fixed before the work?

Each New Check Must Fail on the Old Code First

Before a new check counts, the hub runs it once on the base commit. A bug check passing there proves nothing.

NEW CHECKON THE OLD CODE IT MUSTRun once on the base commitSOreceipt = cart totalchecks the fixmust FAILthe bug is still thereFAIL✓kept: it can see the buga check for what mustnot changemust PASSnothing is broken yetPASS✓kept: it guards the resta check that ran 0 tests,or did the oppositemust FAIL or PASSas above0 TESTS✕dropped“Done means X, right?”due in 4 h · default: leave it outEarly question to youOnly a requirement that can’t becomea check reaches you, once.If it goes unanswered, done locks without it.unanswered: the PR canonly say “Part of #42”
WHY THE OLD CODEA check passing before the fix can’t count. A new feature’s check runs through its command or route.292 / 449
4.2.6Trust › What done meansin the system: Hub › extensions › done gate › definitions
Part 4: Can you trust an agent’s “done”? › 4.2: How is “done” fixed before the work?

Failing Isn’t Enough: It Must Fail at Its Own Check

A new feature’s test must fail on the old code at the check it names. A crash or a timeout proves nothing.

On the old code, the test…Example: “export a document as SVG”So
fails at the check it namesexpect(render(doc, {format: "svg"})).toContain("<svg"), got a PNGkept
passesexpect(render(doc)).toBeDefined()dropped: can’t tell old from new
runs zero testsa typo, so no test was collecteddropped: ran nothing
crashes before its checkexportSvg(doc): TypeError, not a functionfailed elsewhere: redrafted once
times out on a missing buttonclick("Export SVG") waits 30 selsewhere, unless a hang fix names that deadline
catches the crash itselfexpect(() => exportSvg(doc)).not.toThrow()elsewhere, unless the error runs through the code under test

The one redraft

A test dropped for failing elsewhere goes back once to the same drafting job, with only the crash’s file, line and message. They come from the old code alone, so it stays blind.

exportSvg(doc) doesn’t exist yet, so the redraft goes through render(doc, {format: "svg"}). It fails at its check: kept, and you’re never asked.

Only a redraft that fails elsewhere too sends you the early question.

WHYA crash only shows something is missing. Failing at its own check shows the test can catch a wrong answer.293 / 449
4.2.7Trust › What done meansin the system: Hub › extensions › done gate › definitions
Part 4: Can you trust an agent’s “done”? › 4.2: How is “done” fixed before the work?

A New Repo: A Do-Nothing Stand-In Plays the Old Code

With nothing to start, no test can fail at its check, so deep builds a do-nothing program to fail on.

A serviceon a leased port, answers every request with 200 and {}, or an empty page
A commandexits 0 and prints nothing
A moduleits named exports are functions that return nothing
Drafted test, empty repo: “GET /api/todos lists saved todos”On the stand-inSo
expect(await res.json()).toEqual([{title: "milk"}])fails at its check: got {}kept, “proven on a stand-in”
expect(res.ok).toBe(true)passes on a program that does nothingdropped: too weak
expect(body.items.length).toBe(1)TypeError: items is undefinedelsewhere: redrafted once

The limits

deep builds it, never the drafter. One fixed form per kind, so it can’t be shaped to make a test fail.

Only where nothing starts. A new route in an app that already runs goes through the real old code.

Nothing to compare with. “No visible change” and latency checks are left out, and the definition says why.

SAME RULEThe stand-in is the empty repo made loadable. A test that fails at its check there can catch a missing feature.294 / 449
4.2.8Trust › What done meansin the system: Hub › extensions › done gate › definitions
Part 4: Can you trust an agent’s “done”? › 4.2: How is “done” fixed before the work?

Then the Definition Is Locked, and Only You Change It

Its checks proven, the hub locks the definition, recording three things. Four things can follow; read 1 to 4.

Definition of done #42• a hash of its checks• the issue’s revision• the base commitLockedSent to the agent as its targetin its context, and via MCP tool deep_status;re-sent if it trims its context or resumes1The agent disputes a checkvia MCP tool deep_propose, saying why:one ask to you; the check stands till then2Rechecked at every claimthe hash is computed again; same hash:judged as usual; any change:3Someone edits issue #42the working agent: changes nothinga person: a new revision; the agent is told4INVALIDonly you change a locked definitionthe agent can argue with a check, never rewrite it
Timing. Drafting runs beside the agent’s first steps and reads only the base commit, so finishing late changes nothing. A claim made before the lock waits for it while its stop is held, or stays pending.
ONLY YOUA locked definition changes only by your answer. Every claim on the task is judged against the same lock.295 / 449
4.2.9Trust › What done meansin the system: Hub › extensions › done gate › definitions
Part 4: Can you trust an agent’s “done”? › 4.2: How is “done” fixed before the work?

Five Ways to Decide When Work Is Done

Why draft, prove and lock? Each row is one way to decide done, as you would meet it, and what goes wrong.

WHO DECIDESWHAT IT LOOKS LIKEWHAT HAPPENSThe agent says it’s doneits last message“Done, total fixed!”The worker grades itself.Breaks rule 1: an agent’s word is never evidence.DROPPEDThe agent writes its own testsduring the worktests shaped to its own changeThey can send its claim back,but never pass it alone: they bind only the agent.DROPPEDYou write a spec by handfor every taska test plan per issue, by youStrong, but nobody actually writes them.Breaks a design goal: nobody writes specs by hand.DROPPEDA model reads the transcriptand judges it“looks done to me”A model’s judgment alone never makes a PASS.So it is never a gate.DROPPEDDrafted blind, proven, lockedfrom the issue + base commitchecks that fail on the old codeCan’t be gamed, needs no spec, proves the fix.Cost: drafting runs beside the agent’s first steps.CHOSEN
NEXTThe table that follows scores these five ways on five measures. Only the chosen one breaks no hard rule.296 / 449
4.2.10Trust › What done meansin the system: Hub › extensions › done gate › definitions
Part 4: Can you trust an agent’s “done”? › 4.2: How is “done” fixed before the work?

Who Decides Done: What We Compare, and Why

Before the scores on “Who Decides Done”: each row is one column of the next slide’s table, and why it matters.

ColumnWhat it measuresWhy it matters
1Can’t be gamed the worker can’t grade itselfinvariant 1
2Nobody writes specs no hand-written test plansnobody actually writes them
3Proves the fix fails before the fix, passes afterpassing on base proves nothing
4Speed how soon the checks are readythe agent shouldn’t wait
5Covers taste handles judgment callssome requirements need a person
The options on the next slideThe agent says it’s doneThe agent writes its own testsYou write a spec by handA model judges the transcriptDrafted blind, proven on base, locked
NEXTEach option scored on these 5 columns, three diamonds for strong.297 / 449
4.2.11Trust › What done meansin the system: Hub › extensions › done gate › definitions
Part 4: Can you trust an agent’s “done”? › 4.2: How is “done” fixed before the work?

Who Decides What Done Means

Five ways to decide when work is done, scored on what each column measures and why it matters.

OptionCan’t be gamedNobody writes specsProves the fixSpeedCovers taste
The agent says it’s doneDropped
The agent writes its own teststhey bind only the agentDropped
You write a spec by handDropped
A model judges the transcriptnever a gateDropped
Drafted blind, proven on base, lockedfrom the issue + base commitChosen
strong weak breaks a hard rulescores: our reading of the gains and costs recorded in the design
COST WE ACCEPTEDDrafting runs beside the agent’s first steps on your plan. A claim made before the lock waits for it, or stays pending.298 / 449
4.3.1Trust › Verdictsin the system: Hub › extensions › done gate › verdicts
Part 4: Can you trust an agent’s “done”? › 4.3: What verdicts can a claim get?

Five Verdicts, Each With a Reason You Can Act On

The glossary’s five verdicts in full: when the done gate gives each, and what it names so someone can act.

PASS WhenEvery check passed, with enough clean runs.Example3/3 · receiptIt namesHow many clean runs confirm it, pinned to the commit.
FAIL WhenA check failed on every real run.Examplereceipt shows $18.00It namesThe smallest failing case, and where it points: total.ts:42.
BLOCKED WhenSomething outside the code is missing, or it fails on the old code too.Examplepaid run, no budgetIt namesThe cause, the owner, and since when.
INVALID WhenA check ran nothing, can’t fail, or passes on the old code for a fix.Examplenpm test || trueIt namesWhich check or requirement, and why.
INCONCLUSIVE WhenToo few clean runs, a pass and a fail, or only the agent’s own checks.Example1 pass, 1 failIt namesThe runs still needed, or the check to approve.
Every verdict but PASS also becomes an open item that names the evidence that would close it. Only DeepBuild computes verdicts: no agent and no plug-in can write one.
WHY FIVEPass or fail hides why. BLOCKED names an owner, INVALID a broken check, INCONCLUSIVE the runs still needed.299 / 449
4.3.2Trust › Verdictsin the system: Hub › extensions › done gate › verdicts
Part 4: Can you trust an agent’s “done”? › 4.3: What verdicts can a claim get?

When Several Verdicts Apply, the Worst One Wins

A claim has several checks, each with a result; the claim gets the worst one, the highest rung. Two tries at #42.

THE LADDERhigher = worseFAILINVALIDBLOCKEDINCONCLUSIVEpending: still runningPASStry 1try 2Try 1 · the first commitunit testsPASSevery run passedcheckout journeyINCONCLUSIVE1 pass, 1 failreceipt = cart totalFAILfailed on every runFAILverdictTry 2 · a new commit, after the fixverdictunit testsPASSevery run passedreceipt = cart totalPASSevery run passedcheckout journeystill runningPASS3 clean runspendingPASS
The order is FAIL > INVALID > BLOCKED > INCONCLUSIVE > pending > PASS. Pending sits just above PASS, so nothing passes while a check still runs.
ONE COMMIT, ONE VERDICTOther verdicts show at once, and later results on that commit can only push them up the ladder.300 / 449
4.4.1Trust › Flaky checksin the system: Hub › extensions › done gate › checks
Part 4: Can you trust an agent’s “done”? › 4.4: What about checks that pass and fail on the same code?

A Flaky Check Passes and Fails on the Same Code

Try 1’s journey passed and failed on one commit: a flaky check. Rerunning it until it’s green is how it lies.

Flaky checkcheckout journey · one commit, nothing changed✓run 1✓run 2✕run 3✓run 4✓run 5Same code, different answers.Something other than the code moves the result.RETRY UNTIL GREEN, THE OLD WAY✕ fails→ retry →✓ passes→PASSthe failure is hidden;the next person meets itRetrying until green is how flaky checks lie.DEEPBUILDpassed and failed on one commit→INCONCLUSIVEMore runs on the same commit can’t close it. One of the four below can.
A new committhat changes the check’s inputs, so it runs again on new code.
A waiveryou accept one failure by its exact error text, with an end date.
Quarantinethe check stops counting toward verdicts but keeps running and recording.
Your answerone ask to you, and your answer closes the open item.
RULE 2Nothing missing or unrun passes. Yes and no on one commit stays open until one of these four closes it.301 / 449
4.4.2Trust › Flaky checksin the system: Hub › extensions › done gate › checks
Part 4: Can you trust an agent’s “done”? › 4.4: What about checks that pass and fail on the same code?

How Many Clean Runs Make a PASS Believable

How many clean runs is enough for a PASS? You pick p, the failure rate you accept; the curve gives n.

1310301003001%2%5%10%20%30%45% CLEAN RUNS IN A ROW NEEDED, LOG SCALEFAILURE RATE YOU ACCEPT, p 29914959291496
n = ⌈ ln(0.05) / ln(1 − p) ⌉

Read it as: if the check really failed a share p of the time, n clean runs in a row would happen less than 5% of the time.

p = 10% → 29 runsp = 45% → 6p = 1% → 299
# .deepbuild/done.yaml journey:checkout: runs: 3 # or accept: 10% to # compute the runs needed
THE TRADEAccept a higher failure rate and fewer runs prove it. Demand a lower one and the runs climb fast.302 / 449
4.4.3Trust › Flaky checksin the system: Hub › extensions › done gate › checks
Part 4: Can you trust an agent’s “done”? › 4.4: What about checks that pass and fail on the same code?

After a Fail: Two More Runs, and Some Runs Count Neither Way

After a fail, the hub reruns the check at most twice. Five patterns, their verdicts; grey runs count neither way.

ON ONE COMMITRUNS, IN ORDERVERDICTFails, then two more runsevery real run failed✕✕✕FAILFails, then a passa pass ends the extra runs✕✓INCONCLUSIVERuns past its deadlinean overrun counts as a failed runlatelatelatean overrun and a pass: INCONCLUSIVEFAILnames the deadlineA timing check on a busy Macloaded past its core countload✓rerun alonekept, counts neither wayrerun decidesNext commit, inputs unchangedit doesn’t rerunnothing it reads changed, e.g. only README.mdINCONCLUSIVEcarried over
NO LUCKY GREENAfter a fail, at most two more runs. A pass among them ends the runs as INCONCLUSIVE, never as PASS.303 / 449
4.5.1Trust › Every stopin the system: Hub › extensions › done gate
Part 4: Can you trust an agent’s “done”? › 4.5: Why judge every stop, and how does it stay cheap?

Why the Gate Sits in the Stop Hook: Catch It Before the Turn Ends

The gate isn’t a step at the end of a session. It acts at each stop that did work, while the agent can still fix things.

Without the hookagent edits total.ts“Done, total fixed.”it moves on to the next taskan hour later you find $18.00 on the receiptyou re-explain, and the agent rebuilds its context from scratchWith the Stop hookagent edits total.ts“Done, total fixed.”held: quick checks, secondsSENT BACK into the same turn: total.ts:42it fixes the line now, with everything still in mind; the e2e journey starts once the quick checks are green and the turn endsWHEN IT RUNSat a stop whose turn did work: tool calls or editsnever after a stop that only answers you, or after /clearonly the checks whose inputs changed run againWHY THE HOOKDeepBuild isn’t the agent: hooks are its only way in,and the Stop hook is the last moment before the turn endswithout hooks it can only watch, never send backDONE CAN MEAN END TO ENDeach task names its proof depth; if itneeds a browser journey, nothing less closes itearlier stops get quick feedback; PASS waits for e2e
PER TASKDone belongs to each task, not the session: one session can close several tasks, each by its own checks.304 / 449
4.5.2Trust › Every stopin the system: Hub › extensions › done gate
Part 4: Can you trust an agent’s “done”? › 4.5: Why judge every stop, and how does it stay cheap?

Two Kinds of Stop: “I’m Done” and “I Need You”

An agent stops when it thinks it’s finished or needs you. Each kind is handled, and neither is taken on its word.

“I’m done”

The checks runThe same way whatever it says, since a too-early “done” is what the gate is for.

FAIL: sent back in the same turn“sent back 1/3: receipt shows $18.00 · total.ts:42”

PASS: one line in the chat“PASS 4/4 · receipt”

“Want me to open the PR?”An offer to do in-scope, reversible work gets “proceed”.

“I need you”

Sorted by what it would lead to, not its wordsThe call it would make, the task and requirement it names.

Really yours: an ask cardA push, merge, deploy or spend; a step only a person can take; taste; a real choice.

It could do it itself: sent back with the tool“Should I run the tests?” or a page it can open in a signed-in browser you leased.

A saved decision covers it: answeredShown among what was decided for you, with an overrule.

Both hand control back

Either way the agent is about to wait for you, so that’s the moment to check, not every tool call.

Its own view is what’s checked

“Done” is often too early, and “I need you” is often something it could do.

Other stops

An empty “No response requested” gets a nudge to finish, at most three times. An API error isn’t a stop.

WORDS DON’T SORT ITThe checks and the question’s kind come from what the turn did, never from how it phrased its last message.305 / 449
4.5.3Trust › Every stopin the system: Hub › extensions › done gate
Part 4: Can you trust an agent’s “done”? › 4.5: Why judge every stop, and how does it stay cheap?

Inside the Stop Hook: Programs Decide, No Agent Judges

What happens between the agent saying “done” and the reply it reads. Nine steps; only programs decide.

Claude Codethe agentdeep-hookRust, one per hook callthe hub: done gatea program, no modelcheck runnerthe hub’s supervisor1 turn ends: runs the Stop hook, JSON on stdin2 stamps who, what, when, an ID; forwards it3 did this turn do work? then a claim per open task4 validity gate: reads the record, no checks yet5 runs the quick checks the locked definition names6 exit codes, output, how many tests ran7 verdict by rules: zero tests or a masked exit never pass8 reply: block, with what to fix9 prints it; the same turn goes on fixingthe reply Claude Code reads: {"decision": "block", "reason": "SENT BACK 1/3 · receipt shows $18.00, cart $18.01 · total.ts:42"}
NO MODEL JUDGESSteps 2 to 8 are programs. A model only writes checks from the old code, or reads the diff as one check.306 / 449
4.5.4Trust › Every stopin the system: Hub › extensions › done gate
Part 4: Can you trust an agent’s “done”? › 4.5: Why judge every stop, and how does it stay cheap?

Every Stop That Did Work Is Judged, Whatever It Says

Which stops are claims? A stop is the agent ending its turn; its Stop hook fires. Three stops in checkout-web.

STOP 1 · AFTER EDITS› Edit total.ts› Bash npm test“Done: the total is fixed.”judged against #42’s checksClaimSTOP 2 · AFTER EDITS› Edit total.ts› Bash npm run typecheck“Want me to open the PR?”judged exactly the same wayClaimSTOP 3 · ONLY TALKyou: why does the cart say $18.01?(no edits, no commands)“Rounding happens before the coupon.”not judged; no send-backAnswer
The test: did the turn make tool calls or edits since it began? Then the stop is a claim, whatever its last message says. A stop that only answers a question you typed is an answer: it gets no send-back, and open asks wait for the next stop that does work.
WORDS DON’T DECIDEWhat the turn did decides. An honest “not verified yet” is judged exactly like a “done”.307 / 449
4.5.5Trust › Every stopin the system: Hub › extensions › done gate
Part 4: Can you trust an agent’s “done”? › 4.5: Why judge every stop, and how does it stay cheap?

Before Any Check Runs, the Validity Gate

That claim first meets a gate with no model: do its deliverables exist, and was all it cites run here?

THE CLAIM, AT THE STOP“Done: fixed at total.ts:42.receipt.test.ts passes, andnpm test is green.”plus what #42’s definitionsays the work must deliverNO MODEL · BEFORE ANY CHECKvalidity gatetotal.ts:42exists, and was edited in this session✓receipt.test.ts passesthe file exists, but never ran here✕npm test is greenit ran as npm test || true: masked✕docs/rounding.mda deliverable the definition names; absent✕deliverable illustrativeSENT BACKnaming what’s missing:• receipt.test.ts: not run• npm test: exit masked• docs/rounding.md: absentno check has run yet

Deliverables

What the definition says the work must produce. They must exist before anything runs.

Citations

Every file, line, test, run or link the claim cites must resolve, and have been read or run in this session.

No model

The gate reads the record: what the session read, ran and wrote. Nothing is inferred from its words.

Then the checks

Only a claim that passes the gate has its checks run against its locked definition.

CHEAP FIRSTA claim that cites what it never ran is sent back in a moment, without spending a single check run.308 / 449
4.5.6Trust › Every stopin the system: Hub › extensions › done gate
Part 4: Can you trust an agent’s “done”? › 4.5: Why judge every stop, and how does it stay cheap?

How the Validity Gate Knows: It Reads What the Hooks Recorded

“Was it really run here?” is not a guess. The gate looks each claimed fact up in the record the hooks wrote.

THE SESSION’S RECORD, WRITTEN BY ITS HOOKS AS IT WORKED10:01:12tool.afterRead src/total.ts10:01:40tool.afterEdit src/total.ts lines 40–4410:02:05tool.afterBash npm test || true exit 0 · tests ran: 010:02:31tool.afterBash git commit -m "fix rounding"10:02:40stop“Done: fixed at total.ts:42; receipt.test.ts passes”THE GATE MATCHES EACH CLAIMED FACT TO A ROW“total.ts:42”line 42 is in the edit at 10:01:40✓“receipt.test.ts passes”no row runs receipt.test.ts this session✕“npm test” (its own proof)masked by || true, and 0 tests ran✕docs/rounding.md (a deliverable)the definition names it; no row writes it✕SENT BACK: receipt.test.ts not run · npm test masked · docs/rounding.md missing

Its source is the record

Every read, edit and command came through a hook and was written down, so “was it run here?” is a lookup.

Its rules are plain

A citation must match a row; a run must not be masked or run zero tests; each named deliverable must exist.

It costs milliseconds

No model and no check run: a claim built on things that never happened goes back at once.

THEN THE CHECKSOnly a claim the record backs has its checks run, in a clean copy of its snapshot, against its locked definition.309 / 449
4.5.7Trust › Every stopin the system: Hub › extensions › checks-command
Part 4: Can you trust an agent’s “done”? › 4.5: Why judge every stop, and how does it stay cheap?

Which Code a Check Runs On: A Snapshot, Then a Clean Copy

That “clean copy of its snapshot”: the work is frozen without touching your git, then checked out apart.

THE AGENT’S WORKTREE AT THE STOPcheckout-web · HEAD 3f2a1c9src/total.tsedited, not committedsrc/round.tsnew, never addednode_modules/ignored by gitdeep, OFF THE HUB’S EVENT LOOP1copies git’s index, its list of staged files, to a temp file2clears the “assume unchanged” and “skip worktree” flags that hide edits3adds every tracked file, and every untracked one not ignored4writes a tree and a commit, parent HEAD, into its own store“its own store”: DeepBuild’s, which reads your repo’s objects in placeSNAPSHOT 9c1e4b7parent 3f2a1c9holds the edit and round.tsa temporary checkout of ita folder of its own, never yoursnode_modules/cloned copy-on-write, not linked10:03:05 the agent edits total.ts again→ the running check still sees 9c1e4b7; its verdict is marked stalesnapshot

Never your git

Your index, branches and objects stay as they were. Nothing is fetched, and deep never stashes.

Clean worktree?

Then the snapshot is simply HEAD, and the checkout is made the same way.

Status on a match

A commit status goes only to a pushed commit whose tree is the snapshot’s.

WHAT IS JUDGEDThe exact files the agent had at its stop, frozen, so a later edit can’t change a running check.310 / 449
4.5.8Trust › Every stopin the system: Hub › extensions › checks-command
Part 4: Can you trust an agent’s “done”? › 4.5: Why judge every stop, and how does it stay cheap?

One Check Run: Sealed Off, Timed, Its Tests Counted

In that clean copy, the hub’s checks-command runs one check sealed off, then records what happened.

checks-commandthe hub’s extension forcommand checks, here: unitthe supervisorstarts one process for itand can stop its groupTHE RUN, SEALED OFF FROM YOUR MAC (VALUES ILLUSTRATIVE)wherethe clean copy of snapshot 9c1e4b7envcleared; only allowlisted variablesHOMEa new temporary folderprocessone per check, its own group, run token 7f3adeadline90 s, set from its time when draftedcommandnpm test, told to write a report fileWHAT IT RECORDSexit code1tests that ran14, read from the report fileoutputkept as evidence, ev:4be0…outcomefailedhermeticEVERY RUN ENDS AS ONE OF SEVEN OUTCOMES; THE RUNNER NEVER RETURNS A VERDICTpassedfailedran nothing0 tests: INVALIDmissinga cause outside the codeoverranstopped by group; counts as failedstoppeda hub restart cut ituncounteda loaded machine
For a fixThe same run again on the merge base: the check’s own files from the claim, everything else from the base, with the same install. It counts only if the tests that passed were collected there and one failed.
AN OUTCOME, NOT A VERDICTThe run says how it ended. Only the verdict rules turn outcomes into PASS, FAIL or the rest.311 / 449
4.5.9Trust › Every stopin the system: Hub › extensions › done gate
Part 4: Can you trust an agent’s “done”? › 4.5: Why judge every stop, and how does it stay cheap?

Proof Depth: A Green Unit Test Can’t Close a Journey

Past the gate, the checks run. Each requirement names how deep its proof must go; deeper covers shallower.

DEPTH OF PROOFlive runbrowser journeyintegration testunit testdeeper ↑ covers what’s below it#42’S REQUIREMENTNEEDSCOVERED BYRESULTthe live site shows $18.01live runa recorded runit names the deployed server✕can’t pass itcheckout shows $18.01browser journeyunit test onlyno check at its depth✕INVALIDtotal() rounds after the couponunit testunit test✓PASS

Depth

Each approved feature or journey names how deep its proof must go: unit, integration, a browser journey, or live.

Deeper covers shallower

A journey satisfies a unit-level need; a green unit test never closes a journey-level one.

Coverage, claim by claim

Each check lists the requirement IDs it covers. A requirement no check covers can’t pass.

A negative case

Every journey includes at least one, so a check that can’t fail shows up.

RULEA check too weak for a requirement doesn’t count as its cover, so a requirement with no check at its depth is INVALID.312 / 449
4.5.10Trust › Every stopin the system: Hub › extensions › done gate
Part 4: Can you trust an agent’s “done”? › 4.5: Why judge every stop, and how does it stay cheap?

A Second Model Reviews the Diff; Every Number Is Re-Run

Besides tests and journeys, R1 has two more kinds of check. Neither lets a model’s opinion make a PASS.

REVIEW BY A SECOND MODELthe diffthe session’s transcript✕the claim and the PR text✕a second modelreads only the diffONE FINDINGfile: total.tsline: 42rule: round lastquote: “…”Findings come back as items: file, line, rule and the quotedtext, with the reviewer’s prose folded away; valid onesmake one send-back. Finding illustrative.answered by the model that made the change? uncountedNUMBERS RE-RUN AGAINST THEIR SOURCETHE CLAIM SAYSreceipt total for cart A: $18.01THE QUERY BEHIND IT, RE-RUN$18.01✓THE WEEKLY REPORT SAYS1,204 orders this weekTHE QUERY BEHIND IT, RE-RUN1,198✕with an independent recount where one exists;a mismatch fails the claim. Values illustrative.

Its oracle

Every check names one: code, a model or a person. A PASS never rests on a model’s judgment alone.

Which model answered

Read from the job’s own output. Another model of the same family counts, and the verdict line says so.

Only the diff

A test plants markers in the transcript, diff and claim, and finds only the diff’s in the review.

Numbers, not prose

A number a claim states is checked by re-running what produced it, never by reading the agent’s text.

R1 CHECKSCommands, browser journeys, this review and the numbers check: version 0’s four kinds, all run by DeepBuild.313 / 449
4.5.11Trust › Every stopin the system: Hub › extensions › done gate
Part 4: Can you trust an agent’s “done”? › 4.5: Why judge every stop, and how does it stay cheap?

How a Review Finding Counts: Its Quote and Its Rule

The second model’s answer, checked by a program: a finding counts only if its quote and its rule check out.

A JOB THE HUB STARTS: A SECOND MODEL, HEADLESSits only input, the diff: src/total.ts42 + return roundCents(sub - coupon)43 + const tax = parseFloat(rate) * subnot given: the transcript, the claim, the PR textYOUR REVIEW RUBRIC, IN YOUR WIKI (ILLUSTRATIVE)1 round money last2 money stays in integer cents3 no secrets in logsanswered by: model B, read from the job’s output · the change: model AWHAT THE SECOND MODEL RETURNED, CHECKED BY A PROGRAMfindingquote at its line?rule in rubric?total.ts:43 · rule 2“parseFloat(rate) * sub”✓✓kepttotal.ts:42 · rule 1“Math.round(sub)”✕—droppedtotal.ts:43 · “use a tax library”“parseFloat(rate)”✓✕droppedits prose: “Overall this looks solid, but…”folded awayONE SEND-BACK: total.ts:43 · rule 2 · “parseFloat(rate) * sub”

Quote at its line

The quoted text must sit at the file and line it cites in the diff, byte for byte, after one space per whitespace run.

Rule in your rubric

Its rule must name a line of the review rubric your wiki holds. Dropped findings are counted, never sent.

Which model

Read from the job’s output. The change’s own model, or an unnamed one, makes the review uncounted.

A PROGRAM DECIDESThe model proposes findings; a program keeps those that check out, and only they can send a claim back.314 / 449
4.5.12Trust › Every stopin the system: Hub › extensions › done gate
Part 4: Can you trust an agent’s “done”? › 4.5: Why judge every stop, and how does it stay cheap?

Fast Checks Answer in the Chat, Slow Ones Land Later

The stop’s quick checks share a 10 s budget; the task’s own check goes first. The rest wait for a turn that ends green.

Slot 1Slot 2Over budgetgoes to the slow lanecheckoutreceipt shows $18.01 (the task’s own)linttypecheckunit tests: would end at 11 sjourney, review check, release checks: slow lane tooBudget: 10 s for the stopthe 60 s hold is only a capsent back, 8 sstop2 s4 s6 s8 s10 s12 s
In the chat, at the stopagent: “Done, total fixed.”SENT BACK1/3 · receipt shows $18.00 · total.ts:42
After its fix, slow checks runningyou: “still going?”3 checks running · about 4 minthe hub answers from the record; the model is not woken
When the slow lane landsPASS3/3 · receiptdelivered into the session when it lands; until then the claim is pending
ONE LINEEvery stop reply carries one verdict line you see in the session itself. You never have to ask the agent.315 / 449
4.5.13Trust › Every stopin the system: Hub › extensions › done gate
Part 4: Can you trust an agent’s “done”? › 4.5: Why judge every stop, and how does it stay cheap?

Which Stops Start a Heavy Test: Four Questions at Each Stop

The gate fires at every stop, but a heavy test starts only where the agent really stops: no send-back, no loop.

1Did the code change since the last check?no → reuse every result; nothing runs
2Quick checks, within 10 s: any red?yes → sent back; the agent keeps fixing
3Will the agent keep working?a send-back or “proceed” → no heavy test; a session looping on its own (a Codex goal, /loop) → held until the loop pauses
4Otherwise the reply ends the turnthe heavy test starts now, in the background
StopWhat happenedDecided byHeavy test
A 10:02read files only; “shall I go on?”1: no changeno
B 10:05edited; typecheck red2: sent backno
C 10:06fixed; green; “want me to tweak spacing?”3: “proceed”no
D 10:09green; “Done.”4: turn endsstarts on D
10:09:30 you type “also make it bold”; a new turnD keeps running; lands 10:10, stale
E 10:11green; “Done, it’s bold.”4: turn endsstarts on E; its PASS counts
FIVE STOPS, TWO RUNSThe gate fired at all five. Only the two whose reply let the agent stop started the journey.316 / 449
4.5.14Trust › Every stopin the system: Hub › extensions › done gate
Part 4: Can you trust an agent’s “done”? › 4.5: Why judge every stop, and how does it stay cheap?

Heavy Tests Start When the Turn Ends, Never Mid-Work

Browser tests and full suites wait until quick checks are green and the agent stops. A run in flight is never killed.

TimeThe agentA 5-minute browser test
10:00stops; quick checks green; reply ends the turnstarts on A
10:01you type more; it stops green, offers to go on: “proceed”nothing: it’s still working
10:02stops; typecheck fails: sent backnothing
10:03stops; quick checks green; reply ends the turnD queued behind A
10:05A ends: “FAIL on A, 3 stops back”, shown as A’s; D starts
10:10D passes: PASS on the final code

The rules

Starts only when the turn endsQuick checks green, and DeepBuild’s own reply lets the agent stop. A send-back or a “proceed” means the code is about to change.

Never stoppedA run in flight finishes and reports on its own code.

Only the newest waitsOne running and one queued per check; newer code takes the queued place.

Stale stays staleA late result is labelled with its code and never sends the agent back.

Why not mid-work

Only the final code’s result decides PASS. Mid-work runs buy early warning at your Mac’s cost.

Its own reply decides

DeepBuild knows whether it just told the agent to go on. It never reads the agent’s words for this.

On the judged code

The test’s stack serves that stop’s snapshot, from a warm stack, not the folder the agent is editing.

ONCE PER SETTLED CODEA 5-minute test runs when a turn first ends green, then on the latest such code, never once per stop.317 / 449
4.5.15Trust › Every stopin the system: Hub › extensions › done gate
Part 4: Can you trust an agent’s “done”? › 4.5: Why judge every stop, and how does it stay cheap?

When an Agent Is Stuck, or Its Change Is Too Big

Each send-back is a round (1/3, 2/3…). Two brakes end the loop: left, no progress; right, a change far too big.

Stalled claimstop 1SENT BACK 1/3open: receipt, journeystop 2SENT BACK 2/3open: receipt, journeyopen items unchanged on 2 stops in a row,no new passing evidence (or 3 send-backs)NEEDS YOU · ONE DECISIONSplitthe proven part closes,the rest: a new issueFundpay for the liveruns it still needsAccepttake what’sproven, and stopSize readinglines changed, measured with no modelmedian of yourlast 20 acceptedthis claimsent back once:“cut it to what the issueneeds, or say why eachpart is needed”still over: one taste callwith the biggest additionsAlso measured: files, new dependencies, top-levelfolders, files outside the agent’s plan, code no test reaches,duplicated blocks. A reading, never a FAIL.
TWO BRAKESNeither brake makes a FAIL. Each sends the agent back a set number of times, then asks you once.318 / 449
4.6.1Trust › Bug fix #42in the system: Hub › extensions › done gate
Part 4: Can you trust an agent’s “done”? › 4.6: How is a bug fix judged, end to end?

Bug Fix #42 (1 of 2): Checks First, Then a Failed Try

Part 4 on one bug, Claude Code fixing #42. Steps 1 to 9: done is fixed blind, the agent claims, checks say no.

1–4Before the work counts5–7The agent says it’s done8–9The checks say noissue #42receipt $18.001drafting jobissue + base only22 new checks, run on the old code:3checkout shows $18.01FAIL✓receipt = cart totalFAIL✓both fail there, as a fix check mustlocked by hash, with theissue revision and base commit4“Done, total fixed.”5its Stop hook runs deep-hookdeep-hook → hub: agent.stop6done gate: this claimagainst #42’s locked checks7unit testsPASScheckout shows $18.01PASSreceipt = cart totalFAIL8stop blocked: sent back, round 1/3receipt shows $18.00 · total.ts:429The agent gets the smallest failingcase and keeps working, same turn.
SO FARThe agent’s “done” counted for nothing. The locked checks, written before it started, said no.319 / 449
4.6.2Trust › Bug fix #42in the system: Hub › extensions › done gate
Part 4: Can you trust an agent’s “done”? › 4.6: How is a bug fix judged, end to end?

Bug Fix #42 (2 of 2): The Second Try Passes, the PR Closes It

Steps 10 to 12: Claude Code stops again, every locked check passes, and the PR is allowed to close the issue.

10The agent stops again11Every check passes12What you see› Edit total.ts:42› Bash npm test› Stop“Done.”a new commit, judged again againstthe same locked definitionunit testsPASScheckout shows $18.01PASSreceipt = cart totalPASSPASS 3/3pinned to this commita new commit makes it stale againcheckout-web · Claude CodePASS3/3 · receiptPR #57Fix receipt roundingCloses #42You did nothing: no re-checking,no “is it really done?”
A PR says “Closes #42” only when every requirement passed. Otherwise it says “Part of #42” and lists what’s left, and the agent can’t close the issue by hand.
WHAT YOU DIDNothing. The drafting job never saw the work, and “done” counted only once the locked checks passed.320 / 449
4.6.3Trust › Bug fix #42in the system: Hub › extensions › done gate
Part 4: Can you trust an agent’s “done”? › 4.6: How is a bug fix judged, end to end?

Done Means Switched On: What a PR Needs to Say Closes

Behind that “Closes #42”: a PR claim also runs release checks merged with main, and live ones where named.

PR #57fix receipt roundingwants to say“Closes #42”Release checkson its commit mergedwith main, once perhead, in the slow lane✓Live where nameda requirement namingthe deployed server, aschedule or a real account✓Switched on?coupon_v2 is off whereit’s deployed(illustrative)✕The tests it adds5 runs in the full suite,1 with the clock amonth ahead✓a recorded run can’t pass a live onecan’t say “Closes” until youdecide it stays offevery requirement passed → “Closes #42”anything left → “Part of #42”, listing what’s left
Review notes on the PR, and limits the change writes into its own docs, become open items. An agent can’t close an issue by hand while its definition hasn’t passed.
HONEST CLOSE“Closes” only when every requirement passed on the merge with main; otherwise “Part of”, with what’s left.321 / 449
4.7.1Trust › A UI changein the system: Hub › extensions › done gate
Part 4: Can you trust an agent’s “done”? › 4.7: How is a UI change judged?

A UI Change, Judged (1 of 4): The Checks Come First

Your case: done means the total shows above the fold, with before and after. First, what done means, written down.

ISSUE #61 · CHECKOUT-WEB (ILLUSTRATIVE)Keep the order total above the foldon phones. Screenshot attached.DRAFTING JOB, BEFORE THE WORKyour own Claude Code, headlessreads the issue, its screenshot andthe base commit, never the agent’s workTHE DEFINITION OF DONE IT WRITESjourney: checkout, step “cart”screenshot at the phone viewportthe total’s box sits above the folda fact, read from its bounding boxfails on base ✓nothing outside the checkout panel movescompared with the base, step by steppasses on base ✓the cart’s unit tests still passthe fast lanepasses on base ✓Proven on the old code, then locked: the agent can argue with a check, never edit it.

An agent writes them

Your own agent, in a job apart from the working session, drafts the checks from the issue alone.

Facts, not looks

“Above the fold” and “nothing else moved” are measured from the page, so a program can decide them.

Proven first

The fold check must fail on the old page and the others must pass. One that doesn’t is dropped, and you’re asked instead.

NEXTMost repos have none of these checks. Where the code that runs them comes from.322 / 449
4.7.2Trust › A UI changein the system: Hub › extensions › done gate
Part 4: Can you trust an agent’s “done”? › 4.7: How is a UI change judged?

A UI Change, Judged (2 of 4): Who Writes the Code

“Above the fold” runs as code. Two authors wrote it, and neither is the agent doing the work.

1 · DeepBuild’s own code

Written once, the same in every repo

1Drives the browserPlaywright, like any test tool, opens the app DeepBuild started, at the size the check names.
2Records every stepA screenshot, and each checked element’s selector and box on the page.
3Compares with the old pageThe same steps on the base commit; any element whose box moved is listed.
4Keeps the evidenceScreenshots, video and trace, stored by hash, for the card you read.

2 · This task’s check

Written for issue #61 by the drafting job, from the old code only

// checkout-total.journey.ts, drafted from issue #61 at base a1b2c3 test("the total shows above the fold on a phone", async ({ page }) => { await page.setViewportSize({ width: 390, height: 844 }); await page.goto("/checkout?cart=three-items"); const box = await page.getByText("Order total").boundingBox(); expect(box.y + box.height).toBeLessThanOrEqual(844); }); // also drafted: nothing outside the checkout panel moves. // DeepBuild’s compare, on the left, checks that one.
On the old pageit fails: the total’s bottom sits at 1,092 px ✓ so it can fail. Then it’s locked by hash: the working agent can dispute it, never edit it.

Your repo has no such tests?

That’s the usual case. The drafting job writes them at the start, from the issue and its screenshot.

A model writes, code decides

The drafting job is your own agent, headless and blind. Once written, its test is plain code that runs.

What can’t become code

“Looks clean” has no test. It comes to you: as an early question, or as a taste call at the end.

NEXTThe working agent changes the page and says it’s done. What runs, and how long it takes.323 / 449
4.7.3Trust › A UI changein the system: Hub › extensions › done gate
Part 4: Can you trust an agent’s “done”? › 4.7: How is a UI change judged?

A UI Change, Judged (3 of 4): Two Lanes, Two Screenshots

Each stop that did work: quick checks while the agent waits, then the journey screenshots both sides.

THE AGENT SAYS DONE AT 10:02 (ILLUSTRATIVE)Fast lane, while the stop waitstypecheck, the cart’s unit testsa few seconds; reply: “journey running, ~1 min”Slow lane, in the backgroundDeepBuild starts the app for it, on its portsnot your session’s servers; can’t start: BLOCKEDBEFORE · THE BASEfoldTotal $18.01AFTER · THE CLAIMfoldTotal $18.01same step, same viewport, same dataWHAT THE PROGRAM READStotal’s top: 540 px → 114 pxfold at 175 px in this sketch✓outside the checkout panelno element moved✓changed regiondrawn from the recorded boxFacts pass. Left for you: does it look right?that is taste, so it comes to you, next

Only what fits is held

A check waits for the stop only if its usual time fits; none fit, no hold. Tool calls never wait.

Its own copy of the app

The journey runs the snapshot of the agent’s work in a stack DeepBuild starts, so nothing needs to be up in the session.

Every stop, not only the last

Each stop that did work is judged, so a broken step comes back the minute it happens.

NEXTThe facts passed. Whether the new page looks right is a judgment, and judgment is yours.324 / 449
4.7.4Trust › A UI changein the system: Hub › extensions › done gate
Part 4: Can you trust an agent’s “done”? › 4.7: How is a UI change judged?

A UI Change, Judged (4 of 4): Facts Checked, Taste Asked

The facts passed, so the one question left is taste. It comes to you with the evidence beside it, not as a model’s guess.

NEEDS YOU · TASTE CALL · CHECKOUT-WEBKeep the new checkout layout on phones?BEFOREfoldTotal $18.01AFTERfoldTotal $18.01facts: 3 of 3 passchanged: the total, movedup 426 px; nothing elsecaption by the agent:“total moved above items”KeepMove it1You tap Keepone tap; or type why it’s wrong2Verdict: PASSfacts checked, your call made3Kept as a goldenyou blessed it, so the next run compares to it4PR #63 says Closes #61with both screenshots, the change marked beside them (R2 report)

A rule can tell what changed

Boxes and positions come from the page on both sides: what moved, by how much, and what must not.

You decide what’s good

The before and after reach you side by side, the change highlighted; one tap answers.

An agent can describe, not judge

It may caption the change; a model’s opinion is a reading, never the verdict.

WHO DOES WHATAn agent writes the checks and the caption, DeepBuild runs them, and you make the one call that needs taste.325 / 449
4.8.1Trust › The finish linein the system: Hub › extensions › done gate
Part 4: Can you trust an agent’s “done”? › 4.8: What must hold before work counts as finished?

The Finish Line (1 of 3): The Last Stop Runs Everything Still Owed

The agent says it’s finished. Six steps run before anything counts as done, the same at every stop.

1The last stop“Done. Opened PR #63.”a claim for each open task it touched2Validity gateno model: do the deliverables exist,and does every cited file and test resolve?3Every requirement, at its depthwhatever hasn’t passed at this commit runs now:unit tests, then the e2e journey with screenshots4The PR, merged with mainthe repo’s release checks, once per head;a new test runs 5 times, and once a month ahead5Live, if the task needs itthe deployed server or a real phone needs alive run; a recording can’t pass it6Left open, from its own words“still open” or “not verified” lines becomeopen items, and placeholder text is flagged

Nothing special about “last”

The last stop is judged like every stop. It just has nothing left to defer, so every check still owed runs.

Depth decides

Your task named its proof depth: if it’s a journey, the journey must pass at this commit, whatever ran earlier.

Merged, not just branched

A PR’s checks run on its commit merged with main, so it works where it will land.

NEXTAll of that comes back as one verdict. What each verdict means, and what it lets happen.326 / 449
4.8.2Trust › The finish linein the system: Hub › extensions › done gate
Part 4: Can you trust an agent’s “done”? › 4.8: What must hold before work counts as finished?

The Finish Line (2 of 3): One Verdict, and What It Lets Happen

Five verdicts, each with a next step. Only one of them lets the PR say it closes the issue.

VerdictIt meansWhat happens next
PASSevery requirement passed at its depth“Closes #61”, a green commit status; the PR can merge
FAILa check failed, with the line it namessent back into the session, up to three times, then it stops
BLOCKEDa check couldn’t run: the app wouldn’t start, a device is missingone ask to unblock it; never counted as a fail
INCONCLUSIVEran, but not enough: a flaky test, too few clean runs“Part of #61”, listing what’s left to prove
INVALIDthe claim cites what doesn’t exist, or no check is at its depthnothing passes until the evidence is real

Only PASS closes

“Closes #61” needs every requirement proven; anything less says “Part of #61” and lists the rest.

The agent can’t close it

Closing the issue by hand is refused while its definition hasn’t passed.

A stuck loop stops

Two stops with nothing new proven, or three send-backs, and it stops asking the agent and tells you.

NEXTWhere you see all of it: one card per finished task, with the evidence.327 / 449
4.8.3Trust › The finish linein the system: Hub › extensions › done gate
Part 4: Can you trust an agent’s “done”? › 4.8: What must hold before work counts as finished?

The Finish Line (3 of 3): One Card With the Whole Story

When a task finishes you read one card: the verdict, each requirement with its evidence, your calls and what’s left.

RETURN CARD · CHECKOUT-WEB · #61 (R2)PASS4 of 4 requirements · Closes #61 · PR #63✓the total above the foldjourney · before and after, the change marked✓nothing else on the page movedjourney · compared step by step with the base✓the cart’s unit tests14 passed, run 5 times in the full suite✓release checks on mainmerged with main at 3f2a1c9, all greenYour call: “Keep the new layout” at 10:06 · open items: noneturns: 3 · what each touched · agent’s own words folded belowIN R1, BEFORE THE CARDthe verdict line in the agent’s chatthe commit status on GitHubthe session’s page: its line, asks, checksand the journey’s video and screenshotsIF THE SESSION ENDS FIRSTchecks still running keep goingthe verdict lands on the card and withyour next message to that sessionits app and ports end once its processes are gone
WHAT YOU READNot the agent’s summary: what was proven, by what, at what depth, and what’s left. Its own words sit folded below.328 / 449
4.9.1Trust › Defensesin the system: DeepBuild › defenses
Part 4: Can you trust an agent’s “done”? › 4.9: What stops an agent from cheating?

Six Defense Layers (1 of 2): Rules, Guards and Roles

Can an agent cheat this loop or get around it? Six defense layers say no. Here three, each catching one thing.

Fast ruleFail-closed guardSocket role$ pkill -f nodedeep-hook reads rules.jsonno hub needed✕ denied before it runskill by name hits other sessions’ servers:stop the processes you started insteadEdit .deepbuild/done.yamlguard on .deepbuild/fail-closed: when in doubt, or hub down, no✕ denied → use deep_proposea proposal runs at once but decidesnothing until you approve ithubhookreports events onlyagent’s MCPits own session onlyapp + CLIcan answer youweb pagerefused✕a new control token each launch;the socket is readable only by youSTOPS• kill by name or port• switching off DeepBuild’s hooks• a broken or stopped hubSTOPS• gaming its checks• switching off DeepBuild’s hooksSTOPS• an injected answer (a fake yes)• a caller posing as another
FAILS OPEN, EXCEPTHub down, deep-hook lets work on, but fail-closed rules and destructive commands of unknown reach deny.329 / 449
4.9.2Trust › Defensesin the system: DeepBuild › defenses
Part 4: Can you trust an agent’s “done”? › 4.9: What stops an agent from cheating?

Six Defense Layers (2 of 2): You, a Sandbox and the Record

Three more layers, the same way: one picture each, with the threats it stops at the bottom.

OS confirms youSandboxRecord$ deep inboxanswer 1 [y/n]: yTouch ID or your passwordbefore a yes or a saved decision countsyour agents run as you, so they couldtype “y” into your terminal tooagent-built plug-in,or code in a pieceonly what its grantnames gets throughnetwork✕your files✕hub socket✕EVENTWRITERtool.beforehook · checkoutclaim.madehook · checkoutask.answeredapp · youthe writer comes from the connection,never from what the caller says; rowsare only added, never editedSTOPS• an injected answer• typing into a terminal• a malicious extensionSTOPS• a malicious extension• code in a piece• code in a stranger’s PRSTOPS• gaming checks · switching off its hooks• posing as another · terminal typing• hostile issue text · strangers’ PRs · a broken hub
NEXTThe table that follows lists twelve threats and marks which of these six layers stops each one.330 / 449
4.9.3Trust › Defensesin the system: DeepBuild › defenses
Part 4: Can you trust an agent’s “done”? › 4.9: What stops an agent from cheating?

Twelve Threats, and Which Layer Stops Each

Rows: ways things could go wrong. Columns: the six layers of the last two slides. A diamond: that layer stops it.

ThreatFast ruleFail-closed guardSocket roleOS confirms youSandboxRecord
What the layer doesdeep-hook denies before a command runs, hub up or downchecks and specs change only by your approved proposaleach caller’s credential sets what it may doTouch ID or your password for authority and decisionsagent-built code runs walled offevery event kept with its writer
Agent games its checks
Agent switches off its hooks
Injected answer
Caller poses as another
Agent types into a terminal
Hostile text in an issue
Malicious extension
Code in a piece
Code in a stranger’s PR
Kill by name or port
Broken or stopped hub
What a command’s children do
NEXTSix tricks an agent might try to look done without being done, and the layer that catches each.331 / 449
4.9.4Trust › Defensesin the system: DeepBuild › defenses
Part 4: Can you trust an agent’s “done”? › 4.9: What stops an agent from cheating?

Twelve More Threats, and What Stops Each

The table had room for twelve. Each card here: a threat, an example of it, and what in the design stops it.

MCP tools the guards can’t see

e.g. A server update adds a tool that deletes.

Stopped by: It waits for your approval once; an unknown tool counts as a change.

Approvals that drift

e.g. A run tries one more step than you saw.

Stopped by: Your yes binds to the plan’s digest and your click’s token.

Secrets

e.g. A key pasted into a chat.

Stopped by: Redacted on the way in, and a “rotate this key” item opens.

Untrusted repos

e.g. A cloned repo’s .deepbuild/ would run commands.

Stopped by: Nothing runs until you trust the project; until then, watch only.

Tampered updates

e.g. A swapped release download.

Stopped by: Release manifests signed by an offline key whose public half is built in.

Extensions that host shells

e.g. A terminal plug-in can run anything.

Stopped by: Only by the plainly named run-as-you permission, revocable at once.

A panel editing as you

e.g. An agent-built button writes under your name.

Stopped by: Only the editor panel, or a plug-in you granted edit_as_you, with your input.

A plug-in posing as the app

e.g. A fake toast, or a fake secret field.

Stopped by: Its overlays stay in its panel; no secret fields, no status colors.

Pages an agent made

e.g. An HTML report that calls out.

Stopped by: Opened in a wrapper that blocks every network request (R2).

Sound or recording

e.g. A plug-in that starts the microphone.

Stopped by: Sound only after your gesture; mic and camera only while a shortcut is held.

Media that attacks its parser

e.g. A crafted video file.

Stopped by: Decoded only in a sandboxed worker with no network, under caps.

A shared piece’s network

e.g. A game piece that phones home.

Stopped by: Only its one declared relay, and only after you click Join.

ALL TWENTY-FOURWith the twelve on the previous slide, these are all the rows of the design’s threat table.332 / 449
4.9.5Trust › Defensesin the system: DeepBuild › defenses
Part 4: Can you trust an agent’s “done”? › 4.9: What stops an agent from cheating?

One Guard Engine: Each Rule Proven on a Call and Its Twin

The fast rule and the fail-closed guard from the threat table are one engine: each rule is data, proven twice.

ONE GUARD, WRITTEN AS DATAmatch: a kill by name or portscope: every sessionmode: blockreason: it hits other sessions’ serversnext_step: stop what you startedfail_closed: trueguard@1AT INSTALL, PROVEN BOTH WAYSITS PLANTED CALLpkill -f nodemust be denieddenied✓ITS TWINpgrep -f nodemust be allowedallowed✓twin illustrative; an entry that fails either is refused, namedITS MODE IS EARNEDwatchrecords itwarnwarnsblockdenies itit moves up only after a replay of pastcalls proves it precise; fail_closed oneshold even with the hub downEVERY SOURCE OF RULES GOES THROUGH ONE MATCHER, DEEP-HOOK’Sfirst-party defaultsthe rules you wrotea repo’s own rulesan extension’s manifestrules.json, matched at every call

MCP tools too

Each tool counts as read, change, send or destructive, from a facts file or the session’s recorded list. Unknown is a change.

Hints only raise

A readOnlyHint or a get_ name never makes a tool read; a delete_ name makes it destructive.

Hub up

deep-hook sends the entries that matched; the hub decides by scope and mode: record, warn, ask or deny.

Hub down

deep-hook applies the fail_closed entries and allows the rest, so an agent is never stuck.

SAME UP OR DOWNAt install the hub runs deep-hook’s own matcher, so a call is matched the same way with the hub up or down.333 / 449
4.9.6Trust › Defensesin the system: Agent side › deep-hook › guards
Part 4: Can you trust an agent’s “done”? › 4.9: What stops an agent from cheating?

How deep-hook Matches a Command: Unwrap, Then Compare

The guard engine on one call: deep-hook finds what the command really runs, compares each rule, then acts.

ONE CALL AT PreToolUse · codex · api (ILLUSTRATIVE)cd api && env DEBUG=1 nohup bash -c 'pkill -f node' &1reads the callthe command, its arguments, the paths it targets, its environment, what it pipes into2unwraps itsplits at && · drops env, nohup · opens bash -c (shells up to 3 deep)3compares every entryeach guard in rules.json, one matcher: no-kill-by-name matcheswhat it really runs: pkill -f node4actshub up: it acks in 20 mssends the matched entry; the hubdecides by scope and mode: blockhub down: no ack in 50 msapplies only fail_closed entries;this one is, so it still deniesDENIED: it hits other sessions’ servers · stop what you startedSAME WORDS, NOT A KILL: ALLOWEDecho "pkill -f node" >> notes.mda string✓grep -rn "pkill -f node" docs/an argument✓# pkill -f nodea comment✓cat > run.md <<EOF …a heredoc to a file✓Every default entry’s planted call is respelled:quoting, full paths, wrappers (env, command, exec,nohup, timeout, sudo, xargs), nested shells,sequencing, subshells. Every spelling must be denied,and each of the four lines above allowed.matcher
DOES, NOT SAYSThe matcher sees through wrappers and shells, so rewording a command can’t dodge a guard.334 / 449
4.9.7Trust › Defensesin the system: DeepBuild › defenses
Part 4: Can you trust an agent’s “done”? › 4.9: What stops an agent from cheating?

Your Written Rules, Enforced: What Backs Each Line

Many guards start in your own rule files. A rules page shows what enforces each line of your CLAUDE.md.

~/.CLAUDE/CLAUDE.MD (ILLUSTRATIVE)1 Never kill processes by name or port.a guard before the command2 Never use a bare git stash.a guard before the command3 Open a PR only when I ask.an authority rule on push, PR, merge4 Run the checkout journey before done.a requirement in every definition5 Write in short, plain sentences.text only: the list to shrinkrules pageWHAT ENFORCES EACH LINEAN AGENT EDITS THE FILE3 Open a PR only…the rule stays in force; the editbecomes a proposal to youREACHES EVERY AGENTa rule in Codex’s AGENTS.md reachesClaude Code’s sessions too; one youtype reaches every open session atits next prompt

Read at setup

Every rule file you keep for agents: CLAUDE.md, AGENTS.md and the like, for every agent you use.

One rules page

In the wiki: each rule with what enforces it, a check, a guard, a requirement, or text only.

Push, PR and merge

Go ahead only when the thread’s ask names them or a rule covers them, through gh or an MCP tool.

Only you change it

An edit made outside an agent’s tool calls changes the page; an agent’s becomes a proposal.

THE LIST TO SHRINKA rule nothing enforces is only text; the page shows which, so each can become a guard or a check.335 / 449
4.9.8Trust › Defensesin the system: DeepBuild › defenses
Part 4: Can you trust an agent’s “done”? › 4.9: What stops an agent from cheating?

A Command That Could Destroy Files Runs After a Copy

When a destructive command’s reach is unknown, the folders it names are copied first; then it runs in place.

AN AGENT RUNS A SCRIPT IT WROTE (ILLUSTRATIVE)$ ./scripts/clean.sh build/ “$OUT”/*it can delete files git can’t restorereach unknownStaged firsta copy-on-write copy of build/ and $OUT,kept for a set time; then it runsUndoToo big to stagepast the ceiling on files and seconds,set below the agent’s hook timeoutan authority ask: reach unknownThe hub is downnothing can stage it, andnobody can be askeddeniedWhich commands: one that can delete or overwrite files git can’t restore(untracked, ignored or outside the repo), when its reach can’t be worked outbefore it runs, such as an agent-written script or a glob over a folder.

Copy-on-write

APFS on macOS, btrfs or XFS on Linux, ReFS on Windows. The copy is kept for a set time, so the run can be undone.

No such file system

On ext4 or NTFS, a command whose reach can’t be known becomes an ask instead.

What your yes covers

What you were shown, never an extent nobody knew. So an unknown reach gets a copy or an ask.

A ceiling

On files and seconds, set below the agent’s hook timeout. A copy that would pass it is dropped, and the command asks.

UNDOABLE BY DEFAULTWhen nobody can say what a command will delete, it either runs where it can be undone, or it asks.336 / 449
4.10.1Trust › Dodgesin the system: DeepBuild › defenses
Part 4: Can you trust an agent’s “done”? › 4.10: Which ways of looking done get caught?

Six Ways to Look Done (1 of 2): Bending the Checks

Say Claude Code wants #42 to look done without being done: three tricks on the checks, and what catches each.

Hides a failing test1"test": "vitest || true"|| true makes a failure look like successCAUGHT BYcheck health reads the package scriptINVALIDnames the maskEdits what done means2Edit .deepbuild/done.yaml- receipt = cart totalit tries to delete a checkCAUGHT BYa fail-closed rule, hub up or downDENIED→ deep_proposeAdds a test that can’t fail3test("receipt ok", …)it also passes on the old codeCAUGHT BYfix checks also run on the base commitINVALIDcan’t prove the fix
Check healthEach run records how many tests ran and whether a failure could be masked. Zero tests is never a pass.
Fail-closedWhen in doubt, or with the hub down, the rule says no. Checks change only by a proposal you approve.
Base commitA fix check must fail on the code before the fix. One that passes there proves nothing.
RESULTEach trick either fails to land or lands as a named record. None of them reaches you as a question.337 / 449
4.10.2Trust › Dodgesin the system: DeepBuild › defenses
Part 4: Can you trust an agent’s “done”? › 4.10: Which ways of looking done get caught?

Six Ways to Look Done (2 of 2): Dodging the Judge

Three more, this time on the judge, the hub’s done gate: switch off its hooks, talk around it, or grade itself.

Switches off its hooks4hooks = falsewritten into its own configCAUGHT BYhooks watched, and rechecked at startRESTOREDput back at once, naming the callBlames a limit5“usage limit reached”its last message, at the stopCAUGHT BYwhy it stopped comes from hook dataSENT BACKtext isn’t evidenceProves it with its own test6only its own check coversreceipt = cart totalno repo check you approved covers itCAUGHT BYthe agent’s own checks can’t pass a claimINCONCLUSIVEasks you to approve it
RestoredAgent writes to hook configs are denied. A removed entry goes back at once; a disable flag an agent wrote is undone. Both name the call.
Hook dataWhy a session stopped is read from the agent’s own hook payloads and error records, never from its words.
Own checksChecks the agent wrote can send its claim back, but never pass it alone. You can approve one into the repo’s checks.
RULE 1An agent’s word is never evidence: not its last message, not its own tests, not its own config.338 / 449
5Extend and compose
Part 5 asks: How does it grow without breaking? › 9 sections, 5.1 to 5.9, each answering one part of it (running index, slide 14)

Part 5: Extend and Compose

Parts 1–4 built DeepBuild and its trust. Part 5: every place it can be extended, an example of each, how pieces compose, and the rules that keep it safe.

DeepBuildwhere your agents show, not tell1 · Foundation1.1 four parts, 1.2 four jobs1.3 the rules, 1.4 the hub1.5 extensions, 1.6 ways in1.7 hooks, 1.8 the record1.9 storage, 1.10 processes1.11 platforms2 · See and steer2.1 the app, 2.2 the line2.3 asks, 2.4 matching2.5 answers back, 2.6 a taste call2.7 the app’s toolkit, 2.8 where code runs3 · Make: vibe visuals3.1–3.3 what it makes3.4–3.8 documents, frames3.9–3.12 GPU, light3.13–3.15 modules, checks3.16–3.21 3D, play, sound3.22–3.26 budgets, done bar4 · Trust4.1 a claim, 4.2 what done means4.3 verdicts, 4.4 flaky checks4.5 every stop, 4.6 bug fix #424.7 a UI change, 4.8 the finish line4.9 defenses, 4.10 dodges5 · Extend, compose5.1 extension points, 5.2 agents, hooks5.3 hub slots, 5.4 plug-ins5.5 panels, 5.6 canvas packs5.7 modules, 5.8 composing5.9 safety rules6 · In use6.1 what ships, 6.2 first run6.3 MCP tools, 6.4 the CLI6.5 leases, 6.6 the box6.7 your phone, 6.8 the wiki6.9 learning7 · Build it right7.1 looks right, 7.2 tests first7.3 rules, faults, 7.4 kits7.5 comparisons, 7.6 the gate7.7 borrowed, open, 7.8 budgets7.9 measuring, 7.10 six-week plan7.11 Decision 1, 7.12 routing replay7.13 cuts8 · What’s open8.1 scale, 8.2 issues8.3 R1 path, 8.4 risks8.5 owner calls, 8.6 fleets later8.7 next
WHERE WE AREThe highlighted branch is this part; its topics are the slides that follow.339 / 449
5.1.1Extend and compose › Extension pointsin the system: DeepBuild › extension points
Part 5: How does it grow without breaking? › 5.1: Where can DeepBuild be extended?

Every Extension Point, on DeepBuild’s Tree

Part 1 said features on top of the core are extensions. Here is each place one plugs in, how, and who may write it.

On the agent’s sideClaude Code, Codex, Cursor …Adapters→ 343registerAdapter: hooks, caps, factsTS or JSON-RPCDeepBuild, othersFacts files→ 344an agent’s quirks, per versiondatawith its adapterHook handlers→ 345deep.on: add context, or denytyped templatesany extensiondeep hubone per user, always onHub slots→ 346deep.register…: 21 slots, 18 callsone piece eachany extensionPlug-ins→ 350packages built from the hub’s blockssandboxedyour agent, othersBlueprints, kits→ 366a way of working, as one packagea bundleanyone, signedDeepBuild appwhat you look atViews and panels→ 359registerView: a JavaScript panelpanel hostanyone; shipped tooView documents→ 359filters, sorts, columns: no codedatayou, your agentMap layers→ 349registerLayer: rows on the Mapa hub slotany extensionCanvas corethe only part that drawsPacks→ 361recipes, kinds, looks, cue verbsdataanyoneGPU operators→ 360step graphs, or the WGSL subsetdata, loweredanyone, in a packLogic→ 252game rules, a pack’s programsWebAssemblyanyoneModules, backends→ 362Rust crates, one register callcompiled inDeepBuild onlyNEVER EXTENDEDthe kernel’s five parts: the record, the contract, capabilities (grants, quotas, secrets by handle), the two rules, the trusted paththe trusted ring: the supervisor, the installer, the app shell and its question card, the canvas core’s compositor, the device and media gate
HOW TO READ ITEach box is a worked example later in this part; its arrow is the slide. The red row never takes an extension.340 / 449
5.1.2Extend and compose › Extension pointsin the system: DeepBuild › extension points
Part 5: How does it grow without breaking? › 5.1: Where can DeepBuild be extended?

Five Ways an Extension Arrives, From Data to Compiled Code

Who wrote an extension decides how it arrives: from data anyone may write to code only DeepBuild compiles.

← anyone may write itcloser to the core →

1

Data in a pack

RUNSnever by itself; the core expands it at check

WHOanyone

CHECKEDonce per version, with each kind’s kit; then frozen

E.G.report@1’s KPI card

2

WebAssembly logic

RUNSin sandbox@1: no imports; fuel, memory, stack budgets

WHOanyone, in a piece or a pack

CHECKEDthe logic subset, then its fixtures

E.G.the rocket piece’s rules

3

A sandboxed process

RUNSits own process in the OS sandbox; TypeScript, or any language over JSON-RPC

WHOyour agent, or anyone outside DeepBuild’s release

CHECKEDconformance, its tests, a render, a dry run, an access check

E.G.ci-status, the stocks view

4

In-process TypeScript

RUNSinside the hub, as a plain function call

WHOonly DeepBuild’s signed release

CHECKEDpinned, and checked before it loads

E.G.the done gate, resolvers, adapters

5

A compiled canvas module

RUNSin the app, as Rust, fixed at startup by the seal

WHODeepBuild’s repo only, by a merged release

CHECKEDits interface’s kit, then the seal

E.G.the data module’s vector field

One package envelopeExtensions, packs, blueprints and kits install the same way: an owner/name ID, a version, the digest of its files and, optionally, its publisher’s key, trusted on first use.The manifest is read as data before any code loads; a signature that doesn’t verify is refused.
WHY FIVEEach step to the right is closer to the core and needs more trust. The last step, compiled into the app, only DeepBuild takes.341 / 449
5.1.3Extend and compose › Extension pointsin the system: DeepBuild › extension points
Part 5: How does it grow without breaking? › 5.1: Where can DeepBuild be extended?

Every Slot Has a Kit That Must Fail a Planted Wrong Fill

Each place an extension plugs in names an interface, how many may fill it, and a kit. Here: check kinds.

deep.registerCheckfills the slotcheck.kind@1· one fill per kind of check · its kit lives in the conformance package · lands in R1money.reconcilea real runner, from a plug-inpasses the kit: it may fill the slotthen it still has to show it can fail on a taskplanted 1reads “0 failed” from a suite that crashed before it ranfails the kit, with exactly its codea kit that can’t catch it proves nothingplanted 2reports passed after its deadlinefails the kit, with exactly its codea kit that can’t catch it proves nothingplanted 3drops a crashed run’s outputfails the kit, with exactly its codea kit that can’t catch it proves nothingkitcheck.kind@1its fixturesAnd if a kit ever let a planted fill through? The local preflight fails that slot, naming it. A slot with no kit, or no planted fill, fails too.slot

Interface

Each slot names one, name@major, with a digest per minor; only a break takes a new name.

How many

One fill (a check kind, an adapter, an index) or many (resolvers, sources, channels, views, layers).

Kit

The slot’s test cases. One runner in the conformance package runs every kit.

Planted wrong fill

A broken fill the kit must refuse. It is how a slot proves it is hard to fill wrongly.

THE PATTERNEvery extension point in this part has this shape: a slot or a registry, an interface, a kit, and a fault the kit must catch.342 / 449
5.2.1Extend and compose › Agents, hooksin the system: Agent side › adapters
Part 5: How does it grow without breaking? › 5.2: How is a new agent added?

A New Agent: Its Adapter Says What It Can Do

Slide 40 showed an adapter mapping hooks to shared shapes. Adding Cursor (R2) also means declaring caps.

Cursor’s adapter (R2)illustrative

deep.registerAdapter("cursor", { install, // our entries in hooks.json mapHook, // its hooks → shared shapes deliver, // (answer, session) doctor, // its items in deep doctor facts, // adapter.facts@1, per version caps: { holdStop: true, // stop + followup wakeIdle: false, // no route … }, unsupported: { local_chat: ["wakeIdle"] }, })
Your answer to an ask from a Cursor session arrives1Is its stop still held? caps.holdStop, seen firing in this sessionHold the stop: the answer goes back as followup_messageloop_limit raised from its default of 5, so the hold isn’t cut short2Its chat already went idle? Wake it: but caps.wakeIdle is false{ outcome: "unsupported", operation: "wakeIdle", surface: "local chat" }an answer the hub can act on, never a silent no-op that looks like success3So the next route down: the answer rides along with your next promptNext prompt: the one route every agent has

Every cap

holdStop, wakeIdle, steer, followUp, answerPermission, nativeTools, mcp, rewrite, editInput, errorTurnHook, startTurn.

Seen, not claimed

A cap counts in a session only once our hook has fired there, trusted, on a version its facts cover.

One per agent

The adapter@1 slot takes one fill per agent, and one adapter owns each session.

NO AGENT NAMES IN THE COREDelivery picks a route from caps, never from “is this Cursor?”, so a new agent adds no branch to the hub.343 / 449
5.2.2Extend and compose › Agents, hooksin the system: Agent side › adapters
Part 5: How does it grow without breaking? › 5.2: How is a new agent added?

A Facts File per Agent Version, and a Kit of Broken Fakes

Agent quirks change every release, so they live in a data file per version; an uncovered version is only watched.

Its facts fileversions illustrative

# adapter.facts@1 · cursor covers: 1.4 to 1.5 # versions events: stop, preToolUse, … # its names payload: session, tool, args # fields stop: followup_message, loop_limit launch: how to run it headless usage: how to count its usage causes: error texts that name a stop dirs: where it reads skills, MCP open: the link into its own app

Each field names the core rule that reads it, with a conformance case.

Cursor 1.5: a version its facts coverevents read as the facts say; its holds and blocks actCursor updates itself to 1.6not in covers: still recorded, each event marked unverifiedUntil it is checked: watch-onlyits holds and blocks stop acting; health shows one readingThe first 1.6 session runs the smoke testunder your standing approval; once you approve its diff, covers widens to 1.6A new agent release changes a file, never the hub.

The adapter kit’s broken fakes, each must fail

A duplicate event ID; an event after a stop; an answer delivered to another session; a steer that outlived an interrupt; an acknowledgement with no transcript sign; a driven fake that declares a cap it doesn’t honor.

Agents with no adapter code

An agent that speaks ACP, the Agent Client Protocol, needs only facts: bridge version, permission quirks, timeouts (R6).

WHY DATAAgents update themselves often. Kept as data, a new release is a file change plus a smoke test, and an unknown one is only watched.344 / 449
5.2.3Extend and compose › Agents, hooksin the system: Agent side › deep-hook › handlers
Part 5: How does it grow without breaking? › 5.2: How is a new agent added?

Hook Handlers: Many Extensions, One Reply, Typed Context

Any extension can also answer a hook with deep.on. When several do, the hub joins their replies by fixed rules.

claude · checkout-web› Bash git push origin maintool.before firesthe hubcalls every handler,joins replies byextension ID, A to Znotes-botfree text never fills a templatecontext: issue #42’s textpush-guarda deny stands; no handler removes itdeny: “main is protected; open a PR”release-boardtyped values: a handle, a numbercontext: “Release {release} freezes at {time}”slow-lintrecorded in the reply as failedno reply before the hook’s deadlineTHE ONE REPLY THE AGENT GETS[push-guard] denymain is protected; open a PR[release-board] contextRelease r-14 freezes at 17:00failed: notes-bot, naming thefield; slow-lint, past deadlineeach block labelled with its namenames and values illustrativeone reply

deep.on(event, handler)

On session.start, tool.before, tool.after, prompt.submit, agent.stop, merges and releases; it returns context or a deny.

A fixed order

By extension ID, never by load or finish order. Contexts join up to the hook’s bound, cut from the end, never ahead of a deny.

Typed context

Outside DeepBuild’s release, only templates its manifest declares, filled with handles, numbers or values from a closed list.

Never in a template

An outside reading, a source’s free text or transcript text: the handler is recorded as failed, naming the field.

WHY TYPEDAn agent reads every context block. If a plug-in could paste free text in, an issue’s body could give your agent orders.345 / 449
5.3.1Extend and compose › Hub slotsin the system: Hub › extension API › slots
Part 5: How does it grow without breaking? › 5.3: Which hub parts can be swapped?

Twenty Hub Slots, Each With Its Planted Wrong Fill

Each card: a deep.register… call, interface, fills, planted fault (red), release. Polled sources (R2) not shown.

registerCheckR1check.kind@1 · one per kindreads “0 failed” from a crashregisterResolverR1resolver@1 · manyanswers you, naming no decisionregisterSourceR1source@1 · streams · manyskips an event after a resumeregisterSourceR1work.item@1, push.record@1 · manycalls every author a collaboratorregisterEnvironmentR1environment@1 · oneready before its health route isregisterView · a shipped oneR1needs-you@1, session.row@1 … · one eachthe shipped view’s planted casesregisterView · any panelR1panel@1 · manydraws over the question cardregisterAdapterR1adapter@1 · one per agentanswers into another sessionregisterIndexR1index@1 · onekeeps a dropped source’s hitsregisterChannelR2channel@1 · many“delivered”, never acknowledgedregisterActionR2action@1 · manywrites nothing, reports a changeregisterStateSourceR2state-source@1 · one per kindcalls a change undoable; it isn’tregisterLayerR2map.layer@1 · manya row that cites nothingregisterFactsR2repo.facts@1 · manya route at a line with noneregisterModelR3model@1 · one per namecanned text on a timeoutregisterSchedulerR6scheduler@1 · onesuggests switching accountsregisterJobR6job.kind@1 · one per kindoutput used before it’s checkedregisterJobToolR6the kind’s qualification · many per kindlowercases test.upper’s last letterregisterDeviceR6device.class@1 · one per classa bridge that writes as youregisterPortR6port@1 · ≤ 8 a documenta port that sends on a seek
Trials (R4)A slot also lets a challenger run beside the piece in use, judged by measures fixed before it starts; a winner comes to you as one learned change.
WHAT IT BUYSEach slot’s red line is a real way to fill it wrongly. A fill that would make that mistake fails at install, not in use.346 / 449
5.3.2Extend and compose › Hub slotsin the system: Hub › extension API › slots
Part 5: How does it grow without breaking? › 5.3: Which hub parts can be swapped?

A Check Kind for Work Beyond Code: Totals That Reconcile

Part 4’s done gate judges by checks. Work that isn’t code needs new kinds of check, which a plug-in adds.

A money plug-in’s checkillustrative

deep.registerCheck("money.reconcile", runner) // runner(spec, ctx) → // { outcome, testsRun, evidence[] } // spec, from the definition of done: // statement: the bank’s, by handle // bills: readings from bill sources
  1. The drafting job picks it for work that closes books.
  2. Its kit’s planted runners must fail (342).
  3. The agent that did the work can’t be its only author.
“Close September”: the agent says the books matchvalues illustrativeSTATEMENT$4,210.00the bank’s total, by handleBILLS, SUMMED$4,198.0041 bill readings, each with its sourcethe runner returnsoutcome: "failed", testsRun: 1evidence: the $12.00 gap, by hashFAILsmallest case: one bill missing

R2

Service: an endpoint answers in shape and time. Data: a query’s rows hold. Document: each number matches its source.

R3, R6, later

Setting and machine checks with hosts (R3); playtests with logic (R6); money with the money extensions.

Only checks earn it

A runner can’t return a pass without its results; the validator alone makes the verdict.

SAME RULES AS CODEA new kind of check is a plug-in, but no PASS comes without real runs of checks the agent didn’t write.347 / 449
5.3.3Extend and compose › Hub slotsin the system: Hub › extension API › slots
Part 5: How does it grow without breaking? › 5.3: Which hub parts can be swapped?

A Channel to Your Phone: It Carries, the Hub Decides

Reaching you somewhere new is a channel plug-in. It carries asks both ways; the hub decides what an answer counts as.

paseo’s channel (R2)illustrative

deep.registerChannel("paseo", { deliver({ summary, link, thread_key }) // → delivered | stalled | timed_out receive() // → { thread_key, answer, // signature | account_link_id } })

Its kit plants

a channel that reports delivered with no acknowledgement, and one that marks an answer signed with no valid signature.

Many may fill it

Your phone, a chat app, email, a text message (which carries only a link).

the hubrenders the askroutes by kindand urgencychecks the proofdecides what theanswer counts asquiet hours; thenext channel whenone goes unseenthe channela plug-inonly carries:a summary,a link, a threadnever a secret,code or evidencephoneMerge PR #318?default: no · 1 dayYesNosigned with thisphone’s own keydeliverreceivesignature matches the paired phone’s key: a yes that can mergeno valid signature: no authority, no saved decision; at most “I did it” or a taste call
NEXT IN USEPart 6 shows the same channel from your side: one tap, one thread closed everywhere (390).348 / 449
5.3.4Extend and compose › Hub slotsin the system: Hub › extension API › slots
Part 5: How does it grow without breaking? › 5.3: Which hub parts can be swapped?

A Map Layer: Every Row Cites What Names It

Slide 274 showed live rows on the Map. A plug-in adds them with deep.registerLayer; each cites its support.

A services layer (R2)illustrative

deep.registerLayer("services", { rows(project) { // at start; again when // a cited entry changes return { rows: [ { kind: "service", anchor: "api", level: 1, cites: "compose.yml:12" }, … ], links: [{ from: "web", to: "api", rate: "reading:metrics#web-api" }] } }, children(id, level) { … } })

The map.layer@1 kit plants

a row citing nothing; rows that all cite one reading naming none of them; a row in a status color.

Three rows reach the hub’s checkapicites compose.yml:12, naming itkept, and drawn on the Mapits size and color bound to readingspaymentscites nothingrefusedlayer.unsupported, naming row and citationcachepainted in the FAIL colorrefusedstatus colors come only from a verdictSupport that counts: a record entry or state source item named by its anchor,a repo line that holds its name, or a reading keyed by it. Never a model’s answer.Each changed answer is one layer.rows event, its rows in one evidence file, so thescrubber shows rows as they were. A row’s kind names a pack recipe to draw it.
NEXTSlots take one piece each. A plug-in combines many of them: piece 4 of Part 2’s rings of trust, up close.349 / 449
5.4.1Extend and compose › Plug-insin the system: Hub › plug-ins
Part 5: How does it grow without breaking? › 5.4: How does a plug-in do real work?

Plug-ins in Depth (1 of 4): Built From Blocks

Piece 4 of the rings, up close: a plug-in your agent writes from a sentence, built from blocks the hub runs.

You: “Show my CI runs, and tell me when main goes red.”an illustrative sentence12 OF THE BLOCKS THE HUB RUNS FOR PLUG-INSsourceoutside calls, quotassourceoutside calls, quotas1secreta handle, not a valuesecreta handle, not a value2scheduleno overlap, catch-upscheduleno overlap, catch-up3storeits data, in the recordstoreits data, in the record4viewa panel in the appviewa panel in the app5noticeonly ones you askednoticeonly ones you asked6actionread, change or sendchannelreach you elsewhererunnermodel jobs, budgetedlayerrows on the Mapchecka new kind of checkaska question for youyellow: the six this plug-in usesci-status · its manifest, written by your agent1sourcethe GitHub API: its host, quota, timeout, how long an answer stays fresh2secreta GitHub token, by name; you type its value once, into the app shell3scheduleevery 5 minutes; never two runs at once, one catch-up after sleep4storethe last runs, kept in the record under the plug-in’s name5viewa CI panel in the app, drawn with the app’s own components6notice“main went red”, sent only because you asked for itprovidesreadings ci.run@1 (each run’s status and time) that other plug-ins may use
WHY BLOCKSThe hub makes every outside call, holds every secret and records every change, so a plug-in stays small and can’t leak a key.350 / 449
5.4.2Extend and compose › Plug-insin the system: Hub › plug-ins
Part 5: How does it grow without breaking? › 5.4: How does a plug-in do real work?

Installing ci-status: Read, Hash, Check, Then Ask You Once

Your agent wrote that manifest. Six steps take it to a running plug-in; you appear once, in step 4.

INSTALLING ci-status, THE PACKAGE YOUR AGENT WROTE1Read the manifest, as databefore any of its code loads: hosts, a secret by name, a schedule, a view, ci.run@1installer2Hash every file, with its modea symlink is refused; a publisher key is trusted on first use, a bad signature refusedinstaller3Check it before you see itthe kits of the slots it fills, its own tests, a headless render, a dry run, an access checkhub4Ask you once, on the trusted pathwhat it can do, what it can’t, and any access the sentence didn’t need5Write one event, pinnedthe version and your approval together, at user level; deep off covers itrecord6Start it, fencedthe supervisor runs it in the OS sandbox; it speaks JSON lines on stdio, nothing elsesupervisorITS MANIFEST, READ AS DATA (ILLUSTRATIVE)name: local/ci-status version: 0.1.0source: api.github.comsecret: github_token # a name onlyschedule: every 5 minstore, view, noticeprovides: ci.run@1STEP 6: WHAT ITS FENCE ALLOWS✓api.github.com, through the hub✕any other host✕the hub’s socket, your files✕the token’s valuetrusted path
LaterA file changed since its checks ran won’t load until they pass again. No seal: that is only for compiled canvas modules.
CODE LASTIts manifest is data, read first; its code runs only in checks and then fenced, after your one yes.351 / 449
5.4.3Extend and compose › Plug-insin the system: Hub › plug-ins
Part 5: How does it grow without breaking? › 5.4: How does a plug-in do real work?

Plug-ins in Depth (2 of 4): One Call, Inside a Grant

Block 1 at work: the hub makes the plug-in’s call, inside its grant (what you allowed it). Red: a call outside it, refused.

OS SANDBOXci-statusits own process: no networkbut granted hosts, no hub socketTHE HUB · CAPABILITIESapi.github.comnamed in the grantany other hostnot in the grant1schedule fires: read the source2grant names this host? quota left?3adds the token by handle4makes a reading: unit, source, as-ofthe callthe answera call to another hostrefused, recorded as capability.refused:the clause it broke and a digest of the call, never its values

What a grant is

Only limits the supervisor enforces at runtime: the OS sandbox, an egress filter, path containment.

Approved once

On the trusted path (the app, or the CLI after Touch ID), right from the denial.

Changed since checked

A plug-in whose files changed since its checks ran doesn’t load until they pass again.

THE KEY NEVER MOVESThe plug-in names its secret; the hub adds the value to the request header, never to a URL, a log, the record or a prompt.352 / 449
5.4.4Extend and compose › Plug-insin the system: Hub › plug-ins
Part 5: How does it grow without breaking? › 5.4: How does a plug-in do real work?

Plug-ins in Depth (3 of 4): Reusing Another Plug-in’s Data

You want a release board that shows CI status. ci-status already reads GitHub, so the board reuses its readings.

You: “Show each CI run’s status on my release board.”an illustrative sentenceci-statusthe plug-in from before;it already reads GitHubprovidesci.run@1release-boarda new plug-in your agentwrites; no GitHub callusesci.run@11promises2declares it usesCI.RUN@1 · ONE READINGrunmain #812statusfailedas of09:24a JSON SchemaTyped edgeTHE HUB, AT INSTALLboth sides name ci.run@1: wired, like a type check3board wants ci.run@2? the install fails, naming this edgeTHE RECORDeach reading is stored, then the board gets it4never a direct call✕ never crosses the edge:ci-status’s store, secrets, network

Reading

One value a plug-in records, with its source and the time it was true: here, one CI run.

Typed edge

A data shape one plug-in promises and another says it uses. The hub checks both at install.

Compose first

A weekly brief of stocks and CI is two plug-ins’ readings, a schedule and a send: no new data code.

NEXTci-status will ship a new version. The board must keep working: a shadow copy and the board’s own tests.353 / 449
5.4.5Extend and compose › Plug-insin the system: Hub › plug-ins
Part 5: How does it grow without breaking? › 5.4: How does a plug-in do real work?

Plug-ins in Depth (4 of 4): Trying a New Version Safely

ci-status v2 arrives. The hub runs it beside v1, replays the board’s own tests on its output, then asks you once.

ci-status v1in userelease-boarduses ci.run@1v1’s readings, as on the last slideci-status v2beside v1, on the sameevents, with its own store;its output is recordedfor comparison onlyShadow copy (R2)1reaches no one: not the board, you, an agent or a verdictrelease-board’s own tests,replayed on v2’s output; eachoutput checked against ci.run@1Contract test2all passAFTER A WEEK SIDE BY SIDE (DEFAULT)One decision for you: switch · keep both · removeeach keeps its own store, so switching back is instant3✕ one fails: the install fails, naming the edgev1 stays in use; the board never sees v2

Shadow copy

A new version running beside the one in use, on the same events. Its output is recorded, never sent on.

Contract test

The user’s own tests, here the board’s, replayed on the new version’s output. A fail stops the install.

A break, a new name

If v2 removed or retyped a field, it would be ci.run@2; an added optional field is a new minor of ci.run@1.

NEXTFrom one sentence to an installed plug-in: the stocks view, end to end.354 / 449
5.4.6Extend and compose › Plug-insin the system: Hub › plug-ins
Part 5: How does it grow without breaking? › 5.4: How does a plug-in do real work?

A Stocks Plug-in From One Sentence (R2)

The plug-ins so far, end to end: one sentence becomes a stocks panel in five steps, with one approval from you.

“Add a stocks view: my watchlist with live prices, a chart per stock, and alerts when a price crosses a target”Your agent builds itin a copy, on your plan1Checks runthe same as any build2You grant it oncea quotes host, a key by handle3It installs, sandboxedout of process, pinned4A panel appearsdrawn by the app’s parts5ONE APPROVAL, ON THE TRUSTED PATH: ONLY YOU CAN ANSWER IT“stocks” may read prices from one quotes host, and use yourAPI key by handle. It can’t reach anything else.The key never reaches the plug-in; the hub adds it.AllowNoStocksdrawn by the appticker Aticker Bticker Calert at your target
NEXTIt is one of seven test sentences. How well agents build them from the docs is measured, never passed.355 / 449
5.4.7Extend and compose › Plug-insin the system: Hub › plug-ins
Part 5: How does it grow without breaking? › 5.4: How does a plug-in do real work?

How Add Anything Is Measured: Seven Sentences, a Reading

The stocks view is one of seven test sentences. How well agents build them from the docs is measured, not passed.

THE SEVEN TEST SENTENCES, SHORTENED1“Hang every screenshot I take on a line under the menu bar”2“When I hold ⌥Space, look at my screen and point”3“Tell me when a receipt bounces for a real order”4“A stocks view: watchlist, live prices, alerts”store · source · schedule · notice · secret · action← last slide5“Host my agents’ terminals in tabs; keep them running”stream · canvas · raw input · run as you6“Show this repo as a 3D city I can fly into”map layer · fact readers · a source over MCP7“Show my services as a live 3D map”map layer · source · Read now · while shown · seriesONE SENTENCE, BUILT 5 TIMES IN EACH AGENTClaude Code4 of 5 first try: metCodex3 of 5: an open itemmet: at least 4 of 5 built with no repair round, and a medianof at most 1 repair. Otherwise one open item on the extensionguide, naming the sentence, the agent and the step that failed.runs illustrativeHOW STRICT 4 OF 5 IS: THE CHANCE A BUILD MEETS ITworks 90% of the time92%works half the time19%one bad run may pass; a flaky build mostly won’t
Pass or failOne recorded package per agent, replayed: it passes conformance and its sentence’s checks, and the same package with a planted fault is refused.First tier13 methods start the guide; a weather panel needs 3, the stocks view 7.
A READING, NOT A VERDICTA weak sentence opens work on the extension guide; it never fails anyone’s build.356 / 449
5.4.8Extend and compose › Plug-insin the system: Hub › plug-ins
Part 5: How does it grow without breaking? › 5.4: How does a plug-in do real work?

A Plug-in’s Runs Are Judged Too: Schedules and Actions

Part 4’s verdicts apply to plug-ins too: each scheduled run and each action is judged by what the hub recorded.

SIX WAYS ONE RUN OF THE STOCKS SCHEDULE CAN ENDwrote new prices to its storea change its job declared: the run passesPASSno price crossed a targeta no-op its job declared: not countedUNCOUNTEDthe API key is missingno runs until you add it; then one at onceBLOCKEDthe quotes host answered 429held till a call answers; waits double, up to 6 hINCONCLUSIVEany other errorwaits double, up to 6 h; 5 FAILs in a row pause itFAILits process died mid-runsays of each send: sent, not sent or unknownINVALIDAN ACTION: ADD A TICKERfrom the panel, your words or an agentaction.enteredrecorded before the handler startsthe handler runsinside the plug-in’s sandboxaction.reportedverified: true · checked: “read back”changed: taken from the hub’s own record,so a report can’t add or hide a write.no report: unverified · a send never answered:unknown, and never retried on its own
Tests never call liveEvery source call can be recorded and replayed with its secrets stripped, on a clock the test moves, so “the market is closed on Saturday” is a fixture.
WHY JUDGE THEMA schedule that keeps failing shows up as a failing claim with an owner, never as a panel that quietly went stale.357 / 449
5.4.9Extend and compose › Plug-insin the system: Hub › plug-ins
Part 5: How does it grow without breaking? › 5.4: How does a plug-in do real work?

Plug-ins That Host Something Live: Terminals in Tabs

One test sentence hosts your agents’ terminals in tabs. Live blocks make it work, and keep agents from typing in.

DeepBuildclaude · checkout-webcodex · api$ npm test 42 passed$ _a panel with focusterm-hosta plug-in, own processruns the shells, under one plainlynamed permission: run as youapproved once on the trusted path,revocable at oncestreamordered; waits, never dropsraw input: your keys,only while it has focusan agent sends raw inputrefused: it comes only from youanother panel reads the streamrefused: only the panels it opened fornames illustrativethe stream is never written to the record;a snapshot can be saved as evidencequit the app: the shells keep running

Stream

Output too fast to be state, to one panel: a terminal, a log, a REPL. Ordered; it applies backpressure.

Run as you

A shell can’t be fenced by a command list. The supervisor still tracks every process, by run token.

Device bridge, port (R6)

Gear a piece reads, such as a pen; a piece’s port opens only after a person clicks Connect.

Handoff (later)

A long-lived piece hands its open sessions to its next version, with a rollback, so an update kills nothing.

STILL OFF-LIMITSNo piece can let an agent type into another session, and what a screen shows is a reading at best, never evidence.358 / 449
5.5.1Extend and compose › Panelsin the system: App › panels
Part 5: How does it grow without breaking? › 5.5: How does the app change itself?

The App Extends Itself, From the Lowest Rung Up

Every view can change. Your agent composes pieces you have first, then edits a view document, then writes code.

The record shows “did it deploy?” asked of agents nine times in a week. DeepBuild suggests a deploy gadget.1Compose what you havethe CI panel’s gadget, placed on home beside the asksno code2Edit a view documentfilters, sorts, columns, which gadgets go wheredata, no code3Write a JavaScript panelregisterView("deploys", panel, "home")code, and only lastlowest rung firstWHERE A PANEL RUNSShipped: in the app, on the UI thread, 4 ms an update (proposed).Your agent’s: a separate panel host, JIT off. It sendsa tree of elements; the app draws it with its own parts.area: sidebar · home · a tab · the line · replace oneBEFORE IT SHOWS: ITS KIT AND A HEADLESS RENDERpanel@1 plants a panel that reaches the network, runs aprogram, moves focus without your gesture, or draws overthe question card. A new Needs you must pass needs-you@1;the session row and the return card, their own kits.

Suggestions (R2)

Built in a copy on your plan, shown only after the same checks; never an ask; Not now mutes it for a month.

Show what changed

A title-bar switch outlines every added or changed piece with the sentence it came from: Roll back, Remove.

Side by side

Your version runs sandboxed while the shipped one stays one click away. Only the card and access prompts are fixed.

EVERY VIEW IS A PLUG-INThe shipped ones too, and the layout. They register through the same panel slot an extension uses.359 / 449
5.6.1Extend and compose › Canvas packsin the system: Canvas core › packs
Part 5: How does it grow without breaking? › 5.6: How does new GPU work arrive as a pack?

A Pack Brings GPU Work as Data: A Toon Look for the Rocket

Slide 179’s rocket.cel was one operator. A pack carries several, plus step functions they share.

A toon packillustrative

name: toon # owner/toon version: 1.0.0 requires: { modules: { scene3d: … } } functions: toon.ramp@1: ports: { in: { x: f32 }, out: { band: f32 } } steps: … # ≤ 256 operators: toon.cel: material graph use(toon.ramp@1, …) toon.outline: pass graph use(toon.ramp@1, …)
1Pack check, once per versioneach graph and function runs the whole operator check; exactness comes from its steps2One approval, then pinnedyou see what it adds; it installs at user level3The rocket piece names itmaterial.op: toon.cel@1 · passes: [toon.outline@1]4At check, use() is inlined≤ 4 deep, never recursive; counted in the caller’s cost5The core writes the WGSLcompiled and cached; the status guard runs after itRefused, naming it: a shipped name such as glow; an internal step; shader text;a function called exact whose body takes a float step; a load from the network
Step functionA sub-graph with typed ports that any operator calls with use(): one ramp serves the material and the outline, so they band alike. Its registry, gpu.function@1, lands in R2; pack functions and composed graphs in R6.
NO SHADER TEXTA pack brings graphs of public steps; only the core writes the WGSL a GPU runs. Shipped status comes only by review.360 / 449
5.6.2Extend and compose › Canvas packsin the system: Canvas core › packs
Part 5: How does it grow without breaking? › 5.6: How does new GPU work arrive as a pack?

Adding a Kind (1 of 2): A Pack Kind, Built From Data

One registry in use: kind@1, filled by a pack. An illustrative report pack adds a KPI card to the Q3 chart.

1Write a recipetyped inputs, then steps that make items that already existinputs: label · value · unit · width    steps: rect · text · text2Declare the kind in a packits name carries the pack’s, so it never takes a first-party namekinds: report.kpi_card@1 → recipe · children · cost class3Add a rule, with a fix and a planted twinthe rule reads evaluated values only; the twin must break itreport.value_fits: value box ≤ card width − 2 × pad4Check the pack, once per versiondefaults validate · the same bytes twice · cost within 25% of itsestimate · clean examples pass every rule · each twin fails5Use it in a documentan item names the kind; it expands at check into rect and text itemskind: report.kpi_card@1    packs: [report@1.0]Q348vs Q2 44Pack kindexpands at check intokpi.card · rect@1kpi.label · text@1kpi.value · text@1Q3Planted twin48,000,000✕ report.value_fitsfix: widen the card or shorten the value

It can never

Be backed by code, bring a builder, arrays or operators of its own, take a first-party name, or change inside a published version.

Listed for agents

deep_kinds shows its schema, an example, its kit result and its cost at defaults.

Trust

A kind the working agent wrote judges only that agent’s own claims until you approve its pack.

NO SEAL NEEDEDA pack kind never enters the sealed set: it resolves per document through the pinned pack, so adding one needs no new build.361 / 449
5.7.1Extend and compose › Modulesin the system: Canvas core › modules
Part 5: How does it grow without breaking? › 5.7: How is a new kind added to the canvas?

Adding a Kind (2 of 2): A Code Kind, Through the Seal

New code means a DeepBuild module. A real one: the data module’s vector field, drawn as arrows and flow lines.

1Register it in the data moduleone register call adds the kind and its schemavector_field@1: fn · vars · arrows · streams · flow2Own its arrays; declare every readstreams integrate at check (RK4, pinned f64);arrows evaluate each frame from fn3Keep seeking equal to playingthe flow is a trim window in closed form,so no state crosses from frame to frame4Share data, never the kinda group’s warp reads its stream tabledata layout streams@15Prove it with fixturesa cached result equals a clean rebuild, underread-set changes and legal-order shufflesCode kindflow: a trim window in closed formWHAT GETS REFUSED✕ marks2d’s warp names data’s kinda module cycle: startup refused with its reason✕ data writes the core’s bounds array itselfa second writer; it contributes instead, and core checks see it✕ a document uses it in a build without datamodule_missing, naming data; a check that needs it is BLOCKED

Only first-party

Kinds backed by code come only from canvas modules, before the seal. Packs can’t add them.

Checks come free

Contribute to the core’s arrays (bounds, glyph boxes, strokes) and the core’s checks read the new kind unchanged.

Others reach it by data

A follow_stream constraint carries a dot along a stream: data’s own entry, so motion names no data kind.

WHICH ONEDiagram vocabularies, configurator parts and widgets are pack kinds. A kind that needs code of its own, like a builder, needs a module.362 / 449
5.7.2Extend and compose › Modulesin the system: Canvas core › modules
Part 5: How does it grow without breaking? › 5.7: How is a new kind added to the canvas?

Swapping a Backend: One Interface, Proof Before the Switch

A module implements its interface, as a seam’s backend does (slide 196). Here a second engine might replace Rapier.

physics@1what documents and checks seeits digest covers kinds, public arrays,tables, carried state, check kindsand tool entriesInterfaceRapier · in usemeasured · backend bytesa candidate backendanother crate in the repoImplementationboth replay, in replicas:• the migration corpus• the parity fixtures• input tracks you recordednothing live is touchedTrialequalwithin the kit’s tolerancediffers: item · step · fieldThe seal takes one implementation per interface, chosen at buildtime; two are refused, naming both. A document names only kinds.Only your decision switches, keeps or drops it; goldensit changes move with that decision, once per cause.

Equivalence

bit: the reference’s hashes on every fixture. measured: within the behavior kit’s tolerances, as physics is.

State

canonical: a documented layout any implementation reads, as logic’s is. backend bytes: only that crate loads them.

Runtime digest

Names every measured or backend-bytes implementation. Saves, matches, goldens and receipts carry it, so evidence never mixes.

Seams too

Each platform part (GPU, display, fonts, input, audio, network …) is an interface; its backends are implementations.

WHYGoldens and receipts name the backends that made them, so a golden never passes or fails across backends and evidence never mixes.363 / 449
5.8.1Extend and compose › Composingin the system: DeepBuild › composition
Part 5: How does it grow without breaking? › 5.8: How do pieces combine?

Composing at Every Level: Edges, Not Calls

Slide 353 joined two plug-ins by a typed edge. The same rule holds at every level, up to a whole piece.

THE SAME IDEA AT EVERY LEVELblocksa plug-inci-status: source, secret, schedule, store, view, noticea plug-in’s outputsanother plug-inrelease-board uses ci.run@1checksa definition of donerepo spec + task’s own; joins add checkspanelsa viewhome: the asks, then gadgets below themstepsa playbook (R6)each step with its checks, drawn as a linerecipes, packsa piecepiece@1 names studio@1’s rigs; packs name packsone documenta chart, then a filmthe same items, another profile (124)1A use names an interfacename@major at the minor it was built for, never apiece; the hub picks a provider that serves it2Required, or marked optionalremoving a required provider asks you once; anoptional one with none reads missing, never empty3No power through an edgea change through an edge needs the rule or ask anagent’s call would; a send always asks4Changes travel along edgesa new version reopens every user’s claims once, andtheir contract tests run again5No cyclesan install that would close a loop is refused,naming it, as the canvas seal doesFIVE RULES FOR EVERY EDGE
Compose before writingAsked for something new, your agent first builds it from pieces you have, then from view documents, and writes new code last; the change’s origin lists what it reused. The kernel defines the edges and is never itself a piece.
WHY EDGESUses go through the hub and the record, never as direct calls, so every join is typed, versioned and visible in Show what changed.364 / 449
5.8.2Extend and compose › Composingin the system: DeepBuild › composition
Part 5: How does it grow without breaking? › 5.8: How do pieces combine?

A Recipe Composes Primitives: The Rocket Piece, Unfolded

Recipes compose too. The rocket piece is one item naming a recipe; it unfolds into kinds from modules and packs.

The rocket piece: one itemillustrative

packs: [piece@1.0] # version illustrative items: rocket_lab: kind: piece.physics_lab@1 subject: rocket_world controls: { thrust: { kind: press } } measures: { "landing speed": … } rules: rocket_rules # logic item
A build without the physics module? The piece is refused with module_missing, naming it, and a check that needs it is BLOCKED. Nothing is quietly left out.
EXPANDS AT CHECK, NEVER PER FRAME, INTOITS MODULE (OUR READING)a three-point light rigscene3d+ pack studio@1a press named rocket_lab.thrustinputtraces of the last three launchesphysicsa readout and a chart per measuredataa quarter-speed replay of each landingmotionhits heard through foley@1media+ pack foley@1readouts of what the rules writelogicEach derived item is a kind that one canvas module owns; the recipe only namesthem, so the piece runs no code of its own. deep_query lists every derived item.

It declares what it needs

Each recipe names the kinds, canvas modules and packs its inputs need; packs name packs by exact version.

It brings its checks

physics.determinism, logic.determinism, physics.query, honest_numbers: in the brief, so none is dropped.

Change one thing

Inputs first; past them, a patch breaks out one derived item (211).

ONE LEVEL UPThe same items can then take another profile: slide 124’s chart that grows into a film.365 / 449
5.8.3Extend and compose › Composingin the system: DeepBuild › composition
Part 5: How does it grow without breaking? › 5.8: How do pieces combine?

A Blueprint Bundles a Way of Working: Close the Month

The biggest composition: a proven way to do a kind of work, installed like a plug-in, built from pieces you know.

close-the-montha blueprint · contents illustrativeone package envelope: owner/name, version, digest, its maker’s signatureWhat done meanstotals reconcile with each statement; every number in the report matches its source; sent only on your yesCheck kindsmoney.reconcile (slide 347), document, messageA playbook (R6)read bills → reconcile → draft the report → you → send, drawn as a lineBlockssources for vendor bills, a monthly schedule, a store, a sendGrantsthe bill sources’ hosts; keys by handle, never by valueA KIT: A BLUEPRINT FOR ONE GENRE OF GAMEthe grid core kit namespacks: gridcore@1, pixel@1logic libraries a piece linkscheck plug-ins: playtest, cataloga recipe: gridcore.gamethe checks its done holdsIts checks come from the installed kit,never the working agent. A kit anagent wrote binds only its own claims.game.online: a plug-in that uses thegame project’s launch, export and hookthrough typed edges: no canvas orcore change.
Track recordHow often a blueprint passed, and where, is computed from your own record; sharing one carries none of your data. Blueprints come with playbooks in R6.
THE LARGEST COMPOSITEA blueprint adds no new kind of power: every part is a piece from this part, wired by the same edges and grants.366 / 449
5.9.1Extend and compose › Safety rulesin the system: DeepBuild › rules for extensions
Part 5: How does it grow without breaking? › 5.9: What keeps extensions from breaking things?

One Closure Rule, and Contracts That Can’t Drift

Two rules stop extension points drifting: every list is declared one of three ways; every shape is versioned.

EVERY LIST AN EXTENSION COULD JOIN IS ONE OF THREEA slot or a registrywho may fill it, a kit, a planted wrong entry, sincecheck.kind@1 · graph.layout@1Closed, with a reasonwhat would reopen it, exhaustive or extensiblephases: determinism · bands: ring, neverOpen, declared per usereach item or pack lists its owna logic item’s occurrence kindsThe local preflight fails a list with none of the three,and a registry missing its kit, planted entry or since.Hub slots take code that installs and replaces; canvasregistries take data or sandboxed programs. One rule.EVERY CONTRACT ENTRY KEEPS ITS HISTORYR1R2R3ci.run@1since R1 · d1:4c…ci.run@2since R2: a breaking change, so a new nameci.run@1 gets deprecated_since R2, replaced_by ci.run@2,and works through an adapter for one major; each use says so.stable or preview: a preview entry is used only by name,listed in requires.preview, never by a stable package,and it names the issue that tracks it to stable.digests and versions illustrativeA break passes the preflight only with a reviewed filethat quotes the diff line and the workaround.
CoversAPI and JSON-RPC methods, MCP tools, event and document kinds, hub slots, canvas registries, the pack format and logic@1’s exports: each with since, a minor and a frozen digest d1:<hex> of its RFC 8785 bytes, in schemas built from one closed list of node types.
NOTHING GROWS UNSEENA list can’t gain a member without a kit. A shape grows only by a minor that adds; any other change takes a new name.367 / 449
5.9.2Extend and compose › Safety rulesin the system: DeepBuild › rules for extensions
Part 5: How does it grow without breaking? › 5.9: What keeps extensions from breaking things?

Hard to Get Wrong: Eight Rules, and Where Each Bites

All of this part’s safety, on one page. Each row: a rule, the mistake an extension could make, and what happens instead.

THE RULETHE MISTAKE IT STOPSWHAT HAPPENS INSTEADNever the ringan extension draws a fake Yes on the question cardrefused at install: the render check→ 91Sandboxesagent-written code reads your keysit runs out of process, fenced by the OS→ 34Grants, enforceda plug-in calls a host you never allowedthe hub refuses; capability.refused→ 352Kits with planted faultsa runner reads “0 failed” from a crashthe slot’s kit fails it→ 342The closure rulea list grows with no test for its membersthe preflight fails it→ 367The sealtwo physics engines in one buildstartup refused, naming both→ 219name@majora provider changes a shape silentlya break needs a new name; a minor only adds→ 367Shadow copies, contract testsci-status v2 breaks the release boardthe install fails, naming the edge→ 354
And each block’s “never”A secret’s value seen by a plug-in · a notice you didn’t ask for · another plug-in’s store read · a verdict written by an extension, even a first-party one · an ask answered by one without naming your decision. The core refuses each.
RULE 2, FOR EXTENSIONSA kit, like a check, proves nothing until it fails what it should; slide 415 holds every kit to that.368 / 449
6In use
Part 6 asks: What is it like to use? › 9 sections, 6.1 to 6.9, each answering one part of it (running index, slide 14)

Part 6: In Use

Parts 1–5 showed how DeepBuild works and grows; now using it: first run, MCP, CLI, leases, the box, phone, wiki, and how it learns from past work.

DeepBuildwhere your agents show, not tell1 · Foundation1.1 four parts, 1.2 four jobs1.3 the rules, 1.4 the hub1.5 extensions, 1.6 ways in1.7 hooks, 1.8 the record1.9 storage, 1.10 processes1.11 platforms2 · See and steer2.1 the app, 2.2 the line2.3 asks, 2.4 matching2.5 answers back, 2.6 a taste call2.7 the app’s toolkit, 2.8 where code runs3 · Make: vibe visuals3.1–3.3 what it makes3.4–3.8 documents, frames3.9–3.12 GPU, light3.13–3.15 modules, checks3.16–3.21 3D, play, sound3.22–3.26 budgets, done bar4 · Trust4.1 a claim, 4.2 what done means4.3 verdicts, 4.4 flaky checks4.5 every stop, 4.6 bug fix #424.7 a UI change, 4.8 the finish line4.9 defenses, 4.10 dodges5 · Extend, compose5.1 extension points, 5.2 agents, hooks5.3 hub slots, 5.4 plug-ins5.5 panels, 5.6 canvas packs5.7 modules, 5.8 composing5.9 safety rules6 · In use6.1 what ships, 6.2 first run6.3 MCP tools, 6.4 the CLI6.5 leases, 6.6 the box6.7 your phone, 6.8 the wiki6.9 learning7 · Build it right7.1 looks right, 7.2 tests first7.3 rules, faults, 7.4 kits7.5 comparisons, 7.6 the gate7.7 borrowed, open, 7.8 budgets7.9 measuring, 7.10 six-week plan7.11 Decision 1, 7.12 routing replay7.13 cuts8 · What’s open8.1 scale, 8.2 issues8.3 R1 path, 8.4 risks8.5 owner calls, 8.6 fleets later8.7 next
WHERE WE AREThe highlighted branch is this part; its topics are the slides that follow.369 / 449
6.1.1In use › What shipsin the system: Hub › extensions
Part 6: What is it like to use? › 6.1: What is on by default?

What Ships On by Default: Eleven First-Party Extensions

Part 6 walks through what you use. First, what is already switched on: eleven parts that do the daily work.

JUDGE THE WORKdone-gatejudges every stop that did workspec-draftdrafts each repo’s checks, and each task’s donechecks-commandhermetic runs that count their testsjourneysPlaywright runs with video, step by stepRUN AND ANSWERenv-localthe repo’s own stack on leased portsresolver-decisionsanswers only from a saved decisionviewNeeds you, the sidebar, the Map, NumbersREMEMBER AND REPORTwikiwhat it learns, each line with its sourcearchivekeeps transcripts before agents delete themreadingsyour time, agent spend, issue to mergegithubverdicts as commit statusesall eleven run inside the hub,on from the first launch
The floor stays in the core, whatever gate is installed: the validity gate, the definition’s hash check, whose checks count, the base-commit run for a fix, the .deepbuild/ guard and project trust. In safe mode the hub starts with no extension at all, and that floor and the fail-closed guards still hold.
A FLOOR UNDER THE GATENo manifest replaces the done gate until a second gate exists; its floor stays in the core.370 / 449
6.2.1In use › First runin the system: App › setup
Part 6: What is it like to use? › 6.2: What happens the first time you run it?

First Run (1 of 2): One Button, and Your History Becomes a Wiki

Day one: one Set up click starts the hub, adds hooks in watch-only, and turns your history into a wiki of notes.

DeepBuildfirst launchSet upno Settings page;nothing else is askedThe hub starts, and starts again at every loginone per user; it keeps running after you close the terminal1Hooks go into Claude Code and Codexthey judge and record but block nothing, and hold no stop;a few safety rules apply at once, such as no kills by name2Your own agent reads your history into a wikiheadless, on your plan, never pasting history into a prompt: 212 sessions took38 sub-reads (small reads by sub-agents), about 4% of one 5-hour usage window3Watch-onlyAt most 5 open questions, each asked when it matters: how api starts is asked when an agent first starts api.
CHANGE IT IN WORDSThere is no settings page. Say “stop checking lint in shop” and it comes back as a change you approve.371 / 449
6.2.2In use › First runin the system: App › setup
Part 6: What is it like to use? › 6.2: What happens the first time you run it?

First Run (2 of 2): A Repo Gets Its Checks at Its First Session

A repo’s spec: the approved checks Part 4 reuses, drafted at an agent’s first session there; you approve once.

watch-only: nothing blocks, no stop is heldgatedAn agent startsits first sessionin checkout-web1Drafts .deepbuild/from CI steps, scriptsand AGENTS.md;runs nothing yet2Runs each onceonly in a trusted repo;drops any with 0 testsor that can’t start3One card for you4Gates onstops in this repoare now judged;files for you to commit5spec-draftThese 6 checks?Approve
Trust, reusedA repo trusted in Claude Code’s workspace trust or Codex’s trusted projects needs no second answer. Trusted in neither: nothing runs.
In your own wordsInstead of the button, say what to change. It comes back as a diff of the draft, and nothing is written until you apply it.
Later changesA new CI step or a renamed script becomes one proposed diff, not a surprise.
NOBODY WRITES A SPECUntil you approve a repo’s drafted checks, its verdicts are watch-only: nothing blocks and no stop is held.372 / 449
6.3.1In use › MCP toolsin the system: Agent side › deep mcp
Part 6: What is it like to use? › 6.3: What can an agent call?

MCP Tools (1 of 3): The Agent Checks Its Target and Searches

Part 1’s optional MCP tools, in use: mid-task, Claude Code asks DeepBuild three things through deep mcp.

claude · checkout-web · mid-taskMCP toolsdeep mcpone per session,bound to it only› deep_statuswhat am I aiming at?Its locked definition of done, and open asksthe requirements and the checksthat will judge them; open asks: none› deep_search “flaky checkout”has this been fixed before?2 past fixes, each with its sourcesession:01K…#m42 · wiki:repos/checkout…first run’s wiki, decisions, verdicts, open items; read-only› deep_claim expects 3/3 + receiptwhat will the checks show?Saved before any check runsa run that disagrees shows as acontradiction, so a made-up reason shows
PREDICTIONS FIRSTdeep_claim writes down what each check should show before it runs, so an excuse made up afterwards shows.373 / 449
6.3.2In use › MCP toolsin the system: Agent side › deep mcp
Part 6: What is it like to use? › 6.3: What can an agent call?

MCP Tools (2 of 3): One Question for You, and Work Goes On

Part 2’s ask, raised with deep_ask: a card for you, while Claude Code keeps working until your answer lands.

AgentClaude CodeHubrecord, resolversYouNeeds youdeep_ask“delete old migration?”1an authority askno saved decision covers it2NEEDS YOU · AUTHORITYDelete old migration?default: no, in 1 day3“still waiting”returns the ask’s ID45 s before its tool timeoutother work5deep_wait6No7you tap Nodelivers itinto the sessionanswer: noacknowledged8
NO WAITING FOREVERdeep_ask answers “still waiting” before the agent’s tool times out; deep_wait picks up your answer later.374 / 449
6.3.3In use › MCP toolsin the system: Agent side › deep mcp
Part 6: What is it like to use? › 6.3: What can an agent call?

MCP Tools (3 of 3): A Figure, and What No Tool Can Do

Left: deep_show puts a figure on its claim (render-back, Part 3). Right: all eleven tools, and what none can do.

› deep_show before/after figuredeep_showBEFORECart$18.01Receipt$18.00✕off by a centAFTERCart$18.01Receipt$18.01✓they matchreturns to the agent: its issues and a snapshotYou see it when you open it. It is never pushed,and a picture is never proof.WHAT DEEP MCP CAN CALLdeep_status · its targetdeep_search · search past workdeep_claim · predict resultsdeep_ask · ask youdeep_wait · wait for an answerdeep_propose · propose a changedeep_run · run a checkdeep_open_item · add an open itemdeep_evidence · attach evidencedeep_env · start the environmentdeep_show · draw a figureWHAT NO TOOL CAN DO✕ answer an ask✕ change a check✕ decideEach MCP server reaches only the session it serves.
LIMITSAn MCP server can ask, search, claim, propose and show. It can never answer an ask, change a check or decide.375 / 449
6.4.1In use › The CLIin the system: Around it › deep CLI
Part 6: What is it like to use? › 6.4: What can you do from a terminal?

At a Terminal (1 of 2): See Every Session, Answer One Ask

The deep CLI, Part 1’s way in for you and for scripts. Two commands: see every session, then answer one ask.

illustrative output
$ deep status
checkout-web claude-code working 1 ask
api codex 3 checks running
· about 4 min
docs claude-code PASS 3/3
$ deep inbox
1 authority push api to main
default no in 22 h
answer 1 [y/n]: y
confirmed by Touch ID
delivered to api (steer)
deep status is yours, unlike the agent’s deep_status: every session by repo, from the record, even with the hub down.
deep inbox holds the same asks as the app’s Needs you. Steer means your answer joins the agent’s running turn.
Touch ID: push api to main?the OS confirms a person, not a keystroke
Why Touch ID: your agents run as you, so they could type “y” here too.
WHY TOUCH IDA yes to a push or a spend, or any answer saved as a decision, counts only once the OS confirms you.376 / 449
6.4.2In use › The CLIin the system: Around it › deep CLI
Part 6: What is it like to use? › 6.4: What can you do from a terminal?

At a Terminal (2 of 2): A Health Check and an Off Switch

deep doctor says what is wrong and how to fix it. deep off puts every gate back in first run’s watch-only.

illustrative output
$ deep doctor
hub up · hooks trusted in Codex
MCP loaded
codex Stop timeout 600 s, want 45 min
→ fix: deep setup
$ deep off
every gate is watch-only now
fail-closed guards still hold; deep on to undo
deep doctor lists each problem with a stable code, both values and the fix.
The example: Codex’s Stop hook timeout is set once at setup to 45 minutes, so a slow check can still reach a Codex session in the same turn.
deep off is the escape hatch. Watch-only means stops are still judged and recorded, but no verdict blocks and no stop is held. The fail-closed guards still deny.
setup first run’s Set up button, for scriptsspec a repo’s checksfind · read your history by handledebug bundle redacted, for bug reportsshow · open · run · env up · report
ESCAPE HATCHIf DeepBuild gets in the way, deep off makes every gate watch-only at once; the fail-closed guards still hold.377 / 449
6.5.1In use › Leasesin the system: Hub › extensions › leases
Part 6: What is it like to use? › 6.5: How do sessions share ports, machines and files?

Leases (1 of 3): A Port Already Held Is Refused, Not Fought Over

The glossary’s lease, in use: api holds port 3000, so the hub refuses checkout, names api and offers 3001.

apiCodexcheckoutClaude Codeport 3000Leaseheld by api✕ refused: held by api (Codex)next free: 3001port 3001held by checkoutWhat a lease isA shared thing one session holdsso another can’t collide with it.WhyA real pkill once took down asibling session’s stack, and twoworktrees fought over one port.Also leased: test accounts,simulators, screens, GPUs.
A REFUSAL NAMES THE HOLDERSo the second session moves on at once, instead of fighting the first or killing its server.378 / 449
6.5.2In use › Leasesin the system: Hub › extensions › env-local
Part 6: What is it like to use? › 6.5: How do sessions share ports, machines and files?

A Stack per Worktree: deep env up Hands It Its Ports

Where checkout’s 3001 goes: env-local leases each port done.yaml names, then passes it into the stack.

.deepbuild/done.yaml (ILLUSTRATIVE)environment: compose: docker-compose.yml ports: [web, db] ready: http: localhost:${web}/healthwho calls it: you, with deep env up;an agent, with deep_env; or the gate,before a journey on checkout’s claim1env-local reads itthe stack, the two ports it needs, how to tell it’s readyan extension2leases both ports, per worktreeas slide 57 showed: web 3000 is the api session’s, so 3001; db 5432 is freethe hub3starts the stack on thema Docker Compose project named from run token 7f3a; web=3001, db=5432 passed insupervisor4waits for healthGET localhost:3001/health → 200: ready; a seeded database also needs its seed recordenv-local5hands it to the journeynever came up? the journey is missing, so BLOCKED, never FAILjourneysdeep env down: that compose project goes down; each lease ends once no container with its label is left (how processes stop: slide 58)lease
TWO STACKS, NO CLASHEach worktree’s stack gets its own project and leased ports, so two sessions never share one.379 / 449
6.5.3In use › Leasesin the system: Hub › extensions › leases
Part 6: What is it like to use? › 6.5: How do sessions share ports, machines and files?

Leases (2 of 3): A Lease Ends Only When Its Processes Are Gone

api ends, but its test account stays leased until the supervisor (Part 1) proves all that api started is gone.

test account alice@held by apistill held: not yet proven goneapi’s session endsall proven gonecheckout takes itTHE SUPERVISOR CHECKS WHAT API STARTEDPROCESSRUN TOKEN + START TIMENOWnode server✓ matchesgoneplaywright✓ matchesone it can’t prove✕ no token or groupreported onlystill runninggonePast its expiry, a lease is only stale.It ends when its holder has ended andall the supervisor recorded is gone;one it can’t prove never holds it.Run token: a tag in the environmentof each process DeepBuild starts,checked with its start time.
NEVER BY NAMEDeepBuild never kills by name or port. It stops only processes it can prove it started, never by a PID alone.380 / 449
6.5.4In use › Leasesin the system: Hub › extensions › leases
Part 6: What is it like to use? › 6.5: How do sessions share ports, machines and files?

Leases (3 of 3): An Hour on One Mac, and Every Kind of Lease

The hub’s leases on one Mac for an hour: black is api (Codex), yellow is checkout (Claude). Below: each kind.

0 MIN60 MINport 3000api (Codex)port 3001checkout (Claude)test account alice@apicheckoutGPU 0film renderCPU slots (6 of 12)checks, both
Exact keyports, test accounts, phone numbers, screens, simulators, GPUs
Glob (R2)file paths, relative to the repo root, held in every worktree of it
Prefix (R2)document IDs, matched by their start
Pool of nmachine slots, such as CPU slots; refused past n
Each kind is data, lease.kind@1: how its keys match, a cap, a cooldown and a cost. Two leases on one key are refused unless both are shared.
DATA, NOT CODEA new kind of shared thing is one data entry, not new code. A refusal always names the holder.381 / 449
6.5.5In use › Leasesin the system: Hub › extensions › leases
Part 6: What is it like to use? › 6.5: How do sessions share ports, machines and files?

Two Sessions, One Repo: Notices, Dry Merges, Hard Stops (R2)

Leases keep sessions off each other’s ports. For the code, a session map tells each agent what others change.

A · Claude Codebranch fix-42the hub’s session mapwho works where, on whatB · Codexbranch coupon-ci1on its start: A is in this repo, on #422A edits total.tsbefore its edit: A changed total.ts3dry merge of the two branch tips: conflictyour branches conflict in total.ts4A adds migrations/0042_coupon.sqlB’s 0042 is denied: next free is 00435A’s branch mergesrebase before you say done

Session map

A table rebuilt from the record: agent, worktree, branch, issue, changed files, commands, leases. R1 keeps it already.

Dry merges

git merge-tree between branch tips in the hub’s own mirror, off the hook path: no worktree or index is touched.

Hard stops

A taken migration number or unique name, or a leased port, is denied with the next free value.

Facts, not words

Notices carry paths, line ranges, issues and session names, never another agent’s text.

NO MAIL BETWEEN AGENTSNothing types into another agent’s terminal, and one agent can’t instruct another through a notice.382 / 449
6.5.6In use › Leasesin the system: Hub › extensions › leases
Part 6: What is it like to use? › 6.5: How do sessions share ports, machines and files?

Plan Windows, Not Dollars: DeepBuild Waits at Your Reserve

Sessions also share your plan. Its limit is windows, not dollars; DeepBuild reads them and keeps a reserve.

ONE ACCOUNT’S WINDOWS (ILLUSTRATIVE)5-hour window82% usedweekly window41% usedyour reserve: 80%Claude Code: rate_limits.five_hour and seven_day,from its status line · Codex: rate_limits in its logsPAST THE RESERVE, WHO WAITS?your own sessionsnever held by DeepBuildgo onDeepBuild’s own jobsdrafting, wiki reads, the review checkwaitturns DeepBuild causes (R2)a send-back, a continue, a wake-upwaitTHE CLAIM SHOWSBLOCKEDcause: plan window · owner: youcounted as blocked timePer task: #42 took 6% of this 5-hour window, about $3 on an API key (illustrative)Billing mode: an API key set in a session bills that account, never a window

Read locally

From the status line and session logs, with no credential read and no call to a vendor with your tokens.

Missing is unknown

A window a reading leaves out is unknown, never zero, and another account’s sign-in isn’t a reset.

Per task

Tokens summed per session, claim and issue, subagents included, with what the same work would cost on a key.

No reading yet

After 30 minutes with no window while a job waits, one ask: run up to 10 jobs a day without one, or connect the CLI.

NEVER A SWITCHdeep never signs in, never reads a credential file, and never changes a running session’s account.383 / 449
6.6.1In use › The boxin the system: App › the box
Part 6: What is it like to use? › 6.6: How do you start and steer sessions from the app?

Start a Session From the App (R2)

You type a task in the main box; a start card shows what will start, where and how. Read 1 to 6.

DeepBuild · the main boxfix the flaky checkout test1START CARDrepocheckout-webthe page you’re onagentClaude Codeyour default for checkout-webaccount~/.claudeits default homeworktreenew, from origin/mainfetched 2 h agomodeasks before actingthe agent’s own default2start cardSend3FIRST ROUTE THAT CAN RUN ITpaseowhen it runs; not herea terminal the hub hostsClaude Code and piunmodified CLI, run tokenapp-serverCodex4routecheckout-web · Claude Codeworkingstarted in the app · hosted5$ claude "fix the flaky checkout test"› Read checkout.test.ts› Bash npm test -- checkout› Edit checkout.test.tsyour words: its first argumentterminal tab6the card says which route it took, in one lineit keeps running when the app quits or the hub restarts
Only your SendNo agent, MCP call, deep command or plug-in starts one. A plug-in’s request waits as a draft in the box.
Never typed inYour words go in as the CLI’s first argument; later words go through hooks, never as keystrokes.
Your own sign-inThe unmodified agent on your own login, gated by deep-hook like any session you start yourself.
NEVER LEAVE THE APPpaseo is one route among them; without it, DeepBuild starts Claude Code, Codex or pi itself.384 / 449
6.6.2In use › The boxin the system: App › the box
Part 6: What is it like to use? › 6.6: How do you start and steer sessions from the app?

A Worktree of Its Own for Each Session You Start (R2)

A start from the main box gets its own folder and branch, owned by its task until you remove it. Read 1 to 6.

your checkout~/code/checkout-webmain, with your own editsport 3000never touched: no git runs here,no index or file changesorigin/main, as last fetched (2 h ago)1git worktree add, run by the supervisor, off the hub’s event loop~/.deepbuild/worktrees/checkout-web/fix-flaky-testa new branch from origin/main’s tipport 3001its own leases: ports and paths2worktreeworktree.createdowner: task “fix the flaky checkout test” · base a1b2c33WHEN THE TASK SETTLESmergedsettledit stays until you pressRemove on its rowRemove→ worktree.removed4an unpushed commitcan’t be removed there:“unpushed commit, kept”5From a session’s page, the new session shares that session’sworktree under path leases, unless you pick New worktree.6
Never fetches by itselfThe card says how old the last fetch is. A stale base is recorded on the receipt, not refused.
No git in your worktreesDeepBuild never runs git inside an existing worktree or touches another one’s index or files.
Through paseopaseo makes its own worktree workspace, and the record names the same owner: the task.
REMOVED ONLY ON YOUR PRESSNothing deletes a worktree on its own, and one with unpushed work stays.385 / 449
6.6.3In use › The boxin the system: App › the box
Part 6: What is it like to use? › 6.6: How do you start and steer sessions from the app?

Who Does the Work: Pick an Agent, or Let DeepBuild Route (R2)

Pick none, and the card names one by the first rule that holds, skipping an agent at your reserve. Read 1 to 4.

WITH NO AGENT PICKED, THE FIRST RULE THAT HOLDSthe repo’s default agenta decision you saved: “use Claude Code in checkout-web”1the agent of the repo’s last PASSthe most recent task here that reached PASS, from the record2the agent of your last sessionanywhere, when the repo has no task yet3the first agent setup foundwhen there is no history at all4passed over,reason shown:the account thecard would use isat your reserve,or no route herecan start itthen the nextrule or agentEXAMPLE IN CHECKOUT-WEB (WINDOWS ILLUSTRATIVE)1 · Claude Code, your default5 h · 4% left · reserve2 · Codex, the last PASS here5 h · 63% leftSTART CARDagent: Codex“Claude Code at your reserve”Changea readingSend starts it at once; the reserve only changed the name.
Never an askThe card names one and says why, and you change it before Send. Nothing waits on you.
Never holds you backA start of yours never waits at the reserve. The account is named the same way, without the reserve.
From R6A scheduler plug-in can replace this rule, tried side by side with it first.
ALWAYS SHOWN, ALWAYS YOURSThe card names the agent and the reason before you send, and you can pick another.386 / 449
6.6.4In use › The boxin the system: App › the box
Part 6: What is it like to use? › 6.6: How do you start and steer sessions from the app?

One Box: Steer, Follow Up, or Answer a Card in Words

Words for the running turn, the next turn or a card; Steer and After this turn are R2, the rest R1. Read 1 to 6.

CLAUDE CODE · CHECKOUT-WEB · A TURN THAT IS RUNNINGEdit total.tsBash npm testRead cart.tsStopnext turn“use the existing fixture”Steer1read at its next tool call,as PostToolUse context2“then run the e2e suite”After this turn3queued; it starts the next turnfrom: appevery message the app sends carries its origin and its delivery’s request IDNEEDS YOU · TASTE CALLKeep the total above the fold?A · keepB · move itdarker, and keep the total in view“Answers this ask only”kept with this answer; decision: none; never reusedSend4NEEDS YOU · AUTHORITYPush to main?AllowDenyyesSends your words as the reason; this won’t run5typed “yes” → decision: none; the push is deniedonly Allow, pressed once the card arms, runs it6
NEVER ASKED TWICEBox words can answer an open question; an authority card stays open, your words beside it.387 / 449
6.6.5In use › The boxin the system: App › the box
Part 6: What is it like to use? › 6.6: How do you start and steer sessions from the app?

Every Session in One Place (R2)

Sessions from the app, your terminal and the desktop apps share one list, and one that ended resumes here. Read 1 to 5.

SIDEBAR · CHECKOUT-WEBClaude Code · flaky teststarted in the app · hostedworkingCodex CLI · #42 totalin your terminalsays doneClaude desktop · docs copythe Claude desktop appquietCodex CLI · refactor cartin your terminal · endedended1while it runs: a note, or a steer where its adapterallows; it is never moved into the appResume in the app2resumed by exact ID 7f3…in a terminal the hub hosts3only after its process ended:two processes on one threadwould write one transcriptLineAsksChecksChangesTerminalworktree ~/.deepbuild/worktrees/checkout-web/fix-flaky-testbranch: new · base: 3 behind main · leases: port 3001, src/checkout/**4total.ts:42− return round(sum)+ return roundCents(sum)uncommitted, from the hooksnever by running git in its worktree; read onlyArchive5
Wherever it startedThe app, your terminal, the Claude desktop app or the Codex app: one list, by repo.
Changes, worktree, leasesIts diff, its branch and base, and every lease it holds, on its page.
ArchiveHides a row until it shows new activity. It deletes nothing and stops nothing, and an open ask blocks it.
WHILE IT RUNS, IT STAYS YOURSA session started elsewhere is never moved; once it ends, Resume opens it here.388 / 449
6.6.6In use › The boxin the system: App › the box
Part 6: What is it like to use? › 6.6: How do you start and steer sessions from the app?

One Account per Session (R2)

An account is an agent home you signed into yourself; the start card names one per session. Read 1 to 5.

~/.codexyour own plan, signed in by yousign-in filesnever openedDeepBuild’s hooksset up in each home~/.codex-workyour work account, signed in by yousign-in filesnever openedDeepBuild’s hooksset up in each home1START CARDagent: Codexaccount: ~/.codex-work2CODEX_HOME=~/.codex-workone variable set, nothing else changedonly the path passes; no credential3account homeROOM, PER HOME, NEVER A STATUS COLOR (ILLUSTRATIVE)~/.codex-work5 h · 31% left · resets 14:20week · 70% left~/.codex5 h · 88% left · resets 16:05week · 54% left4A session already running in ~/.codex keeps ~/.codex: DeepBuild neverchanges a running session’s account, signs in, or suggests a switch.5
An account is a homeA config home you signed into with the agent’s own login: CLAUDE_CONFIG_DIR or CODEX_HOME.
Every home seenSetup puts its hooks in each home you add, so every home’s sessions show and its windows are read.
Tied reposA repo you tied to one account starts only in that account’s homes.
YOUR LOGIN, YOUR HOMESYou sign in with the agent’s own login; DeepBuild only passes the home’s path.389 / 449
6.7.1In use › Your phonein the system: Around it › channels
Part 6: What is it like to use? › 6.7: How do you answer away from your desk?

Your Phone (1 of 2): One Tap on an Ask, Signed (R2)

A channel carries asks beyond the app, here to paseo’s phone app (paseo runs agents). Read 1 to 8.

Codex · api“merge PR #318?”hubthread 7f31Needs you, on your Macmerge PR #318?thread 7f32channelpaseo phone app (R2)summary, link, thread34DeepBuild · CodexMerge PR #318?default: no · 1 dayYesNo5signed withthis phone’s key6signature checked:it counts as authority7delivered intothe session8
SIGNEDAn authority yes from a phone counts only when the phone’s own device key signed it. An unsigned one is refused.390 / 449
6.7.2In use › Your phonein the system: Around it › channels
Part 6: What is it like to use? › 6.7: How do you answer away from your desk?

Your Phone (2 of 2): One Thread, Closed Everywhere (R2)

Part 2’s one thread per ask, on three surfaces: one answer closes all three. Below: who may answer what.

App · Needs youmerge PR #318?thread 7f3✓ answered: yesCLI · deep inboxmerge PR #318?thread 7f3✓ answered: yesPhone · paseomerge PR #318?thread 7f3✓ answered: yesone answer, on the phone, closes thread 7f3 on all three at onceWHAT YOU SENDWHERE IT MAY COME FROM“I did it”, or a taste callany channel you’ve verifieda check or an undo backs thema yes with authority: merge, push, spendthe trusted path: the app, the CLI once the OS confirms you,or a paired phone that signs ita text messagecarries only a linknever a secret, code or evidence
ONE THREADOne item is one thread on every channel, so an answer anywhere closes it everywhere, and you’re never asked twice.391 / 449
6.8.1In use › The wikiin the system: Hub › extensions › wiki
Part 6: What is it like to use? › 6.8: What does DeepBuild know about you?

The Wiki (1 of 3): Every Line Keeps Its Source

The wiki your agent built at first run: plain markdown about you and your repos, each line with its source.

~/.deepbuild/wiki/repos/checkout-web.mdcheckout-web• Run the checkout journey before saying done.• The stack starts with npm run dev.• Open question: how does api start?Not established here: 1 line an agent inferred, 0 from outsidecontent, 0 whose source changed. None of this is a check result.THE EXACT QUOTE“always run the checkout journey…”WHERE IT CAME FROMsession:01K…#m42, a messageWHEN IT WAS TRUEthe date of that sessionHOW IT WAS KNOWNfrom you; or your decision, a repo file ata commit, an agent’s guess, outside contentHOW MANY AGREEa proof count of matching sources
NO SOURCE, NO LINEA line whose quote isn’t in its source is dropped. Summaries help find things but are never cited.392 / 449
6.8.2In use › The wikiin the system: Hub › extensions › wiki
Part 6: What is it like to use? › 6.8: What does DeepBuild know about you?

The Wiki (2 of 3): Agents Read a Slice, Then Search by Handle

A handle is a pointer like session:01K…#m42. Agents get a short slice, then find and read the rest by handle.

A new session startsit knows your rules from turn one1the hub hands over a short sliceyour rulesthis repo’s pageopen questions› deep find “how do we test checkout?”23 hits, each a handle with a line of contextsession:01K…#m42wiki:repos/checkout-web.mdev:sha256…› deep read session:01K…#m423that message only, capped at 8,192 charactersa cut reply says where to continuedeep find and deep read are commands of the deep CLI (see At a Terminal).Big things, like long logs, go to a sub-read: a sub-agent reads them and only its short answer comes back.
BY REFERENCEYour history is never pasted into a prompt. Agents get handles and read one slice at a time.393 / 449
6.8.3In use › The wikiin the system: Hub › extensions › wiki
Part 6: What is it like to use? › 6.8: What does DeepBuild know about you?

How a Wiki Line Is Written: Its Quote Must Be at Its Handle

First run read your history by handle too: your agent cites a handle and a quote; a program checks both.

FIRST RUN, AND EACH NEW BATCH OF SESSIONS1archivecopies each transcript into evidence, by hash2pattern matching, then a filtera cheap “worth keeping?” check before any model reads3your own agent, headlessreads by handle, in batches, on your plan4its answer, as structured findingseach: a line, the handle it cites, the exact quoteby handleA PROGRAM CHECKS EACH FINDING, NO MODEL (ILLUSTRATIVE)handlegiven?quotethere?keysin it?“Run the checkout journey before saying done”session:01K…#m42 · “always run the checkout journey…”✓✓✓written“api listens on port 4000”session:01K…#m51 · “start api first, then web”✓✓✕inferred“Coupons ignore case”session:01K…#m57 · quote not in that message✓✕—droppedrepos/checkout-web.md · Run the checkout journey before saying done.kept with it: the quote, session:01K…#m42, the file’s hash, when it was true, how known: from you

At its handle

Byte for byte in the slice the handle names, once Unicode forms and runs of spaces are normalized.

Keys in the quote

A path, command, port, variable or version the line states must appear in its quote, or it reads inferred.

Checked again before use

Before a line is used, its quote is looked for again; gone from a changed file, the line reads drifted.

NO QUOTE, NO LINEYour agent proposes what the wiki says; a program writes only what its source really says.394 / 449
6.8.4In use › The wikiin the system: Hub › extensions › wiki
Part 6: What is it like to use? › 6.8: What does DeepBuild know about you?

The Wiki (3 of 3): What It Learns, It Can Roll Back

An agent proposes what it learned (deep_propose), never writes it. A change starts small, widens while it helps.

› deep_propose“checkout tests need the seed fixture”a learned changeone small diff + the quotes behind itan event: learn.proposedagents propose;they never apply or widena change, even their ownWHERE IT APPLIESthis sessionwhere it was learnedthis repoafter it helps again andpast tasks replay no worseall your reposonly with your OK, or arule you approvedrepos/checkout-web.md+ checkout tests need the seed fixturequote · source · when it was trueUndo: append learn.rolled_backNothing is deleted. Later changes that cite this one are flagged.↺
OUTSIDE CONTENTA line that rests only on a fetched page, an issue or a search never enters the start slice until you promote it.395 / 449
6.9.1In use › Learningin the system: Hub › learned layer
Part 6: What is it like to use? › 6.9: How does it learn from past work?

Learning From Past Work (1 of 8): Where Each Lesson Goes

Eight things that happen in your work, and the one place each lesson lands. The next slides take them one at a time.

What happened
What it becomes
Who lets it apply
From
You answer an ask
a saved decision, matched by kind and scope
you, on the card that asked
R1
Your past sessions, at setup
wiki lines, each with its quote and source
a program checks every quote
R1
An agent finds something mid-work
a learned change, via deep_propose
you, or a rule you approved; never an agent
R1
A check disputed, your overrule, a bug after a PASS
how this repo’s definitions get drafted
held for you if it drops a check that caught a bug
R1
A task closes, or rework lands
a fix record
a drafted check, kept only if it fails on the old code
R2
The same question asked again and again
a suggestion: a gadget or a tab
you tap Add
R2
The same taste answer three times
a taste rule, bounded by checks
your yes
R4
A failure class that keeps coming back
a guard: watch, warn, then block
a replay proves it precise first
R4
NEVER A PROMPT DUMPPast work is never pasted into an agent’s prompt. Each lesson lands in one place, with its evidence, and can be undone.396 / 449
6.9.2In use › Learningin the system: Hub › learned layer
Part 6: What is it like to use? › 6.9: How does it learn from past work?

Learning From Past Work (2 of 8): A Base That Learning Can’t Touch

Two layers. Learning writes only the top one; the bottom one is yours. Refusals name what they protect.

The base: only you change it
the kernel’s two rules and the four invariantsthe specs and checks you approvedyour decisions and answersevery rule you typed, always in the start slice

Changed only in your words, as a diff you approve.

The learned layer: what learning may touch
wiki claims, and the slice agents read at startrules DeepBuild offers, such as taste rulesimprovements to extensions and playbooksstep specs, such as how to run shop’s journeyshow definitions get drafted, and compositions

A closed list: a change aimed anywhere else is refused.

The hub, two learned changes it refusesillustrative

● learn.proposed target: spec:shop “drop the coupon journey” DeepBuild refused · spec:shop is in the base ● learn.proposed start slice: remove “never push without asking” DeepBuild refused · a rule you typed stays in the slice
WHYLearning can make agents better, but it can never weaken a check or a decision you made. The core checks the target, not a label.397 / 449
6.9.3In use › Learningin the system: Hub › learned layer
Part 6: What is it like to use? › 6.9: How does it learn from past work?

Learning From Past Work (3 of 8): Every Fix Leaves a Record (R2)

Bug #42 from Part 4, after it merged. What went wrong, why the old checks missed it, and what proves the fix now.

fix record · checkout-web #42illustrative

problem: receipt shows $18.00, checkout $18.01 class: money rounded in two places gap: #31 added receipts and passed with no check that receipt = cart total mechanism: one rounding step in total.ts, shared by checkout and receipt proved by: journey “receipt = cart total” sources: task #42, its checks, its rework round
When it’s keptEach closed task, and each piece of rework, leaves one record.
Five fieldsThe problem, its failure class, the gap in the definition that let it through, how the fix works, and the check that now proves it.
The gap matters mostIt says what an earlier definition missed, so the next one can ask for it.
NEXTA week later, in another repo, a new task touches a total.398 / 449
6.9.4In use › Learningin the system: Hub › learned layer
Part 6: What is it like to use? › 6.9: How does it learn from past work?

Learning From Past Work (4 of 8): The Next Definition Reads Old Fixes (R2)

A new task in another repo. The drafting job finds the rounding fix and turns its gap into a check for this task.

.deepbuild/ · invoices-api #7, draftedillustrative

task: "#7 add a tax line to the invoice" r1 the invoice shows a tax line check: npm test -- invoice # reused r2 invoice total = sum of its lines, in cents check: invoice-total.test.ts # suggested from: fix:checkout-web#42 if: the total is rounded in more than one place
Who looksThe drafting job, your own agent run headless, searches fix records from every repo by keyword: total, rounding.
What it showsEach suggestion names its source record, how that fix worked, and the condition it depends on.
Then the usual ruleA suggested check counts only if it fails on the old code at its own assertion, like any drafted check.
ONE BUG, LEARNED ONCEThe rounding gap found in checkout-web becomes a check in invoices-api before anyone ships the same bug.399 / 449
6.9.5In use › Learningin the system: Hub › learned layer
Part 6: What is it like to use? › 6.9: How does it learn from past work?

Learning From Past Work (5 of 8): The Gate Learns What Done Means

When checks miss bugs or keep failing on things you don’t care about, the next definitions change, not the old ones.

What the hub saw, and the change it proposesillustrative

three signals from checkout-web’s past tasks ● #48 the agent disputed “footer pixels match”; you agreed: noise ● #53 you overruled a FAIL on the footer again ● #57 PASS, then a bug: coupon codes ignore case DeepBuild learn.proposed drafting for checkout-web: DeepBuild − footer pixel checks + a mixed-case coupon case replay on past tasks: 20 tasks, 0 regressions
What it learns fromChecks the working agent disputed, your overrules, and bugs that got through after a PASS.
What changesHow this repo’s definitions get drafted, as one learned change with its evidence and replay.
What it can’t drop aloneA change that would drop a check that once caught a real bug waits for you.
BOTH WAYSFewer checks you keep calling noise, more checks where bugs got through. Neither touches a check you approved.400 / 449
6.9.6In use › Learningin the system: Hub › learned layer
Part 6: What is it like to use? › 6.9: How does it learn from past work?

Learning From Past Work (6 of 8): A Lesson Spreads Only When Proven

A change starts in the session it came from. It reaches more of your work only when a replay it can’t tune says it helps.

Before the cutoff: fitThe change is built from these sessions only.
After the cutoff: scoreIt is judged only on sessions it never saw. Both numbers are reported.

Frozen before it runs

The task IDs, variants, models, repeats, metrics and comparison rule are fixed before either side runs.

Nothing quietly dropped

A missing, failed or duplicated pair stays in the count and never shows improvement. A missing metric stays missing, not zero.

Helps again, replay cleanFrom its session to its repo (R2). To all your repos only with your OK or a rule you approved.
Replay differsIt stays in its session and names the step that differs.
Too few or too noisy: INCONCLUSIVEIt stays where it is. It widens nothing, and revokes nothing by itself.
WHY SO STRICTA lesson that only looks helpful is how a tool slowly gets worse. Invariant 2 holds here too: nothing unproven passes.401 / 449
6.9.7In use › Learningin the system: Hub › learned layer
Part 6: What is it like to use? › 6.9: How does it learn from past work?

Learning From Past Work (7 of 8): “What Did You Learn This Week?”

Ask in plain words. You get every learned change with its evidence, scope and replay, and can roll any of them back.

The app’s box, or ask your agentillustrative

> what did you learn this week? DeepBuild 4 learned changes since Mon 12 Oct 1 wiki checkout-web: tests need the seed fixture · session:01K…#m42 · repo · 0 worse 2 drafting checkout-web: + mixed-case coupon case · #57 · repo · 0 worse 3 step spec: how to start shop’s journeys · session:01K…#m88 · session 4 wiki you: prefers small PRs · session:01K…#m13 · all repos, your OK > roll back 2 DeepBuild learn.rolled_back 2 · nothing deleted · nothing cited it
Each line showsThe change, its evidence by handle, how far it has spread, and its replay result.
Undo is one more eventRolling back appends learn.rolled_back. Later changes that cite or supersede it are flagged.
Back to any dateA snapshot is a position in the log. Rolling back to a date undoes each change after it, newest first, and agents start from exactly that slice again.
SEE IT, UNDO ITEvery lesson is visible with its evidence, and none is permanent unless you keep it.402 / 449
6.9.8In use › Learningin the system: Hub › learned layer
Part 6: What is it like to use? › 6.9: How does it learn from past work?

Learning From Past Work (8 of 8): Later, Every Lesson Learned Once (R4)

R4, Keep, is the release about past experience: a mistake one agent made, no agent makes again.

watch→warn→blocka guard climbs only after a replay proves it precise

Guards for failure classes

A class that keeps coming back, such as a kill by name or a port fight, gets a guard that only watches, then warns, then blocks.

Fix it at the highest level

Structure first, then types, a lint that names the fix, a test, a hook. A note in a rules file comes last.

A premise review

When two fixes that share an assumption fail the same check, the assumption itself goes to your inbox.

Every agent’s memory, in one wiki

Claude Code’s and Codex’s memories compiled into the wiki, lessons ranked for you to keep or remove.

Configuration evals, #112

Before an instruction file, skill, hook or policy changes, real past tasks are replayed with and without it.

Taste rules, #109

The same taste answer three times offers a rule, bounded by checks on element boxes; never for prices or totals.

R4’S BARGuarded failure classes stay away for 30 days, and no correction has to be given twice.403 / 449
7Build it right
Part 7 asks: How do agents build it without getting it wrong? › 13 sections, 7.1 to 7.13, each answering one part of it (running index, slide 15)

Part 7: Build It Right

Agents build DeepBuild from its issues. First: how its design makes their work hard to get wrong. Then the numbers version 0 must hold, six weeks of work, the rule that decides, and the cuts.

DeepBuildwhere your agents show, not tell1 · Foundation1.1 four parts, 1.2 four jobs1.3 the rules, 1.4 the hub1.5 extensions, 1.6 ways in1.7 hooks, 1.8 the record1.9 storage, 1.10 processes1.11 platforms2 · See and steer2.1 the app, 2.2 the line2.3 asks, 2.4 matching2.5 answers back, 2.6 a taste call2.7 the app’s toolkit, 2.8 where code runs3 · Make: vibe visuals3.1–3.3 what it makes3.4–3.8 documents, frames3.9–3.12 GPU, light3.13–3.15 modules, checks3.16–3.21 3D, play, sound3.22–3.26 budgets, done bar4 · Trust4.1 a claim, 4.2 what done means4.3 verdicts, 4.4 flaky checks4.5 every stop, 4.6 bug fix #424.7 a UI change, 4.8 the finish line4.9 defenses, 4.10 dodges5 · Extend, compose5.1 extension points, 5.2 agents, hooks5.3 hub slots, 5.4 plug-ins5.5 panels, 5.6 canvas packs5.7 modules, 5.8 composing5.9 safety rules6 · In use6.1 what ships, 6.2 first run6.3 MCP tools, 6.4 the CLI6.5 leases, 6.6 the box6.7 your phone, 6.8 the wiki6.9 learning7 · Build it right7.1 looks right, 7.2 tests first7.3 rules, faults, 7.4 kits7.5 comparisons, 7.6 the gate7.7 borrowed, open, 7.8 budgets7.9 measuring, 7.10 six-week plan7.11 Decision 1, 7.12 routing replay7.13 cuts8 · What’s open8.1 scale, 8.2 issues8.3 R1 path, 8.4 risks8.5 owner calls, 8.6 fleets later8.7 next
WHERE WE AREThe highlighted branch is this part; its topics are the slides that follow.404 / 449
7.1.1Build it right › Looks rightin the system: The project › proof
Part 7: How do agents build it without getting it wrong? › 7.1: Why is “the tests pass” not enough?

Looks Right, Is Wrong: A Resolver That Passes Its Test

Agents build DeepBuild issue by issue. One builds #23’s resolver: its test goes green, and it’s still wrong.

THIS WEEK · BUILT AND TESTED BY ONE AGENTissue #23 · Resolver“Never ask the same question twice”A repeated question isanswered without reachingthe inbox1resolver.ts · written by the agentkey = hash(ask.kind, ask.question.toLowerCase(), ask.repo)2keyed on the wordingits test, written by the same agentask(“Merge my fix PR #57?”)you: yesask(“Merge my fix PR #57?”)answered for you1 PASSEDsame words both times, so one key: green3NEXT WEEK · REAL USEClaude, in checkout-web, after you said yes to #57:“Merge my fix PR #61? The release waits on it.”new words, new keyThe same question reaches you againsame kind, same scope: rule 4 says never twice4

1Passes only what it sees

The resolver above: its one test repeats the same words.

2Special-cases a fixture

A plug-in that spots its kit’s fixture repo by its paths, and is right only there.

3Edits a test

#42’s receipt check changed to expect $18.00, or a skip marker added.

4Blesses its first output

The first physics hash it records becomes the golden, bug and all.

THE GAPOne agent writes the code and its tests, then reports they failed first. Rule 1: its word is never evidence.405 / 449
7.1.2Build it right › Looks rightin the system: The project › proof
Part 7: How do agents build it without getting it wrong? › 7.1: Why is “the tests pass” not enough?

How We Know It Works: Twelve Layers of Proof

Twelve layers stand between a design sentence and a wrong build. Each row: a wrong program that layer stops.

LAYERA WRONG PROGRAM IT STOPSWAYSSLIDE12341Criteria with IDs and a tracea test still “proving” a criterion that was reworded→ 4072Tests first, by a blind joba test that checks only the agent’s own example→ 4083Wrong programsa test that “failed” only because its file was missing→ 4094Universal rules as propertiesa run count of 2 where 1 is right→ 4115Lifecycle tables, every ordera late answer that overrides a default→ 4126The hub, simulated with faultsa restart that hands out a log number twice→ 4137Kits: planted fills, held-out casesa resolver tuned to the cases it can see→ 4158Differential, relations, reftestsa table that reads the clock; a recipe drawn unlike its parts→ 4169Outside first answers, triagea first hash blessed with its bug inside→ 41810The cheat corpus#42’s check edited to expect $18.00→ 42111The edit guarda golden re-recorded to match what the code now draws→ 40812API diffs, the ecosystem corpusa crate change that breaks a pack shipped last release→ 422WAYS, FROM THE LAST SLIDE:1 passes only what it sees2 special-cases a fixture3 edits a test4 blesses its first output
READ IT ASEach layer assumes the ones above it can be gamed. No single place decides alone.406 / 449
7.2.1Build it right › Tests firstin the system: The project › proof
Part 7: How do agents build it without getting it wrong? › 7.2: How are tests written before the code?

Every Criterion Has an ID, and Each ID Needs a Test

Layer 1. Issue #23’s criteria get IDs from their words; tests name the ID they prove; one lane checks both.

ISSUE #23’S CRITERIA, EACH WITH ITS IDTESTS, EACH NAMING ONETHE TRACE LANE#23.4e6c122acriterion 1A repeated question is answeredwithout reaching the inboxrepeat.test.tscovers: #23.4e6c122a#23.0da92878criterion 2A question of a different kind orscope still reaches the inboxkind-scope.test.tscovers: #23.0da92878#23.9b2b7eb2criterion 3Overruling a decision changesfuture answersno test names itIDs computed for this slidethe PR says “Closes #23”for each criterion, a tagged test that:1 ran, wasn’t skipped, failed on a wrong program2 the same3 none: nothing names #23.9b2b7eb2refused: “Closes #23”it may say “Part of #23”, listing 3And if criterion 2 is reworded?Its words change, so its ID does. kind-scope.test.ts names an ID the issue no longer has: the lane fails, naming the tag.

An ID from the words

#23.<8 hex>: the start of the SHA‑256 of the criterion’s normalized text.

A test names its ID

A tag in the test itself, so the link lives in code, not in a table kept by hand.

The trace lane

Part of the local preflight, the checks the repo runs on the Mac before a merge. From week 3 the gate reads the same tags.

A checked shape

A lint flags a criterion that doesn’t name what it observes, a threshold with its unit, a wrong case that fails it, and its depth.

BOTH WAYSNo criterion without a test that ran and could fail, and no test still pointing at words that changed.407 / 449
7.2.2Build it right › Tests firstin the system: The project › proof
Part 7: How do agents build it without getting it wrong? › 7.2: How are tests written before the code?

Tests First, Written by a Job That Never Sees the Code

Layer 2. Part 4’s blind drafting job, turned on DeepBuild: one job writes #23’s tests, an agent the code.

TEST JOBa separate agent jobnever sees the codeissue #23the designthe base commitreads only thesetests/acceptance/23/repeat.test.ts · kind-scope.test.ts · …written first, through surfaces #23 namesprotected, like .deepbuild/the implementing agent neveredits themIMPLEMENTINGAGENTsees the tests, neverthe job that wrote themit reads them as its targetwrites resolver.tsruns them: red, then greenedits repeat.test.tsrefused: an acceptance testa dispute, then a redraftthe test job writes it again,blind; if it fails too, it stands;else the owner sees both drafts
The edit guardfrom the first commit, before the gate exists and beside it after, the preflight refuses a change that deletes, skips, weakens or re-records a test, golden or expected output that covers a criterion, found by its tag, unless it comes as a separately approved proposal. It guards the four invariants and every Decided row the same way.
Week 3once the gate judges this repo, it judges again each task that landed before it existed. One that doesn’t reach PASS reopens before week 4.
RULE 3, FOR THE BUILDThe agent that writes the code can’t change the tests that judge it; it can only propose.408 / 449
7.2.3Build it right › Tests firstin the system: The project › proof
Part 7: How do agents build it without getting it wrong? › 7.2: How are tests written before the code?

A Test Counts Only If It Fails on a Wrong Program

Layer 3. A fix’s test must fail on the merge base, on its assertion; new code’s must fail a twin or a mutant.

preflight · a fix’s test, run on the merge base› vitest tests/acceptance/42Error: Cannot find module ’./round-cents’0 tests ranexit 1THE OLD READING“It failed on the base, so the test can fail”NOWIt failed before any test started: a missing file proves nothing.INVALIDnaming why: no test was collected on the base

Three wrong programs that do count

The merge base, for a fix

#42 before the fix rounds before the coupon. The receipt test fails on its assertion, $18.00 ≠ $18.01. It counts.

A twin the criterion names

#23 names one: a resolver that trusts its own count of what was charged. Its budget test must fail that twin.

A mutant of the new lines

New code has no old version to fail on, so the trace lane makes small wrong copies of it: next slide.

The base runfor a fix takes the test’s own files from the change and the rest from the merge base, with the same install. It counts only when a test that passes on the change was collected on the base and failed there, the way its criterion says. For new code, such as ./resolver in #23, the base run decides nothing; the twin or a mutant does. The PR’s “Fails before” line is the preflight’s run, not a statement.
RULE 2, FOR TESTSA test that can’t fail proves nothing, like a check that can’t fail. So it doesn’t count.409 / 449
7.2.4Build it right › Tests firstin the system: The project › proof
Part 7: How do agents build it without getting it wrong? › 7.2: How are tests written before the code?

A Mutant That Survives Shows a Line No Test Checks

Layer 3, continued. For new code, the lane makes its own wrong programs: small edits to the lines added.

resolver.ts · lines this change adds1if (ask.kind !== rule.kind) return none2if (ask.pr.thread !== rule.thread)3 return none4if (ask.pr.lines <= rule.maxLines)5 return rule.answer6return noneMUTANT: ONE SMALL CHANGETHE TESTSline 1: !== becomes ===killed by kind-scope.test.tslines 2–3: thread check gonekilled by thread.test.tsline 4: <= becomes <survives: no test sits at the limitline 5: returns none insteadkilled by repeat.test.tsTHE FIX: A PAIR OF TESTS AT THE EDGEa PR of exactly maxLines: answeredone line more: it reaches youthe line 4 mutant is now killedcode and limit illustrative

Mutant

A copy of the code with one small change, such as < for <=: a wrong program the lane makes itself.

A survivor

A line the tests run but never check. It is listed with its diff, so the gap has a name.

Kills nothing?

A criterion whose tests kill no mutant and name no twin is INVALID for that change.

Where it runs

cargo-mutants on Rust, StrykerJS on TypeScript: in the release preflight and on demand, never on push.

THE SAME EDGE RULEEvery threshold in a kit carries a pair: one step past it must fail, one step inside must pass.410 / 449
7.3.1Build it right › Rules, faultsin the system: The project › proof
Part 7: How do agents build it without getting it wrong? › 7.3: How are rules about every case, and crashes, tested?

A Rule That Says “Every” Is Tested on Thousands of Cases

Layer 4. One example can’t test “every”. A generator draws cases, shrinks a failure, and keeps it.

PART 4’S RUN COUNT, WRITTEN AS CODEn = Math.ceil(Math.log(0.05) / Math.log(1 - p))ITS TWO EXAMPLE TESTSp = 10%expects 29 runsp = 45%expects 6 runsBoth pass: two hand-picked points of a rule meant for every p.THE PROPERTY, CHECKED ON GENERATED pn is the least whole number with (1 − p)n ≤ 0.05checked with exact decimals, in test code beside the real one050%100%1,000 values of p, drawn from a recorded seedshrunk to p = 95%: the code says 2 runsthe rule says 1, since 0.05 ≤ 0.05and p = 0 gives−Infinity runs

Universal words

A rule with every, never, only or always gets a generated test that names its generator and the criterion.

Shrunk, then kept

A failure is cut down to its smallest case, which stays as a fixture, a saved test input.

1,000, then 100,000

Cases per rule in each local preflight, then in the release one, from recorded seeds: fast-check, proptest.

The fix here

n found by exact comparison on p. A p of 0, 100% or outside them makes the check BLOCKED, naming it.

WHY GENERATEDHand-picked cases sit where the author looked. A generator looks where nobody did, by seed.411 / 449
7.3.2Build it right › Rules, faultsin the system: The project › proof
Part 7: How do agents build it without getting it wrong? › 7.3: How are rules about every case, and crashes, tested?

An Ask’s Life Is One Table, and Every Order Is Tried

Layer 5. An ask moves only by its table, and a test tries every order of events in a small world.

AN ASK’S TABLE, AS STATES AND MOVES (SIMPLIFIED)queuedshownlaterfoldedheldclosedclosed as: answered · decided for you · escalated· defaulted · unanswerable · cancelled · superseded· moot; any other close is recorded as unansweredONE ORDER IT MUST GET RIGHT: A LATE ANSWER16:59:59you tap Yes on your phone: “Push api to main?”sent17:00:00the deadline passes: default no, appended firstclosed: defaulted17:00:01your Yes reaches the hubafter the closeThe first to append decides. The late Yes is refused, namingthe outcome, the channel and when it closed; it never reachesthe agent. The default can still be undone from Needs you.wrong program: a hub that records the late Yes as answeredtimes illustrative
Every order, in a small world2 sessions · 2 asks · 1 lease · 2 devices · 1 hub restart · 1 clock step back · 1 deadline. A test walks every reachable state: each object reaches an end; two events in either order end the same, or in a named conflict; a crash in any state recovers from the log to that state. It runs locally when a change touches a table, and in full at release.
One table eachask, ask-task, lease, claim, attempt, waiver, open item, session binding, degrade level. Recorded logs, from real hook transcripts and the simulator, are read back against them: a move a table doesn’t allow fails, naming the event.
EVERY WAIT ENDS, CHECKEDNot a list of fixtures but every reachable state of a small world, each shown to reach an end.412 / 449
7.3.3Build it right › Rules, faultsin the system: The project › proof
Part 7: How do agents build it without getting it wrong? › 7.3: How are rules about every case, and crashes, tested?

The Hub Crashes at Every Write Point, One at a Time

Layer 6. The hub is handed its clock and disk, so a seeded test runs it on fakes and cuts power at any write.

THE HUB’S WRITE POINTS, EACH NUMBERED1events committed,saved first2a block of lognumbers taken3the spool readafter downtime4the spoolremoved5an evidence filemoved into place6the guard’s rulesfile rewrittenPASS 1cut the power at each point in turn, then restartPASS 2make the Nth write fail, for each N in turnPASS 3tear the last write not yet synced, then reopenAFTER EACH RESTART, ALL OF THESE HOLDno ID appears twice, no log number is reusedevery saved-first commit is keptevery spooled event is there onceevery evidence file matches its hasha claim that lost an event is INVALIDa check run cut off records “stopped, hub restarted”, runs againevery table equals its rebuild from the logThe test disk proves itself:it keeps writes only until each file’s sync, so it must lose a commit made without one.
Beside itfaults with an expected verdict each, such as a full disk or an expired token; a decoy process with no run token that cleanup must leave running; real sessions in a pseudo‑terminal; and recorded hook payloads replayed with planted drift: a renamed field turns that agent’s holds watch‑only. The crash suite runs locally when a change touches the hub core’s storage, and in full at release.
PART 1’S PROMISE, TESTEDA crash can lose stream lines, never a verdict (slide 48). Now checked at every write.413 / 449
7.3.4Build it right › Rules, faultsin the system: The project › proof
Part 7: How do agents build it without getting it wrong? › 7.3: How are rules about every case, and crashes, tested?

One Crash Run: Power Cut at Write Point 5, Then Reopen

One run: scripted peers drive the hub on a fake clock and disk, and the cut drops what wasn’t synced.

THE HARNESS (SEED 4127, ILLUSTRATIVE)deep-hookdeep mcpthe app’s streamthe CLIscripted peers, not realprogramsthe hub coreclock: virtualdisk: the test diskboth handed inITS WRITES, IN ORDER1claim.made committed, saved firstsynced2log numbers 1041–1104 takensyncedtool.after lines, in a batchnot synced5receipt.png moved into placepoints 3 and 4 (the spool) aren’t in this runCUT at write point 5the test disk keeps what each file synced,drops the rest: the batch and the moveREOPENED ON THE SAME DISK; THE HARNESS CHECKS✓claim.made is there once✓the next log number is past 1104✓receipt.png absent, or it matches its hash✓the open claim: INVALID, events lost✓the cut check run: stopped, runs again✓every table equals its rebuild
Then the nextThe same seed, cut at write point 6, and so on; then pass 2 fails the Nth write, and pass 3 tears the last unsynced write. The test disk must also lose a commit made without a sync, or it proves nothing.
CHOSEN, NOT LUCKYReal crashes are rare and random; this one is picked, repeats by its seed, and is checked line by line.414 / 449
7.4.1Build it right › Kitsin the system: The project › proof
Part 7: How do agents build it without getting it wrong? › 7.4: How do we avoid fitting only the visible cases?

Held-Out Cases: Fitting the Visible Ones Isn’t Enough

Layer 7. An ask’s key comes from its fields, not its words. Three resolvers meet #23’s key file.

PAIRS OF ASKSSHOULDKEY FROMTHE WORDINGWORDING, PLUSTHE FILE’S PAIRSKEY FROMTHE FIELDSIN #23’S KEY FILE“Merge my fix PR #57? It unblocks the release.”“Merge my fix PR #61? The release waits on it.”same keywrongrightrightIN #23’S KEY FILEyour own fix PR #57your own fix PR #215same keywrongrightrightIN #23’S KEY FILEyour own fix PR #57a PR another thread openedtwo keysrightrightrightHELD OUTthe first pair, IDs renamed:another repo, PRs #388 and #391same keywrongwrongrightFAILFAILPASSThe agent can read the key file and fit to it. It can’t fit to cases drawn at each run.

Held-out variants

The gate runs each fixture’s siblings, never sent to the agent; the preflight draws fresh ones each run: renamed IDs, a shifted time, an extra row.

Seeded kit cases

Each hub slot’s kit draws more cases at install, from a seed recorded then, never shipped with its guide.

A planted fill per rule

Each kit rule has its own wrong entry that breaks it alone, and each item a kit declares its own broken fake.

THE EXAM, NOT THE SAMPLEThe agent sees its target, never the whole exam, so fitting the sample fails.415 / 449
7.5.1Build it right › Comparisonsin the system: The project › proof
Part 7: How do agents build it without getting it wrong? › 7.5: How do two ways of computing check each other?

Differential Tests: The Fast Path Must Equal the Slow One

Layer 8. Where DeepBuild keeps a fast path, a test compares it with the slow path it stands in for.

THE HUB: A TABLE KEPT LIVE, AGAINST ONE REBUILTLIVE, AS EVENTS ARRIVEport 3000 · apistale? noworked out at 09:20, clock readREBUILT FROM THE LOGport 3000 · apistale? yesrebuilt at 09:31, clock read againWrong program: a table that reads the clock. A fixture thatrebuilds a second later never sees it.Now: a table reads events alone, never a clock, settingor file; a lease goes stale by an event that says so.1,000 generated event streams, with ties, clock steps and latereplays: live equals rebuilt, row by row.THE CANVAS: FIVE LAWS ON EVERY PATCH THE FUZZER DRAWSQ3 chart, revision 7writer A: q3 48 → 52writer B: title → “Q3 sales”A then Bhash 5e1c…B then Ahash 5e1c…1a dry run predicts exactly what the commit then returns2a refused patch leaves every byte as it was3a patch, then its undo, gives the old hash back4two writers’ separate patches: one hash, either order5the quick check after a patch finds what a full check findstimes and hashes illustrative
Also comparedgenerated documents on Vello CPU and Vello GPU, and in the app and the web player; generated logic programs on wasmtime and in the browser; each GPU operator against a CPU interpreter of its steps.
WHY IT CATCHESShortcuts hide in fast paths. The slow path is the definition, so any difference is a bug with a name.416 / 449
7.5.2Build it right › Comparisonsin the system: The project › proof
Part 7: How do agents build it without getting it wrong? › 7.5: How do two ways of computing check each other?

Pictures That Check Each Other: Reftests and Relations

Layer 8, for pictures: two documents that must draw alike, or a change whose effect is known ahead.

A REFTEST: TWO DOCUMENTS THAT MUST DRAW THE SAMEthe rocket pieceone item naming a recipekind: piece.physics_lab@1subject: rocket_worldits expansion, written outthe items the recipe makes:light rig · press · tracesreadouts · replay · soundsdrawn on one Macpixel for pixel the sameOther pairs: a pack kind and its expansion · opacity 1 andno group · a layer drawn by GPUI and by the GPU layer · seek and playA RELATION: A CHANGE WHOSE EFFECT IS KNOWNExposure +1 EV, one stop: twice the light.Before tone mapping, every pixel must double.0.210.420.050.100.330.66planted twin:exposure that adds lightinstead of multiplying:0.05 becomes 0.26, not 0.10.The relation fails it.pixel values illustrativeOthers, each with its planted twin: lights A and B together equal A’sframe plus B’s, bloom off; a mesh split into instances keeps its hash.

Reftest

Two documents meant to look the same, drawn on the same machine and compared. No stored frame needed.

Relation

A change to the input whose effect on the output is known ahead, so the answer needs no golden either.

Planted twin

Each relation ships a wrong program it must catch, so a relation too loose to fail proves nothing.

SAME MAC, NO STORED ANSWERBoth sides draw on one machine, so no tolerance across GPUs and no stored frame to bless.417 / 449
7.5.3Build it right › Comparisonsin the system: The project › proof
Part 7: How do agents build it without getting it wrong? › 7.5: How do two ways of computing check each other?

A Golden’s First Value Must Come From Outside the Code

Layer 9. A golden, a stored result a check compares against, catches change. It can’t catch a first mistake.

BEFORE: THE FIRST OUTPUT BECOMES THE TRUTH1 the rocket’s first buildits drag pushes the wrong way2 its step hashes recordeda3f9…: nobody can read a hash3 blessed as the goldenlater runs match it: the bug is keptNOW: A HASH BECOMES THE TRUTH ONLY IF SOMETHING OUTSIDE THE CODE AGREESan answer worked on paperfree fall, a pendulum’s periodanother project’s test dataits upstream tests, fed our outputa value written in the issueset before any code rana second, blind buildwritten from the interface alone,by a job that never saw the firstAt least one such fixture passes:the first blessing names it, so the truth has a source.None: the golden is regression only.It guards later changes, and never proves a criterion.the drag bug and the hash illustrative

GPU goldens

A first blessing waits until the fixture’s paper-worked and CPU-reference checks pass on the same commit.

A driver update

Blessed by drawing again the commit the goldens were recorded at, never a later one.

A CPU reference

Counts as an answer only once it matches numbers the issue states, and its own planted twin fails.

REGRESSION ONLYA golden with no outside answer still catches change; it can’t prove the first build right.418 / 449
7.5.4Build it right › Comparisonsin the system: The project › proof
Part 7: How do agents build it without getting it wrong? › 7.5: How do two ways of computing check each other?

A Golden Is Positive, Negative or Untriaged

Layer 9, continued. Positives pass, known-wrong results fail by name, and new ones decide nothing.

STORED RESULTS FOR ONE FIXTURE: THE ROCKET’S LANDING FRAME7a3f…POSITIVEblessed by your decision, on the reference Macc41e…POSITIVEan alternative, for another backend’s fingerprint09bd…NEGATIVEknown wrong, kept with its bug: flame over the pade2d0…UNTRIAGEDre-recorded by an agent; it decides nothingdigests and the bug illustrativeA NEW RENDER’S DIGEST, AND WHAT IT MEANS= a positivePASSthe only way to pass= a negativeFAILnames the known bugnew, or untriagedDECIDES NOTHINGwaits for your decision

Positive

A result you blessed. A fixture may keep one per backend fingerprint: the GPU, OS and drivers it ran on.

Negative

A result known to be wrong, kept with its bug, so the bug coming back fails by name.

Untriaged

Anything new. An agent that re-records a golden only adds one of these, and it decides nothing.

A RE-RECORD ISN’T A FIXRe-recording adds an untriaged result. Only your decision makes one positive.419 / 449
7.5.5Build it right › Comparisonsin the system: The project › proof
Part 7: How do agents build it without getting it wrong? › 7.5: How do two ways of computing check each other?

A Pixel Tolerance Gets a Ceiling and a Window Bound

Comparing pictures needs a tolerance. “Within one code on 99.9% of pixels” lets 0.1% differ by any amount.

A 1920 × 1080 FRAME: 2,073,600 PIXELScheckout-web · Claude CodeTHE LINE’S PASS CHIPexpectedPASSdrawnPASS40 × 24 = 960 pixels,each about 120 codes offA code value: one step of a color channel’s 0 to 255.pixel counts real; the chip’s size and color illustrativeTHE RULES, ONE BY ONEWithin 1 code on 99.9% of pixels0.1% is 2,074 pixels that may be off by anything. 960 < 2,074.passes it: wrongA ceiling: no pixel off by more than Mthe chip is off by about 120: far past any ceilingfails it: rightA window: no k × k square with more than j offevery square inside the chip is wholly offfails it: rightM, k and j are set per fixture, each with its reason.
Whereevery tolerance that lets a share of pixels differ. For example, GPUI’s 2D against Vello CPU’s on the same layer: interior pixels within one code value on 99.9%.
SMALL BUT WRONGA wrong status chip or a missing glyph is a few hundred pixels: too few for a share, plain to a ceiling.420 / 449
7.6.1Build it right › The gatein the system: The project › proof
Part 7: How do agents build it without getting it wrong? › 7.6: Which known cheats must the gate refuse?

The Cheat Corpus: Ten Known Hacks the Gate Must Refuse

Layer 10. Beyond Part 4’s six tricks: hacks agents have been caught using, each planted as a false “done”.

ONE PLANTED CHEAT, ON #42#42’s drafted receipt check, by a shell write› sed -i ’s/18.01/18.00/’ …- toBe(“$18.01”)+ toBe(“$18.00”)the guard missed itThe hub kept the approved check’s bytes by digest.The claim is judged on those, never on the edit.receipt = cart total: $18.00 ≠ $18.01never PASS; the edit becomes a proposal naming the fileFAILTHE TEN KNOWN HACKS, EACH A PLANTED FALSE “DONE”1a test edited to expect the wrong value2a skip marker3exit(0) before the assertions4a special case on the fixture’s input5a patched clock6a verify that always returns true7an overridden equality8a re-recorded golden9a swallowed exception10a check command thatno longer runs the test
Each onejoins the seeded false “done” claims the gate is tested on, one per row of its verdict table, each with its expected verdict and a clean twin that must PASS.
BOTH HALVESEach cheat must be kept from PASS and its clean twin must pass, so a gate that refuses everything fails too.421 / 449
7.7.1Build it right › Borrowed, openin the system: The project › proof
Part 7: How do agents build it without getting it wrong? › 7.7: What do we borrow, and what stays open?

Borrowed From Projects That Already Do This

None of these layers is new. Each comes from projects that learned it the hard way.

TechniqueWho already does itWhere it lives in DeepBuild
Criterion IDs traced to teststhe Rust Reference, OpenFastTracethe trace lane: no “Closes” without a tagged test
Tests the solver never seesSWE-bench; EvalPlus, about 80× more inputsheld-out variants at the gate and in the preflight
Fails before, passes afterSWT-Bencha fix’s test fails on the merge base, for its reason; new code’s tests fail a twin or a mutant
Mutants of changed linesGoogle; cargo-mutants, StrykerJSthe trace lane’s mutation runs
Generated cases, shrunkQuickCheck at Volvo and Klarna; fast-check, proptestevery rule that says every, never, only or always
Every order of a protocolTLA+ at AWSask and lease tables, walked in a small world
Simulation with faultsFoundationDB, TigerBeetle; SQLite’s crash teststhe hub on a handed-in clock and disk
Generated inputs, comparedCsmith, Wasmtime’s fuzzing; GraphicsFuzzinputs across two engines; rendering relations
Reftests with bounded fuzzweb-platform-tests, Firefox, Chromium, Unrealreftest pairs; a ceiling and a window bound
Golden triageSkia Gold; Unreal’s alternativespositive, negative and untriaged results
Reward hacks as testsOpenAI’s monitoring work, METR, ImpossibleBenchthe gate’s cheat corpus
The ecosystem before releaseRust’s Crater, JetBrains’ Plugin Verifiereverything made or shipped, rerun; new failures hold it
Exact codes, fixes appliedrustc’s UI tests and run-rustfixeach case names its exact codes; a fix is applied, then checked
AlsoAPI diffs in every pull request (cargo-semver-checks, API Extractor) · one grant check per extension method (Deno, WASI, Figma).
WHY BORROWAt AWS, TLA+ found a DynamoDB data-loss bug that design review, code review and testing had all passed.422 / 449
7.7.2Build it right › Borrowed, openin the system: The project › proof
Part 7: How do agents build it without getting it wrong? › 7.7: What do we borrow, and what stays open?

What Stays Open: Calls for the Owner, Maps to Redo

49 calls stay with the owner, grouped below with an example each. One job comes first: redo the oracle maps.

Hook and guards2 calls

Should a missing rules file deny every edit? The 20 ms hook ack and the trusted path are now decided.

The done gate8 calls

Should Decision 1 count a gate that never passes as failing? Run mutants on your repos’ checks too?

Asks and budgets3 calls

What makes an option irreversible? Which path patterns, and which case rules, does a lease use?

Extensions, the wiki5 calls

How fast an agent’s guess fades from the wiki. How a shape’s digest is computed is now decided.

The question card5 calls

Should each answer record which card you saw? Should tests get their own input source for the card?

Canvas, rendering, media22 calls

Compare after every patch, not only at the end? Ceilings for picture scores, rig numbers, the hash function.

From the research4 calls

IDs on every design sentence; agent-proposed checks qualified by mutants; a proposed-API tier; a version matrix.

Oracle maps firstredo

The pages tying canvas criteria to other projects’ tests fell behind the issue split: 88 problems in 172 maps, 185 issues with none, 27 old criteria to re‑check.

The rulethis draft adopts every change that only adds tests, generators, simulations or kit rules. A change to behavior, the hook protocol, a decided row or a frozen payload, a new ask, an unset number or a moved criterion waits for the owner.
NEXTBehavior is half of it. Version 0 must also hold budgets, starting with the hook that runs on every step.423 / 449
7.8.1Build it right › Budgetsin the system: The project › plan
Part 7: How do agents build it without getting it wrong? › 7.8: How fast must each part be?

The Hook Runs on Every Step, So It Gets Under 10 ms

Version 0 holds DeepBuild to budgets. First deep-hook’s: one tool call, hub up (top) and down. Right: p95.

HUB RUNNINGClaude CodeEdit total.tsstart deep-hook≈ 27 ms< 10 ms targethook overheadthe edit runsHUB STOPPEDClaude CodeEdit total.tsstart deep-hookno hub, or no ack from ittarget: gives up within 50 msthe edit runs anywayfail opendeep-hook lets the step through and keeps the event, so the hub gets it later.WHAT STARTING A PROGRAM COSTS: ESTIMATES (OWNER’S MAC, OCT 5) UNTIL WEEK 1 MEASURES AGAINa native binary27 msNode52 msPython75 msdeep-hook is a native binary: the cheapest startp95100 tool calls, fastest first.95 add under 10 ms: that is the p95.The slowest 5 may take longer.
WHY SO STRICTHooks run on every tool call of every agent, and a stopped or stuck hub must never slow an agent down.424 / 449
7.8.2Build it right › Budgetsin the system: The project › plan
Part 7: How do agents build it without getting it wrong? › 7.8: How fast must each part be?

Six More Budgets, So DeepBuild Can Run All Day

The hub, the app, the record and the checks share your Mac with the agents all day. Each number is a target.

a backlog oftranscripts to read5,000 events a secondbatched writessaved many at a timein SQLite’s logdeep hub150 MB resident0.5% of a core when idlethe recordunder 1 GB for 30 heavy daysnot counting evidenceDeepBuild app300 MB with 30 sessions1% of a core when idlethe inbox loads in under 1 s,with 30 days of historyNEEDS YOUTHE REFERENCE MAC’S 12 CPU CORESchecks: at most half at once,queued per worktreefree for the agentsand their stacksEACH RELEASE AGAINST THE LASThook overhead✓hub idle CPU✕dashed: last release + margin (illustrative)
ENFORCEDA release fails if hook overhead or the hub’s idle CPU gets worse than the last release by more than a set margin.425 / 449
7.9.1Build it right › Measuringin the system: The project › plan
Part 7: How do agents build it without getting it wrong? › 7.9: How is speed measured and gated?

The Perf Gate Now: Gate the Middle, Show the Tail

So the perf gate now runs base and change 20 times each, taking turns. The middle run decides; the slow tail can’t fail.

merge base20 runsyour change20 runs, taking turnsp50p50fail line: a p50 past here is more than 50% worse✓p95p95same code, yet the two p95s are 50% apartTIME PER RUN → (ILLUSTRATIVE)p50: the middle run, half are faster · p95 of 20 runs: the 19th, so one slow run moves it

20 runs a side

Base and change take turns, so both see the same load.

p50 decides

More than 50% worse than the merge base fails the change.

p95 is shown

Reported beside it, never gated: 20 runs are too few.

One reference Mac

A 16-inch MacBook Pro, M3 Pro. Elsewhere a result is only a reading.

CPU time

Wall time counts only against the preflight’s 5-minute cap.

LESSONBetween identical binaries the p95 of 20 runs still moved past 50%. Gate only what 20 samples can decide.426 / 449
7.10.1Build it right › Six weeksin the system: The project › plan
Part 7: How do agents build it without getting it wrong? › 7.10: What gets built in six weeks?

Version 0 in Six Weeks: Five to Build, One to Use It

With its budgets set, DeepBuild’s own build plan: six weeks, each ending in an exit test. Week 6 is real use.

dogfood: from week 3, deep gates its own repoWEEK 1Record andhooks✓sessions recorded,hook under 10 msWEEK 2Asks anddelivery✓an answer reachesan idle sessionWEEK 3Gates andverdicts✓a false “done”is blockedWEEK 4See it✓a video and a tastecall in the appWEEK 5Codex andspecs✓every repo’s specdrafted, approvedWEEK 6Real use✓Decision 1: go on,narrow or stop2 spikes1 spikeDecision1

Spike

A short, throwaway trial that settles one choice first, like Part 3’s GPU handoff spike.

Exit test

What must work at the end of a week before the next one starts.

Dogfood

DeepBuild used on its own work: from week 3 it judges its own changes.

Under the gate

Agents build it from DeepBuild’s GitHub issues. A full PASS goes straight to main; nothing else lands.

VERSION 0R1, the first release (Part 3): five weeks of building, a week of real use, then Decision 1.427 / 449
7.10.2Build it right › Six weeksin the system: The project › plan
Part 7: How do agents build it without getting it wrong? › 7.10: What gets built in six weeks?

Weeks 1 to 3: The Record, Then Asks, Then Verdicts

Top: what each week builds (yellow: spikes and dogfood). Bottom: the exit test that ends the week.

1
Week 1

Record and hooks

spikes: desktop hooks first; drafting by handspike: Effect, a TypeScript library, or plain TS? 1 dayevent logevidence storehubdeep-hookcontracts frozen (message formats fixed)sandbox (agent-built code walled off)
EXIT TEST
09:12tool.beforeEdit total.ts09:15tool.beforeBash npm test09:20claim.made“done”✓

a day of real sessions recorded, hook under 10 ms at p95

2
Week 2

Asks and delivery

inboxresolver (answers from saved decisions)budget ledger (checks budgets an answer cites)tasks that close themselvesStop hold (reply before the agent stops)waiter (wakes an idle session)deep_ask
EXIT TEST
CLI inbox› keepClaude · idleanswer: keepsame question again → answered for you

a CLI answer reaches an idle session; a repeat never reaches you

3
Week 3

Gates and verdicts

dogfood: deep gates its own repohermetic checks (sealed runs)verdict rulesrun countsbase-commit runs (old code too)leasesa stop’s questions sorted by kindthe verdict line
EXIT TEST
seeded bug, says “done”FAILthe real fixPASS

blocks a seeded false “done”, passes the real fix

BUILT BYAgents, from the issues. From week 3 DeepBuild’s own gate judges each change: only a full PASS lands.428 / 449
7.10.3Build it right › Six weeksin the system: The project › plan
Part 7: How do agents build it without getting it wrong? › 7.10: What gets built in six weeks?

Weeks 4 to 6: See It, Add Codex, Then Use It for Real

Week 4 makes the work visible, week 5 adds Codex and drafted specs, week 6 is a week of real use.

4
Week 4

See it

spike: gpui-kit, the app toolkit, 2 daysthe appjourneys (scripted browser runs, recorded)deep env up (a test environment, with leases)
EXIT TEST
checkout-webjourney video · 0:12Keep the total above the fold?Keep

a journey video in the app; a taste call answered there reaches the agent

5
Week 5

Codex and specs

Codex adapter (DeepBuild’s link to Codex)the wiki (what DeepBuild learns)spec drafting (what done means, per repo)definitions of done drafted
EXIT TEST
checkout-webspec drafted✓apispec drafted✓deepbuildspec drafted✓

every repo’s spec drafted and approved, none written by hand

6
Week 6

Real use

a dogfood week across Claude Code and Codex, from the checkout
EXIT TEST
seven days of real useD1keep goingnarrowstop

used for a week; then Decision 1: keep going, narrow, or stop

NEXTDecision 1 is a rule fixed before week 6 starts. The next two slides show how it decides.429 / 449
7.11.1Build it right › Decision 1in the system: The project › plan
Part 7: How do agents build it without getting it wrong? › 7.11: What decides whether to keep going?

Decision 1: Three Bars Decide Whether to Keep Going

After the owner’s week of real use, a rule written in advance decides. Every row must hold; a miss: narrow or stop.

Dogfood weekmeasures + labelled setfixed before it startshashedfingerprinted, so nobodycan quietly change it laterEvery seeded false “done” is blocked30 false claims from real pastsessions, pinned by SHAblocked: all 30seeded false done✓≤ 1 of 30 held fixes marked FAIL or INVALIDreal fixes that held up, labelled by aperson without running DeepBuildwrongly failed: at most 1held fix✓“Is it done?” per merged change, halvedagainst the baseline: the owner’spast sessions, kept privatebaselinethe weekillustrative✓Guardrails: no more rework, no more defaultsthan the baseline and the share fixed with the measures✓Keep goingif every row holdsNarrow or stopif any row misses;the owner picks which
FIXED FIRSTThe bars, the measures and the labelled set are hashed before the week, so the result can’t move the goalposts.430 / 449
7.11.2Build it right › Decision 1in the system: The project › plan
Part 7: How do agents build it without getting it wrong? › 7.11: What decides whether to keep going?

Why Decision 1 Counts Only What the Owner’s Labels Confirm

The third bar counts “is it done?” messages. A program must recognize them, and a guess is not enough.

1 · A PATTERN MATCHER GUESSES“is the receipt fixed now?”is it done?is it done?✓“why did you stop?”otheris it done?✕“did #42 pass?”is it done?is it done?✓“done? then push it”is it done?other✕guessowner’s labelillustrative messagesIn the October replay, pattern matching agreed with labels onlyIt counts messages for Decision 1; it never matches questions.33–54% of the time0%100%2 · SO THE OWNER LABELS FIRSTat least 100 messages, drawn at randomfrom the baseline and the dogfood week,mixed, with their dates hiddenA classifier counts only whereit agrees with those labels.3 · A BLIND AUDIT AT THE ENDDECIDED FOR YOU · 1 OF 40–60Keep the total above the fold?? hidden40 to 60 automatic answers,defaults and “proceed” replies, eachshown as its question, withoutwhat was decidedThe owner’s pick changes nothing;each mismatch becomes a test case.
WHY LABELSA metric that can’t classify the owner’s messages can’t decide anything.431 / 449
7.12.1Build it right › Routing replayin the system: The project › plan
Part 7: How do agents build it without getting it wrong? › 7.12: How do failures reach the right place?

One Bad Merge Broke 688 Jobs: Send One Message, Not 688

Decision 1 tests one person’s week. The routing replay tests asks at scale on public history: 688 failures, one cause.

One mergebrings GCC 16,a compiler update688 JOBS FAILED IN ONE EVALUATIONHydra is the public build server of nixpkgs, a largepackage collection. One evaluation is one build pass.This replay reads only that public history,fetched once into a snapshot kept as evidence.ROUTE ONE ASK PER FAILING JOB688asks to someoneONE SEND-BACK PER CAUSEto the merge’s owner,all 688 together,one 14-day deadline1send-back per cause
WHAT IT TESTSInvariant 4 at scale: DeepBuild sends one change’s failures to its owner together, with one deadline.432 / 449
7.12.2Build it right › Routing replayin the system: The project › plan
Part 7: How do agents build it without getting it wrong? › 7.12: How do failures reach the right place?

What the Replay Counts, and Why It Isn’t an A/B Test

Left: what else the same replay counts. Right: why a live trial couldn’t decide this at all.

THE REST OF THE REPLAY120 newly failing jobs, across 107 evaluations,each routed to an owner with a 14-day deadline14 daysin real life, 18 ownedfailures sat past 14 daysThe replay counts how many still would, and asks per week,against the 688 that routing per job sends for one merge.WHY NOT AN A/B TEST?A/B testsplit merges into two arms, with and without, and comparearm A: with routing… 1,700 to 48,000 mergesarm B: without… 1,700 to 48,000 mergesper arm, to decidepowerthe chance a test spots a real effectunder 3% on nixpkgs: every kind of change came back INCONCLUSIVESo routing is checked by replaying recorded history.
NEXTThe plan is also what it leaves out: ideas cut because they would break a rule, and ideas pushed later.433 / 449
7.13.1Build it right › Cutsin the system: The project › plan
Part 7: How do agents build it without getting it wrong? › 7.13: What was cut, and why?

Cut: Anything That Could Fake What You Trust

The plan’s cuts, by the rule each protects. First: nothing may fake the question card (Part 2) or a verdict.

DeepBuild appNEEDS YOU · AUTHORITYCodex wants to push to main.Allow onceNoquestion cardweb page, plug-in or agent codea look-alike “PASS” or cardOnly DeepBuild’s own code draws a verdictor the card where you grant authority.Anything that could draw a fake one is cut.
✕
A web view in the app
→
The question card is the only trusted surfaceno web view at all; web output opens in your browser
✕
Raw plug-in shaders
→
A WGSL subset that the core lowers insteada cost a plug-in declares would only be its word
✕
Third-party compiled canvas modules
→
Registries insteadunsafe Rust could bypass the declared reads the canvas relies on
RULEA cut comes back only as a tracked stretch issue: planned work that undoes a refusal, never a quiet edit.434 / 449
7.13.2Build it right › Cutsin the system: The project › plan
Part 7: How do agents build it without getting it wrong? › 7.13: What was cut, and why?

Cut: Code in Documents, and Effects That Break Replay

Second: seek equals play (Part 3). Right: four ideas cut since a frame would depend on more than document and time.

SEEK MUST EQUAL PLAY0:010:020:030:040:050:060:07play from 0:01 to 0:070:07or jump straight to 0:07Both must give the same frame,pixel for pixel.An effect that blends in earlier framesgives a different 0:07 after a jump.Checks and exports need the exact frame;so does a document that is only data.
✕
Temporal effects in checks or exports
→
Seek must equal playallowed in the live view only, with a fixed window
✕
JS expressions in motion graphics
→
Documents hold no codevalues are data an agent can check and patch
✕
Characters drawn by code
→
puppet@1 rigs, as datalogic only sets values; characters are data or assets
✕
A path tracer in the live view
→
Final frames path traced offline, by hasha film’s finals come from our own offline mode, seeded per frame
WHYA frame must depend only on the document and the time, so any frame can be checked, replayed or exported exactly.435 / 449
7.13.3Build it right › Cutsin the system: The project › plan
Part 7: How do agents build it without getting it wrong? › 7.13: What was cut, and why?

Cut or Later: Outside the Scope, or a New Screen

Third: outside the scope, or a new screen. Red: cut, with the reason. Yellow: later, when a need or the owner asks.

✕
An Omniverse dependency
→
Not takenNVIDIA’s proprietary 3D runtimes: need an RTX GPU, no macOS
✕
MMO scale: big worlds, crowds
→
Out of scopemultiplayer stays at 2 to 8 players
✕
A Settings page
→
Change things in words insteadwhere you read what’s set is an open owner call (Q6, Part 8)
◆
Dense meshlets
→
Later, when a brief needs itvery detailed meshes drawn in small clusters; need an M3 or newer Mac
◆
A wall view, a presenter window
→
Later, only if the owner wants thema big-screen view of every session, a window to present from: new screens wait for the owner
cutlater
NEXTWhat’s still open: the issues, R1’s path, the risks nobody has measured, and the calls only the owner can make.436 / 449
8What’s open
Part 8 asks: What is still undecided? › 7 sections, 8.1 to 8.7, each answering one part of it (running index, slide 15)

Part 8: What’s Still Open

Can Part 7’s plan start? What the issues hold, R1’s longest chain, the risks nobody has measured, and the calls only the owner can make.

DeepBuildwhere your agents show, not tell1 · Foundation1.1 four parts, 1.2 four jobs1.3 the rules, 1.4 the hub1.5 extensions, 1.6 ways in1.7 hooks, 1.8 the record1.9 storage, 1.10 processes1.11 platforms2 · See and steer2.1 the app, 2.2 the line2.3 asks, 2.4 matching2.5 answers back, 2.6 a taste call2.7 the app’s toolkit, 2.8 where code runs3 · Make: vibe visuals3.1–3.3 what it makes3.4–3.8 documents, frames3.9–3.12 GPU, light3.13–3.15 modules, checks3.16–3.21 3D, play, sound3.22–3.26 budgets, done bar4 · Trust4.1 a claim, 4.2 what done means4.3 verdicts, 4.4 flaky checks4.5 every stop, 4.6 bug fix #424.7 a UI change, 4.8 the finish line4.9 defenses, 4.10 dodges5 · Extend, compose5.1 extension points, 5.2 agents, hooks5.3 hub slots, 5.4 plug-ins5.5 panels, 5.6 canvas packs5.7 modules, 5.8 composing5.9 safety rules6 · In use6.1 what ships, 6.2 first run6.3 MCP tools, 6.4 the CLI6.5 leases, 6.6 the box6.7 your phone, 6.8 the wiki6.9 learning7 · Build it right7.1 looks right, 7.2 tests first7.3 rules, faults, 7.4 kits7.5 comparisons, 7.6 the gate7.7 borrowed, open, 7.8 budgets7.9 measuring, 7.10 six-week plan7.11 Decision 1, 7.12 routing replay7.13 cuts8 · What’s open8.1 scale, 8.2 issues8.3 R1 path, 8.4 risks8.5 owner calls, 8.6 fleets later8.7 next
WHERE WE AREThe highlighted branch is this part; its topics are the slides that follow.437 / 449
8.1.1What’s open › Scalein the system: The project › open work
Part 8: What is still undecided? › 8.1: How big is the design so far?

299,000 Words of Design, 29 Lines of Code

DeepBuild’s twelve days of design wrote a large, detailed plan; almost none is built. Next: the issues that hold the plan.

THE DESIGN299,000words in two design docs:technical-design.mdcanvas-primitives.mdTHE CODE29 lines of source: crates/deep-hook and packages/cliWHAT AN ACCEPTANCE CRITERION IS#42 · receipt total is off by a centunit tests passcheckout journey worksreceipt = cart totalacceptance criteriaeach one a check must proveCRITERIA BY RELEASE · 3,984 IN ALL, COUNTED OCT 18R11,110R2761R62,003R1 is version 0. R6 is mostly the canvas: films, 3D and games.R3 to R5 hold the rest.
WHERE IT STANDSOn Oct 17: one issue closed (#12, the repo skeleton), two PRs merged (#235, #242). The rest is design.438 / 449
8.2.1What’s open › Issuesin the system: The project › open work
Part 8: What is still undecided? › 8.2: What do the open issues hold?

579 Open Issues, Three in Five of Them for R6

Counted live on GitHub on Oct 18. One square per open issue, colored by the release it belongs to.

3 in 5RELEASE AND ITS MILESTONE NAMEISSUESCRITERIAR1Prove done, and see it1251,110R2Find, and trust the numbers102761R3Change with proof438R4Keep758R5CI29R6Run your workflow3382,003—no milestone (#11, team server)15R1 also has #12, closed. 3,984 criteria in all, counted Oct 18.15 are epics; 63 more are split into 255 PR-sized parts.
SNAPSHOTwindoliver/deepbuild, Oct 18, read-only. Area labels: view 397, extension 356, security 77, core 42, adapter 24.439 / 449
8.3.1What’s open › R1 pathin the system: The project › open work
Part 8: What is still undecided? › 8.3: What is R1’s critical path?

R1’s Longest Chain: 18 Issues, Each Waiting on the Last

R1’s critical path, from the issues’ Depends on lines on Oct 17: the longest line where each waits for the one before.

#311core schemasweek 1#312adapter APIweek 1#313conformanceweek 1#314manifestweek 1#348ext hostweek 1#349ext slotsweek 1#18CC adapterweek 1#25CC deliveryweek 2#303ask-tasksweek 2#29gate runnerweek 3#30cmd checksweek 3#322done gateweek 3#323open itemsweek 3#82judge stopsweek 3#84real asksweek 3#344rules pageweek 5–6#345guard entriesweek 5–6#346rules that askweek 5–6critical pathYellow: week 1 · white: weeks 2 and 3 · grey: weeks 5 and 6. Week 4 is off it. CC: Claude Code. Split trackers #13 and #121 left out.
READ IT ASNothing in R1 can finish sooner than this chain. Speeding up work that is not on it doesn’t help.440 / 449
8.3.2What’s open › R1 pathin the system: The project › open work
Part 8: What is still undecided? › 8.3: What is R1’s critical path?

What Can Run Beside R1’s Chain, and What Has Slack

Work off the chain can start early or run in parallel. Only the chain itself sets R1’s length.

chain#311#312#313#314#348#349#18#25#303#29#30#322#323#82#84#344#345#346week 1week 2week 3weeks 5–6week 4: the app (#35), a 14-issue linebranches off hereruns beside the chainDAY 0#337 gpui-kit spike, part 1#80 desktop-hooks spikenothing open to wait on: both can start now#39#39 Codex adapter: a line of 11slack7 to spare
RISKEven in PR-sized parts, the chain runs from week 1 to week 5, so a thin first slice, the verdict spine, goes first.441 / 449
8.4.1What’s open › Risksin the system: The project › open work
Part 8: What is still undecided? › 8.4: What hasn’t been measured yet?

Five Unmeasured Facts That R1’s Spikes Will Settle

Untested facts DeepBuild’s design rests on. Left to right: when a test settles each. Up: what breaks if wrong.

week 1weeks 2–4WHEN A TEST SETTLES IT →HOW MUCH BREAKS IF WRONGthe corea routea featureCodex fires PreToolUse for MCP callsbreaks: the MCP guardsPreToolUse: the hook before each tool callHooks fire inside codex execbreaks: child sessionsCodex run as a command by another agentWaking the desktop app (untested)breaks: same-turn deliveryfallback: the Stop hold, then your next messageEffect beats plain TypeScriptbreaks: hub internalsEffect is a TypeScript library; spike #56 decidesThe gpui-kit spike passesbreaks: the whole appelse a Swift fallback (#60)
BY DESIGNThe riskiest facts sit in week 1’s spikes on purpose, so they are tested before anything is built on them.442 / 449
8.4.2What’s open › Risksin the system: The project › open work
Part 8: What is still undecided? › 8.4: What hasn’t been measured yet?

Five More That Wait for R2 to R6

The same chart for later releases: channels, the canvas, exports and games are built later, so tested later.

R2R2–R3R6WHEN A TEST SETTLES IT →HOW MUCH BREAKS IF WRONGthe corea routea featurepaseo hooks, livebreaks: R2 channelsnever tested: needs paseo installedMetal compile time under 20 msbreaks: the first framecompiling GPU shaders may take longerGPU export estimatesbreaks: export speedhow fast export runs if frames stay on the GPU: not yet measuredFuel and net-feel numbersbreaks: games in R6fuel: the step budget for a piece’s logicMetalFX and OIDN replay bit for bitbreaks: final framesan upscaler and a denoiser must repeat exactly
NOTEEvery fuel, net-feel and GPU-export number here is still an estimate; nothing has measured it yet.443 / 449
8.5.1What’s open › Owner callsin the system: The project › open work
Part 8: What is still undecided? › 8.5: Which calls can only the owner make?

Six Calls Only the Owner Can Make

Questions only the owner may settle, besides the wall view. The last one has a default until the owner decides.

Owner callSettings
Where do you read current settings, with no Settings page?
Ask deadlines, batch times, quiet hours, the five-ask cap; Part 7 cut the page.
Owner callReturn card
A decision layout on the return card?
It would be a new UI surface, so it waits for the owner.
Owner callDecision 1
Does a missed Decision 1 bar mean narrow, or stop?
The design says the owner chooses (Part 7).
Owner callEngine numbers
Engine calls waiting on measurements
Three engine choices need measured numbers first.
Owner callExplainer films
A check that fails a film showing wrong math
Decided yes, but never filed as its own issue.
Owner callFrame time
May an absolute p95 cap fail a change?
For now, by default: a frame-time p95 gates, over 300+ frames.
RULEA reversal of a refused line is filed as a stretch issue. A new UI surface, real spend or a moved criterion waits for the owner.444 / 449
8.6.1What’s open › Fleets laterin the system: DeepBuild › scale later
Part 8: What is still undecided? › 8.6: Can it grow to cloud fleets and teams?

Scale Later (1 of 3): Hundreds of Agents, What Fits and What Doesn’t

If your agents move to the cloud by the hundreds, the record keeps up. What runs the work, and you, don’t.

Already fits
900/s300 agents writing about 3 events a second each, against one hub’s budget of 5,000 a second. One writer per person still works.
addressEverything reaches the hub at an address, so it can move to a machine you own.
whoEvery event names its project, session, person and who may see it, so a team’s record splits by project later.
Doesn’t fit one machine
½ coresChecks, their stacks and agents’ sandboxes run on one Mac, at most half its cores. Hundreds of agents need more machines.
1 personAsks reach you. Nobody answers hundreds of agents one card at a time.
plansEach task also runs a drafting job and a review on your plans, so usage per account (R2) limits a fleet before the machine does.
NOT THE FOCUSVersion 0 is one person on one Mac. This part says only what must hold now so growth is an extension, not a rewrite.445 / 449
8.6.2What’s open › Fleets laterin the system: DeepBuild › scale later
Part 8: What is still undecided? › 8.6: Can it grow to cloud fleets and teams?

Scale Later (2 of 3): Four Things the Core Keeps From the Start

Small now, with a caller already: a host in every key, one way to run work, runs that declare their needs, and a fence.

Every lease and run names its host R1 #237
Leases on two hosts never overlap, and a pool such as cpu.slot counts per host.
{host: local, kind: port, key: 5173}
One host contract R1 #236
The supervisor is host@1’s local implementation; SSH hosts (R3) and a cloud sandbox are more. Checks never learn where they ran.
start(token, folder, env, leases) · signal · wait · facts
Each run says what it needs R1 #29
R1 places every run on local; later, a placement picks any host that fits from the same record.
run 4f1  host: local
  needs: 2 cores, 3 GB, stack slot, 0 GPUs, ~90 s
A writer generation R2 #572
A restore, or moving the hub, raises it. A client that saw a newer one refuses a hub left behind.
restore: generation 5 → 6
old laptop hub reports 5 → refused
WHY THESE FOUREach one is a field or a contract that would otherwise have to be added to every key, record and call later.446 / 449
8.6.3What’s open › Fleets laterin the system: DeepBuild › scale later
Part 8: What is still undecided? › 8.6: Can it grow to cloud fleets and teams?

Scale Later (3 of 3): Fleets and Teams, as Extensions

What comes later, built on the four seams, and what DeepBuild will not build.

Checks in cloud sandboxes

A host extension runs each check and its stack in a sandbox restored from a snapshot, paused while it waits, secrets kept outside. Placed by need; capacity follows the queue, not CPU.

Agents in the cloud

deep-hook reaches your hub over an authenticated link. Fast rules stay local, so a slow link never weakens a guard; each route’s timing is measured, never assumed.

Asks at fleet scale

A rate per person on Needs you. Past it, asks with one key share a card; the rest wait in deadline order and still take their safe default.

A team

One record per project, each with one writer; people see what their scope allows. Copies are never merged. Epic #11.

Not proposed

A scheduler or cluster of DeepBuild’s own, a shared database for one person’s record, or different people’s agents writing one record.

Where the lessons come from

How sandbox services, cluster managers and durable-execution engines grew: one writer, the host in every key, fence stale writers, place by need.

WHENNo release yet: each starts when a fleet or a team asks, on the four things the core already keeps.447 / 449
8.7.1What’s open › Nextin the system: The project › open work
Part 8: What is still undecided? › 8.7: What gets built first?

Then the Verdict Spine: One Line in the Chat, First

R1’s first exit: one stop travels the whole way and comes back as a verdict in the chat.

verdict spine12 pieces, 25 tasks with what they need (two only in part), all in weeks 1 to 3 and labelled spine: the smallest slice that proves the ideaClaude Code“done, total fixed”Stop hookthe agent stopsdeep-hookpasses it onhublogs the claimchecks3 run for realthe chatone verdict lineSENT BACK1/3 · receipt shows $18.00, cart $18.01 · total.ts:42the line the spine must put in the chat, using the deck’s running exampleTHENThe rest of R1to week 6; replanned past 3 weeksBuilt by agentsfrom the issuesUnder the gateevery change judgedPush on PASSa full PASS goes to main
WHYThe spine proves invariants 1 and 2 on real sessions. Everything else is built on top of it, by agents, under it.448 / 449
DeepBuildgithub.com/windoliver/deepbuild
◆

Where your agents show, not tell.

Docs: docs/technical-design.md and docs/canvas-primitives.md · the plan is the issues and milestones.

Design draft 6.9.40 (1de288c) · October 18, 2026449 / 449