# Design Workflow

> 통합 디자인 워크플로 스킬 — Path A(Claude Design 핸드오프 번들 가져오기, 필요시 Figma 추출기 경유)와 .moai/design/(research·system·spec)에서 design-brief 컨텍스트 로딩을 처리합니다. DTCG 토큰을 검증하고 브랜드 컨텍스트 헌법 우선순위를 보장합니다. /moai design 워크플로에 사용 — 일반 디자인 시스템 문서용이 아닙니다. Use for the /moai design workflow: Path A Claude Design handoff-bundle import (via Figma extractor when needed), design-brief context loading from .moai/design/, DTCG token validation, and brand-context constitutional priority.

- Skill: `modu-ai/design-workflow` (Agent Skill)
- Install (CLI): `npx skillmds@latest add modu-ai/design-workflow`
- Raw SKILL.md: https://api.skillmd.com/api/skills/modu-ai/design-workflow/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Design & Media
- Author: modu-ai (https://skillmd.com/u/modu-ai)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/modu-ai/design-workflow

---


> ⚠️ **개발 런타임 전용** — 이 스킬은 MoAI-ADK(Claude Code) 환경을 전제한다. Claude Cowork(Desktop)에서는 `.moai/config` 의존으로 동작하지 않을 수 있다. Desktop 사용자는 `cd-*` 체인(design-brief → design-prompt-builder → design-slop-check)을 사용한다.

# Design Workflow (`design-workflow`)

Unified `/moai design` workflow skill. Handles two complementary responsibilities:

1. **Design artifact import** — Path A (Claude Design handoff bundle, ZIP/HTML) and Path
   B1 (Figma extractor via meta-harness). Produces DTCG-validated design tokens at
   `.moai/design/tokens.json` for `expert-frontend` consumption.
2. **Design-brief context loading** — Auto-loads human-authored briefs from `.moai/design/`
   (`spec.md`, `system.md`, `research.md`) into the orchestrator prompt before
   `expert-frontend` or `design-brand-system` runs.

Brand context (`.moai/project/brand/`) is the constitutional parent across all paths — no
path may override brand constraints (design constitution §3.1, §3.3).

## Quick Reference

**Reserved output paths** (design constitution §3.2, must not collide with human files):
`tokens.json`, `components.json`, `assets/`, `import-warnings.json`, `brief/BRIEF-*.md`,
`copy.json`, `path-selection.json` — all under `.moai/design/`.

**Path selection** (presented via AskUserQuestion when `/moai design` needs choice):
1. **Path A — Claude Design** (권장) — handoff bundle (ZIP or HTML)
2. **Path B1 — Figma** — meta-harness generates `moai-harness-figma-extractor` dynamically

Selection persisted to `.moai/design/path-selection.json`.

**Context-loading priority order** (REQ-2 / AC-4 from absorbed design-context skill):
`spec > system > research`. When token budget exceeded, drop in REVERSE priority — never
drop `spec`. Default `token_budget: 20000` from `design.yaml design_docs.token_budget`.

**Token estimation**: `estimated_tokens = ceiling(char_count / 4) * 1.10`.

## Implementation Guide

### Part 1 — Path A: Claude Design Handoff Bundle

**Supported formats (Phase 1)**:
- `ZIP` — Claude Design export with `manifest.json`, `tokens.json`, `components/`, `assets/`
- `HTML` — single-file Claude Design export

**Unsupported (Phase 2 roadmap)**: DOCX, PPTX, PDF, Canva link — return
`DESIGN_IMPORT_UNSUPPORTED_FORMAT` and guide to Path B.

**Version whitelist**: Check `manifest.json` `format_version` against
`supported_bundle_versions` in `.moai/config/sections/design.yaml`. Current default: `["1.0"]`.
Mismatch → `DESIGN_IMPORT_UNSUPPORTED_VERSION`.

**Parsing flow**:
1. Receive bundle file path from orchestrator
2. Validate file existence → `DESIGN_IMPORT_NOT_FOUND` if missing
3. Validate format (extension + magic bytes: `PK\x03\x04` for ZIP, DOCTYPE/`<html` for HTML)
4. **Security scan before extraction** — list ZIP entries; reject executables (`.sh`, `.exe`,
   `.bat`, `.cmd`, `.ps1`, `.py`, `.rb`, `.pl`), symlinks, path traversal (`../`, `..\`),
   absolute paths → `DESIGN_IMPORT_SECURITY_REJECT`
5. Read `manifest.json`, validate version
6. Extract: `tokens.json` → `.moai/design/tokens.json`; `components/` → `components.json`;
   `assets/**` → `.moai/design/assets/`; `copy.json` → `.moai/design/copy.json`
7. Validate token structure (required keys: `colors`, `typography`, `spacing`); missing
   keys → warning, not failure
8. Report extraction results

**Expected ZIP structure**: `manifest.json` (format_version, claude_design_version,
created_at) + `tokens.json` (colors, typography, spacing, radii, shadows) + optional
`components/` (HTML or JSON specs) + optional `assets/` (images, fonts, icons) + optional
`copy.json` (structured copy).

**Output token schema** (normalized to MoAI): top-level keys `colors`, `typography`,
`spacing`, `radii`, `shadows`, plus `source: "claude-design-bundle"` and `bundle_version`.

**Field normalization** (silent rename, logged in import-warnings.json):
`primary_color`/`brand_color` → `colors.primary`; `heading_font` →
`typography.fontFamily.heading`; `base_spacing` → `spacing.base`.

**Asset safety**: Validate image MIME (png, jpg, gif, webp, svg, ico) and font formats
(woff2, woff, ttf, otf). Reject nested ZIPs. Strip script tags from SVG metadata.

### Part 2 — Path B1: Figma Extractor (Meta-Harness)

**Prerequisite**: the harness policy `moai-meta-harness`. Path B1 does NOT ship a
static Figma skill — it is generated dynamically. When user selects Path B1, invoke
`moai-meta-harness` to generate `.claude/skills/harness-figma-extractor/SKILL.md`
(project-scoped and user-owned via `harness-*` prefix — `moai update` never
overwrites). Meta-harness Phase 5 (Customization) collects via Socratic interview:
Figma file ID, page selectors mapping pages to token categories, credential reference
(env var name like `FIGMA_TOKEN`; value NEVER stored in skill file). Generated extractor
produces `tokens.json` + `components.json` at `.moai/design/`; DTCG validation runs before
`expert-frontend` consumption.

### Part 3 — Design-Brief Context Loading

Auto-loads human-authored briefs during Phase B2.5 of `/moai design` when
`design_docs.auto_load_on_design_command: true`. Can also be invoked standalone with
explicit `dir` argument.

**Configuration resolution**: Read `design_docs` from `.moai/config/sections/design.yaml`.
If absent, use compiled-in defaults:
- `dir: .moai/design`
- `auto_load_on_design_command: true`
- `token_budget: 20000`
- `priority: [spec, system, research]`

Log `design_docs not configured — using defaults` when key absent.

**Bare-token → filename mapping**:
- `spec` → `<dir>/spec.md`
- `system` → `<dir>/system.md`
- `research` → `<dir>/research.md`

**Steps**:
1. **Directory check**: Glob `<dir>/`. Missing → emit header only and log
   `design docs not initialized — run /moai init or SPEC-DESIGN-DOCS-001 to create`.
2. **Auto-load gate**: From Phase B2.5, check `auto_load_on_design_command`. False → skip.
3. **Parallel Read**: Issue all candidate file Reads in a single batched parallel tool-call set.
4. **Filter `_TBD_` files**: A file with only scaffold content (lines blank, `_TBD_`,
   headings without bodies, or `<!--`/`>` comments) is skipped. Log
   `skip: <token> — _TBD_ only`.
5. **Token budget enforcement**: Include in priority order until cumulative
   `estimated_tokens` would exceed budget. Overflow → drop lowest priority (`research`
   first, then `system`; never `spec`). Single file too large → truncate at nearest
   `##`/`###` boundary and append `> truncated: <filename> at char_offset=N`.
6. **Build output block** — first non-empty line MUST be exactly `## Design Context (from
   .moai/design/)`. For each file, prepend `> source: .moai/design/<filename>` then
   content (or truncated).
7. **Warnings section** (when unreadable files encountered): append
   `> warnings: [<token1> unreadable: <reason>, ...]` after the content.

**All-`_TBD_` case**: header-only output + log
`design docs present but all are _TBD_ — no content loaded`.

### Error Codes (Path A)

- `DESIGN_IMPORT_NOT_FOUND` — bundle path missing → guide to Path B
- `DESIGN_IMPORT_UNSUPPORTED_FORMAT` — non-ZIP/HTML → guide to Path B
- `DESIGN_IMPORT_UNSUPPORTED_VERSION` — version not in whitelist. Required stderr (all 3
  lines mandatory): `Detected bundle version: v<N>`; `Supported versions: <list from
  design.yaml>`; `Switch to path B: run /moai design and select 'Code-based brand design'`.
- `DESIGN_IMPORT_SECURITY_REJECT` — executables/symlinks/traversal/absolute paths
  detected. List offending entries. Do NOT create `.moai/design/` directory.
- `DESIGN_IMPORT_MISSING_MANIFEST` — ZIP without `manifest.json` → guide to Path B

**Fallback guidance** appended to every error: instruct user to run `/moai design` and
select "Code-based brand design (design-brand-system)" after ensuring
`.moai/project/brand/visual-identity.md` is complete.

### Partial Bundle Recovery

Valid bundle missing optional components → extract what's available, log warnings to
`.moai/design/import-warnings.json`, proceed with partial output. Never silent failure.

### Part 4 — 번들 없이 브랜드에서 바로 시작하는 경로

핸드오프 번들도 Figma도 없이 **브랜드 자산에서 곧장 디자인을 만드는** 요청이면 아래 순서로 진행합니다.
`design.yaml`(`.moai/config/sections/design.yaml`) 값을 따르고 임계값을 코드에 박지 않습니다.

1. `design-system-prep` + `design-brand-system` — 브랜드 자산 → DESIGN.md + DTCG 토큰 (WCAG 2.1 AA)
2. `design-copywriting` — 브랜드 톤에 맞춘 카피 (생성 시점부터 AI 슬롭 회피)
3. `design-iteration-loop` — Builder-Evaluator 품질 루프 (최대 5회, pass_threshold 0.75, 4차원 채점)

UX 프롬프트 패턴이 필요하면 `design-prompt-builder`를 함께 씁니다.

## Works Well With

`design-brand-system` (Path B fallback / context consumer), `design-handoff`
(produces `claude-design-handoff/` for Path A), `design-iteration-loop` (uses tokens +
context as baseline), `moai-meta-harness` (generates figma extractor for Path B1),
`expert-frontend` (primary consumer), `.claude/rules/moai/design/constitution.md` (brand
priority + reserved paths).

## Common Rationalizations

- "Skip security scan for trusted bundles" — "trusted" is unverifiable. Scan every bundle, no exceptions.
- "Drop spec.md when budget tight" — spec.md is priority 1, never dropped. Drop research → system → escalate.
- "_TBD_ files contain useful context" — `_TBD_` means scaffold-only. Skip to avoid polluting the prompt.
- "Path B1 needs a hardcoded Figma extractor" — Path B1 uses meta-harness generation. Static Figma skill prohibited.
- "Brand context is one input among many" — brand context is the constitutional parent; conflicts resolve in favor of brand.

## Red Flags

- Bundle parse proceeds without security scan
- ZIP entries containing `../`, symlinks, or executables accepted
- `manifest.json` version validation bypassed
- Design context block missing canonical header `## Design Context (from .moai/design/)`
- `spec.md` dropped when budget exceeded (priority violation)
- Figma API token value stored inside skill file (only env var name allowed)
- Output written outside `.moai/design/` reserved path set

## Verification

- [ ] Path A security scan rejects fixture with `..` and symlinks
- [ ] Path A produces `.moai/design/tokens.json` with normalized schema
- [ ] Path B1 invocation triggers `moai-meta-harness` (no static skill)
- [ ] Context-load output starts with `## Design Context (from .moai/design/)`
- [ ] Budget truncation appends `> truncated: <filename> at char_offset=N`
- [ ] All-`_TBD_` case emits header + log only
- [ ] DTCG validation runs on Path A and Path B1 outputs
- [ ] the DTCG frozen-guard CI test references this skill name

REQ coverage: (internal provenance omitted)..003, (Path A); REQ-1..16 (context).

<!-- absorbed from design-workflow-import + design-workflow-context per the skill consolidation policy -->

