29 KiB
P2 — Design Direction 스테이지 설계
- 날짜: 2026-07-13
- 상태: 설계(brainstorm 승인 + §15 열린항목 결정 + 4 구조수정 반영) — 구현 전
- 관련: design-craft-upgrade, design-system-pipeline, P1 venture-bootstrap
- 로드맵: 리뷰 2번째 핵심결함(디자인 탐색 없이 design-system으로 조기고착) 해소 = P2.
§1. 문제 (리뷰 2번째 핵심결함)
현재 /design-system 파이프라인은 design-brief 세우기 → tokens → components → screens → preview로 바로 들어간다. design-brief의 reference cluster가 탐색 없이 단번에 확정되고, 그 순간 시각 방향이 고착된다. 빠진 것:
- 방향 발산 부재 — 2~3개의 서로 다른 시각 방향을 실물로 세워 비교하는 단계가 없다. LLM은 단일 brief를 generic 평균("modern/clean")으로 채운다(design-craft 근거: vague prototyping = generic, NNGroup).
- 비평 게이트 부재 — generic·미분화 산출을 되돌리는 critique 루프가 없다. preview_ui는 기술 품질(렌더됨·대비·포커스)만 보고 방향의 독창성/일관성은 보지 않는다.
- 조기고착 방지 선행조건 부재 — "방향 승인 전 시스템 고착 금지"가
/design-system진입에 강제되지 않는다. - FAM-DESIGN에 리드 부재 — FAM-CONSULTING(CONSULT-EM)·FAM-DOC-CONSULT(DOC-LEAD)와 달리 FAM-DESIGN에는 발산을 프레이밍하고 수렴을 종합하는
lead-role-id가 없다. - 입력 brief 자체가 조기고착의 원천 — reference cluster·색·typography·layout·token·visual metaphor가 이미 박힌 design brief를 발산의 입력으로 주면 "방향이 정해진 뒤 발산하는" 모순이 된다. 따라서 발산 이전 입력(direction-input-brief)과 승인 이후 시스템 입력(design-system-brief)을 분리해야 한다(§3).
cascade의 design 스테이지는 역할 관점 fan-out(PRD/RFC/data-model/threat-model)이라 시각 방향 발산은 그 안에 없다.
§2. 결정 요약
확정 문장: design-direction은 제품 cascade에 종속된 별도 named child plan이다. UI-bearing standard/heavy 작업에서 강제되며, 독립 발산·단일 방향 수렴·coded prototype·비평 재작업 루프를 state machine으로 보장한다. 승인 결과는 부모 workflow, 제품 결정, direction-input-brief hash에 바인딩되고 /design-system의 선행조건으로 사용된다.
접근법 A(별도 named plan, venture-bootstrap과 동형)를 택한 이유: 리뷰의 결함(탐색 없이 조기고착)을 구조로 막으려면 발산→수렴→비평이 강제 스테이지여야 한다. 게이트+커맨드만(C안)은 P1의 핵심 교훈("prose가 아니라 hook 강제")을 위반하고, cascade design 스테이지 내부 삽입(B안)은 단일 스테이지를 오염시키고 non-UI cascade에 죽은 하위단계를 남긴다.
정제 6종(사용자 승인): ①부모 workflow 바인딩(§3) ②namespaced 스테이지(§4) ③critique 실패 역전이(§4) ④divergence 3안 동일 대표화면 coded slice(§11) ⑤평균금지 스키마 강제(§6) ⑥/design-system 게이트 tier 한정+바인딩+staleness(§7).
4 구조수정(사용자 지시, 구현 계획 전 필수):
- S1. brief 입력/출력 분리 — direction-input-brief(발산 이전) vs design-system-brief(승인 이후). 바인딩·staleness 앵커는 direction-input-brief-sha256(§3).
- S2. approved-direction을 terminal로 — 스테이지별 산출물 재명명: decision→selected-direction, prototype→winner-prototype, critique→design-review, approved(terminal)→approved-direction. critique 통과 전엔 승인 아티팩트가 존재하지 않는다(§4/§5).
- S3. 리뷰 패널(자기승인 차단) — critique는 다관점 패널이 평가, DES-DIRECTOR는 종합만. producer는 자기 방향의 필수 reviewer 불가(§5/§8/§9).
- S4. 방향 독립성 격리 강제 — 3안은 각자 다른 producer-run-id + context-package로 격리 생산, 형제 산출물 must-read 금지(§9/§11).
§15 열린항목 결정: ①/design 자동 spawn + /design-direction 수동 유지(dedup) ②guard_tools 특수보호 없음(불변 report만) ③preview_ui --url-path 미확장(별도 갤러리 패키지) ④secondary-influence-id 제거→adopted-elements 원자 예외 최대1(§6).
§3. child-plan 바인딩 + brief 분리 (정제 ① + 구조수정 S1)
design-direction은 venture-bootstrap 같은 독립 lifecycle이 아니다. 특정 제품 결정에서 파생되는 자식 workflow다.
brief 분리 (S1) — 조기고착 재발 방지
direction-input-brief → design-direction → approved-direction → design-system-brief → design-system
- direction-input-brief(발산 이전 입력): 제품 목표 · 핵심 사용자 · 핵심 작업 · 정보 밀도 · 필수 접근성 · 브랜드 제약 · 피해야 할 클리셰 · 대표 화면 요구 · 기술·플랫폼 제약.
- 포함 금지(넣으면 lint Hard Fail): 최종 reference cluster · 확정 색상 팔레트 · 확정 typography · 확정 layout grammar · 확정 token · 선택된 visual metaphor. (이게 있으면 발산 전에 방향이 고착됨.)
- design-system-brief(승인 이후, 기존
design-brief-spec.yaml의 design-brief 역할): 입력 =direction-input-brief-ref+approved-direction-ref/sha256. reference cluster·색·typography·token은 여기서 승인된 방향으로부터 확정(발명 아님).design-brief-spec.yaml에brief-phase: system-ready와 approved-direction 인용 필드를 추가.
바인딩 메타 (child 원장 state/<wf>/workflow.yaml)
plan: design-direction
parent-workflow-id: product-cascade-001 # 필수 — 부모 제품 cascade wf-id
product-decision-id: PD-001 # 필수 — 부모 decide 산출(ExecutiveDecisionPacket) id
company-context-ref: org-os/01-company/company-context.yaml
direction-input-brief-ref: <path> # 발산 입력(design-brief 아님)
direction-input-brief-sha256: <hash> # staleness 앵커 (§7)
- 바인딩이 없으면 한 제품 방향을 다른 제품/오래된 brief에 재사용할 수 있다 — P1의 company↔product seam과 동형.
state_engine.py init에--parent-workflow,--product-decision,--direction-input-brief인자. 미지정 시 design-direction init 거부(BlockedReport). parent wf-id는 실존 원장, product-decision-id는 부모 원장의 accepted decision-packet과 대조.
부모 원장의 child 등록 (dedup 근거, §10)
child-workflows:
design-direction:
workflow-id: product-001-direction-01
input-brief-sha256: ...
status: running | approved | stale
§4. 스테이지 그래프 (정제 ②③ + 구조수정 S2)
스테이지 (전역 그래프 충돌 방지 위해 전부 접두어)
design-direction-intake
design-direction-discovery
design-direction-divergence
design-direction-decision
design-direction-prototype
design-direction-critique
design-direction-finalize
design-direction-approved # terminal
unified-stage-graph에 위 8개 추가(venture-bootstrap 스테이지 추가와 동형). intake도 일반 cascade intake와 구분. critique pass 직후 바로 approved로 가지 않고 finalize를 하나 더 거친다 — approved-direction 불변 report 작성과 부모 원장 등록(§10)이라는, critique 자체와는 다른 책임을 별도 stage로 분리해 "패널 통과"와 "최종 확정·부모 바인딩"을 섞지 않기 위함이다.
스테이지별 산출물 이름 (S2 — 의미와 상태 일치)
| 스테이지 | 산출 아티팩트 |
|---|---|
| divergence | direction-set(3안, 각 격리 생산) |
| decision | selected-direction(1안 선택 + rejected + locked-invariants, 사람 선택) |
| prototype | winner-prototype(승자 핵심흐름 coded) |
| critique | design-review-panel(다관점 verdict + 종합) |
| finalize | approved-direction(불변 report — 위 전부를 hash로 묶음) + 부모 원장 design-direction-approval 등록 |
| approved(terminal) | (신규 아티팩트 없음 — finalize 산출물의 유효성·해시·바인딩이 8점 검증을 통과했음을 표시하는 종료 상태) |
critique 통과 전에는 approved-direction이 존재하지 않는다(finalize에서 비로소 작성된다). selected-direction은 "선택"이지 "승인"이 아니다.
전이 (선형 아님 — critique 실패 역전이 포함, 전부 allowed-by: [OPS-ORCH])
intake → discovery : parent-binding-present
discovery → divergence : direction-input-brief-valid (S1 포함금지 통과)
divergence → decision : directions-diverged (§9 독립성 6검사)
decision → prototype : selected-direction-accepted (1안 선택 + 사람 acceptance)
prototype → critique : winner-prototype-present
critique → prototype : critique-revision-requested (역전이: minor revision)
critique → divergence : concept-rejection-recorded (역전이: concept flaw)
critique → finalize : direction-critique-passed (패널 pass + winner preview_ui receipt)
finalize → approved : approved-direction-valid + approval-receipt-bound
+ parent-approval-link-recorded (report 확정+hash 일치 + acceptance receipt 바인딩 + 부모 원장 등록)
전이 9종(순방향 7 + 역전이 2).
┌──────────────── concept-rejection-recorded ───────────────┐
↓ │
-divergence → -decision → -prototype → -critique ── pass ──→ -finalize → -approved
↑ │
└── minor rev ─┘
§5. 아티팩트/스키마 (4종)
계약 파일: org-os/06-agent-work/design-direction-spec.yaml(4 아티팩트 함께 정의) + JSON Schema(validator 소비).
(a) direction-set (-divergence 산출)
direction-set:
representative-screen: # 3안이 공유하는 동일 대표 화면 (비교 가능성 핵심)
id: SCREEN-CORE-TASK
kind: first-entry | core-task | signature-moment # 버튼/카드 갤러리 금지
description: ...
directions:
- id: DIR-001
producer-role-id: DES-VISUAL
producer-run-id: RUN-001 # 격리 생산 증거 (S4)
context-package-id: PKG-001
concept-artifact: ...
reference-cluster: # 6집중, 각 '나르는 신호'(형용사 금지)
- { name: ..., signal: ..., why-relevant: ... }
visual-thesis: ...
layout-grammar: ...
interaction-grammar: ...
typography-token-direction: ...
coded-slice: <path> # representative-screen 구현 경량 slice
render-manifest: <ref> # 갤러리 렌더 receipt 참조
(b) selected-direction (-decision 산출 — 사람 선택, 아직 승인 아님)
selected-direction:
selected-direction-id: DIR-002 # 정확히 1개
rejected-directions: # 모든 비선택에 reason 필수
- { id: DIR-001, reason: ... }
- { id: DIR-003, reason: ... }
locked-invariants: [...] # 최소 3개
flexible-elements: [...]
adopted-elements: # optional, 최대 1개 (§6 — 원자 예외, secondary 대체)
- from-direction-id: DIR-001
element-id: typography-scale
description: "본문 크기 비율만 채택"
rationale: "고밀도 데이터 화면 판독성 우수"
affected-invariants: []
parent-workflow-id: ...
product-decision-id: ...
direction-input-brief-sha256: ...
selection-acceptance-receipt: ... # 사람 선택 acceptance
(c) design-review-panel (-critique 산출 — 다관점, S3)
design-review-panel:
target-prototype: <path>
preview-receipt: <ref> # winner 프로토타입 실제 렌더 preview_ui receipt
reviews:
- { reviewer-role-id: DES-PROD, reviewer-run-id: ..., lens: product-fit, verdict: pass, report-ref: ..., report-sha256: ... }
- { reviewer-role-id: UX-RESEARCHER, reviewer-run-id: ..., lens: usability, verdict: ..., ... }
- { reviewer-role-id: DES-VISUAL, reviewer-run-id: ..., lens: distinctiveness, verdict: ..., ... } # producer-run-id와 상이해야
- { reviewer-role-id: DES-PLATFORM, reviewer-run-id: ..., lens: systematizability, verdict: ..., ... }
- { reviewer-role-id: GTM-PMM, reviewer-run-id: ..., lens: market-memorability, verdict: ..., ... }
- { reviewer-role-id: ENG-FE, reviewer-run-id: ..., lens: implementability, verdict: ..., ... }
synthesis:
role-id: DES-DIRECTOR
verdict: pass | minor-revision | concept-flaw
unresolved-dissent: []
distinctiveness/generic-risk 판정 기준(reference-signal-fidelity, generic-adjective-risk="modern/clean"이면 weak, layout-information-hierarchy, token-consistency)은 각 reviewer가 관찰+근거로 기록(자기채점 금지). synthesis.verdict가 §4 역전이 구동.
(d) approved-direction (-finalize 산출 — 불변 report, S2)
-critique pass 직후의 -finalize stage에서 작성된다(terminal인 -approved가 만드는 것이 아니다 — -approved는 이 report의 유효성·hash·acceptance receipt·부모 원장 등록이 전부 확인된 뒤 도달하는 종료 상태). 경로: <workspace>/completion-records/<child-workflow-id>/approved-direction-<timestamp>.report.yaml(불변 report, guard 특수보호 불요).
approved-direction:
selected-direction-ref: ...
selected-direction-sha256: ...
final-prototype-ref: ...
final-prototype-sha256: ...
critique-report-refs: [...]
critique-pass-receipt: ...
locked-invariants: [...]
approved-at: ...
parent-workflow-id: ...
product-decision-id: ...
direction-input-brief-sha256: ...
부모 원장엔 파일 복사 없이 hash-bound 참조만:
design-direction-approval:
report-ref: ...
report-sha256: ...
child-workflow-id: ...
JSON Schema
.claude/schemas/에 selected-direction·design-review-panel·approved-direction schema. (direction-set는 lint가 검사.)
§6. 평균 금지 = 스키마 강제 (정제 ⑤ + secondary 제거)
hook은 시각적 독창성은 판정 못 하나 "선택 대신 평균내는 구조적 실패"는 차단한다. lint_design_direction.py(=lint_company_context.py 형제)의 Hard Fail:
- selected-direction-id 정확히 1개(0·복수 = Hard Fail), direction-set 실존 id.
- 모든 비선택(rejected)에 reason 필수(빈 사유 = Hard Fail).
- locked-invariants ≥ 3.
- rejected ∪ {selected} = direction-set 모든 id(누락·유령 id = Hard Fail).
- secondary-influence-id 필드가 있으면 Hard Fail(제거됨 — 평균의 뒷문).
- adopted-elements: 최대 1개. element-id 필수, rationale 필수. selected의 locked-invariants를 침범하면 Hard Fail. "분위기/감성/스타일" 같은 포괄 표현이면 Hard Fail(원자적 element-id만 허용).
Warning: reference-cluster가 형용사만("modern/clean/minimal/sleek") → generic-risk 경고. direction-input-brief에 §3 포함금지 항목이 있으면 Hard Fail(발산 전 고착 방지).
§7. /design-system 게이트 (정제 ⑥ + 구조수정 gate)
tier 어휘 정합: 사용자 "standard/high" = 하네스 standard/heavy(governance-tiers High: heavy).
UI-bearing 판정 (proxy 아님 — 명시 필드 우선)
부모 decision-brief(ceo-intake 산출)에 명시 필드:
deliverable-profile:
ui-bearing: true
ui-kind: product | admin | internal-tool
governance-tier: standard
판정 우선순위: ① decision-brief ui-bearing 명시값 → ② 산출물 타입/요구에서 파생 → ③ FAM-ENG-FRONTEND 포함 여부(fallback). 누락 + standard/heavy + UI 가능성 있으면 warning 또는 fail-closed(안전측).
게이트
UI-bearing && tier ∈ {standard, heavy} → design-direction-approved 필수 → 없으면 Hard Fail(BlockedReport)
UI-bearing && tier = light → Warning + 기존 승인 방향 있으면 반드시 상속
non-UI → N/A (child plan 생성 안 함)
direction-approved는 boolean 아님 — 바인딩 검사
state_engine._has_direction_approval(wf)(= _has_preview_receipt 형제)가 부모 원장의 design-direction-approval 참조를 따라가 확인:
- approved-direction 불변 report 존재(completion-records 경로)
- schema/validator(lint_design_direction) 통과
- acceptance receipt 존재(acceptance_log accepted, report-sha256 바인딩 — P1 hash 바인딩 재사용)
- report hash 일치(receipt report-sha256 == 실제 파일 hash — 수정 시 mismatch)
- parent-workflow-id 일치
- product-decision-id 일치(부모 accepted decision-packet)
- direction-input-brief-sha256 일치
- critique pass receipt 존재(design-review-panel synthesis=pass + winner preview_ui receipt)
staleness (자동 무효화)
current direction-input-brief-sha256 (실측) != approved.direction-input-brief-sha256 → 승인 무효
매 평가 시 현재 direction-input-brief 파일 hash 재계산 대조(P1 company-context-lint live 평가와 동형). product-decision supersede 시도 무효.
§8. 역할 신설 + 리뷰 패널 (구조수정 S3)
- DES-DIRECTOR: FAM-DESIGN
lead-role-id(synthesis-lead). 발산 프레이밍(discovery→direction-input-brief 정련) + 3안 원본 종합 수렴(decision) + critique 종합(단독 평가자 아님). CONSULT-EM/DOC-LEAD 동형. - DES-VISUAL: FAM-DESIGN fan-out 워커. 방향별 아트디렉션(각 방향 격리 생산, §11).
리뷰 패널(critique 평가자 — DES-DIRECTOR는 종합만):
| lens | 역할 |
|---|---|
| 제품 흐름·핵심 작업 (product-fit) | DES-PROD |
| 사용성·인지부하 (usability) | UX-RESEARCHER |
| 시각적 독창성·일관성 (distinctiveness) | DES-VISUAL(생산 안 한 별도 run) |
| 시스템화 가능성 (systematizability) | DES-PLATFORM |
| 시장 전달·기억성 (market-memorability) | GTM-PMM |
| 구현 손실·기술 가능성 (implementability) | ENG-FE(FAM-ENG-FRONTEND) |
| 최종 종합 | DES-DIRECTOR |
패널 pass 조건(구조화): 필수 reviewer lens 전부 존재 · producer-run-id ≠ 각 reviewer-run-id(생산자가 자기 방향 필수 reviewer 불가) · critical blocker 없음 · 각 review report hash 검증 · DES-DIRECTOR synthesis 존재.
변경 파일: roles.yaml(+2), role-profiles.yaml, role-working-methods.yaml(design-craft 근거 embed), capability-families.yaml(FAM-DESIGN member-role-ids += [DES-DIRECTOR, DES-VISUAL], lead-role-id: DES-DIRECTOR) → gen_agents.py 재생성. roles 73→75, family 28·lens 12 불변.
§9. 강제기 / predicate
state_engine.py (신설)
- predicate:
parent-binding-present,direction-input-brief-valid,directions-diverged,selected-direction-accepted,winner-prototype-present,critique-revision-requested,concept-rejection-recorded,direction-critique-passed,direction-approved(복합 §7). - helper:
_directions_diverged(wf)— S4 독립성 6검사: ① direction ≥ 3 ② producer-run-id 전부 상이 ③ context-package-id 전부 상이 ④ 각 worker의 must-read에 형제 direction 산출물 없음 ⑤ 동일 representative-screen ⑥ 각 coded-slice + render-manifest 존재._selected_direction_ok(wf)(lint 통과 + 평균금지 + adopted-elements 규칙)._critique_panel_ok(wf)(§8 패널 pass 조건 — producer≠reviewer run-id 포함)._has_direction_approval(wf)(§7 8검사 + staleness)._current_input_brief_sha(ref).
_PROTECTED_FACTS에 신규 fact 키 전부 추가(자기신고 차단 — P1 동일).- CLI:
state_engine.py check-direction-approved --workflow WF(advisory 조회, /design-system·/design 진입이 호출).
lint_design_direction.py (신설)
lint_file(path, kind) -> (hard_fails, warnings). §6(selected-direction 평균금지) + direction-input-brief 포함금지(§3) + direction-set 구조 강제. run_all·doctor 배선.
collaboration-map.yaml (수정)
design-to-build-contract에 direction-gate 추가(design-system-gate 형제):
direction-gate:
requires: design-direction-approved
enforced-by: state_engine._has_direction_approval
applies-to: [FAM-ENG-FRONTEND]
hard-if: tier in [standard, heavy] # light: warning + 상속
must-read-designs(FAM-ENG-FRONTEND)에 approved-direction을 선행으로 추가(design-system preview receipt와 함께).
guard_tools.py — 변경 없음 (§15 결정 ②)
approved-direction은 기존 immutable report 경로에 생성, 부모 원장엔 hash-bound reference만. 별도 mutable canonical 파일을 두지 않으므로 특수 직접쓰기 보호 불요. 일반 report immutability로 충분.
§10. 커맨드
/design (수정 — 자동 spawn + dedup, §15 결정 ①)
UI-bearing && tier ∈ {standard, heavy} 판정(§7 우선순위) → 유효 child 없으면 자동 init/spawn → /design-direction 절차 실행 → child approved까지 부모 design 전이 대기.
dedup(중복 생성 방지): (parent-workflow-id + product-decision-id + direction-input-brief-sha256)로 기존 child 검색 —
- 일치 & running → resume
- 일치 & approved → 재사용
- hash 상이 → stale 처리 후 신규 child 생성
사용자가
/design을 돌렸는데 나중에/design-system에서 갑자기 막히지 않도록, 방향 탐색이 필요한 순간(/design)에 child를 자동 시작.
/design-direction (신설 — 수동 진입점 유지)
용도: 독립 실행 · 중단 후 resume · critique 실패 후 재진입 · stale 승인 재생성 · child 복구/디버깅. 인자 --parent-workflow --product-decision --direction-input-brief. 각 스테이지 종료 시 state_engine transition, 산출 시 record + acceptance_log append accepted(P1 deadlock 교훈 — 커맨드 본문에 명시).
/design-review (신설)
critique 패널 실행(§8). 프로토타입 대상 다관점 verdict 산출. -critique에서 호출되거나 임의 프로토타입에 독립 실행.
/design-system (수정)
진입 선행조건에 check-direction-approved. UI+standard/heavy면 승인 없을 시 BlockedReport, light면 경고+상속. 입력 brief = design-system-brief(approved-direction 인용, §3).
§11. divergence 충실도 + 독립성 (정제 ④ + 구조수정 S4 + Q2)
- 각 방향 = concept artifact · reference cluster(6집중) · visual thesis · layout/interaction grammar · typography/token direction · signature interaction · 대표 화면 1개 경량 coded slice.
- 대표 화면 = 첫 진입 / 핵심 작업 / signature moment 중 하나. 버튼·카드 수준 금지. 3안 모두 동일 대표 화면(
representative-screen.id공유, lint 강제). - 독립 생산(S4): 3안은 각자 다른
producer-run-id+context-package-id로 격리 실행. 각 worker의 must-read에 형제 direction 산출물 금지(한 에이전트가 A/B/C를 한 번에 쓰면 표면만 다른 동일 사고 —_directions_diverged가 거부). - 비교 렌더(§15 결정 ③): 3 slice를 별도 Vite 갤러리 패키지의 root(ComparisonGallery)로 묶어 기존
preview_ui.py로 root 1회 렌더 → 3-way PNG(receipt).--url-path확장 없이 최단·재현성._directions_diverged가 이 render-manifest 요구.
design-direction-preview/
src/{DirectionA,DirectionB,DirectionC,ComparisonGallery}.jsx
App.jsx # ComparisonGallery를 root에서 렌더
- 수렴 후
-prototype: 승자 방향 핵심 사용자 흐름 전체 coded →-critique(preview_ui + design-review-panel). 통과 후에야/design-system이 그 방향으로 재사용 토큰+컴포넌트 확장.
§12. 하네스 정합성 영향
- 카운트: roles 73→75(실측). family 28·lens 12 불변. FAM-DESIGN
lead-role-id획득 → gen_agents가 DES-DIRECTOR synthesis-lead + DES-VISUAL 워커 생성. 갱신할 구체 단언:test_enforcement.py:722role-working-methods covers 73 roles→ 75.- FAM-DESIGN
member-role-ids카운트 단언(있으면) 3→5. - gen_agents agent 총수 단언(doctor·test 있으면) 신규 2 반영.
- gen_agents.py 재생성 필수.
.claude/agents/*.md는 생성물 — 수기편집 금지. - doctor.py:
check_design_direction_wiring신설 — 스키마 존재, lint 배선, DES-* 등록, 커맨드→에이전트 참조 무결성. - execution-plans.yaml:
design-directionplan(§4 스테이지 + 바인딩). state-transition-rules.yaml: 전이 8종 + condition-catalog. - design-brief-spec.yaml:
brief-phase: pre-direction | system-ready+ approved-direction 인용 필드 추가(design-system-brief가 승인 방향 소비). - 기존 불변식 유지: report immutability, evidence 등급, 권한(외부 side-effect 기본금지; npm/chrome 로컬빌드 허용), design-brief 없이 컴포넌트 생성 금지.
§13. 테스트 (test_design_direction.py 신설, standalone check() 규약)
기본 8종: ①평균금지 negative(selected 0/2개, rejected reason 누락, locked<3) ②평균금지 positive ③staleness(input-brief sha 불일치→승인 무효) ④바인딩 검사(parent/product-decision 불일치, critique·preview receipt 없음) ⑤게이트 tier 분기(UI+standard 승인없음→Hard Fail; UI+light→Warning; non-UI→N/A) ⑥critique 역전이(minor-revision→prototype, concept-flaw→divergence, pass→approved) ⑦directions-diverged(3안 미만·대표화면 불일치·render-manifest 없음→거부) ⑧바인딩 부재 init 거부.
추가 11종(구조수정 검증): 9. 동일 producer-run-id가 3안 생산 → divergence 거부. 10. DES-VISUAL producer가 자기 방향 필수 reviewer → critique 거부. 11. selected-direction만 있고 최종 approved-direction 없음 → /design-system 거부. 12. critique 전 생성된 approval artifact → 승인으로 불인정. 13. direction-input-brief hash 변경 → child·approval 모두 stale. 14. /design 재실행 시 같은 binding child 중복 spawn 안 하고 resume. 15. 승인 immutable report 수정 → hash mismatch로 게이트 거부. 16. secondary-influence-id가 스키마에 들어오면 거부. 17. adopted-elements 허용량 초과·locked-invariant 침범 → 거부. 18. ui-bearing=true + standard/heavy인데 child 없음 → /design 자동 생성. 19. ui-bearing=false → child plan 생성 안 함.
§14. 비목표 (YAGNI)
- 시각적 독창성 자동 정량 판정(hook이 미적 채점) — hook은 구조적 평균금지·바인딩·격리·렌더 receipt만 강제, 미적 판단은 패널/사람.
- 3안 각각 풀 프로토타입 — divergence는 동일 대표화면 slice만, 풀은 승자만.
- preview_ui
--url-path다중 route 순회 — 별도 갤러리 패키지로 대체(실제 요구 생기면 후속). - Figma MCP·비주얼 회귀 스냅샷 diff — 후속.
- 제품 cascade 밖(마케팅 사이트 등) 적용 — 우선 제품 child로 검증 후.
§15. 열린항목 — 결정 완료
- 자동 spawn + 수동 유지:
/design이 UI+standard/heavy에서 child 자동 init/spawn(dedup),/design-direction은 독립·resume·재진입·재생성·복구용 수동 진입점 유지(§10). - guard_tools 특수보호 없음: approved-direction은 immutable report 경로에 생성, 부모 원장엔 hash-bound reference만. mutable canonical 파일 없음 → 일반 report immutability로 충분(§9).
- preview_ui 미확장: 비교 갤러리를 별도 Vite 패키지 root로, 기존 preview_ui root 1회 렌더(§11).
- secondary-influence-id 제거: 평균의 뒷문. 대신 원자적
adopted-elements최대 1개(element-id+rationale 필수, locked-invariant 침범·포괄표현 금지, §6).
§16. 구현 체크리스트
design-direction-spec.yaml(direction-set/selected-direction/design-review-panel/approved-direction + direction-input-brief) + 3 JSON Schemadesign-brief-spec.yaml에 brief-phase + approved-direction 인용(design-system-brief 분리)- roles/role-profiles/role-working-methods/capability-families에 DES-DIRECTOR(lead)+DES-VISUAL → gen_agents 재생성
- execution-plans.yaml
design-directionplan(namespaced 스테이지 + 바인딩) - state-transition-rules.yaml 전이 8종(역전이 2) + condition-catalog
- state_engine.py predicate/helper(독립성 6검사·패널·8검사·staleness)/_PROTECTED_FACTS/CLI + init 바인딩 인자
- lint_design_direction.py(평균금지·포함금지 Hard Fail) + run_all/doctor 배선
- collaboration-map.yaml direction-gate + must-read
- /design(자동 spawn+dedup) · /design-direction · /design-review · /design-system 선행조건
- test_design_direction.py(19종) + 카운트 단언 갱신(test_enforcement:722 →75) + doctor check
- 전체 green(run_all) + doctor OK