Files
llm-wiki/docs/superpowers/specs/2026-06-06-harness-audit-report.md

15 KiB
Raw Permalink Blame History

title, source_type, status, confidence, tags, last_reviewed
title source_type status confidence tags last_reviewed
LLM Wiki 하네스 설계 감사 — deep-research 기준 33파일 × 8원칙 llm-generated draft medium
harness
claude-code
audit
automation
design
2026-06-06

하네스 설계 감사 보고서 (read-only)

⚠️ 시점 스냅샷 (2026-06-06 감사 당시): 본 보고서는 구현 전 상태를 기술한다. 이후 Spec A 가 G1·G5·G6 을, Spec B 가 G3·G7 을 해소했다. 특히 §3 G1("--hook 이 항상 exit 0")·G6("claim_gate 테스트 0개")는 현재 코드에서 더 이상 사실이 아니다(--hook fix-up 시 exit 2, test_wiki_claim_gate.py 존재). 우선순위 판단 시 docs/superpowers/README의 Spec A/B = DONE 상태를 함께 보라. 남은 미해소: G2(Spec D, 보류), G4(Spec C, 진행 예정).

기준선: Claude Code 내장 deep-research Workflow 스크립트 (CLI 바이너리에서 추출, 350행 — /tmp/deep_research_script.js). 대상: .claude/ 하네스 33파일 (agents 10 · commands 22 · hooks 3 · settings 2 · skill 1 — 일부는 commands에 포함, 실제 채점 파일 33개). 방법: 5개 read-only 감사 에이전트를 병렬 dispatch, 동일한 8원칙 루브릭 + 고정 output-spec 적용 → 본 문서로 합성. 파일 변경 없음.

메타: 이 감사 자체가 deep-research 패턴(fan-out readers → 고정 schema → synthesize)으로 수행됨. dogfooding.


§0. deep-research가 "잘 설계된 하네스"인 8가지 이유 (루브릭)

# 원칙 deep-research 구현 한 줄 정의
P1 강제된 output-spec agent() 마다 JSON schema (required/enum/minItems), tool-layer 검증 + 모델 재시도 구조화 출력이 경계에서 검증되는가, 산문 희망인가
P2 결정론적 오케스트레이션 pipeline()/[barrier]가 JS 코드, 각 barrier에 왜 막는지 주석 fan-out/순서가 코드인가 controller-LLM 판단인가
P3 적대적 정족수 검증 3표/claim, ≥2 refute면 kill, "불확실하면 refuted=true", 기권≠통과 독립 회의론자 + 기계적 kill 임계값 vs 단일심사/자문
P4 우아한 저하 + funnel stats 모든 early-return이 유효한 PARTIAL 리포트 + stats funnel 부분결과 경로 + 깔때기 통계를 내는가
P5 무삭제 보장 budgetDropped[]/dupes[] 추적·노출, 캡이 보임 캡/탈락/스킵을 명시 보고하는가 silent인가
P6 증거 + grep 자가검증 claim마다 verbatim 인용 원문 인용 + grep 검증
P7 최소권한 + 단일직무 작은 단일목적 에이전트 scoped tools:, 하나의 일
P8 명명된 상수 MAX_FETCH, VOTES_PER_CLAIM 상단 임계값이 한 곳에 명명 vs 산문에 흩어진 매직넘버

채점: MATCH / PARTIAL / GAP / N-A.


§1. 33파일 × 8원칙 매트릭스

1-A. agents (10) — 대부분 GATE(read-only judge) + 3 WORKER + 1 ORCHESTRATOR

File P1 P2 P3 P4 P5 P6 P7 P8
branch-depth-auditor PARTIAL N-A PARTIAL no quorum GAP N-A MATCH MATCH MATCH
coverage-auditor PARTIAL PARTIAL GAP single judge GAP N-A MATCH PARTIAL MATCH
project-readiness-auditor PARTIAL N-A PARTIAL no vote GAP N-A MATCH MATCH MATCH
wiki-adversarial-reviewer MATCH N-A PARTIAL no N-vote/default-refute PARTIAL N-A MATCH MATCH PARTIAL
wiki-decision-researcher PARTIAL PARTIAL N-A PARTIAL PARTIAL MATCH MATCH PARTIAL
wiki-diagram-reviewer MATCH N-A MATCH measured+HARD-STOP GAP MATCH MATCH MATCH MATCH
wiki-doc-author MATCH N-A N-A PARTIAL GAP PARTIAL MATCH PARTIAL
wiki-link-verifier MATCH N-A N-A PARTIAL MATCH MATCH MATCH PARTIAL
wiki-research-lane MATCH N-A PARTIAL MATCH PARTIAL MATCH MATCH MATCH
wiki-source-summarizer MATCH N-A N-A PARTIAL PARTIAL MATCH MATCH MATCH

