--- name: illustrate-blueprint description: >- Illustrate a UI-pattern blueprint from the blueprint-ontology repo as an interactive schematic in this app. Use when asked to illustrate, add, render, or build the illustration for a blueprint — e.g. "illustrate the table blueprint", "add the feed blueprint", "/illustrate-blueprint stack". Reads the source contract from ../blueprint-ontology, authors the typed data module and a bespoke specimen, registers the pair, and verifies the build. --- # Illustrate a blueprint Turn one blueprint from the `blueprint-ontology` repo into an interactive illustration in this app (`blueprints`, deployed at https://blueprints.apoena.dev). Read `CONTEXT.md` (ubiquitous language) and `DESIGN.md` (architecture) at the repo root first if you haven't this session — they define the vocabulary (Illustration, Viewer, Specimen, Readout, Companion, Function) used throughout. ## What an illustration is The generic **Viewer** (`src/components/BlueprintViewer.vue`) renders every generic part — title block, legend, function tabs, the full-view Readout, the composition map, and the state machine — from a blueprint's **typed data**. You author two things per blueprint and register them: | File | What it is | | ------------------------------------ | --------------------------------------------------------------------------------------------------------- | | `src/data/Blueprint.ts` | the `Blueprint` object — the contract as typed data (see the `Blueprint` type in `src/data/blueprint.ts`) | | `src/specimens/Specimen.vue` | the **bespoke** static visual mock (left pane), with per-function highlighting | | `src/data/blueprints.ts` | one line registering the `{ blueprint, specimen }` pair under its slug | Registering in `blueprints.ts` is all that's needed — the Gallery (`/`) and the route `/b/` both derive from the registry automatically. Do **not** hand-edit the router or the Gallery. > **This is interpretive authoring, not parsing.** `DESIGN.md` D1 deliberately > rejects auto-generating from the ontology: the specimen must be hand-built, and > the contract material (behaviors, invariants, failures, performance) has to be > **redistributed per function**. Do the transcription by hand, faithfully. ## Reference examples Study the closest existing pair before you start — copy its shape, don't reinvent: | Kind | Data module | Specimen | Notes | | ---------------------- | --------------------------------- | -------------------------------------- | ---------------------------------------------------------------------- | | **Feature** (set) | `src/data/listBlueprint.ts` | `src/specimens/ListSpecimen.vue` | reuses the shared `LOADSTATE_MACHINE` (`src/data/loadStateMachine.ts`) | | **Feature** (set) | `src/data/gridBlueprint.ts` | `src/specimens/GridSpecimen.vue` | 2D tile layout | | **Feature** (temporal) | `src/data/calendarBlueprint.ts` | `src/specimens/CalendarSpecimen.vue` | annotates one surface per function | | **Capability** | `src/data/rememberMeBlueprint.ts` | `src/specimens/RememberMeSpecimen.vue` | defines a **bespoke** state machine + new `SmKind`s | ## Workflow ### 0 · Read the source blueprint The source of truth is the sibling repo, default `../blueprint-ontology` (confirm the path if it's not there). For a blueprint with slug ``, read all three: - `blueprints//README.md` — the prose contract - `blueprints//.als` — the formal model (the real invariants/behaviors) - `blueprints//.test.als` — checks that pin the contract The README anatomy is fixed: **Signature → UI snapshot → State machine → Behaviors → Invariants → Functional analysis → Critical performance → Failure modes → Formal model**. Map it to the `Blueprint` type like this: | README section | `Blueprint` field | | -------------------------------- | ------------------------------------------------------------------------------- | | `# Name` + intro one-liner | `name`, `tagline` | | Signature / Standard composition | `sig` (`header`, `fields`, `types`), `role`, `extendsName`, `composesCount` | | Relations | `related[]` (`{ name, relation }`) | | UI snapshot (ASCII sketch) | informs the **Specimen** — not a data field | | State machine | `stateMachine` — reuse `LOADSTATE_MACHINE` or author a bespoke one (see step 2) | | Behaviors | distributed into `functions[].behaviors[]` (`{ sig, pre, eff }`) | | Invariants → Core | top-level `coreInvariants[]` | | Invariants → per-behavior | the owning `functions[].invariants[]` | | Functional analysis (the table) | **`functions[]`** — one row = one `BlueprintFunction` | | Critical performance | distributed into `functions[].perf[]` | | Failure modes | distributed into `functions[].failures[]` | | Formal model | rendered automatically from `slug` in the footer | ### 1 · Decide role and state-machine strategy - **Role** — `"feature"` (a pattern the user interacts with: List, Grid, Calendar) or `"capability"` (composes onto a host: Async, RememberMe, MFA). Set `extendsName` (the base/host) and, for features that compose capabilities, `composesCount`. - **State machine** — - Set features that compose Async + Paginated + Pullable (List, Grid, Feed, Table…) **reuse** the shared machine: `import { LOADSTATE_MACHINE }` and set `stateMachine: LOADSTATE_MACHINE`. - A blueprint with its own lifecycle authors a **bespoke** `StateMachine` (`nodes` with hand-placed `x/y/w/h`, `edges`, `initId`, `caption`, `field`). Copy the layout approach from `rememberMeBlueprint.ts`. - **If the bespoke machine has transition kinds not already in `SmKind`**, add them to both `SmKind` **and** `SM_COLORS` in `src/data/blueprint.ts` (a color per kind). Reuse an existing kind whenever the semantics match. - A blueprint with no lifecycle simply omits `stateMachine`. ### 2 · Author `src/data/Blueprint.ts` Export a `const : Blueprint`. Conform exactly to the `Blueprint` interface — open `src/data/blueprint.ts` and follow it field by field. Start the file with a header comment citing the ontology source (README + `.als`), like the existing modules do. Per function (one per Functional-analysis row): - `id` — short, kebab/lowercase, **stable**; the specimen switches on it. - `name` — the table's Function name. - `fig` — `"01"`, `"02"`, … in table order (shown as `FIG.NN` in the specimen cap). - `caps` — the blueprint(s)/capability that provide this function (drives the composition-map links and the Readout's "source capability"). - `verb` — the table's Responsibility, tightened to one imperative sentence. - `state` — `[name, type]` pairs for the state this function touches. - `behaviors` / `invariants` / `failures` / `perf` / `notes` — pull the matching lines from the README's Behaviors / Invariants / Failure modes / Critical performance sections. Leave arrays empty (`[]`) when a function has none. Fill `composition` when the pattern is a host-plus-capabilities or a capability over a host: `caps[]` (nodes, mark the core one `core: true`), `funcs[]` (function names in order), `links[]` (`[capId, functionName]` pairs). The composition map only renders when `composition` is present. ### 3 · Author `src/specimens/Specimen.vue` The Specimen is a **static** (never live) visual mock of the pattern's real UI, bespoke to this blueprint. Contract: - `