.canvas Directory Contract
Status: Draft V1 · App-agnostic format spec · Last updated 2026-06-16
Working group notes, feature specs, and implementation plans.
View all tagsStatus: Draft V1 · App-agnostic format spec · Last updated 2026-06-16
The Agent Client Protocol (https://agentclientprotocol.com/) as the default outward wire of any conforming agent system. The mapping between this guide's internal shapes and ACP's wire vocabulary; method-by-method correspondence; where the protocol and the guide diverge and how the adapter handles each seam.
Provider profile for consuming Codex from an external agent system. Defines what Codex provides, how a host should adapt it into an ACP-consuming runtime, and the boundaries around tools, sessions, filesystem authority, and image generation.
Decision/RFD on whether Grida should host an agent-provider class — driving an external ACP agent (Claude Code / Codex) the user already pays for, with Grida as ACP consumer and an MCP server of its own tools. The forever-cost ledger, the narrow delta over BYOK, and a reversible path.
How Grida Desktop adapts agent-daemon sandbox policy to srt and supervises the AgentSidecar process.
Desktop binding of GRIDA-SEC-004 for AgentSidecar, the renderer bridge, HTTP perimeter, sandbox, and secrets discipline.
Desktop userData files owned by AgentSidecar, including auth.json, recent files, workspaces, and SQLite session storage.
A guide for implementing an LLM-driven agent system. Implementation-agnostic, normative, and meant to play the same role for agent runtimes that LSP plays for language tooling or that ACP plays for editor ↔ agent integration. Names the invariants every implementor MUST honor and the policies each implementor picks.
Working group hub for AI-related docs. Two layers — the implementation-agnostic agent system RFC, and the Grida-specific bindings (canvas tools, image tools, host tool surface) that ride on top of it.
| feature id | status | description | PRs |
The guide pins AI SDK v6 as the chunk-shape substrate every conforming implementation speaks internally. This page captures the implementor notes that live outside AI SDK's own docs — the token-usage normalization rule, where the SDK's tool-loop helper fits, and the things the RFC adds on top.
Alignment's reference-frame rule — selection-relative for many, container-relative for one — and equal-gap distribution, correct under rotation and mixed parents.
Exposed contract of Grida's local agent system, the package boundary, and the tests that pin it during refactor.
Stacking order as sibling order within a parent — the four arrange operations as pure reorderings of the sibling sequence, and the on-canvas sort gesture that drags a member to a new slot.
Motivation
The command that converts a selection into a laid-out flex container — one per selection partition — by wrapping and inferring the layout from the members' arrangement.
Living document. Every known issue in the billing surface (subscriptions,
Working group documents for the Grida billing surface (subscriptions,
Glossary and reference for how an agent handles binary attachments the model cannot natively read. Three resolution paths (provider-native multimodal, skill-per-format, shell-based conversion), a format matrix, the scratch-space pattern for archive extraction, and the boundary between protocol and implementor.
Non-destructive path booleans — the operand model, order semantics, live re-evaluation, release and flatten.
Grida's specialized subagents (titler, compactor, planner) — concrete bindings of the RFC's specialized-subagent pattern with the Grida-specific tier, model, sentinel, and cost discipline.
The universal specification of the Grida canvas editor — its concepts, contracts, and the verification doctrine that any conforming implementation (web, native, headless) satisfies.
Canvas-specific AI toolset for editing Grida design documents — scene-graph operations, specialized inserts, canvas exec/lint/format, and resource lookup.
FRD for clipboard support in the SVG editor: the payload is a standalone SVG document, not a private format. Specifies the two extraction operations (standalone payload vs in-document clone), the five kinds of context a lifted subtree leaves behind and the policy for each, command and history semantics, placement, transport ownership, and the paste-is-load trust model.
User intent representation. The multipart user-message shape, file references vs attachments, inline commands, mentions, editor context, attachment handling, and the lowering rules that turn what the user composes into what the model sees.
The on-canvas handle that edits a rectangle's corner radius in place — cardinality, placement, drag mapping, clamp, and the link/split modifier.
Doctrine for running frontier models as agent models without burning money on waste. The agent-loop cost model (every token is re-billed every step), the ledger of measured leaks — missing prompt caching, tool-result echo, unbounded replay, window/threshold/tier decided separately — and the quality-first ordering that spends effort on quality-neutral fixes before quality-tradeoff ones.
Realtime multi-instance editing of one Grida document — durable identity, optimistic replication with authority order, and convergence.
A working group draft describing the Grida ID Model (for CRDT) feature for the core engine.
Convert text to its glyph-outline vector paths — the deliberate, font-baking counterpart to editable type; per-node and in-place, distinct from flatten's union.
CSS → Grida IR property mapping table and TODO tracker.
Chromium Blink's single source of truth for CSS property metadata, used as a reference for browser-grade CSS cascade implementation
Renderer-agnostic model for attaching glyphs (arrowheads, markers, ticks) to 2D paths using the path's local frame.
The developer experience contract. A canonical inspection format every implementor exposes, the export paths a session can be read through, what the inspection tool exposes, replay semantics, and the DX checklist a conforming implementation passes.
Grida Desktop is one host implementation of the agent RFC. These docs are delta-only — every fact here depends on the Electron + macOS/Linux/Windows host shape.
RFD for the open problem behind #775: NodeId is parse-ephemeral, so there is no reference that survives a load() — let alone an external rewrite of the file. Frames the gap, scopes the candidate identity contracts (positional path, id attribute, semantic anchor), and sets the promotion gate before any public API lands.
The exclusive nested-editing slot and its taxonomy — content modes (text, vector, with width as a vector facet) vs paint sessions (gradient, image) — replacing the flat production union.
The editor's state domains — content, authoring context, view, interaction, collaboration — and the lifecycle contract each domain membership implies.
Proposal for a typed per-node element IR that replaces tag-switch intent dispatch in @grida/svg-editor with capability-gated records, centralising round-trip invariants.
| feature id | status | description |
Question-and-answer index over the Agent System guide. Doubles as an entry point (read the question, jump to the page) and as a conformance test (if a Q cannot be answered from the RFC, the RFC owes a clarification). Answers are normative and derived from the linked page; they do not invent policy beyond what the guide says.
Scope: Fonts & Images (WASM / Embedded)
Implementation details behind importing .fig files into Grida.
The destructive combine — convert a selection's shapes into one vector node per selection partition, baking geometry and discarding the originals.
| feature id | status | description |
| feature id | status | description |
Tracking docs for the Grida IR schema and how external formats map into it.
The bedrock the rest of the guide rests on. AI SDK v6 as the streaming substrate, directory-rooted execution, the locked fundamental tool set summary, sandbox placement, the watchdog, the case for web search as a special fundamental tool, and the cross-cutting invariants every implementation MUST honor.
The on-canvas name labels drawn above root frames and trays — the labeling rule, the badge/plain taxonomy, screen-anchored placement, in-place rename, and the root-frames bar as their aggregate.
How the locked fundamental-tool RFC lands in Grida. Naming map (RFC id → Grida id), backend adapter table, per-tool deviations Grida ships, and where each tool lives in the monorepo.
The gradient session edits one gradient paint on the canvas: its
Grida-specific tool surfaces and bindings of the agent RFC. Fundamentals as Grida ships them, canvas tools (scene-graph search, specialized inserts, exec/lint/format, resource lookup), and image-generation tools.
| feature id | status | description | PRs |
Grida Gateway (GG) — how an untrusted native client runs Grida-hosted AI without its own API key via scoped-token federation, a first-party metered gateway, and server-side entitlement.
The Grida IR is the in-memory scene graph used by all Grida rendering, layout, and editing pipelines. It is the single representation that CSS, HTML, SVG, and .grida files all target.
A curated corpus of openly-licensed visual assets, and the model by which
Wrap a selection into a new adopting parent — a group or a container — once per selection partition, with world position and order preserved; and ungroup as the inverse.
The layers tree — reversed presentation order, external selection, drag math in document order, and virtualization at document scale.
The undo/redo backbone — entries as data, transactions, gesture framing, burst framing, origin taxonomy, and what history must never contain.
Investigation, bugs, and architectural lessons from a v1 hit-test implementation in @grida/svg-editor — input to the v2 hit-test architecture.
How HTML elements map to Grida IR nodes. For CSS property mapping, see css.md.
Renders HTML+CSS to a Skia Picture for opaque embedding on the canvas
The structure-and-semantics study that informs the Skia-backed SVG
| feature id | status | description |
FRD for inserting <image> elements into the SVG editor. The editor accepts an image insertion at a point given a resolvable href and host-supplied intrinsic size; turning a local file into a usable URL, and loading bytes to learn a natural size, are host-owned I/O. Specifies the insertion contract, the responsibility boundary, drop/paste transport ownership, href authoring, and the P1 round-trip guarantee for the inserted element.
The image session edits one image paint on the canvas: the placement
This document proposes the philosophical basis for image manipulation tools that enable AI agents to generate, enhance, and transform visual content within the design canvas.
The input pipeline — surface events, routing priority, the command vocabulary, the keybinding model, and modifiers as live gesture configuration.
Hypothesis
Import, export, and clipboard — files in, files out, and document fragments across editor instances.
Foreign content crossing into the editor — the drop format matrix, the paste sniffing order, placement rules, and the paste-is-load trust doctrine.
Isolation Mode restricts what the renderer draws and hit-tests to a specific
| feature id | status | description | PRs |
Overview
Universal positioning, dimensions, layout management with anchors, flex and grid.
The session-lifecycle event channel — the small, multi-subscriber surface through which the core announces turn-started / turn-finished / approval-requested moments to consumers that are not the chat renderer. Why an event surface and not consumer-specific wiring, the event vocabulary and its fields, volatility and ordering semantics, the projection over the host wire, the notification consumer policy (focus gating, click-to-attend), and the boundary against a user-facing hooks system.
The agent server as a long-lived, discoverable local process — one server, many clients. The discovery contract (registration record, persistent credential, atomic publish, single-daemon convergence), the authenticated probe and protocol gate, connect-or-spawn, the browser exception, and the production shape.
A catalog of node and subtree properties where a zoom-aware Level-of-Detail
The MarkdownNode renders GFM (GitHub Flavored Markdown) directly to a Skia Picture using pulldown-cmark's event stream and Skia's textlayout::Paragraph API. No HTML/CSS pipeline is involved — the markdown source is walked and drawn in a single pass.
| feature id | status | description |
How user-plugged MCP servers and other external connectors compose with the locked tool set. The bulk problem, tool_search, OAuth, dynamic refresh, and trust policy for untrusted MCP servers.
The modifier-held spacing readout — hold alt and hover to measure the space between the selection and any other node.
| feature id | status | description | PRs |
| feature id | status | description | PRs |
Procedural fractal Perlin noise effects with SVG filter semantics
The arrow-key family — translate nudge, resize nudge, in-flow reorder, sub-mode nudges, and the empty-selection camera pan.
| feature id | status | description | PRs |
A paint session is the editing context for one paint — a single
Core / Modeling
The storage layer. The three-table session schema, the save-on-chunk policy, the JSON-column discipline, the id strategy, and the event-log opt-in. SQLite is the default; the schema ports to any engine that supports JSON columns and indexed string keys.
Short record of the BYOK-only AgentHost contract decisions after removing the hosted grida-cloud provider.
The unit lattice of the canvas — its visual render, and the deliberate split between rendering the grid and snapping to it.
Plan mode as a host-owned operating regime, not a model state. The plan/build pair, the four-invariant transition contract (mode is injected context; the agent proposes but never effects a switch; a transition is a human-gated re-injection; the plan is a reviewed artifact), the symmetry between entering and exiting, who may initiate a transition, and the read-only harness with its single carve-out.
Working group documents for Grida platform and infrastructure topics.
Why Grida Desktop runs a long-lived Node agent sidecar alongside Electron main, what it owns, and where the boundary sits. The three-process model and the composed daemon.
RFD for editing the non-path SVG shapes (rect, circle, ellipse, line, polyline, polygon) as vector geometry: native writeback while the tag can express the edit, promotion to <path> when it cannot — the timing, target, conic representation, and round-trip invariants that keep the conversion honest.
Per-side stroke widths for rectangular shapes (CSS border equivalent)
Reference sheet for estimating GPU render cost of 2D scene operations
Why Grida Desktop URL-loads grida.co/desktop/* instead of bundling editor source — the "one editor codebase, two hosts" doctrine and the path-scoped window.grida bridge.
Specification for rendering untrusted SVG documents inertly in the SVG editor: hardening is a projection choice at the rendering surface, never a mutation of the document model. Names the execution-vector inventory the projection must neutralize, the surface obligations that constrain the strategy, the inert-projection requirements, the named costs, and the residual risks left to the host.
A summary of optimization techniques for achieving high-performance
How the desktop renderer obtains host-owned resource bytes (workspace files — text, images, video) — the buffered-vs-streamed transport model, the privileged media scheme, and why the host proxies rather than handing the renderer or main process its own file authority.
Fonts & Images (WASM / Embedded)
Purpose
The edge rulers — screen-space frame chrome reading canvas coordinates — and the persistent per-scene guides they author.
The three runtime environments an agent can be hosted in — web (limited capabilities), cloud sandbox (ephemeral container/VM), and computer (the user's machine). How the locked tool set degrades and which capabilities each environment provides.
srt is named here as the reference sandbox implementation for the computer environment — the only mature, ready-to-go option matching the capability surface this guide describes. The protocol does not lock to it; implementors MAY substitute any equivalent.
| feature id | status | description | PRs |
The per-session, system-managed, ephemeral filesystem area where an agent does working I/O and where produced files land by default — distinct from the durable workspace. The scratch contract (host-owned and per-session; ephemeral with durability only by promotion; the default output sink; reachable without per-operation approval yet inside sandbox containment; not the workspace), its lifecycle, and what hosts are free to vary.
This document describes the selection behavior for pointer interactions and
See also: the UX-narrative sibling spec at
The per-parent partition of a multi-node selection — why a cross-parent selection presents as N overlay boxes, and which commands act per-partition versus on the whole-selection union.
How a session is born, grows, survives interruption, is compacted, rewound, or forked, and how it switches models per turn. The loop semantics, the chunk stream, the abort path, the run-state machine, the permission-scope layering, and the session-status back-channel.
Two layers of knowledge an agent reaches for beyond its tools. Skills (lazy, advertise-then-load, agent picks when relevant) and project instructions (eager, unconditional, the floor every session stands on).
Gesture-time alignment — the snap family (geometry, space, pixel grid) as interpretation stages, with the guide chrome that explains them.
Placeholder — snapping vector anchors and segments while vector-editing. Deferred with the vector-edit feature.
How node-level opacity interacts with fill and stroke paint when they
How an agent delegates to a child running the same loop. Agent modes, the task tool, blocking vs background, recursion, permission inheritance (deny rules always win), inspectability, awareness, specialized subagents (title / summary / compaction), and plan/build mode as an opinionated pattern hosts may layer.
Design note for the SVG editor's in-document subtree-clone operation: the second of the clipboard FRD's two extraction operations. Specifies the no-closure/no-shell verdict, verbatim-id collision semantics, placement and paint order, who moves during a clone-drag, the mid-drag modifier toggle, the one-undo-step history bracket, and the repeating-offset duplicate (⌘D remembers the translate delta).
The canvas interaction layer — hit tiers, gestures, intents, and the HUD chrome inventory the reference editor must implement.
Index of design notes for the @grida/svg-editor TypeScript SDK — element IR proposal, hit-test architecture, transform pipeline critique, Policy Class glossary.
SVG → Grida IR property mapping and TODO tracker.
Pattern fills for SVG shapes — tiling a subtree as a repeating paint
This document describes the testing methodology and tools used to evaluate SVG rendering accuracy in Grida Canvas.
Status: Active — describes the current import strategy.
Multi-instance document replication — optimistic three-layer state, authority and rebase, presence — and the two-instance conformance contracts.
The pointer→node resolution mathematics — hit chains, graph-distance targeting, descent, deep-select, additive rules, and the marquee predicates including containment suppression.
Why creating text in an SVG editor is click-to-place rather than drag-to-size, and why an empty text element is treated as a deletion.
Motivation
Motivation
Non-normative — a collection of good-to-know practical notes and host/environment gotchas that inform canvas work but do not rise to a spec.
The authoring tool system — tool taxonomy, activation, per-tool insertion gestures, container adoption, and the text/pencil authoring flows.
The design discipline for shaping an agent tool before it is written — the doctrine behind the tool contract. A tool is a contract authored for a consumer that cannot be renegotiated with and cannot be migrated. Minimal surface, host config off the arguments, grounded and honest knobs, auto-resolved inputs, context-frugal and clearly-failing results, and when to reach for a tool versus a connector versus a skill.
The tool contract. The locked fundamental set, what every tool must self-describe, the result envelope, truncation, and how permissions are evaluated at the tool-call boundary.
Context dump on the transform pipeline in @grida/svg-editor — what's done, what's broken, what's load-bearing for the IR redesign.
The two structural behaviors of the move gesture — clone-on-translate (duplicate under a held modifier, live-toggleable) and hierarchy change (re-parenting mid-drag with the drop-target overlay).
The alpha backdrop — the checkerboard beneath everything that makes "nothing is painted here" visible.
Keyboard selection traversal — Enter/Shift+Enter walk down and up the tree, Tab/Shift+Tab walk across siblings, and traversal keeps its result visible.
A canvas-level organizational primitive for grouping design elements without participating in layout.
Anything that fires a turn besides a human typing in the compositor. Scheduled wakeups, external webhooks (CI / GitHub / generic), programmatic API calls, MCP-pushed events, and agent self-scheduled wakeups. Trigger envelope shape, queue semantics, interactive-vs-hosted execution, agent self-scheduling pattern, lifecycle bounds, and the boundary with background subagents.
The host states what happened; the client renders it. The turn-lifecycle wire vocabulary must carry the identity of the message the core actually fired and explicit started/finished/aborted transitions, so a client never infers which queued item became a real turn from its own optimistic mirror. The authority direction, the lifecycle contract, why reconstruction forks across consumers, and the migration from a state-only status channel.
The single point where competing demands to start a turn on one session are serialized, ordered, and drained. The ingestion model, the queued_at data shape, the run-state machine that drains the queue, the single-flight / FIFO / no-preemption invariants, the drop rules, restart behavior, and the core-vs-surface boundary that keeps the queue authoritative in the core.
A working group draft describing the Unicode Coverage Tracker (UCT) feature for the core engine.
Summary
Survey of how the web platform and peer editors render untrusted SVG without executing author script: the script-execution vector inventory, allowlist sanitization (DOMPurify, tldraw), the secure static image mode, iframe sandboxing, parse-into-model editors (Figma, Penpot, Excalidraw), and what a host CSP does and does not neutralize.
UX patterns that ride on top of the compositor and push back into the protocol. Queued sends, sidecar chat as ephemeral fork, and memory as a built-on-top layer. The compositor itself, file refs, attachments, mentions, commands, editor context, and the user-view-vs-model-view lowering rules live in compositor.md.
UX Surface documents specify Grida editor's specific practical UX specifications for surface interactions, selection, targeting, and related user interface behaviors.
The variable-width stroke profile — width stops parameterized along a path, their interpolation into a stroke outline, and the width facet that authors them.
The vector content-edit mode and the pen — the network model, sub-selection, hover-armed projection, bending, tangent mirroring, and the disconnect-not-exit escape semantics.
The vector-network model behind Grida's vector editing: the topology a
Spec for the Vertex Transform Box: treating a multi-vertex sub-selection in path-edit as a single transformable object (translate / scale / rotate via one affine), the interaction model, the session-persistent frame, the policy, and the design questions deferred.
The read/view modality split. Why a text read and a visual view are separate tools, the perception-tool contract, the input matrix (bitmaps now, rendered sources later), how a tool result becomes a provider image block, and the retention policy that keeps perceived pixels from re-filling context every turn.
Why a tool-result image must be hoisted into a user-message image part on the OpenAI-compatible wire, and how to do it as an AI SDK consumer. The Chat Completions tool role is text-only, so the SDK stringifies a tool-output media block to base64 text the model cannot decode. The fix is a prepareStep transform that re-attaches the image as a user message — the SDK-specific realization of the neutral vision RFC's stage-and-reattach strategy.
Why Real WASM Benchmarking Matters
Welcome to the Grida Working Group documentation!