402 lines
29 KiB
Markdown
402 lines
29 KiB
Markdown
# P2 — Design Direction 스테이지 설계
|
||
|
||
- 날짜: 2026-07-13
|
||
- 상태: 설계(brainstorm 승인 + §15 열린항목 결정 + 4 구조수정 반영) — 구현 전
|
||
- 관련: [design-craft-upgrade](2026-07-08-design-craft-upgrade-design.md), [design-system-pipeline](2026-07-08-design-system-pipeline-design.md), [P1 venture-bootstrap](2026-07-12-p1-company-venture-bootstrap-design.md)
|
||
- 로드맵: 리뷰 2번째 핵심결함(디자인 탐색 없이 design-system으로 조기고착) 해소 = P2.
|
||
|
||
## §1. 문제 (리뷰 2번째 핵심결함)
|
||
|
||
현재 `/design-system` 파이프라인은 `design-brief 세우기 → tokens → components → screens → preview`로 **바로** 들어간다. design-brief의 reference cluster가 **탐색 없이 단번에 확정**되고, 그 순간 시각 방향이 고착된다. 빠진 것:
|
||
|
||
1. **방향 발산 부재** — 2~3개의 서로 다른 시각 방향을 실물로 세워 비교하는 단계가 없다. LLM은 단일 brief를 generic 평균("modern/clean")으로 채운다(design-craft 근거: vague prototyping = generic, NNGroup).
|
||
2. **비평 게이트 부재** — generic·미분화 산출을 되돌리는 critique 루프가 없다. preview_ui는 *기술 품질*(렌더됨·대비·포커스)만 보고 *방향의 독창성/일관성*은 보지 않는다.
|
||
3. **조기고착 방지 선행조건 부재** — "방향 승인 전 시스템 고착 금지"가 `/design-system` 진입에 강제되지 않는다.
|
||
4. **FAM-DESIGN에 리드 부재** — FAM-CONSULTING(CONSULT-EM)·FAM-DOC-CONSULT(DOC-LEAD)와 달리 FAM-DESIGN에는 발산을 프레이밍하고 수렴을 종합하는 `lead-role-id`가 없다.
|
||
5. **입력 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`)
|
||
```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)
|
||
```yaml
|
||
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` 산출)
|
||
```yaml
|
||
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` 산출 — 사람 선택, 아직 승인 아님)
|
||
```yaml
|
||
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)
|
||
```yaml
|
||
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 특수보호 불요).
|
||
```yaml
|
||
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 참조만:
|
||
```yaml
|
||
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 산출)에 명시 필드:
|
||
```yaml
|
||
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` 참조를 따라가 확인:
|
||
1. approved-direction 불변 report 존재(completion-records 경로)
|
||
2. schema/validator(lint_design_direction) 통과
|
||
3. acceptance receipt 존재(acceptance_log accepted, report-sha256 바인딩 — P1 hash 바인딩 재사용)
|
||
4. report hash 일치(receipt report-sha256 == 실제 파일 hash — 수정 시 mismatch)
|
||
5. parent-workflow-id 일치
|
||
6. product-decision-id 일치(부모 accepted decision-packet)
|
||
7. **direction-input-brief-sha256 일치**
|
||
8. 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 형제):
|
||
```yaml
|
||
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:722` `role-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-direction` plan(§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. 열린항목 — 결정 완료
|
||
|
||
1. **자동 spawn + 수동 유지**: `/design`이 UI+standard/heavy에서 child 자동 init/spawn(dedup), `/design-direction`은 독립·resume·재진입·재생성·복구용 수동 진입점 유지(§10).
|
||
2. **guard_tools 특수보호 없음**: approved-direction은 immutable report 경로에 생성, 부모 원장엔 hash-bound reference만. mutable canonical 파일 없음 → 일반 report immutability로 충분(§9).
|
||
3. **preview_ui 미확장**: 비교 갤러리를 별도 Vite 패키지 root로, 기존 preview_ui root 1회 렌더(§11).
|
||
4. **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 Schema
|
||
- [ ] `design-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-direction` plan(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
|