1. Goals and constraints

1.1 Goals#

Goal Consequence in the architecture SRS
One write path. Every change is a registry command, applied on a draft by the document core, committed as a group of signed events. Nothing else mutates a document. §2.5, CMD-13, CMD-17, CMD-18
Parity between people and agents. The registry is the API. The editor, ud, the Plugin API layer and MCP tools are callers of it, never owners of logic. A conformance test enumerates the registry. CMD-19, CMD-20
Figma-compatible surface. Layer 1 (Figma MCP tool names and parameters) and layer 2 (the figma global) are thin adapters over layer 3. Node and property names in the core are Figma’s where Figma has one. CMD-1, CMD-10, CMD-15
Same geometry everywhere. One document core, one layout engine, one text engine, one display list, compiled for Node and for the webview from the same TypeScript. §2.5, TXT-5, LAY-9, NFR-8
Files that merge. Flat node map, fractional sibling indexes, property-level events, derived layout. PLT-3, COL-4, NFR-2
Fluid on large files. Incremental folding, incremental layout, tiled rendering with level of detail, a spatial index, a replica of the document in the webview. NFR-1, CAN-11, CMD-31
Safe by default. Strict CSP, scripts in a WASM sandbox, bridge sockets private to the user, SVG sanitised before it becomes nodes. NFR-4, CMD-11

1.2 Constraints#

  • TypeScript (strict) everywhere in src/; plain ES modules and custom elements in media/, under the SoftForge page contract: no framework, no bundler, no stylesheets (UI-3). The no-bundler rule is the webview’s: the CLI and the extension host are bundled with esbuild (ADR-9, §15.1).
  • No native Node modules (PLT-9). WebAssembly is allowed and used for a closed list only: HarfBuzz (text shaping), the ICU4X segmenter (line and grapheme breaking, §6.3), resvg (raster export on host and CLI), the JPG and WebP encoders (§15.4), QuickJS (the use_figma sandbox).
  • The extension host runs on VS Code 1.108+ (Electron’s Node). The CLI runs on Node.js 22+ or, from a VS Code terminal, on VS Code’s own runtime (§15.5). Node 20 reached end of life on 2026-04-30 and is not supported.
  • The webview loads nothing from the network (CSP, §13).
  • vscode is imported only in src/host/vscode/ and src/extension.ts. Everything else runs in the development server, in the CLI and in plain Node tests.
  • No eval or new Function anywhere that runs in the webview (CSP forbids it); this rules out code-generating validators such as Ajv on the webview side (§3.3).