Experiment 03 · Design systems

A registry an agent can read

Four components, described once as data. Pick a request below and watch it get checked against that data — the same gate a tool-calling agent would have to pass.

01 · The registry

Four components, described once as plain data — no JSX. This is the manifest a human reads as docs and an agent reads as a tool schema. Same file, two readers.

{
  "Button": {
    "name": "Button",
    "description": "A single clickable action. The only control in this registry that should trigger a side effect.",
    "props": {
      "variant": {
        "kind": "enum",
        "values": [
          "primary",
          "secondary",
          "ghost",
          "destructive"
        ],
        "default": "primary",
        "description": "Visual weight and intent. destructive is reserved for actions that delete or revoke — never use it for emphasis."
      },
      "size": {
        "kind": "enum",
        "values": [
          "sm",
          "md",
          "lg"
        ],
        "default": "md",
        "description": "Physical size."
      },
      "disabled": {
        "kind": "boolean",
        "default": false,
        "description": "Removes the button from interaction. The label must still explain why, if it isn't obvious from context."
      },
      "loading": {
        "kind": "boolean",
        "default": false,
        "description": "Shows a spinner in place of the icon slot. Implies disabled, but the visible label must stay put."
      }
    },
    "a11y": [
      "Always render a real text label — icon-only buttons need an aria-label, not a bare icon.",
      "loading must not replace the label with only a spinner; a screen reader still needs an accessible name."
    ]
  },
  "Badge": {
    "name": "Badge",
    "description": "An inline status or category marker. Carries no interaction.",
    "props": {
      "tone": {
        "kind": "enum",
        "values": [
          "neutral",
          "accent",
          "success",
          "warning"
        ],
        "default": "neutral",
        "description": "Semantic tone — pick the one that matches what the badge is reporting, not just the colour you want."
      }
    },
    "a11y": [
      "Renders as a <span>, never a <button> — if it needs to be clickable, it isn't a Badge, it's a Button."
    ]
  },
  "Alert": {
    "name": "Alert",
    "description": "A block-level message about the state of the page or an action just taken.",
    "props": {
      "tone": {
        "kind": "enum",
        "values": [
          "info",
          "success",
          "warning",
          "danger"
        ],
        "default": "info",
        "description": "Determines both colour and how assertively it's announced to assistive tech."
      },
      "title": {
        "kind": "string",
        "required": true,
        "description": "A short, specific heading. Required — an Alert with no title has nothing for a screen reader to announce first."
      }
    },
    "a11y": [
      "tone: \"danger\" or \"warning\" renders role=\"alert\" (interrupts immediately).",
      "tone: \"info\" or \"success\" renders role=\"status\" (announced politely, doesn't interrupt).",
      "title is mandatory. It's the one prop this registry marks required, and the validator enforces it."
    ]
  },
  "Card": {
    "name": "Card",
    "description": "A padded, bordered layout container. Purely structural — no tone, no interaction.",
    "props": {},
    "a11y": [
      "If the content inside is a distinct region (not just decoration), give it a heading — don't rely on the Card itself to convey meaning."
    ]
  }
}
02 · Ask for a UI

Pick a request. Each one resolves to a fixed proposal — a stand-in for the plan a tool-calling agent would produce after reading the registry above. Nothing here calls a model; the point is the step that happens after the model call, the one that actually keeps it honest.

03 · What got proposed

The simulated tool call for this request — a component name plus a bag of props, before anything checks it.

{
  "component": "Card",
  "props": {},
  "children": [
    {
      "component": "Badge",
      "props": {
        "tone": "accent"
      },
      "text": "Popular"
    },
    "Pro plan — $19/mo",
    "Everything in Free, plus unlimited projects and priority support.",
    {
      "component": "Button",
      "props": {
        "variant": "primary",
        "size": "lg"
      },
      "text": "Choose Pro"
    }
  ]
}
04 · Validated against the registry
✓ Valid
Popular

Pro plan — $19/mo

Everything in Free, plus unlimited projects and priority support.