1-B. capture commands (5) — 2 ORCHESTRATOR + 3 SCAFFOLD

File P1 P2 P3 P4 P5 P6 P7 P8
daily N-A N-A N-A PARTIAL N-A N-A MATCH N-A
branch PARTIAL N-A GAP PARTIAL N-A PARTIAL MATCH N-A
branch-spec PARTIAL PARTIAL prose-advisory PARTIAL LLM-judge PARTIAL MATCH PARTIAL MATCH GAP
project PARTIAL N-A N-A PARTIAL N-A N-A MATCH N-A
project-spec PARTIAL PARTIAL prose loop PARTIAL LLM-judge PARTIAL MATCH PARTIAL MATCH GAP

1-C. transform/quality commands (7) — 2 TRANSFORM + 3 GATE + 1 QUERY + 1 MIGRATION

File P1 P2 P3 P4 P5 P6 P7 P8
ingest GAP N-A N-A GAP PARTIAL MATCH MATCH N-A
tag GAP N-A N-A GAP N-A N-A MATCH N-A
lint PARTIAL PARTIAL (post-hoc) PARTIAL advisory PARTIAL MATCH PARTIAL MATCH PARTIAL
query GAP N-A PARTIAL N-A N-A MATCH MATCH N-A
depth PARTIAL MATCH linter→LLM gate PARTIAL single auditor PARTIAL N-A N-A MATCH PARTIAL
coverage PARTIAL MATCH gate ordering PARTIAL single auditor PARTIAL N-A N-A MATCH PARTIAL
migrate-claims PARTIAL MATCH Phase0-4 interlock PARTIAL default-UNSUPPORTED MATCH MATCH MATCH MATCH PARTIAL

1-D. output + invest commands (10) — 4 DERIVE + RESEARCH/LEDGER/PLAN/REVIEW

File P1 P2 P3 P4 P5 P6 P7 P8
projectize PARTIAL N-A N-A GAP N-A PARTIAL MATCH GAP
interviewize PARTIAL PARTIAL gate steps N-A GAP N-A PARTIAL MATCH GAP
blogify MATCH PARTIAL gate steps N-A GAP N-A PARTIAL MATCH GAP
explain PARTIAL N-A N-A GAP N-A PARTIAL MATCH N-A
invest-daily PARTIAL N-A (delegates DR) N-A GAP GAP PARTIAL no grep MATCH GAP
invest-decide PARTIAL PARTIAL gate steps PARTIAL soft-block GAP N-A GAP no grep MATCH GAP
invest-ingest PARTIAL PARTIAL PARTIAL REJECT-excl GAP N-A PARTIAL MATCH N-A
invest-plan PARTIAL PARTIAL N-A GAP N-A PARTIAL MATCH PARTIAL
invest-research PARTIAL N-A (delegates DR) PARTIAL no quorum GAP N-A MATCH self-grep MATCH N-A
invest-review PARTIAL PARTIAL N-A GAP N-A GAP no grep MATCH PARTIAL

1-E. infra: hooks + settings + skill (6) — 결정론 backbone

File P1 P2 P3 P4 P5 P6 P7 P8
wiki_structure_lint.py PARTIAL PARTIAL post-hoc, exit0 항상 N-A MATCH fail_by_type PARTIAL hook[:10] PARTIAL MATCH MATCH templates SSOT
wiki_claim_gate.py MATCH MATCH PreToolUse exit-2 PARTIAL keyword block PARTIAL GAP PARTIAL MATCH GAP inline 하드코딩
test_wiki_structure_lint.py PARTIAL MATCH N-A PARTIAL PARTIAL PARTIAL MATCH PARTIAL
settings.json PARTIAL PARTIAL Post=after-fact N-A N-A N-A N-A MATCH N-A
settings.local.json N-A N-A N-A N-A N-A N-A GAP blanket Bash N-A
wiki-workflow/SKILL.md PARTIAL GAP advisory dispatch PARTIAL PARTIAL N-A MATCH MATCH PARTIAL re-list

