AI tools write interface faster than anyone can review it
AI output multiplies inconsistency. Each agent produces plausible code. Across teams, that becomes many local versions of the same components, raw values instead of tokens and accessibility gaps, all at a speed review cannot match.
The design system is not machine-readable. Rules live in documentation and in people's heads. Linters cover a small part. Agents cannot read the rest.
Every tool wants your code in its cloud. New platforms ask for broad access and keep your system in their own format. Leaving becomes expensive.
The model choice keeps changing. You do not want governance that only works with one assistant or one provider.
A small team carries a large system. In the zeroheight Design Systems Report 2026, 16% of design systems are run by one person and 56% of teams name staffing as their biggest challenge.
zeroheight Design Systems Report 2026 (survey of 147 practitioners), figures as published in zeroheight's launch webinar.
Loom keeps AI-written interface on-system, in your repository
Agents get the real system, and a verifier
Any agent that speaks MCP gets 17 tools to search the system, read contracts and tokens, export the system as one DESIGN.md file, check a composition, audit code and propose changes. The checks are deterministic: they give the same answer whichever model wrote the code. Working Working
Governance as code, in your repository
Rules, owners, exceptions, proposals, patterns and deprecations are versioned files in a loom/ folder in your repository. Severity is set per area by its owner; accessibility rules are always errors. Working The rules command runs in any CI from a copy of the repository and fails the job when an error remains. Partial What does not work yet: a packaged CI step. Concept
Your model, your keys
Any agent that speaks MCP can use your system, whichever model it runs on. Working For agents that Loom runs for you, provider setup for Anthropic Claude, OpenAI and any OpenAI-compatible gateway is in development. Concept
Your infrastructure, your repository
The command line and MCP server run on your own machines today. Partial What does not work yet: a packaged CI step and Loom cloud are planned. Concept Output is files your team reviews, or draft pull requests; Loom never merges. Partial What does not work yet: automatic pull requests have been tested against simulated hosts, not a client repository.
Least-privilege access
The GitHub App asks for three permissions: metadata, code (writing only to Loom's own branches) and pull requests. Each token covers one repository; broader tokens are refused. Partial What does not work yet: the App is not yet registered on GitHub. GitLab and Azure DevOps use the same interface. Partial
Controls you can audit
Network access to the MCP server requires a token of at least 32 characters. Working Repository content in tool results is fenced and marked as untrusted. Working Every tool call is logged with token counts and cost estimates, with caps per run. Working Every draft an agent writes is labelled as AI-generated. Working Engagement working copies are deleted at the end, with a receipt. Partial We do not train models on your data. Our commitment
Autonomy you control, per area
Area owners choose Observe, Suggest (default), Auto with guardrails or Full. Even Full keeps pull requests with passing checks, a hard-deny list, undo, a record and an organisation-wide cap. The mode per area is a record today and the stricter-mode rule is enforced. Partial What does not work yet: agents acting on their own under these modes. Until then, every change waits for a person. Concept
Loom asks for the least access that works
The permissions below are read from the GitHub App's manifest and from the code that requests each token.
What the GitHub App may do, and nothing more
From the codeOpens labelled, AI-disclosed draft pull requests with Loom's design-system changes for human review. Never merges, never changes settings, CI or secrets.
| Operation | Code | Pull requests | Metadata |
|---|---|---|---|
| Audits and scans | read | none | read |
| Posting a report on a pull request | read | write | read |
| Opening Loom's draft pull requests (on Loom's own branches) | write | write | read |
Never requested: administration, workflows, secrets, checks write, or merge.
github-app/manifest.json and src/git-host/github-app.ts when this page is built; a unit test checks that every token stays inside the manifest.The architecture keeps the core neutral
How Loom fits your stack
DiagramYour side
- Your repository
- CI
- Figma
- AI assistants
- MCP server
- Command line
- Pull requests
Loom core
technology-neutral
- Tokens
- Contracts
- Rules
- Layers
- Governance
Readers and writers
- React
- React Native
- Other stacks Concept
Loom cloud Planned
Recording of real output
A recorded session: a scripted agent against Loom Base, our own design system (MIT), with real server output. The replay types each call as the agent sent it and shows each result after its recorded latency, shortened for the page. Server output is in English.
- Agent
I need a destructive "delete workspace" action with a confirmation. What does the system have?
- Loom ·
search_system· 145 ms→ search_system({"query":"delete confirm danger","kind":"component","limit":5})20 results for "delete confirm danger" (lexical ranking). Top: Dialog (dialog, 0.8, beta), ConfirmAction (confirm-action, 0.46, beta), ToastRegion (toast-region, 0.41, beta), Tag (tag, 0.27, beta), Alert (alert, 0.25, beta)
• Dialog (dialog, strong, confidence 0.8) — import { Dialog } from "@loom/base/native";• ConfirmAction (confirm-action, partial, confidence 0.46) — import { ConfirmAction } from "@loom/base/native";• ToastRegion (toast-region, partial, confidence 0.41) — import { ToastRegion } from "@loom/base/native"; - Loom ·
get_entity· 34 ms→ get_entity({"id":"Button"})Button: Starts an action in the current view: save, publish, open a dialog, run a check.
- Agent
Here is my first draft. It reaches for an MUI Modal, guesses a variant prop, uses two primary buttons and hard-codes a colour and a margin.
- Loom ·
check_composition· 48 ms→ check_composition({"tsx":"import { Card, Button, Heading, Text } from \"@loom/base/native\";\nim…"})Off-system: 3 errors, 2 warnings across 6 nodes.
- [warning] Text has style set: overriding a system component's styling is drift from its contract. → Customise through the component's slots, variants or overridable tokens wit…- [error] Button has no "variant" prop. → Did you mean "tone" ("primary" | "secondary" | "quiet" | "danger")? primary: the one main action in a view; secondary: other actions; q…- [error] <Modal> is not part of Loom Base (imported from "@mui/material"). → Closest system components: AILabel (ai-label), Dialog (dialog), Drawer (drawer). If none fits, draf… - Loom ·
check_composition· 5 ms→ check_composition({"tsx":"import { Card, Button, Text, Stack, ConfirmAction } from \"@loom/bas…"})On-system: 0 errors, 0 warnings across 5 nodes.
components: Card, Stack, Text, Button, ConfirmAction - Loom ·
audit_code· 117 ms→ audit_code({"files":[{"path":"src/settings/SettingsPage.tsx","source":"import React from \"react\";\nimport { Button as MuiButton, Dialog…Drift found: 11 errors, 11 warnings — 7 colours, 9 dimensions, 1 non-system import, 1 re-implemented component.
✗ src/settings/settings.css:2 Hard-coded colour #fffdf8 (background). → Use var(--base-color-palette-cotton-0) ().✗ src/settings/settings.css:5 Hard-coded dimension 16px (padding). → Use var(--base-space-scale-6) (16px).✗ src/settings/settings.css:5 Hard-coded dimension 20px (padding). → Use var(--base-space-scale-7) (20px). - Loom ·
get_guidelines· 11 ms→ get_guidelines({"topic":"illustration"})Guidelines for illustration: missing. 0 sections. Missing: Loom Base has no dedicated illustration guideline. Do not invent one: follow existing foundations, and use propose_change (kind "guideline") to draft it for review.
missing: Loom Base has no dedicated illustration guideline. Do not invent one: follow existing foundations, and use propose_change (kind "guideline") to draft it for review. - Agent
Research uploads need a drag-and-drop file area. Nothing in the system does that, so I will draft a proposal rather than ship a one-off.
- Loom ·
propose_change· 399 ms→ propose_change({"kind":"component","title":"FileDropzone","need":"Researchers attach interview recordings and notes to a journey. Set…","…Draft component-filedropzone-6af1d4b4 written to drafts/component-filedropzone-6af1d4b4.json (status: proposed, labelled AI-generated, not yet human-reviewed). Intake: extend. 7 existing alternatives listed; impact: 5 declared dependents.
impact: 5 declared dependents (partial graph)status: proposed; system source modified: false - Loom ·
check_composition· 69 ms→ check_composition({"tsx":"import { Modal } from \"@mui/material\";\nimport { Button } from \"@loo…"})Off-system: 4 errors, 5 warnings across 6 nodes.
- [warning] Raw <h1> used where the system provides Heading. → import { Heading } from "@loom/base/native";- [error] Button has no "variant" prop. → Did you mean "tone" ("primary" | "secondary" | "quiet" | "danger")? primary: the one main action in a view; secondary: other actions; q…- [error] Button has no "variant" prop. → Did you mean "tone" ("primary" | "secondary" | "quiet" | "danger")? primary: the one main action in a view; secondary: other actions; q… - Agent
The booking flow needs a date range picker. Does the system have one?
- Loom ·
search_system· 17 ms→ search_system({"query":"date range picker for booking","kind":"component","limit":5})No component matches "date range picker". Closest partial matches: ComboBox (combo-box, partial match, confidence 0.24, beta: covers "picker" but not "date range"); FormField (form-field, partial match, confidence 0.24, beta: covers "picker" but not "date range"); LooseThreads (loose-threads, partial match, confidence 0.24, beta: covers "picker" but not "date range"). Logged as an unmet need. If this is a real gap, draft it with propose_change instead of building it off-system.
• ComboBox — partial match: covers "picker" but not "date range"• FormField — partial match: covers "picker" but not "date range"• LooseThreads — partial match: covers "picker" but not "date range" - Loom ·
search_system· 14 ms→ search_system({"query":"show an error when payment fails","kind":"component","limit":3})51 results for "show an error when payment fails" (lexical ranking). Top: ErrorSummary (error-summary, 0.93, beta), AIStatus (ai-status, 0.74, beta), Alert (alert, 0.74, beta)
• ErrorSummary (error-summary, strong, confidence 0.93) — import { ErrorSummary } from "@loom/base/native";• AIStatus (ai-status, strong, confidence 0.74) — import { AIStatus } from "@loom/base/native";• Alert (alert, strong, confidence 0.74) — import { Alert } from "@loom/base/native"; - Loom ·
list_unmet_needs· 5 ms→ list_unmet_needs({})1 unmet need from 1 request; 0 over the threshold (3 requests from 2+ requesters in 30 days). "date range picker" x1.
• "date range picker": 1 request(s), 1 requester(s) — Below threshold: needs 2 more request(s) and 1 more client(s) or team(s) within 30 days.
We show our own numbers
- 17 MCP tools; 5 to 399 milliseconds per call in the recorded session on Loom Base. Working
- The audit runs on code it was never tuned for: a package it had never seen, scored across eight areas in 2.4 seconds with no configuration. Working
- 50 of 50 parity tests for components written for React and React Native from one contract. Partial Three components so far, and native tests do not yet run on devices.
- Two pilots on 25 October 2026 found gaps in the audit on real, private apps; both were fixed the same day, with tests. Working
Speed from AI is an opportunity worth taking. Governing what it writes is what keeps that speed safe.
Questions
Is this a wrapper around a model? No. The core is technology-neutral and deterministic: tokens, contracts, rules, layers and governance, with checks that run without a model.
What happens if we stop using Loom? You keep everything. Tokens, contracts, rules and governance records are files in your repository.
Do you hold ISO 27001 or SOC 2? Not today. We answer security questionnaires directly.
Which stacks? The audit reads React, TypeScript, CSS and plain HTML apps. Loom writes React and React Native. Other stacks are candidates.
What about Figma? Figma stays a source of truth. Loom supports paid Figma plans, Professional and up.