Files
company-haness/.claude/commands/design-direction.md
T

21 KiB

description
description
direction-input-brief(불변)를 입력으로 discovery→3안 독립발산→단일수렴(평균금지)→승자 prototype→비평 재작업 루프→finalize를 거쳐 approved-direction을 산출한다. 제품 cascade 종속 child(1회성 사이클), 모든 전이는 OPS-ORCH 집행.

당신은 Orchestrator다. design-direction — 제품 cascade(/design)에 종속된 child plan이다(execution-plans.yaml design-direction). 입력은 부모 workflow <p>가 이미 /decide에서 accepted한 product-decision report-id <PD>와, 부모가 발산 이전에 불변화(freeze)한 direction-input-brief 경로다. 공개 웹·신규 제품·대규모 리디자인이면 부모의 /experience-foundation이 이미 approved여야 하며, brief는 accepted competitive benchmark/experience blueprint/wireframe set exact ref+SHA를 포함한다. 이 IA·콘텐츠·screen purpose는 세 방향 모두 동일하다. 브리프는 여기서 만들지 않고 수정하지도 않는다(발산 이후 항목인 reference-cluster/color-palette/typography/layout-grammar/tokens/visual-metaphor가 섞여 있으면 python3 .claude/hooks/lint_design_direction.py <brief> direction-input-brief가 거부한다 — 발산 전 고착 방지). 모든 상태 전이는 OPS-ORCH가 집행한다(워커·des-director·des-visual은 보고서만 생산).

활성 cycle 포인터: design-direction-active는 읽기 전용이며 canonical artifact-submitted 이벤트 순서에서 각 artifact-kind의 최신 revision을 사용한다.

0. dedup — 동일 바인딩(parent+product-decision+brief-hash) 중복 방지

  1. brief의 sha256을 계산한다(dedup·staleness 판정에 쓴다).
  2. 기존 자식 조회:
    python3 .claude/hooks/state_engine.py find-child-direction --parent-workflow <p> --product-decision <PD> --direction-input-brief-sha256 <brief-sha256>
    
    • 없음(None) → 신규 cycle. 새 child workflow-id를 정한다(예: <p>-direction-<PD 앞 8자>, 사람이 추적 가능하면 형식은 자유 — dedup은 이름이 아니라 원장의 parent-workflow-id+product-decision-id 필드로 판정된다).
    • 있고 stage != design-direction-approved 이며 stale=False(브리프 해시 동일)running: 그 workflow-idresume한다 — 현재 stage에서 guard로 다음 스테이지 가능 여부만 확인하고 이어서 진행(처음부터 다시 밟지 않는다).
    • 있고 stage == design-direction-approved 이며 stale=Falseapproved 재사용: 이미 승인된 방향이 있다. 새로 발산하지 않고 그 child의 approved-direction report를 그대로 반환한다(멱등).
    • 있고 stale=True(그 사이 브리프가 바뀜) → 기존 child는 낡은 바인딩이다. 과거 child는 건드리지 않고(불변 이력 보존) 새 child workflow-id로 신규 cycle을 연다.
  3. init(신규/resume 공통, idempotent): python3 .claude/hooks/state_engine.py init --workflow <child> --plan design-direction --parent-workflow <p> --product-decision <PD> --direction-input-brief <brief-path> 부모 원장 실존 + <PD>가 부모에서 정확히 accepted 됐는지(위조/substring 우회 불가, _al_accepted_ids) + brief 파일 실존을 검증한 뒤에만 원장을 만든다(위반 시 exit 1, 원장 미생성). 이미 원장이 있으면 그대로 반환(overwrite 없음). stage는 자동으로 design-direction-intake.
  4. intake 완료 → discovery 진입: guard --workflow <child> --to design-direction-discovery가 parent binding과 brief lint를 통과하면 complete-stage --workflow <child> --actor OPS-ORCH --to design-direction-discoveryenter-stage --workflow <child> --to design-direction-discovery --actor OPS-ORCH를 실행한다.

0.5 pre-direction — DES-PROD 제품/UX 프레이밍 (frame-divergence 선행 input, 필수)