§2. 강점 — deep-research 수준 이상 (건드리지 말 것)

  1. P6 증거 규율이 최강. self-grep verbatim 검증이 wiki-source-summarizer·wiki-research-lane·wiki-diagram-reviewer·/migrate-claims·invest-research에서 기계적으로 명세됨(grep -nF/sed -n). deep-research보다 강함.
  2. P7 최소권한·단일직무가 깨끗. 9/10 에이전트가 scoped tools: + "Shortcut Trap" 반-합리화 가드. (유일 예외: settings.local.json blanket Bash.)
  3. 결정론 layer가 존재. deep-research에는 없는 wiki_structure_lint.py(582행, 이진 PASS/FAIL) + wiki_claim_gate.py(exit-2 block) — 문서-쓰기 경계 게이트.
  4. 두 개의 "골드 표준형" 파일이 이미 존재 → 내부 템플릿으로 승격 가능:
    • wiki-diagram-reviewer.md — P1·P3·P5·P8 동시 MATCH. 측정된 카운트 + HARD-STOP→0 + 명명 상수(≤10/≤8/≤1/≥95). 다른 judge 에이전트의 본보기.
    • /migrate-claims.md — P2·P4 MATCH. Phase0-4 hard interlock(Phase2는 Phase1 미완 시 BLOCKED), default-refute(UNSUPPORTED_DECISION), >10파일→슬라이스, COMPLETE/PARTIAL/BLOCKED verdict. 다른 오케스트레이터의 본보기.

§3. 횡단 체계적 갭 (deep-research가 더 체계적인 지점) — 영향순

G1 — 결정론 backbone이 실제로 막지 않는다 가장 구체적·고위험

wiki_structure_lint.py--hook 모드는 findings가 있어도 항상 sys.exit(0) (line 531) → 풍부한 린터가 경고 프린터일 뿐 게이트가 아님. 게다가 PostToolUse라 사후. 유일한 실제 차단은 wiki_claim_gate.py(PreToolUse + SubagentStop)인데 5개 path-prefix만 커버wiki/projects, 모든 invest-*, 파생 wiki/interview|portfolio|blog, raw/errors쓰기-시점 강제 전혀 없음. (블라스트: H / 레버리지: H)

G2 — 오케스트레이션이 산문-자문이지 코드가 아니다

branch-spec·project-spec은 fan-out/barrier를 번호 매긴 LLM 지시("통과 시 dispatch", "8c 루프백 반복")로 표현. 비순응 controller가 단계를 건너뛰어도 탐지 가능한 위반이 없음. deep-research의 [barrier](코드)와 대비. (단 /depth·/coverage·/migrate-claims은 P2 MATCH — 이미 깔끔한 linter→LLM 순서.) (블라스트: H / 레버리지: H, 단 Workflow는 Claude 전용)

G3 — 검증에 verdict 라벨은 있으나 정족수/kill 기계장치가 없다

모든 judge가 단일 패스(adversarial-reviewer, depth/coverage/readiness auditor, invest-research KEEP/REJECT). N-vote·default-refute·기권≠통과 없음. 역설: wiki-adversarial-reviewerINSUFFICIENT_CONTEXT는 불확실성을 PASS 쪽으로 — deep-research(불확실→refute)의 정반대. invest-decide는 규칙 위반을 soft-flag(설계상 사용자 주권이나 P3 PARTIAL). (블라스트: M / 레버리지: H)

G4 — funnel stats가 거의 어디에도 없다

wiki_structure_lint.pyfail_by_type/fail_by_rule만 유일. 어떤 judge·command도 deep-research funnel(후보→처리→탈락→확정)을 안 냄. /ingest가 promotable 항목을 silent 누락했는지 알 수 없음; coverage-auditor가 관심사를 몇 개 열거했는지 보이지 않음. (블라스트: M / 레버리지: M)

G5 — P8 SSOT 분열(split-brain)

structure_linttemplates/에서 매핑을 도출(강함). 그러나 claim_gate는 섹션명·컬럼을 inline 하드코딩, SKILL.md는 source_type를 재나열 → 택소노미 사본 3개, drift 위험. 임계값(90/30/14일, cap 6, ≥5 findings, ≥95)도 산문에 분산. (블라스트: M / 레버리지: M)

