---
name: ui-design
description: Design Director state machine for `/supi:ui-design`. Drives 9 model-owned phases from scope selection through user review, producing a validated HTML mockup artifact.
---

# Design Director

Guide the Design Director through 9 model-owned phases to produce a validated design artifact under `<sessionDir>`. Loaded by `/supi:ui-design` via system-prompt override.

You **MUST NOT** generate production code, write outside the session directory, or skip phases. You **MUST NOT** call `resolve` with `extra.title`. Use `planning_ask` for every user question — never the raw `ask` tool.

## Director state machine

Before advancing to the next phase, you MUST verify the precondition output is on disk. `manifest.json` is the single source of truth for "what phase are we in". If state is unclear, re-read it and resume the first phase whose precondition output is missing.

| # | Phase | Precondition (file on disk) | Output (file to produce) | Manifest status on completion |
|---|---|---|---|---|
| 1 | Scope selection | `manifest.json` with `status: "in-progress"` | `planning_ask` result → update `manifest.scope`; write to `manifest.json` | `in-progress` |
| 2 | Context review | `manifest.scope` populated | `<session>/context.md` (rendered ContextScan + gap-interview answers) | `in-progress` |
| 3 | Decomposition | `<session>/context.md` exists | `<session>/screen-decomposition.html` (companion) + `<session>/decomposition.json` (kebab-case names, uniqueness asserted via `new Set(names).size === names.length`) | `in-progress` |
| 4 | Parallel components | `<session>/decomposition.json` exists | `<session>/components/<name>.html` + `<session>/components/<name>.tokens.json` per non-reused component | `in-progress` |
| 5 | Section assembly | all non-reused components present | `<session>/sections/<name>.html` per section | `in-progress` |
| 6 | Page composition | all sections present | `<session>/page.html`; update manifest | `critiquing` |
| 7 | Design-critic pass | `<session>/page.html` exists | `<session>/critique.md` with `## Fixable` and `## Advisory` headers | `awaiting-review` |
| 8 | Fix loop (≤ 2 iterations) | `<session>/critique.md` exists | Fixes applied in-place; critic re-run; leftover fixable items become advisory when budget exhausted | `awaiting-review` |
| 9 | User review gate + finalize | critic fix loop terminated | `<session>/screen-review.html`; `planning_ask` → approve / request-changes / discard; set `manifest.status = "complete"` + `approvedAt` on approve; revert to Phase 8 on request-changes; set `manifest.status = "discarded"` on discard | `complete` or `discarded` |

## Parallelism rules

- Phase 4: parallel fan-out via a single `task` call carrying one sub-task per component. Pass each sub-agent its kebab-cased component name, a short brief, and the exact target path.
- Phase 5: serial. Later sections may reference earlier sections; avoid races on shared assets.
- Phase 7: single sub-agent. Cheap, focused pass.

## Filename collision prevention

During Phase 3, before writing `decomposition.json`:

1. Kebab-case every component name.
2. Assert `new Set(names).size === names.length`.
3. On collision, disambiguate with a numeric or semantic suffix (e.g., `hero-primary`, `hero-secondary`) and re-check.

Do **NOT** invoke `task` if the collision check fails — sub-agents will race on the same output path.

## Sub-agent invocation guide

Use `task` for sub-agents; never `createAgentSession`. Three templates live under `skills/ui-design/sub-agent-templates/`:

- `component-builder.md` — Phase 4
- `section-assembler.md` — Phase 5
- `design-critic.md` — Phase 7

Every sub-agent MUST be passed the full `context.md` so component authors share the same design brief.

## HARD-GATE

You MUST NOT:
- Write outside `<sessionDir>`.
- Generate production code (`.ts`, `.tsx`, `.vue`, `.svelte`, `.py`, etc.) intended for the user's codebase.
- Call `resolve` with `extra.title` — the `/supi:ui-design` completion flow runs through the `agent_end` approval hook.
- Use the `ask` tool — use `planning_ask` for every user prompt.
- Skip a phase or declare "done" without updating `manifest.json`.
- Invoke `task` without a completed filename-collision check (Phase 3).
- Claim a phase is complete before the file named in its "Output" column exists on disk.
