Editing together↑ Why · A team gets a launch page ready together Three people on one page in launch week, one of them on a train: editing together is that week.
Two people editing one page today take turns, or one overwrites the other. Here the whole page is the document, and an AI is one more person on it.
Live
Every tab on a page edits the same page, live
Open a page in a second tab or window, and both are the same page, with nothing in between but the browser.
Shown when two tabs on one page see each other's edits within 50 ms.
How The browser's own channel and storage, for sync
1 of 1 test passed · 1 place in the code
- passed two tabs on one page see each other's edits (over a transport that drops, duplicates and reorders)
test/editor.spec.mjs:9 - code
editor/sync.ts:4
Browser tests run against commit bc06d12 on 2026-10-24.
Edits made offline merge when you reconnect
Nobody's edit is lost and every copy ends the same, whatever order edits arrive in.
Shown when two tabs and a scripted agent's tab edit one page with the channel between them cut, reconnect, and end byte-for-byte equal, with every edit present.
1 of 1 test passed · 2 places in the code
- passed edits made apart merge, and every copy ends the same (over a transport that drops, duplicates and reorders)
test/editor.spec.mjs:23 - code
editor/doc.ts:4 - code
editor/sync.ts:4
Browser tests run against commit bc06d12 on 2026-10-24.
Devices and agents edit one page at once, through the relay↑ Why · Jo's notes and code are on every device, and still files Jo's notes are the same on the phone and the laptop, edited on both.
The same edits as between tabs, carried sealed between your devices.
Shown when two browsers on two devices and an agent edit one doc offline, then online, and converge, with nothing readable in the relay's capture.
How Sharing: tabs first, then your devices
Not built: nothing in the code or tests names this yet.
You see who else is here, and where
A cursor and a selection per person, with their name, as in a shared doc.
Shown when with two tabs open, each shows the other's cursor at the right character and selected element.
How The browser's own channel and storage, for sync
1 of 1 test passed · 1 place in the code
- passed each tab shows the other's cursor at the right character
test/editor.spec.mjs:92 - code
editor/presence.ts:5
Browser tests run against commit bc06d12 on 2026-10-24.
Undo undoes only your own edits
Undoing my edit never undoes yours or the agent's.
Shown when after interleaved edits in two tabs, each undo reverts only its own.
1 of 1 test passed · 1 place in the code
- passed undo undoes only this tab's edits
test/editor.spec.mjs:115 - code
editor/doc.ts:55
Browser tests run against commit bc06d12 on 2026-10-24.
Typing feels local
An editor that waits on the network feels broken; edits apply on your screen first and travel after.
Shown when a keystroke paints in under 16 ms, and reaches another tab in under 50 ms at the median.
1 of 1 test passed · 1 place in the code
- passed a keystroke paints at once and reaches the other tab quickly
test/editor.spec.mjs:56 - code
editor/text.ts:5
Browser tests run against commit bc06d12 on 2026-10-24.
The editor syncs over anything that carries bytes
The editor asks a transport only to send and receive bytes, so changing the transport changes nothing else.
Shown when every editing test passes over the browser's channel and over a test transport that delays, drops, duplicates and reorders messages.
How The browser's own channel and storage, for sync
2 of 2 tests passed · 1 place in the code
- passed two tabs on one page see each other's edits (over a transport that drops, duplicates and reorders)
test/editor.spec.mjs:9 - passed edits made apart merge, and every copy ends the same (over a transport that drops, duplicates and reorders)
test/editor.spec.mjs:23 - code
editor/sync.ts:4
Browser tests run against commit bc06d12 on 2026-10-24.
Comments
Comment on anything, and the comment stays with it
On a word, a sentence or any element. A comment follows its text through edits and its element through moves.
Shown when a comment on a phrase stays on that phrase after text is inserted before it, and on a section after the section is moved.
How Comments
1 of 1 test passed · 1 place in the code
- passed a comment stays on its words through edits, and on its block through moves
test/together.spec.mjs:19 - code
editor/comments.ts:5
Browser tests run against commit bc06d12 on 2026-10-24.
Reply, resolve, and find resolved threads again
Shown when a thread replied to in one browser and resolved in another shows resolved in both, and is listed under resolved.
How Comments
1 of 1 test passed · 1 place in the code
- passed a thread replied to in one tab and resolved in another is resolved in both
test/together.spec.mjs:54 - code
editor/comments.ts:5
Browser tests run against commit bc06d12 on 2026-10-24.
AI↑ Why · Sam lets an AI help, and decides what it sees The AI sees only the section Sam picks, and its edits wait to be taken.
The AI reads only what you send it, when you ask
You choose the provider and the model, or bring your own key, and the request holds what you selected and nothing else. With AI off, nothing about a page leaves the browser at all.
Shown when with AI off, editing makes no request; with it on, requests go only to the chosen provider, and hold only the selection.
How AI
1 of 1 test passed · 1 place in the code
- passed the AI is sent only the selection, only when asked, only to the chosen provider
test/together.spec.mjs:105 - code
editor/ai.ts:7
Browser tests run against commit bc06d12 on 2026-10-24.
The AI edits through the same moves as a person
Insert a component, set a prop, change a style from the allowed list, move a block, change text. It has no way to write code.
Shown when fuzzed AI tool calls change nothing outside the allowed moves, and every call outside them is refused with a reason.
How AI
1 of 1 test passed · 1 place in the code
- passed fuzzed AI calls change nothing outside the allowed moves, and each refusal says why
test/together.spec.mjs:135 - code
editor/ai.ts:7
Browser tests run against commit bc06d12 on 2026-10-24.
The AI's edits are a suggestion you accept
They arrive on a copy of the page, shown as changes against yours, and merge only when someone accepts them, whole or in part.
Shown when an AI edit leaves the shared page unchanged until accepted, and accepting one change of three merges exactly that one.
How AI
1 of 1 test passed · 1 place in the code
- passed the AI's edits wait on a copy, and accepting one of three merges exactly that one
test/together.spec.mjs:233 - code
editor/ai.ts:7
Browser tests run against commit bc06d12 on 2026-10-24.
The AI is a named collaborator
Its cursor shows while it works, its edits carry its name in history, and undoing them undoes only its own.
Shown when after an accepted AI edit, history names the AI as its author, and undo by its author reverts it alone.
How AI
1 of 1 test passed · 2 places in the code
- passed the AI is named in history, and undoing its edit undoes only its own
test/together.spec.mjs:261 - code
editor/ai.ts:7 - code
editor/history.ts:5
Browser tests run against commit bc06d12 on 2026-10-24.
An agent's work arrives as a fork you approve
Merging the fork is a call, so policy answers allow, deny or ask, and an ask shows the diff between the fork and its base.
Shown when under ask, an agent's merge waits, and the ask holds the diff.
How AI
Not built: nothing in the code or tests names this yet.
Changing the page↑ Why · Sam changes the café's page without waiting on anyone Sam changes the hours, the menu and a photo by pointing at them on the page.↑ Why · A team gets a launch page ready together One person changes the colours while another rewrites the words.
Most people can't change a colour, move a section or add a form without a developer. Here you point at anything and change it, and everyone sees it change.
Styles
The pencil picks any element and shows its styles
For each property, where its value comes from: set on this element, a theme token, or the component's default.
Shown when picking each element of a fixture page lists its properties with the right source for each.
How shadcn's components on Radix, for the chrome · CSS tokens and one stylesheet, for styles
1 of 1 test passed · 1 place in the code
- passed the pencil picks each element and lists its properties with where each comes from
test/changing.spec.mjs:10 - code
editor/panel.tsx:71
Browser tests run against commit bc06d12 on 2026-10-24.
A style change shows for everyone at once
Shown when a colour changed in one browser repaints the other within a second, without a reload.
How CSS tokens and one stylesheet, for styles
1 of 1 test passed · 1 place in the code
- passed a style or a token changed in one tab repaints the other
test/editor.spec.mjs:280 - code
editor/style.ts:5
Browser tests run against commit bc06d12 on 2026-10-24.
Change a token, and every use of it changes
Colours, type, spacing and radii are named tokens, so a theme is a handful of values, not a thousand edits.
Shown when changing --accent repaints every element that uses it, and none
that doesn't.
How shadcn's components on Radix, for the chrome · CSS tokens and one stylesheet, for styles
1 of 1 test passed · 1 place in the code
- passed a style or a token changed in one tab repaints the other
test/editor.spec.mjs:280 - code
editor/style.ts:5
Browser tests run against commit bc06d12 on 2026-10-24.
Styles are a fixed list of properties and checked values
A style is data an edit writes, so it can hold nothing that loads or runs,
and nothing that escapes the page. Any CSS goes in a stylesheet, drawn
only where it can't escape (build/any-css).
Shown when a fuzzed style map renders with every disallowed property and value dropped, and the page's controls stay on top.
How CSS tokens and one stylesheet, for styles
1 of 1 test passed · 1 place in the code
- passed a fuzzed style map renders with every disallowed property and value dropped
test/editor.spec.mjs:256 - code
editor/style.ts:5
Browser tests run against commit bc06d12 on 2026-10-24.
Moving things
Drag any block anywhere, and edits to it survive the move
Dragging a section in most collaborative editors deletes it and inserts a copy, so someone typing in it loses their edit. Here a move is one operation.
Shown when one browser moves a section while another types in it; both end with the section in its new place and the typing in it.
1 of 1 test passed · 2 places in the code
- passed a section dragged while another tab types in it keeps the typing
test/editor.spec.mjs:136 - code
editor/doc.ts:4 - code
editor/main.tsx:410
Browser tests run against commit bc06d12 on 2026-10-24.
Two moves of one block at once never duplicate or lose it
Shown when fuzzed concurrent moves, including moves into each other, always end with every block exactly once and no cycles.
1 of 1 test passed · 1 place in the code
- passed fuzzed concurrent moves never duplicate, lose or loop a block
test/editor.spec.mjs:160 - code
editor/doc.ts:4
Browser tests run against commit bc06d12 on 2026-10-24.
Cut and paste within the page is a move
So it keeps the block's identity, its styles and anyone's concurrent edits.
Shown when a block cut and pasted keeps its id and a concurrent edit.
1 of 1 test passed · 1 place in the code
- passed a block cut and pasted keeps its id and an edit made to it meanwhile
test/changing.spec.mjs:199 - code
editor/doc.ts:262
Browser tests run against commit bc06d12 on 2026-10-24.
Components
Insert any component from the library
By typing / in the text or from a panel, like a block in a document.
Shown when every component in the library can be inserted into a fixture page, and renders.
How Preact, for components · shadcn's components on Radix, for the chrome
1 of 1 test passed · 1 place in the code
- passed every component in the source's library can be inserted, and works
test/changing.spec.mjs:56 - code
editor/editor.ts:244
Browser tests run against commit bc06d12 on 2026-10-24.
A component's settings are a form, made from its schema
Each component declares its props and their types; the editor makes the form, and checks every value against the schema.
Shown when each prop type has a field, and a value that breaks the schema is refused with a message.
1 of 1 test passed · 1 place in the code
- passed a component's settings are a form from its schema, refusing what breaks it
test/changing.spec.mjs:90 - code
editor/panel.tsx:245
Browser tests run against commit bc06d12 on 2026-10-24.
A new component is made from existing ones
Select some blocks, name them, and they become a component with the props you choose to expose, without code.
Shown when a component made in the editor appears in the library and can be inserted.
1 of 1 test passed · 3 places in the code
- passed blocks made into a component appear in the library and can be inserted
test/changing.spec.mjs:143 - code
editor/doc.ts:299 - code
editor/library.ts:7 - code
editor/panel.tsx:307
Browser tests run against commit bc06d12 on 2026-10-24.
Changing a component changes every copy, keeping each copy's changes
As in a design tool: an instance follows its component, except where it was changed.
Shown when a component edited after three instances were placed updates all three; an overridden prop keeps its override.
1 of 1 test passed · 1 place in the code
- passed changing a component changes every copy, except what a copy changed
test/changing.spec.mjs:162 - code
editor/library.ts:7
Browser tests run against commit bc06d12 on 2026-10-24.
Source↑ Why · Priya adds what only code can do, and stops being asked for words Priya reads what an edit really changed, as text.
One button flips between the page and its source
The source is the page's text form, the same text git holds.
Shown when on every fixture page, the source shown imports back to the same page.
1 of 1 test passed · 1 place in the code
- passed on every fixture page, the source shown imports back to the same page
test/changing.spec.mjs:225 - code
editor/textform.ts:17
Browser tests run against commit bc06d12 on 2026-10-24.
The source shows everyone's edits as they happen
Shown when an edit in one browser's page appears in another browser's source view within a second.
1 of 1 test passed · 1 place in the code
- passed the source shows another tab's edits as they happen
test/changing.spec.mjs:258 - code
editor/editor.ts:265
Browser tests run against commit bc06d12 on 2026-10-24.
Editing the source edits the page
A change typed in the source becomes the same edits a person would make on the page, so it merges with theirs.
Shown when a word changed in the source and a concurrent style change on the page both survive.
1 of 1 test passed · 1 place in the code
- passed a word changed in the source and a style changed on the page at once both survive
test/changing.spec.mjs:271 - code
editor/editor.ts:265
Browser tests run against commit bc06d12 on 2026-10-24.
A real app↑ Why · Priya adds what only code can do, and stops being asked for words Priya's booking widget comes from the app's source, built like any code.↑ Why · Sam changes the café's page without waiting on anyone The booking form keeps taking bookings while Sam edits around it.
The page you edit is the app, not a picture of it: its tabs switch, its forms submit, its charts draw, while you change the words around them.
Components with behaviour come from the app's source
Written by developers, reviewed, built and shipped like any code; the editor places and configures them.
Shown when a component added to the source appears in the library after a build, and works in the page.
1 of 1 test passed · 1 place in the code
- passed every component in the source's library can be inserted, and works
test/changing.spec.mjs:56 - code
editor/components.tsx:5
Browser tests run against commit bc06d12 on 2026-10-24.
Nothing an edit writes ever runs
An edit is a tree of component names, props, styles and text. There is nowhere in it for a script.
Shown when a fuzzed page full of scripts, handlers, javascript: URLs and
style expressions renders nothing executable; the CSP allows scripts from
the site's own origin only.
How Content and code
1 of 1 test passed · 2 places in the code
- passed text full of scripts and handlers stays text, and the CSP allows only the site's own scripts
test/editor.spec.mjs:297 - code
editor/doc.ts:4 - code
editor/href.ts:2
Browser tests run against commit bc06d12 on 2026-10-24.
New code takes a rebuild
Code merged by two people can be valid and wrong, and nothing would show it, so new behaviour is written in the source and built, never pasted into the page.
Shown when the editor offers no way to add a script, and a page naming a component the build doesn't have shows a placeholder.
How Content and code · TypeScript and esbuild, for the editor and the build
1 of 1 test passed · 4 places in the code
- passed the editor offers no way to add a script, and an unknown component is a placeholder
test/yours.spec.mjs:207 - code
editor/build.mjs:5 - code
editor/components.tsx:5 - code
ui/build.mjs:5 - code
ui/check.mjs:4
Browser tests run against commit bc06d12 on 2026-10-24.
Code drafted in a doc runs only once its pull request merges
A page that needs its own code drafts it as a text node; only the built module the merge records ever runs.
Shown when an unmerged code node renders as text.
How Content and code
Not built: nothing in the code or tests names this yet.
The page keeps working while you edit it
Shown when in edit mode a fixture page's tabs switch, its form validates and its counter counts, while text around them is edited.
1 of 1 test passed · 1 place in the code
- passed the page's tabs switch, its form validates and its counter counts while it is edited
test/editor.spec.mjs:223 - code
editor/render.tsx:6
Browser tests run against commit bc06d12 on 2026-10-24.
Any page renders, however edits merged
Two valid edits can merge into something no single edit made. The page draws an unknown or invalid part as a marked placeholder and never fails.
Shown when fuzzed concurrent merges never throw while rendering.
1 of 1 test passed · 1 place in the code
- passed fuzzed concurrent merges never throw while rendering
test/yours.spec.mjs:147 - code
editor/render.tsx:6
Browser tests run against commit bc06d12 on 2026-10-24.
An app is a component: built code, state in docs
An app with real behaviour (the agent, a terminal, a calendar) is built in git like a counter, and everything it keeps (a transcript, its settings) lives in docs of its own, so it follows you to any device.
Shown when an app's state written on one device reaches another, and the app renders from it there with no state of its own.
How Content and code
Not built: nothing in the code or tests names this yet.
A schema change migrates content
So devices on the old release keep working while the new one rolls out.
Shown when release N renders N+1's docs with placeholders only, and N+1 renders N's.
How Content and code
Not built: nothing in the code or tests names this yet.
Yours↑ Why · Sam changes the café's page without waiting on anyone Sam's page stays Sam's: in Sam's browser and files, with no server to trust.
Versions↑ Why · A team gets a launch page ready together Nobody loses work: anything can be gone back to.
Go back to any earlier version
Every editing session is a version you can see, compare and return to; returning is a new edit, so nothing is lost.
Shown when restoring a version renders exactly what that version rendered, and the history still holds what came after.
1 of 1 test passed · 1 place in the code
- passed restoring a version renders what it rendered, and keeps what came after
test/yours.spec.mjs:11 - code
editor/history.ts:5
Browser tests run against commit bc06d12 on 2026-10-24.
A page is readable text in git↑ Why · Priya adds what only code can do, and stops being asked for words Priya reviews a page's changes in the pull request already in use.
Each page exports to its text form, with its ids, and imports back.
Shown when export then import of every fixture page renders the same.
1 of 1 test passed · 1 place in the code
- passed every fixture page exports to text and imports back to the same page
test/changing.spec.mjs:299 - code
editor/textform.ts:17
Browser tests run against commit bc06d12 on 2026-10-24.
Save a page as a file, and open it anywhere
A page kept in one browser is lost with that browser's data, so it is always one click from a file you own, with its history.
Shown when a page saved to a file and opened in a fresh browser profile renders the same and keeps its history.
1 of 1 test passed · 1 place in the code
- passed a page saved to a file opens in a fresh browser the same, with its history
test/yours.spec.mjs:60 - code
editor/history.ts:5
Browser tests run against commit bc06d12 on 2026-10-24.
History is kept outside the doc too
A doc that merges badly takes its history with it, so each named version is also kept in git, as text.
Shown when a doc deleted and rebuilt from the mirror renders the same.
Not built: nothing in the code or tests names this yet.
An edit merged in git comes back as edits↑ Why · Priya adds what only code can do, and stops being asked for words Priya edits a page in git, and it merges with the live edits.
Shown when a block moved in git keeps its concurrent live edits.
Not built: nothing in the code or tests names this yet.
Private and shared
No server ever reads your page↑ Why · Sam lets an AI help, and decides what it sees Sam can say what was sent and to whom, because nothing else leaves.
There is no server for pages. Today they, their comments and their history are kept in this browser's storage; between devices they travel sealed.
Shown when once the editor has loaded, editing, commenting and reloading make no network request.
1 of 1 test passed · 1 place in the code
- passed once loaded, editing makes no request
test/editor.spec.mjs:203 - code
editor/store.ts:5
Browser tests run against commit bc06d12 on 2026-10-24.
A grant on one doc reaches no other↑ Why · Sam lets an AI help, and decides what it sees An agent let into one doc can read nothing else.
A doc is the unit of sharing, of permission and of damage.
Only granted writers' edits are taken in↑ Why · A team gets a launch page ready together Only the team's edits reach the page; a reader can't push one.
A reader cannot push; a writer cannot pass on a stranger's edits.
Relays never see an edit
Merging, compacting and search happen on your devices.
Publishing
Published pages are plain HTML
Publishing renders a version to static HTML and CSS, and only components with behaviour load script. This site is the same.
Shown when a published fixture renders the same as in the editor, and reads fully with scripts off.
How One renderer, pinned by the commit · This site · Publishing
1 of 1 test passed · 1 place in the code
- passed a published page is plain HTML that reads in full with scripts off
test/yours.spec.mjs:108 - code
editor/publish.ts:5
Browser tests run against commit bc06d12 on 2026-10-24.
Plain files↑ Why · Jo's notes and code are on every device, and still files Jo's notes open in the editor, and on disk they are still the same markdown files.↑ Why · Priya adds what only code can do, and stops being asked for words An edit in the editor is a diff of only its own lines in Priya's pull request.
A markdown file opens and saves back byte for byte
The doc is the truth and the file is printed from it, in the file's own format: every block keeps the lines it was read from, so a block nobody changed is written exactly as it was.
Shown when every markdown file in this project opens in the editor and prints back byte for byte.
How Plain files: the doc is the truth, the file a projection
1 of 1 test passed · 1 place in the code
- passed every markdown file in the project opens and prints back byte for byte
test/files.spec.mjs:40 - code
editor/markdown.ts:9
Browser tests run against commit bc06d12 on 2026-10-24.
An edit changes only its own lines
A changed block rewrites only the span that changed, keeping its line breaks; a moved block moves its lines; a new list item or table row is written the way its neighbours are.
Shown when one word changed in a wrapped paragraph changes one line of the file; a block moved through the doc moves its lines and nothing else; a list item and a table row inserted through the doc take their neighbours' marker and pipes.
How Plain files: the doc is the truth, the file a projection
1 of 1 test passed · 1 place in the code
- passed an edit changes only its own lines, and blocks moved or added through the doc keep the file's style
test/files.spec.mjs:67 - code
editor/markdown.ts:9
Browser tests run against commit bc06d12 on 2026-10-24.
A file another program changed comes in as edits
What git or another editor wrote is taken in as the smallest edit, so every block keeps its id, its comments and its history, and the file printed back is what that program wrote.
Shown when a file rewritten outside the editor, with a paragraph added and a word changed, comes in with the other blocks' ids and a comment still on its words, and prints back byte for byte what was written.
How Plain files: the doc is the truth, the file a projection
1 of 1 test passed · 2 places in the code
- passed a file another program changed comes in as edits, keeping ids and comments, and prints back as written
test/files.spec.mjs:132 - code
editor/editor.ts:328 - code
editor/markdown.ts:9
Browser tests run against commit bc06d12 on 2026-10-24.
Saving never overwrites a change made on disk
A save writes only over the version the editor last read; if the file changed since, that change is taken in and merged first.
Shown when a file changed on disk after it was opened, then saved from the editor with an edit of its own, holds both changes.
How Plain files: the doc is the truth, the file a projection
1 of 2 tests passed · 2 places in the code
- not run a test
services/files/tests/base.rs:1 - passed saving over a file changed on disk keeps both changes
test/files.spec.mjs:174 - code
editor/file.ts:13 - code
services/files/src/lib.rs:13
Browser tests run against commit bc06d12 on 2026-10-24.
Tags the editor can't draw are kept, and edited as text
A component only the site draws, such as <Serves />, shows as a
placeholder with its settings, which can be changed, and is written back
as it was.
Shown when every <Serves /> in a spec file shows as a placeholder naming it,
and a note changed in the panel changes that tag's line alone.
How Plain files: the doc is the truth, the file a projection
1 of 1 test passed · 4 places in the code
- passed the site's tags show as placeholders, and a changed setting changes that tag's line alone
test/files.spec.mjs:196 - code
editor/doc.ts:177 - code
editor/markdown.ts:9 - code
editor/panel.tsx:266 - code
editor/render.tsx:78
Browser tests run against commit bc06d12 on 2026-10-24.
A file on any of your machines opens in the editor and saves there
Open a machine's folder from the page and click a markdown file: it opens in the editor, and a second after you stop typing it is saved on that machine, changed by exactly your edit. The machine itself refuses a save made over a version it no longer holds.
Shown when end to end, a browser pairs a Linux machine holding this site's
docs, opens docs/why.md, types a word, and the file on the machine
differs by that one line; a write over a stale version is refused there;
the relay's capture holds none of the file.
How Plain files: the doc is the truth, the file a projection
1 of 1 test passed · 1 place in the code
- passed a test
e2e/node/pair.spec.mjs:95 - code
web/app/edit.js:16
A file changed on its machine comes into the open editor
What git or another editor writes on the machine shows in the open file within seconds, and anything typed meanwhile is kept.
Shown when end to end, the machine rewrites the open file while an edit is still unsaved; the editor shows the rewrite, and the file then holds both.
How Plain files: the doc is the truth, the file a projection
1 of 1 test passed · 1 place in the code
- passed a test
e2e/node/pair.spec.mjs:95 - code
web/app/edit.js:16
Safe to change↑ Why · Sam lets an AI help, and decides what it sees An AI that could restyle the screen still can't make deny look like allow.↑ Why · Sam changes the café's page without waiting on anyone Whatever Sam changes, there's a way back to a page that works.
One bad change today can take down the whole screen, or another pane. Here some parts can't be edited at all, each pane stays in its rectangle, and there are several ways back, each independent of what it rescues.
Containment
The shell can't be edited live
Whatever shows you a change to approve can't be editable by whoever made the change: an agent that could restyle the ask could make deny look like allow.
Shown when an agent holding every grant but Admin cannot write shell data without an ask.
How Four rings
Not built: nothing in the code or tests names this yet.
A pane reaches nothing outside its rectangle
Not by writing, styling, the top layer, code or input.
Shown when a hostile fixture pane tries every escape and changes nothing outside its rectangle.
How Four rings
Not built: nothing in the code or tests names this yet.
Asks are drawn only outside every pane
A pane can draw a perfect copy of an ask, so the real one is the shell's, and no click inside a pane answers it.
Shown when a pane's synthetic click on its copy of an ask answers nothing.
How Four rings
Not built: nothing in the code or tests names this yet.
Recovery
The address names the shell's version
Back previews an earlier version in this tab, and ?ui=safe ignores shell
data entirely.
Shown when loading ?ui=safe over shell data that hides the chrome shows the
chrome.
How Escapes
Not built: nothing in the code or tests names this yet.
One chord can't be rebound or covered
Phones get a fixed gesture.
Shown when no shell data can bind the chord, and its popover is on top under every fixture.
How Escapes
Not built: nothing in the code or tests names this yet.
A broken theme can't hide the shell
Shown when the shell's chrome passes contrast under fixture themes built to hide it.
How Escapes
Not built: nothing in the code or tests names this yet.
A bad shell build boots the last good one
Shown when a build whose self-check never passes boots the previous one.
How Escapes
Not built: nothing in the code or tests names this yet.
A change that could lock you out is a trial
A change to input or visibility, and every agent change, reverts in 15 s unless confirmed with the chord, which proves the escape still works.
Shown when an unconfirmed trial reverts; one that unbinds the chord is refused.
How Escapes
Not built: nothing in the code or tests names this yet.