Files
company-haness/docs/superpowers/specs/2026-07-10-p1-structural-quality-design.md
T

11 KiB
Raw Blame History

P1 구조적 품질 복구 — 설계/실행 스펙

status: approved supersedes: (none) follows: 2026-07-10-p0-execution-integrity-design.md applies-to-version: company-haness @ fix/p0-execution-integrity date: 2026-07-10

배경 / 범위

P0(실행 무결성) 완료 후, 리뷰의 P1(#7–16, 구조적 품질) 10건을 적용한다. P1은 P0보다 파일이 얽혀 있고(여러 항목이 gen_agents.py·validate_report.py·guard_tools.py·commands·test_enforcement.py에 수렴), 3건(#7 wave/cascade 통합, #13 SSOT YAML 실행화, #14 acceptance-event 모델)은 아키텍처를 재구성하는 큰 작업이다. 따라서 한 번의 대량 병렬이 아니라 **트랜치(tranche)**로 나눠 실행한다.

공유 규칙 (모든 P1 work-package)

  • .claude/tests/test_enforcement.py는 편집 금지(공유 충돌점). 각 package는 자기 테스트를 새 파일(test_p1_<topic>.py)에 쓴다. 기존 assertion이 깨지면 정확히 어느 케이스가 왜 깨지는지 + 새 기대값을 보고만 하고, 오케스트레이터가 리뷰 단계에서 한 곳에서 반영한다.
  • CLAUDE.md/README.md 편집 금지. 트랜치 종료 시 오케스트레이터가 정직성 반영.
  • git commit/branch 금지. workspace 필요 시 ORGOS_WORKSPACE=_sandbox.
  • P0 계약(report-header·evidence receipt·workspace 강제·context_package·70 agents)을 깨지 않는다. 끝에 doctor + 전체 suite green 유지.

트랜치 맵

Tranche 1 (병렬-안전, 파일 소유 배타) — 지금

WP 결함 쓰는 파일(배타)
P1-A #12 lens vs 전문성 .claude/hooks/lens_cap.py, org-os/00-role-registry/lens-registry.yaml, .claude/tests/test_p1_lens.py(신규)
P1-B #15 /consult 분기 + 렌더 열화표시 .claude/commands/consult.md, .claude/hooks/render_consult.py, .claude/hooks/consult_exhibits.py, .claude/tests/test_p1_consult.py(신규)
P1-C #16 디자인 파이프라인 discovery+검증 .claude/commands/design-system.md, .claude/hooks/preview_ui.py, org-os/06-agent-work/design-brief-spec.yaml, .claude/tests/test_p1_design.py(신규)
P1-D #10 audit Write + #9 primary-artifacts .claude/hooks/gen_agents.py, org-os/00-role-registry/tool-permission-matrix.yaml, org-os/06-agent-work/context-package-spec.yaml, .claude/hooks/validate_report.py, .claude/schemas/, .claude/tests/test_p1_artifacts.py(신규), 생성물 .claude/agents/*.md

주의: P1-A는 role-profiles.yaml편집하지 않는다(gen_agents가 읽음) — 서브스페셜티 축은 lens-registry.yaml에 둔다. P1-D만 gen_agents.py/validate_report.py/schemas를 만진다.

Tranche 2 (순차 — Tranche 1 이후)

WP 결함 소유 파일 의존
P1-E #11 guard default-deny 경계 .claude/hooks/guard_tools.py, .claude/settings.json(permissions.deny/allow) tool-permission-matrix(P1-D 확정 후 read)
P1-F #8 구현 루프 .claude/commands/build.md, org-os/00-role-registry/role-working-methods.yaml(eng), .claude/skills/build-loop/(신규) gen_agents(P1-D) 후 재생성
P1-G #14 acceptance-event 모델 new_report.py, .claude/hooks/acceptance_log.py(신규), report schema, completion-record status schema(P1-D) 후

Tranche 3 (아키텍처 — 설계 결정 후)

  • #7 wave↔cascade 실행모델 통합: commands 전체 + collaboration-map/state-transition-rules/execution-policy. 비파괴 버전(두 흐름 유지하되 workflow-id/state 어휘 통일 + cascade=preset 문서화 + 리뷰가 짚은 모순 제거: README "항상 ceo-intake" vs 중간시작, collaboration-map에 GROUND 추가, divergent /decide의 결정 생성, anchoring)로 스코프.
  • #13 SSOT YAML 실행화: template-driven validator/renderer, state-transition 검사기, scorecard 계산기 중 최고가치 12개만 우선. (전부는 별도 대공사.)

→ Tranche 3는 트랜치 1–2 종료 후, 오케스트레이터가 스코프/설계를 사용자에게 제시하고 진행.


Tranche 1 상세

P1-A — lens diversity ≠ domain coverage (#12)

현상: lens_cap.role_lenses()가 role별이 아니라 family lens를 모든 멤버에 복사 → 아키텍트 7명 모두 LENS-TECH로 간주 → standard tier에서 1명만 남고 나머지 전문분야가 삭제됨. 처방: lens 다양성domain/sub-specialty 커버리지를 별도 축으로. 같은 lens라도 서로 다른 sub-specialty role은 중복이 아니다(application vs system architecture, PM vs TPO, product vs platform design).

  • lens-registry.yaml에 sub-specialty 축 정책(같은 lens 내 distinct sub-specialty 허용 상한: light≤2, standard≤3, heavy=무제한 등 — 리뷰 취지에 맞게 선택) + 필요한 role→sub-specialty 매핑을 둔다(role-profiles는 건드리지 않음).
  • lens_cap.py: "같은 lens 워커 2+ → 위반"을 "같은 lens AND 같은/미분화 sub-specialty → 위반; distinct sub-specialty는 tier 상한까지 허용"으로 교체. 진짜 중복(동일 role·미분화)만 잡고 전문분야 삭제를 멈춘다.
  • 기존 test_enforcement.py의 lens_cap 3케이스가 바뀔 수 있음 → 새 기대값을 보고만 하고 test_p1_lens.py에 신규 케이스(아키텍트 7명 standard에서 통과, 동일 role 2회는 여전히 위반 등) 작성. 수용: 아키텍처 fan-out(7 distinct roles)이 standard에서 부당하게 1명으로 깎이지 않음; 진짜 중복은 여전히 차단.

P1-B — /consult 문서-컨설팅 분기 실제화 + 렌더 열화표시 (#15, +#16의 D2/Mermaid 부분)

현상: consult.md가 문서 컨설팅이면 FAM-DOC-CONSULT를 고른다고 설명만 하고, 실제 FRAME/ANALYZE/SYNTHESIZE 절차는 비즈니스 5분과로 하드코딩. 또 render_consult가 D2/Mermaid 렌더 실패 시 코드 텍스트를 넣은 SVG로 대체하면서 성공 처리(열화 은폐). 처방:

  • consult.md: engagement 유형(business vs doc-consulting)에 따라 lead/workers/output-contract데이터로 분기. 문서 컨설팅이면 doc-lead + doc-writer/ia/visual/edu가 실제 FRAME/ANALYZE/SYNTHESIZE 각 단계에 배선되게(설명이 아니라 절차). 두 경로가 대칭이 되도록.
  • render_consult.py(+필요 시 consult_exhibits.py): D2/Mermaid(또는 exhibit) 렌더 실패 시 fallback-SVG를 쓰되 결과에 degraded 표시(파일명/메타/stderr 경고 + 비영점 신호 or 리포트 플래그)로 "성공"으로 위장하지 않는다.
  • test_p1_consult.py: 문서-컨설팅 분기가 doc-family를 실제로 선택하는지(커맨드 파싱/구조 검증 수준) + 렌더 열화가 감지되는지.
  • 기존 test_enforcement.py의 render_consult 케이스가 깨지면 새 기대값 보고. 수용: 문서 리뷰 요청에서 writer/IA/visual/edu가 빠지지 않음; 렌더 열화가 조용히 성공으로 처리되지 않음.

P1-C — 디자인 파이프라인 discovery-first + 실질 검증 (#16)

현상: design-system.md가 React+CSS+Vite를 전사 고정으로 못박고 기존 stack/컴포넌트/브랜드/데이터밀도를 조사하지 않음. preview_ui.py는 build+PNG 존재만 확인(접근성/키보드/대비/반응형/상태/인터랙션/비주얼회귀/콘텐츠밀도/기존 시스템 정합 미검증). 처방:

  • design-system.md: discovery → reuse/adapt/create 판단을 먼저. 기존 시스템 조사 단계 추가. 고정 Vite 경로는 greenfield-react preset으로 격하(기본이 아니라 옵션). 기존 프로젝트면 그 stack/토큰/컴포넌트를 우선 재사용.
  • preview_ui.py: 최소한 대비(contrast)·반응형 viewport(복수 width)·상태(loading/empty/error/overflow)·키보드 포커스 가시성 중 실현 가능한 자동 체크를 추가하고, build 실패/degraded를 성공으로 처리하지 않는다. 스크린샷 존재=품질 아님을 코드/문서로 명확히.
  • test_p1_design.py: preset framing·discovery 단계 존재, preview_ui의 신규 체크·fail-loud.
  • 기존 test_enforcement.py의 design-system/preview_ui 케이스가 깨지면 새 기대값 보고. 수용: 기존 프로젝트에서 stack 강제하지 않음; preview가 build/PNG 존재만으로 통과시키지 않음.

P1-D — audit-agent Write 권한 + primary-artifacts 분리 (#10, #9)

현상(#10): gen_agents의 TOOLS가 audit family(아키텍처/보안/QA/Legal/VPEng 13개)에 Read/Grep/Glob/Bash/WebFetch/WebSearch만 줘서 보고서를 쓰라면서 Write가 없음 → Bash redirection 우회(보고서 불변 guard 우회) 위험. 반대로 GTM/OPS엔 불필요한 Edit/Bash. tool-permission-matrix.yaml·frontmatter·guard가 서로 다른 정본. 현상(#9): 생성 worker가 산출물을 report 하나로 제한 → RFC/데이터모델/threat-model/API계약/실제코드 대신 보고서 안 몇 줄로 대체됨. 처방:

  • tool-permission-matrix.yamltools의 단일 정본으로 삼고, gen_agents의 TOOLS 매핑을 거기서 파생(또는 정합). audit agent에 Write 부여(자기 보고서/설계 산출물 작성용) — 단 보고서 불변 guard는 유지(새 파일만). 불필요한 Edit/Bash 정리.
  • primary-artifacts[]completion-report분리: context-package expected-output과 report schema에 primary-artifacts:[{path, kind, sha?, verification}]를 두고, 보고서는 실물의 경로·검증·리스크를 담는 envelope임을 gen_agents 본문 계약에 명시(“보고서 안 요약으로 실물을 대체하지 말 것”). build/design/spec 유형은 실물 아티팩트를 요구.
  • validate_report.py: 해당 report-type이면 primary-artifacts가 존재하고 각 path가 실존(가능하면 receipt/hash와 연계)하는지 검사(P0 receipt 로직과 정합, 시그니처 C3 유지).
  • .claude/schemas/: primary-artifacts 필드 추가(공통/유형별).
  • test_p1_artifacts.py: audit agent가 Write 보유, primary-artifacts 누락 시 build-type 차단, 경로 실존 검사.
  • gen_agents 개수 계약(70)·기존 본문 검증을 깨지 않게(라우터/워커/lead 구조 유지). 기존 test_enforcement.py의 gen_agents/tool 관련 케이스가 깨지면 새 기대값 보고. 수용: audit agent가 Bash 우회 없이 Write로 보고서·설계 산출; 실물 아티팩트가 report와 분리되어 요구·검증됨; tools 정본 일원화.

트랜치 종료 처리(오케스트레이터)

  1. 각 package 결과 리뷰(자기신고 아님 — 직접 재현).
  2. 깨진 test_enforcement.py assertion을 보고된 새 기대값으로 한 곳에서 반영 + 전체 suite 재실행.
  3. doctor + gen_agents --check(70) + lint_refs + 전체 테스트 green 유지.
  4. CLAUDE.md/README 정직성 반영(트랜치별 변경 요약).
  5. settings.json 복원(P1 종료 시).