왜 이 스텝이 있나(F3 fix, 2026-07-16 실측): §1 discovery의 method인 DES-DIRECTOR/frame-divergence 계약의 required-inputsDES-PROD/pre-direction 이 same-workflow Accepted 로 산출한 direction-input-brief 를 요구한다(org-os/00-role-registry/role-working-methods/design.yaml, 둘 다 active). 이 스텝을 건너뛰면 §1의 des-director spawn이 context_package.py handoff 게이트에서 handoff input:direction-input-brief 부재hard block 된다(과거엔 이 스텝이 문서에 없어 사이클이 첫 spawn에서 막혔다). 브리프 파일은 부모 /design이 동결하지만, 계약이 요구하는 Accepted upstream 산출물은 여기서 DES-PROD가 만든다 — 제품/UX 프레이밍이 비주얼 발산 프레이밍보다 앞서는 더 풍부한 흐름이다.

des-prod(role-id DES-PROD, method-id pre-direction)를 context-package로 spawn(mode=converge, must-read=direction-input-brief + 부모 product-decision, task-boundaries에 brief 수정 금지·비주얼 해법 지정 금지). DES-PROD는 동결 브리프를 분석·정당화(수정 아님)하여, 대표화면이 왜 signature moment인지와 3안이 두고 갈라질 divergence-axes 후보(≥2, tension만 — 구체 팔레트/타이포/레이아웃/메타포 금지)를 낸다. 이 리포트의 primary-artifact 는 동결 브리프.

  • new_report.py --workflow <child> --role DES-PROD --stub --artifact-kind pre-direction-framing --stage design-direction-discovery로 typed envelope를 발급해 채운다(report-header BLUF 필수).
  • 등재: artifact-kind: pre-direction-framing으로 submit-artifact --actor OPS-ORCH.
  • 수용: producer DES-PROD와 다른 DES-DIRECTOR가 review-artifact --decision accepted --reviewer DES-DIRECTOR로 정확한 revision을 승인한다.
  • 이 뒤 §1의 des-director context-package 검증이 통과한다(handoff input 충족). context_package --role 은 소문자 카드명(des-prod/des-director)으로 넘긴다 — 카드 파일명과 case-verbatim 일치해야 함(F2).

1. design-direction-discovery — 불변 brief 분석 + 발산 영역 계약

des-director(DES-DIRECTOR)를 context-package로 spawn(mode=converge, must-read=direction-input-brief만 — 다른 방향 자료 없음, task-boundaries에 brief 수정 금지를 명시). direction-input-brief를 분석만(수정 아님) 하여 findings·constraints-restated·opportunity-notes를 낸다. 이때 브리프의 representative-screen-requirement를 구체 화면 하나(id/kind/description, kind ∈ first-entry|core-task|signature-moment)로 못박는다 — 다음 divergence의 3안이 전부 이 화면을 구현한다.

  • new_report.py --workflow <child> --role DES-DIRECTOR --stub --artifact-kind direction-discovery --stage design-direction-discovery로 envelope를 발급하고 payload에 필수 필드를 쓴다.
  • 린트: python3 .claude/hooks/lint_design_direction.py <path> direction-discovery(hard fail 0).
  • 등재: artifact-kind: direction-discoverysubmit-artifact --actor OPS-ORCH.
  • 이어서 DES-DIRECTOR가 **별도 divergence-charter**를 만든다. direction-set이라는 이름을 여기서 쓰지 않는다 — charter는 작업 전 지시서이고 direction-set은 작업 후 결과 묶음이다. charter는 정확히 3개 방향에 대해 design-question·layout-topology·navigation-model·typography-voice·imagery-strategy· motion-model·dominant/exclusive/forbidden-primitives를 정의하고, 모든 방향 쌍이 6개 축 중 최소 4개에서 갈라짐을 pairwise-separation으로 증명한다. 팔레트 이름만 다르거나 같은 centered-card shell을 공유하면 lint hard fail이다.
  • new_report.py ... --artifact-kind divergence-charter --stage design-direction-discovery로 발급 → lint_design_direction.py <path> divergence-charter → submit → producer와 다른 design-approver가 accepted.
  • 완료/진입: direction-discovery와 accepted divergence-charter가 모두 있을 때만 complete-stage --to design-direction-divergenceenter-stage --to design-direction-divergence.

2. design-direction-divergence — 3안 독립 발산(평균 없음)

