One live artifact beside the conversation
This morning the canvas was a grid of tiles. This afternoon it is one document open beside the chat, edited in place by you and by the agent, with a version for every change and a log of all of them. What the grid got wrong, and what replaced it. Release notes 2026-09-15 — vocion-core#354.

Status: shipped. vocion-core #354 is merged onto the release branch release/2026-09-15-rail (the commit inside it is 8daff9bc) and deployed to a deployment we operate. It adds migration 0101_artifact_version.sql, on top of #350's 0100. The pull request is still landing on main individually behind that release branch. This post supersedes A canvas beside the conversation, published this morning, which describes a design that has been removed.
What the grid got wrong
The canvas that shipped this morning (#333) was a grid: you asked for a picture of something, got tiles, and arranged them. Sort a column, drag a tile, type into an empty slot to fill it.
It was a good demo and the wrong object. Two problems showed up within hours of using it.
A grid asks you to be a dashboard author. Every answer arrives as a new tile, so the question “no, make the third column currency” has no obvious target — there is no "it" in a grid, there is a slot number. And a wall of tiles is a snapshot: the moment you want to change one, you are really asking for a second version of it, and the grid had nowhere to put that.
So it was replaced, whole, on the same day, by the model that Claude.ai and Cloudflare converged on: one artifact, open beside the chat, live.
The right-hand pane holds exactly one thing, full height. Title editable in the header, the version line beside it, History, Export, Copy link, and the folder it lives in. The turns that changed it carry a chip you can click to reopen that version.
What you can do with it
Change it by asking. Make the third column a number and sort by owner. Two new tools — read_artifact and update_artifact — mean that is an update to the thing on screen, not a second thing beside it. The open artifact travels back as the turn's page context, so "this", "the table" and "the doc" resolve without an id, and the system prompt carries an explicit block telling the agent that an instruction of that shape means update, never render a new one.
Change it by hand. A markdown artifact is a plain textarea — ⌘S saves, Esc discards. A table lets you edit cells, rename a column, change a column's type, and add or remove rows. Charts, records, links and files are title-and-folder only.
“⌘S saves a new version · Esc discards · sorting stays a view, not a version.” Sorting a column is a way of looking at the table; it is not a change to it, and it does not make history.
See every version, and go back. Every write — the agent's tool call and your Save alike — goes through one service, so there is one history rather than two half-records.
Four versions, each with who made it and what changed. “Restore this version” writes a new version carrying the old content — it never rewrites the history behind it.
Three rules make that history readable rather than noisy:
- Restore never rewrites. Restoring v2 writes v6 with v2's content. Nothing is lost and nothing is retconned.
- Your own save bursts collapse. Saves by the same person inside thirty seconds fold into the head version, so a paragraph typed in four passes is one version. An agent write never collapses, and one person's save never folds into another's.
- Concurrency does not clobber. Your save carries the version you started from. If the agent moved the head while you were typing, the write is refused and the pane offers Review theirs or Keep mine.
Find them later. /dashboard/artifacts is the log — type and folder chips as filters, search, and per row the kind, the version count, the last editor, when, the folder, and the conversation it came from. /dashboard/canvases 308s to it, because that URL is in people's pins and in links they already sent.
Everything made beside a conversation, in one list. A row opens the conversation with that artifact in the pane — or the artifact on its own, if the conversation is gone.
What is gone
CanvasGrid, ArtifactTile, EmptyTile and the canvas reducer are deleted, along with place_tile, the tile_slot and tile_span parameters on the render tools, the canvas save/list/get/remove/export handlers, the ?grid=open and ?canvas= parameters, and three drag-and-drop dependencies that nothing else imported.
The canvas table itself stays, and so do the three dead columns on artifact. Dropping a table is a contract step, not an expand step: they are marked unused in the migration header, in a COMMENT ON TABLE, and in the schema file, and they go in a later release. docs/canvas.md became docs/artifacts.md and opens by saying that the blog post published this morning described a tile grid and that the product moved the same day.
Where this lives in the repo
vocion-core#354, shipped on release/2026-09-15-rail (8daff9bc).
- Pane and editors:
packages/core/src/features/dashboard/artifacts/—ArtifactPane.tsx,VersionMenu.tsx,MarkdownArtifactEditor.tsx,TableArtifactEditor.tsx,ArtifactLog.tsx - One write path:
packages/core/src/services/ArtifactService.ts—updateArtifact,restoreArtifactVersion,COLLAPSE_WINDOW_MS,normaliseFolder - Tools:
packages/core/src/services/agents/tools/editArtifacts.ts; the prompt block is inservices/agents/harness.ts - Handlers:
packages/core/src/routers/Artifacts.ts - Schema:
packages/core/migrations/0101_artifact_version.sql, plus a concurrent index build inmigrations/concurrent/0101_artifact_org_updated_index.sql. Additive only; the journal now ends0099_decision_alignment · 0100_team_measures · 0101_artifact_version - Streaming into the pane: the
artifactevent gainedpendinganddelta; the fold ismergeArtifactEventintraceReducer.ts, and a settled event replaces the accumulated body so a dropped or duplicated delta cannot leave the pane showing something the database does not hold - Docs:
docs/artifacts.md
Screenshots above are from a fixture workspace. The full 0000→0101 chain — 102 migrations — was applied to a clean Postgres before the deploy, with both artifact and artifact_version present afterwards.
Related: A canvas beside the conversation (superseded) and Artifacts as data, and an authenticated route.