G6 — 차단 훅에 테스트가 없다

유일한 exit-2 차단기 claim_gate.py유닛 테스트 0개; 비차단 린터는 잘 테스트됨. 고-블라스트 컴포넌트가 덜 테스트됨(비대칭). (블라스트: M / 레버리지: L)

G7 — 에이전트 출력은 어디에서도 schema 검증되지 않는다

모든 에이전트가 산문("첫 글자 # + 고정 Output 블록 + STOP 체크리스트")을 반환, 희망으로 검증. deep-research의 초능력(tool-layer JSON schema + 재시도)이 부재. 단 — 이건 Claude Code가 Agent 호출에 schema를 강제하는 native 수단이 없어서(현재 Workflowagent({schema})만 가능) 부분적으로 플랫폼 제약. (블라스트: M / 레버리지: M)


§4. 우선순위 (레버리지 × 블라스트, 낮은 아키텍처 위험 우선)

순위 항목 레버리지 블라스트 아키텍처 위험 3-플랫폼?
1 structure_lint --hook 차단화(CRITICAL/WARN 티어) + claim_gate 커버리지 확장 + SSOT 중앙화 G1·G5 H H 낮음(기존 강화) 공유 hook
2 judge 5종에 return-schema 강제 + adversarial-reviewer에 N-vote/default-refute/기권≠통과 G3·G7 H M 낮음
3 reporting-standards에 funnel-stats 계약 + ingest/coverage/depth/decision-researcher 출력에 stats 블록 G4 M M 낮음
4 claim_gate 유닛 테스트 + diagram-reviewer/migrate-claims를 "골드형 템플릿"으로 문서화 G6 M L 낮음
5 invest-daily/decide 강화: 숫자당 grep self-verify, 규칙 위반 hard-block 옵션 G3·부분 M M 낮음 Claude 전용
6 branch-spec/project-spec를 결정론 Workflow 스크립트로 변환 G2 H H 높음 Claude 전용

6번이 "딥 재아키텍처"(앞서 보류). 1~4번이 기존 아키텍처를 deep-research 메커니즘으로 경화하는 안전한 길.


§5. spec 분할 권고 (각각 자체 spec→plan 사이클)

  • Spec A — "결정론 backbone을 진짜 게이트로" 첫 슬라이스 후보. (순위 1)
    • wiki_structure_lint.py --hook: CRITICAL(broken-link/missing-required-section)에 exit-2, WARN은 exit-0 유지 → 사후 경고를 사전 차단으로.
    • wiki_claim_gate.py: path-prefix 커버리지를 wiki/projects·invest-*·파생 산출물로 확장.
    • SSOT 중앙화: 섹션명·컬럼·source_type 매핑을 단일 모듈로(두 훅 + SKILL이 소비).
    • --hook findings 잘림([:10]) 시 "N more suppressed" 명시(무삭제).
    • 왜 먼저: 다른 모든 spec이 "backbone이 막는다"를 전제. 위험 최저, 블라스트 최고(비차단-린터는 사실상 잠재 결함).
  • Spec B — "judge 에이전트 schema + quorum" (순위 2): depth/coverage/readiness/adversarial/diagram에 return-schema; adversarial-reviewer·게이트에 선택적 N-vote + default-refute + 기권≠통과. P1+P3 동시 상승.
  • Spec C — "funnel stats + 무삭제 계약" (순위 3): reporting-standards + 핵심 명령 출력에 stats 블록.
  • Spec D (보류, 딥) — "branch-spec/project-spec 결정론 오케스트레이션" (순위 6): Workflow 변환, Claude 전용, 최고 레버리지·최고 위험. 사용자 명시 opt-in 필요.

§6. claim traceability 검사 (감사 메타)

본 감사는 5개 슬라이스 매트릭스에서 파일별 evidence(file:line)를 근거로 했고, 미적용 원칙은 N-A(이유)로 분리했다. 임의 보강 없이 갭은 GAP으로, 단정 불가는 PARTIAL로 표기했다. 이 보고서는 변경을 가하지 않는 read-only 산출물이며, 다음 단계는 사용자가 §5의 첫 슬라이스(Spec A)를 승인할 때 spec→plan으로 진행한다.

상태: draft (검토 전). 외부 파생 금지.