des-visual(DES-VISUAL)을 3개의 완전히 격리된 subagent로 띄운다. 이 workflow는 판단 난도가 높으므로 tier: light를 사용할 수 없다(최소 standard). 각 run은:

  • 별도 --task(예: direction-a/direction-b/direction-c)로 python3 .claude/hooks/context_package.py --compile --workflow <child> --task direction-a --role DES-VISUAL --mode divergent --tier <tier>를 각각 컴파일 → context_package.py <pkg> exit 0 검증 → 출력된 context-package:/context-package-sha256: 2줄을 그 spawn 프롬프트 최상단에 포함(guard_tools spawn gate 강제). 이 패키지의 sha256이 그 방향의 context-package-id가 된다.
  • OPS-ORCH가 spawn 직전 발급하는 고유 값(예: <child>-divergence-<task>-<UTCstamp>)을 producer-run-id로 그 워커에 전달 — 워커는 자기 산출물의 producer-run-id 필드에 그대로 echo한다. 3개 run 모두 값이 달라야 하고(hard fail — _directions_diverged), 이 값들은 나중에 /design-review의 distinctiveness 리뷰어가 이 run과 겹치지 않는지 판별하는 기준이 된다.
  • must-read/non-goals에 형제 방향의 산출물·경로를 명시적으로 배제한다. must-read는 direction-input-brief + direction-discovery + 자기 id의 divergence-charter 항목이다. 다른 방향 charter 항목과 산출물은 읽지 않는다.
  • 각 run은 동일한 의미적 signature moment를 자기 charter의 조형 영역에서 구현한다. direction-set에는 reference-cluster(3~6, 방향 쌍 name 중복 최대 1)·visual thesis·layout/interaction grammar·typography-token direction·primitive-inventory와 함께 hash-bound reference-board·full-size-preview·coded-slice를 넣는다. foundation 적용 작업은 direction-set top-level에 experience-blueprint/wireframe-set exact ref+SHA를, 각 방향에 동일한 content-contract-sha256: <wireframe-set SHA>를 기록한다.
  • 각 방향을 같은 실제 viewport에서 개별 full-size로 렌더한다. 비교 이미지는 그 PNG들의 contact sheet로 만들며, 세 앱을 좁은 iframe 세 칸에 넣어 responsive breakpoint를 왜곡하지 않는다. preview_ui.py receipt는 build/DOM/contrast/focus/viewport의 render-health 증거일 뿐 심미 품질 증거로 부르지 않는다.
  • new_report.py ... --artifact-kind direction-set --stage design-direction-divergence로 발급한 envelope payload에 direction-cycle-id·representative-screen·directions·comparison-preview를 넣고 divergence-charter-ref+sha256으로 작업 전 계약에 바인딩한다. 린트는 envelope payload를 검증한다.
  • 세 안은 동일한 accepted blueprint/wireframe의 콘텐츠·IA·task/state contract를 사용한다. 바꾸는 것은 visual/interaction expression이며, 정보구조를 바꿔 서로 다른 문제를 푸는 것처럼 보이게 하지 않는다. 품질 평가는 absolute 점수만 쓰지 않고 benchmark의 table-stakes/avoid/differentiation에 대한 pairwise 비교를 기록한다.
  • 선택 전 비교감사(필수): 새 DES-VISUAL run을 method-id: compare-directions로 spawn한다. 이 run만 sibling isolation의 예외이며 charter·3안 원본·reference board·full-size preview를 모두 읽는다. 모든 방향 쌍을 layout/navigation/type/imagery/motion/primitives 6축으로 비교하고 4축 미만 차이, 공통 primitive shell, reference 과다중복을 blocking으로 기록한다. comparative-divergence-audit verdict는 pass|revise|re-diverge. foundation 적용 작업은 competitive benchmark exact ref+SHA 및 최소 3개의 benchmark-relative-findings(table-stakes/avoid/differentiation 대비)를 추가한다.
  • lint_design_direction.py --divergence-bundle <audit> <direction-set> <charter> 통과 후 audit를 submit하고, producer와 다른 DES-DIRECTOR가 accepted한다. audit pass 전에는 decision 진입 불가다.
  • 등재 + 완료/진입: directions-divergeddivergence-audit-passed가 모두 참일 때만 complete-stage --to design-direction-decisionenter-stage --to design-direction-decision.

3. design-direction-decision — 단일 수렴(평균 금지)

