Skip to content

Architecture

Three layers

┌─────────────────────────────────────────────────────────────┐
│  Agent Interface (AGENTS.md, CLAUDE.md)                     │
│  ─ How any LLM picks up this repo and behaves like a senior │
│    designer                                                 │
└─────────────────────────────────────────────────────────────┘
                             │ reads from
┌─────────────────────────────────────────────────────────────┐
│  Skills + Agents + Commands                                 │
│  ─ Task-specific playbooks (skills/)                        │
│  ─ Persona-specific reviewers (agents/)                     │
│  ─ User-invocable shortcuts (commands/)                     │
└─────────────────────────────────────────────────────────────┘
                             │ cites
┌─────────────────────────────────────────────────────────────┐
│  Knowledge Base (knowledge/)                                │
│  ─ Structured, deduplicated, model-readable                 │
│  ─ Generated by tools/extractors/ from refs/                │
│  ─ Hand-written overrides marked with `<!-- hand-written -->`│
└─────────────────────────────────────────────────────────────┘
                             │ derived from
┌─────────────────────────────────────────────────────────────┐
│  Source Material (refs/)                                    │
│  ─ Sparse-cloned upstream design systems                    │
│  ─ READ-ONLY. Never edit.                                   │
│  ─ Refresh via `git -C refs/<repo> pull`                    │
└─────────────────────────────────────────────────────────────┘

Why model-agnostic?

The user invokes design work from multiple agent surfaces (Claude Code, Codex CLI, sometimes Cursor). Knowledge encoded in markdown + JSON survives across:

  • Claude Code's skill system
  • Codex CLI's AGENTS.md convention
  • Generic prompt context for any LLM

Encoding the same knowledge as Claude-specific skill files would lock it in. We use the skill system for ergonomics, but the source of truth is plain markdown.

Knowledge file contract

Every file under knowledge/ follows this shape:

---
title: <human-readable title>
source: <upstream URL or "hand-written">
extracted_at: <ISO date, omit if hand-written>
applies_to: [<framework or scope tags>]
---

# <title>

<single, focused topic. Under 400 lines.>

If a file is generated, it must include the source path so a human can trace it back.

Extractor contract

Each extractor in tools/extractors/:

  1. Reads from a single refs/<source>/ directory.
  2. Writes to a single knowledge/<category>/ directory.
  3. Is idempotent — running twice produces the same output.
  4. Never overwrites files marked <!-- hand-written -->.
  5. Documents its source paths in its own header.

Skill file contract

skills/<skill-name>/
├── SKILL.md          # Claude Code skill manifest (frontmatter + body)
├── PLAYBOOK.md       # Step-by-step process (read by any agent)
├── TEMPLATE.md       # Output template, if applicable
└── examples/         # Worked examples

Codex CLI reads PLAYBOOK.md directly. Claude Code uses SKILL.md for invocation, but both files share the same content — SKILL.md is PLAYBOOK.md with frontmatter wrapping.

Why not vector embeddings?

Considered, rejected for this version:

  • Knowledge fits well under 50K tokens once curated. Direct file reads are faster and cheaper than vector retrieval.
  • Markdown is grep-able and human-auditable. Vectors are not.
  • Future: if knowledge grows past ~100K tokens, add an optional embedding index in tools/index/ without changing the source-of-truth layer.

Refresh cadence

Action When
git -C refs/<repo> pull Monthly, or when a new feature in upstream is referenced
./tools/extractors/run-all.sh After any refs/ update
Hand-written knowledge/ review Quarterly, or after major ecosystem shifts

Runtime and release boundaries

The public product surface and its internal implementation have separate owners:

Boundary Source of truth Responsibility
Public identities cli/lib/capability-manifest.json Route, skill, command, agent, MCP tool, and SDK export names
Plugin inventory .claude-plugin/plugin.json Installed Claude assets and package metadata
Route catalog cli/lib/route-catalog.mjs Stable route definitions and route ID validation
Route operation cli/lib/route-operation.mjs Shared read-only route payload assembly for CLI, SDK, and MCP
Start operation cli/lib/start-operation.mjs Shared route, design-contract, review-state, next-step, and effect-boundary assembly for CLI, SDK, MCP, and Console
Route engine cli/lib/route.mjs Scoring, parsing, reference enrichment, and evaluation
Design quality contract cli/lib/design-quality-report.schema.json Versioned evidence, finding, status, permission, and approval shape
Design quality validation cli/lib/design-quality-contract.mjs Dependency-free report validation and derived-summary consistency
Website Console source bundle docs/website-console/source-bundle.js Provenance and revalidation data contract without DOM access
Website Console UI docs/website-console/app.js DOM, storage, graph, copy, and Markdown rendering
Python capability audit tools/audit/capability_manifest.py Package-independent validation of the canonical identity contract

The manifest protects names and counts; it does not dispatch runtime behavior. Each runtime owner keeps an explicit implementation so a metadata change cannot silently change execution.

The design quality contract is another pure boundary. It does not inspect a target repository, start a browser, or mutate a file. Future CLI, SDK, MCP, Console, and browser adapters must produce the same report shape and pass the same validator. Runtime owners may collect different evidence, but they cannot weaken unverified status or the report's permission boundary.

The start operation is also pure. It reads the design-ai corpus needed to choose a route and build the existing design contract, but it does not open declared local paths, fetch repository or page URLs, inspect screenshots, write files, or execute the returned next command. Website Console accepts only start payloads that retain that zero-write, zero-target-mutation, zero-external-action performed boundary.

Artifact ownership

Generated artifacts have distinct write and verification commands:

Artifact Generate Verify without mutation
knowledge/COVERAGE.md npm run coverage:generate npm run coverage:check
Documentation staging tree tools/build-docs.sh npm run docs:check builds the final MkDocs site
npm tarball npm pack npm run package:check, then npm run package:smoke

Strict audits and release workflows use the verification commands. They must not repair tracked files as a side effect. This keeps a passing CI run reproducible from the committed tree and makes stale generated artifacts fail with an actionable regeneration command.

The npm package intentionally omits clone-only extractors. Its strict audit preserves that already-verified extractor inventory from the bundled coverage report while recomputing every packaged knowledge, skill, example, and component section.

npm run release:preflight runs every non-publishing release gate except the packed tarball execution smoke. npm run release:check adds that smoke once. Release and publish workflows run the preflight, build their final tarball, and smoke-test that same artifact before release or publication.