12 KiB
description
| description |
|---|
| 기존 프로젝트를 먼저 discovery하고 reuse/adapt/create를 판단한 뒤, design-brief(제약층)에서 코드 디자인 시스템+화면을 만들고 headless chrome으로 실제 UI를 렌더·품질검증한다. Figma 불필요·rate-limit 없음. |
당신은 Orchestrator다. DESIGN-SYSTEM — 상위 제약(design-brief)에서 코드 디자인 시스템 + 화면 + 실제 UI 미리보기·품질검증을 산출한다.
입력(인자): 주제/제품 + 대상 디렉터리(기본 design-system/). 예: /design-system <프로젝트> 개발자 콘솔 · dir=design-system.
층 관계(중요): design-brief=제약(무엇을), design-craft skill=방법(어떻게), 디자인 시스템=코드로 굳힌 tokens+컴포넌트(재사용 실체), 프론트 코드=매체. DESIGN.md·skill의 대체가 아니라 완성이다.
조직 정본은 org-os/08-design/이다. generated/DESIGN.md는 그 정본에서 생성된 도구 어댑터일 뿐이며 제품 전략·IA·와이어프레임을 대신하지 않는다. 프로젝트는 전체 정본을 복사하지 않고 selected release exact ref/SHA + component subset + 명시적 delta만 ui-design.design-system-bindings에 연결한다.
대원칙: 스택을 못박지 않는다. discovery가 정한다. 기존 프로젝트가 있으면 그 stack·토큰·컴포넌트를 먼저 재사용한다. 스택은 고정값이 아니라 **preset(선택지)**다 — 그린필드일 때만 greenfield-react 프리셋을 쓴다. 예전처럼 React+CSS+Vite를 전사 기본으로 강제하면, 이미 Vue/Tailwind/디자인시스템/브랜드가 있는 프로젝트를 무시하고 밀도·컨벤션이 안 맞는 화면을 찍어낸다.
절차
- Pre-work:
report_tags.py --tag <주제>로 관련 과거 결정 must-read. workflow-id 정한다(wf-<slug>).
0b. design-direction 승인 게이트(Task 13 — Blocker 10): /design-system은 /design 3b를 거치지 않고 단독으로도 호출될 수 있으므로, 여기서 다시 확인한다 — design.md의 선행 게이트를 우회해 곧장 이 커맨드로 들어오는 경로를 막는다. 부모 cascade workflow(<PARENT-cascade-wf> — 이 design-system 작업이 속한 상위 제품 cascade. design-direction child workflow가 아니다)를 대상으로:
python3 .claude/hooks/state_engine.py check-direction-approved --workflow <PARENT-cascade-wf>
부모로 질의해야 하는 이유: _has_direction_approval의 parent-shape 는 child 가 design-direction-approved stage 까지 실제로 종료됐음을 요구한다 — child workflow-id 로 질의하면 design-direction-finalize 단계에서도 YES 가 나올 수 있어 "전이 가능"과 "최종 승인"을 혼동한다(design-direction.md 6번 참고).
- standard/heavy tier +
NO(exit 3) → 진행하지 않는다. BlockedReport(사유: 승인된 design-direction 없음 — 먼저/design-direction을 완주하거나/design의 선행 게이트를 통해 진입해야 함)를 내고 종료. - light tier +
NO→ 하드 블록 아님. 경고를 report-header risks 에 남기고, 기존에 부모 원장에 기록된 승인이 있으면(과거 cycle) 그것을 상속해 진행한다(없으면 승인 없이 진행 — light 는 과설계 금지 원칙상 허용). YES(exit 0) → 정상 진행.- brief-phase 요구: 이 게이트를 통과했다는 것은 design-direction 이 이미
finalize(brief-phase=system-ready 로 취급)를 지났다는 뜻 — 이 커맨드는 그 승인된 방향의 locked-invariants/selected-direction 을 존중하며 시스템을 만든다(방향을 재발산하지 않는다).
0c. experience + 조직 release 게이트:
python3 .claude/hooks/state_engine.py check-experience-foundation --workflow <PARENT-cascade-wf>가NO면 해당 workload가 요구하는 foundation을 먼저 완주한다.python3 .claude/hooks/compile_design_system.py --check후python3 .claude/hooks/design_registry.py --surface <surface> --state <candidate|stable>로 필요한 최소 subset을 조회한다.org-os/08-design/releases/<version>.yaml의 exact SHA와 release-id, component-ids, 프로젝트 delta(tokens/components)를ui-design.design-system-bindings에 기록한다. release state와 project delta는 별도이며 로컬 복제를 stable 정본처럼 승격하지 않는다.
-
① DISCOVERY (필수·최우선 — brief보다 먼저): 대상 프로젝트에 기존 시스템이 있는지 먼저 조사한다. 아무 것도 조사하지 않고 스택을 고르는 것은 금지.
- stack:
package.json/lockfile/설정으로 프레임워크(React/Vue/Svelte/…)·번들러(Vite/Next/…)·언어·CSS 방식(CSS변수/Tailwind/CSS-in-JS) 식별. (없으면 = greenfield) - design-system: 기존 디자인시스템/컴포넌트 라이브러리/테마 존재 여부·위치(예:
design-system/,packages/ui, MUI/Chakra/자체). - tokens·brand: 기존 토큰 SoT(CSS 변수/theme 파일)·브랜드 색·타이포·로고·간격 규율.
- components: 재사용 가능한 기존 컴포넌트 인벤토리(무엇이 이미 있나 → 다시 만들지 말 것).
- data-density: 데이터 밀도(대시보드/테이블 과밀 vs 마케팅/저밀도) — 토큰·레이아웃 결정에 직결.
- 산출: discovery 노트를
design-brief.yaml의existing-system(있으면)에 기록.
- stack:
-
② 판단: reuse / adapt / create (근거를
design-brief.yaml의stack-decision에):- reuse — 적합한 기존 디자인시스템/토큰/컴포넌트가 있으면 그것을 소비한다. 새 시스템을 만들지 않는다. 대상 디렉터리 대신 기존 컴포넌트·토큰 위에서 화면을 조립.
- adapt — 부분적 시스템(토큰만/일부 컴포넌트)이면 그 컨벤션 안에서 확장한다. 새 축을 함부로 도입하지 않는다.
- create — 기존 시스템이 없거나(그린필드) 부적합하면 preset을 골라 새로 만든다.
- preset
greenfield-react: React + CSS 변수(tokens.css) + Vite. (이것이 유일한 preset이 아니라 그린필드 React용 기본 preset이다.) - 대상 프로젝트가 이미 다른 스택이면 create여도 그 스택의 토큰·컴포넌트 관례를 따른다(React를 강요하지 않는다).
- preset
-
③ design-brief (skill:
design-craft+design-brief-spec.yaml): 대상에design-brief.yaml을 세운다 — brief(무엇/누구/달성) → references(구체 신호 3~6, "modern/clean" 금지) → tokens(값+의도+경계) → decisions(판단로직) → donts(5+). references·tokens는 discovery 결과(기존 브랜드·데이터밀도)를 반영한다(빈 추론층=generic). 이게 없으면 컴포넌트 생성 금지. -
④ 구현 (판단에 따라):
- reuse/adapt — 기존 토큰/컴포넌트 위에서 화면(screens)을 조립. 기존 컴포넌트에 없는 것만 그 시스템의 관례로 추가.
- context-package(spawn 전 필수 게이트, finding P0-2):
des-platform및 FAM-ENG-FRONTEND 후보에서 planner가 고른 concrete role을 띄우기 전python3 .claude/hooks/context_package.py --compile … && python3 .claude/hooks/context_package.py <pkg>(exit 0)로 패키지를 만들고, 출력된 package path/hash를 spawn 프롬프트에 포함한다. design-brief는 must-read/shared-constraints로 동봉한다. - create · greenfield-react preset (subagent
des-platform→ 선택된 frontend concrete role):src/tokens.css— 토큰을 CSS 변수로(값+경계 주석).--accent는 primary/focus 전용 등 경계 반영.src/components/*.jsx(+components.css) — Button(variant)·Card·Input 등 재사용 컴포넌트, 토큰만 소비(var(--*), 하드코딩 색 금지). 컴포넌트별 판단로직·금지 반영.:focus-visible가시 표식 필수(outline을 죽이면 box-shadow 등으로 대체).src/screens/*.jsx— 컴포넌트를 조립만(새 스타일 금지).src/preview.jsx에 컴포넌트 갤러리 + 화면 + 상태(loading/empty/error/overflow) 데모를 건다.
- 근거·산출은
.report.yaml(report-header BLUF).
-
⑤ 미리보기 + 품질 게이트(실제 UI 검증):
python3 .claude/hooks/verify_run.py --workflow <wf> --agent <role> --session <id> --category acceptance-criteria --subject ui-render-gate [--source-revision-sha256 <sha>] -- python3 .claude/hooks/preview_ui.py <dir> --out <dir>/preview.png --viewports 360,768,1280 --check-css [--states "loading=/#/loading,empty=/#/empty,error=/#/error"]→ npm install→vite build→로컬서버→렌더 검증(dump-dom)+반응형 스크린샷+정적 CSS 품질(대비·포커스). Figma·rate-limit 없이 실제 렌더. 중요 — 스크린샷 존재 ≠ 품질: preview_ui는 build 성공+PNG 존재만으로 통과시키지 않는다. 앱이 런타임에 안 붙어#root가 비면(빈 화면), 빌드가 빈 번들이면, WCAG 대비가 critical이면, 포커스 표식이 없으면 **게이트가 실패(비영점)**한다. 스크린샷을 읽어 육안 검증도 병행(accent 남발·하드코딩색·정렬·클리핑·데이터밀도). -
⑥ 게이트/보고: report-header(BLUF)로 종합 + 산출 경로(패키지·PNG들·게이트 결과). 게이트 실패 시 고치고 preview 재실행(개선 루프).
python3 .claude/hooks/lint_design_system_adherence.py --ui-report <ui-design.report.yaml> --target <dir>로 release SHA, raw color token, local component-id 중복, 조직 component의 무신고 로컬 재구현을 검사한다. 정당한 로컬 확장만delta.components에 id와 사유를 남긴다. DESIGN.md 변경 검토는python3 .claude/hooks/compile_design_system.py --diff <project-DESIGN.md>로 정본 대비 unified diff를 확인한다.
스택 (preset — 고정 아님)
기본 스택은 없다. discovery가 결정한다.
- 기존 프로젝트 있음 → 그 stack/tokens/components 우선 재사용(reuse/adapt). 다른 스택을 덮어씌우지 않는다.
greenfield-reactpreset(그린필드 React용): React + CSS 변수 + Vite. tokens는tokens.css의 CSS 변수 = design-brief 토큰 1:1(SoT). 컴포넌트는var(--*)만 소비(하드코딩 색 금지). Tailwind-first(토큰 갇힘)·순수HTML(컴포넌트 없음) 아님.- 그 외 스택(create이지만 non-React) → 해당 생태계의 토큰·컴포넌트 관례로.
규칙 / 불변식
- discovery-first: 기존 stack/design-system/brand/components/data-density를 조사하지 않고 스택을 못박지 않는다. 기존 시스템이 있으면 create보다 reuse/adapt 우선.
- design-brief 없이 컴포넌트 생성 금지(제약>묘사). references는 형용사가 아니라 구체 신호(기존 브랜드·밀도 반영).
- 컴포넌트는 토큰만 소비 — 하드코딩 색 금지(component CSS에 hex 금지, 토큰은 tokens.css/기존 토큰 SoT에만).
- 화면은 컴포넌트 조립 — 화면에서 새 컴포넌트 스타일을 만들지 않는다(디자인 시스템 SoT 보존).
- 품질은 게이트를 통과해야 성립: preview_ui의 렌더 검증·대비·포커스·반응형 게이트를 통과하지 못하면 "완료"가 아니다. 스크린샷 존재만으로 품질 주장 금지. 품질은 반복 개선 루프(build→검증→고치기)에서 나온다 — 무료 Figma와 달리 여기선 무제한.
- report-header 없이 종료 금지. evidence 실존. external side-effect(배포/PR 등) 기본 금지 — npm/vite/chrome 로컬 빌드는 허용 범위.
산출/handoff
<dir>/(또는 reuse 시 기존 시스템 위): design-brief.yaml(+existing-system·stack-decision)·tokens·components·screens·preview +preview.png(들, 반응형).- engine 선택은 tool-neutral이다. local HTML/Stitch/Figma/v0/Framer 중 가용 adapter를 쓰되
.claude/schemas/design-engine-output.artifact.schema.json의screen-refs/editable-source/preview-url/screenshots/design-system-ref/source-provenance/verification을 항상 내고validate_design_engine_output.py로 검증한다. - 다음: 실제 제품 연결은 이 컴포넌트로 화면 확장(
/build), 또는 디자인 검토가 필요하면 이 코드를 Figma로(선택, gated).