des-director(DES-DIRECTOR, synthesis-lead)가 3안의 원본(coded-slice·개별 report)을 전부 읽는다(synthesis-rehydration, 요약 아님). HUMAN-001의 결정은 A/B/C/NONE이다.

  • A/B/C: selection-decision: selected와 정확히 1개 selected-direction-id를 기록한다. rejected-directions는 나머지를 모두 덮고, locked-invariants ≥3, adopted-elements 최대 1개다.
  • NONE: selection-decision: none-of-the-above, selected id/locked/adopted 요소 없이 세 안을 모두 사유와 함께 reject한다. 엔진은 prototype으로 보내지 않고 design-direction-discovery로 되돌린다. 세 안을 평균내거나 가장 덜 나쁜 안을 고르지 않는다. 어느 경우든 secondary-influence-id 필드는 절대 넣지 않는다. direction-set-ref+direction-set-sha256로 direction-set에 바인딩하고 parent-workflow-id/product-decision-id/direction-input-brief-sha256를 그대로 echo한다.
  • 린트(번들 검증): python3 .claude/hooks/lint_design_direction.py --bundle <selected-direction-path> <direction-set-path>.
  • 수용: 시각 방향은 취향·브랜드 판단을 포함하므로 HUMAN-001이 review-artifact --decision accepted --reviewer HUMAN-001로 승인한다. EXEC-CPO/에이전트 단독 승인은 상태엔진이 거부한다.
  • 등재 + 완료/진입: HUMAN-001 승인 뒤 selected면 prototype으로 진행한다. none-of-the-above면 complete-stage --actor OPS-ORCH --to design-direction-discoveryenter-stage --to design-direction-discovery --actor OPS-ORCH로 돌아가 brief framing을 재검토한다.

4. design-direction-prototype — 승자 핵심흐름 coded prototype

승자 방향의 locked-invariants/adopted-elements를 그대로 지키며 DES-VISUAL+ENG-FE가 대표 화면 하나가 아니라 **핵심 흐름(core-flow, 여러 화면/상태)**을 코드로 확장한다. 이 단계에서는 방향 전용 토큰만 쓰며, DES-PLATFORM의 공용 컴포넌트/시스템화는 visual-craft pass 뒤 /design-system에서 한다. 거친 탐색값을 일찍 시스템화해 generic component shell로 굳히지 않는다. revision은 첫 사이클이면 1, critique 재작업이면 +1.

  • python3 .claude/hooks/preview_ui.py <prototype-dir> --out <prototype-dir>/preview.png --viewports 360,768,1280 --check-css [--states "loading=...,empty=...,error=..."] → 이 receipt가 preview-receipt-ref/preview-receipt-sha256.
  • artifact-kind: winner-prototype, stage=design-direction-prototype envelope payload에 direction-cycle-id, selected-direction-ref+sha256, prototype-path+sha256, preview-receipt-ref+sha256, revision을 쓴다. 린트는 payload를 검증한다.
  • 등재 + 완료/진입: winner-prototype submit 후 complete-stage --actor OPS-ORCH --to design-direction-critiqueenter-stage --to design-direction-critique --actor OPS-ORCH.

5. design-direction-critique — /design-review 7-lens 패널 → verdict로 라우팅

/design-review --workflow <child>를 호출한다(패널 절차는 design-review.md 참고 — producer-run-id ≠ reviewer-run-id를 그 커맨드가 강제한다). 반환된 design-review-panel 아티팩트를 이 커맨드가 등재하고 전이를 라우팅한다(design-review.md 자체는 상태를 전이시키지 않는다):

  • 등재: artifact-kind: design-review-panelsubmit-artifact.
  • verdict = passcomplete-stage --actor OPS-ORCH --to design-direction-finalize --evidence <panel-path>enter-stage --to design-direction-finalize --actor OPS-ORCH.
  • verdict = minor-revisioncomplete-stage --actor OPS-ORCH --to design-direction-prototype --evidence <panel-path>enter-stage --to design-direction-prototype --actor OPS-ORCH. 같은 cycle/selected-direction을 유지하고 revision만 올린다.
  • verdict = concept-flawcomplete-stage --actor OPS-ORCH --to design-direction-divergenceenter-stage --to design-direction-divergence --actor OPS-ORCH. 새 cycle artifact는 새 id로 submit한다.

6. design-direction-finalize — approved-direction 불변 report + 부모 원장 기록

approved-directionlint_design_direction.py에 전용 kind가 없다 — 별도 lint 커맨드로 미리 검증할 수 없으며, state_engine.py전이 시점에 _has_direction_approval으로 링크·id·hash·receipt 바인딩만 검증한다. 따라서 direction-cycle-id·critique-report-refs·critique-pass-receipt·locked-invariants·approved-at 등 설계 명세의 구조적 필드 존재는 lint로 강제되지 않는다 — operator가 수동으로 ensure해야 한다.

des-directorartifact-kind: approved-direction report를 불변 경로에 쓰고 submit-artifact --actor OPS-ORCH로 등록한다.

  • 수용: producer와 다른 EXEC-CPO가 review-artifact --decision accepted --reviewer EXEC-CPO로 승인한다.
  • 부모 원장 기록(유일한 등록 경로): python3 .claude/hooks/state_engine.py register-direction-approval --parent-workflow <p> --child-workflow <child> --report <workspace-상대경로> --report-sha256 <sha> — child stage가 finalize/approved인지, report 파일 실존+hash 일치, 부모에 기존 충돌 approval이 없는지 전부 재검증한 뒤에만 부모 원장에 design-direction-approval(report-ref/report-sha256/child-workflow-id)을 기록한다(guard_tools가 직접 YAML 편집을 막으므로 이 CLI가 유일한 경로).
  • 완료/진입: exact 8점 approval 검증이 통과하면 complete-stage --workflow <child> --actor OPS-ORCH --to design-direction-approved --evidence <report-path>enter-stage --workflow <child> --to design-direction-approved --actor OPS-ORCH, 마지막으로 terminal stage를 complete-stage로 닫는다.
  • 다음: 부모 cascade는 python3 .claude/hooks/state_engine.py check-direction-approved --workflow <p>(부모 workflow로 질의 — child로 질의하면 finalize에서도 YES가 나올 수 있어 "전이 가능"과 "최종 승인"을 혼동한다)로 승인 완료를 확인하고 /design-system·/spec으로 진행한다.

규칙 / 불변식

  • 격리: divergence의 3 run과 critique의 7 lens는 각자 독립 context-package로 spawn한다 — 형제의 산출물을 must-read에 넣지 않는다(발산·비평의 다양성이 여기서 나온다).
  • 격리 예외: comparative-divergence-audit만 세 방향 원본을 함께 읽는다. 비교 렌즈를 격리하면 "다르다"는 주장을 검증할 수 없다.
  • 리뷰 veto: critique는 7개 lens 모두 pass여야 한다. distinctiveness/visual-craft concerns, blocking·critical finding, unresolved-dissent는 DES-DIRECTOR synthesis가 덮을 수 없다.
  • 평균 금지: decision은 정확히 1개를 고르거나 none-of-the-above로 전부 거절한다(secondary-influence-id 금지). adopted-elements는 최대 1개, locked-invariants는 침범 불가.
  • producer ≠ reviewer: 어떤 divergence run이 만든 방향도 critique에서 자기 자신을 심사하지 않는다(/design-review 참고).
  • 스크린샷 존재 ≠ 품질: preview_ui.py는 반드시 실제로 실행해 evidence-ledger receipt(exit 0)를 남긴다 — 문서만으로 렌더를 위장할 수 없다.
  • 모든 상태 전이는 OPS-ORCH가 집행한다(state-transition-rules.yaml의 design-direction 9개 전이 전부 allowed-by: [OPS-ORCH]).
  • 보고서는 불변이며 직접 원장 편집 대신 submit-artifact/review-artifact/ complete-stage/enter-stage/register-direction-approval만 쓴다.
  • 권한: npm/vite/headless chrome 로컬 빌드·렌더는 허용 범위(design-system.md와 동일). slack/PR/deploy/secret/db-write 등 external side-effect는 기본 금지.
  • report-header(BLUF) 없이 종료 금지. evidence 없는 confidence:High 금지.
  • submit은 승인과 다르다. 다음 워커 spawn 전 producer와 다른 권한 있는 reviewer가 review-artifact해야 method-contract handoff gate가 통과한다.
  • coded-slice 는 디렉터리가 아니라 파일 경로여야 한다(F6)_directions_diverged(state_engine)와 lint_design_direction._file_shaopen(coded-slice) 로 hash 대조하므로 디렉터리면 크래시한다. direction-set 의 각 direction 은 coded-slice 를 대표 파일(예: directions/<id>/Workbench.jsx)로, coded-slice-sha256 을 그 파일 해시로 채운다(워커 프롬프트에도 명시).
  • direction-set을 OPS-ORCH가 쓰면 orchestrate 계약 full 준수가 필요하다(F7) — envelope의 top-level method-execution에 active contract hash와 required step-results를 두고, accept 전 validate_report.py를 통과시킨다.

산출/handoff

  • completion-records/<child>/approved-direction-<ts>.report.yaml(불변) + 부모 원장 design-direction-approval 링크.
  • 중간 산출물: direction-discovery·direction-set·selected-direction·winner-prototype·design-review-panel(각 completion-records// 경로, 통합 원장 artifacts에 등재).
  • 다음: 승인된 방향을 입력으로 /design-system(코드 디자인 시스템 확정) 또는 직접 /spec으로 진행.