Files
llm-wiki/docs/superpowers/specs/2026-06-02-coverage-gate-design.md
T

10 KiB

coverage 완전성 게이트 — 설계

작성: 2026-06-02 · 상태: 합의됨 · 짝 문서: 2026-06-02-branch-spec-assembly-pipeline-design.md

1. 배경 / 문제

현재 파이프라인에는 깊이 게이트(/depth)는 있지만 완전성 게이트는 없다.

  • /depth(R1~R4)는 노트에 적힌 결정이 충분히 깊고 코딩 가능한지 검사한다.
  • 그러나 "적어야 할 결정이 다 적혔는가" 는 어느 축도 보지 않는다. 브랜치의 In scope 리스트는 /branch 생성 시 사람이 손으로 쓴 것이며, 그 리스트 자체의 완전성은 게이트되지 않는다.
  • 결과: In scope가 불완전해도 /depth는 통과한다. 실제 사례 — feature-business-rule-validation-contract가 "Ready" 판정을 받았지만, ad hoc grep 결과 i18n 메시지 정책 / 입력 정규화 / fail-fast 오류수집 정책 등 표준 검증 관심사가 어느 브랜치에도 결정으로 존재하지 않음이 드러났다.

ca-tmpl은 보편적 백엔드 프로젝트가 갖춰야 할 항목을 빠짐없이 담는 템플릿이 목적이므로, 완전성(coverage)은 깊이만큼 중요한 축이다.

비유: /depth는 "네가 푼 문제는 잘 풀었다"를 채점하지만 "3번 문제를 통째로 안 풀었다"는 못 잡는다. /coverage가 그 빠진 문제를 잡는다.

2. 범위

순수 추가 + 최소 수정. depth 게이트의 형제(sibling)로 설계.

산출물 성격
.claude/commands/coverage.md /coverage 명령 (브랜치 모드 + 프로젝트 모드)
.claude/agents/coverage-auditor.md 2차 LLM 의미 감사 서브에이전트 (읽기 전용)
rules/coverage-gate.md 판정 규칙 (3단계 심각도 + 명명된 실패 모드) — branch-depth-gate.md의 짝
wiki/projects/ca-tmpl/coverage-matrix.md 프로젝트 전체 현황표 (자동 생성물, 손유지 금지)
(린터 확장)/coverage 인라인 변경(2026-06-02): 공유 린터를 건드리면 기존 노트 대량 파손 → 1차 결정론 검사를 coverage.md 인라인(grep, target 한정)으로 구현. 공유 린터 무수정
(수정) templates/branch-note-template.md ## Coverage 섹션만 추가(optional 마커). governing_docs:template 에 안 넣음(§4.1 구현 노트)
(수정) .claude/commands/branch-spec.md /coverage 자동 실행 끼우기

명시적 비범위:

  • 외부 taxonomy(OWASP 등)를 기준으로 삼지 않는다 — 기준은 프로젝트 자체의 canonical 문서.
  • .codex / .agents 병렬 포트는 후속(이번엔 .claude만).
  • 기존 브랜치 노트 일괄 마이그레이션(governing_docs 소급 부여)은 후속 — 점진 적용.

3. 확정된 설계 결정

ID 결정 근거
DD1 범위 = 브랜치 레벨 + 프로젝트 레벨 (둘 다, 계층적) 브랜치 slice 완전성 + 브랜치 집합 전체의 owner-less 관심사 둘 다 필요
DD2 기준 = 설계 문서 1순위 → 선례 브랜치 → ca-tmpl 코드. 겹치면 owner 브랜치 위임 사용자 방법론: "문서가 제일 먼저 기준, 그걸 ca-tmpl에 구현, 겹치면 owner 위임". 외부 taxonomy 아님
DD3 구조 = 2단계 (얇은 결정론 린터 + LLM coverage-auditor) depth 패턴 미러링. 기계로 볼 수 있는 건 1차에서 싸게, 의미 비교는 2차
DD4 판정 = 3단계 심각도 (Blocking / Should-fix / Advisory). Covered = Blocking 0 depth와 동일. owner 위임 케이스를 Blocking 아닌 Should-fix로 분리 → false block 방지
DD5 접근법 C (하이브리드). 브랜치→문서 매핑은 frontmatter governing_docs 한 줄로 명시, ## Coverage와 프로젝트 matrix는 자동 생성(손유지 금지) drift 회피(이번 세션 교훈: 손유지 SSOT는 어긋난다 — registry 주석 L580 stale 사례). tag 추론은 엉뚱한 문서를 잡을 위험 → 명시 한 줄로 차단
DD6 끼우는 위치 = /branch-spec 맨 끝, /depth와 나란히. 둘 중 하나라도 실패 시 /branch-spec으로 루프백 두 게이트 대칭. coverage가 찾은 빠진 항목을 채우고 → 그 새 결정을 depth가 다시 깊이 검사 → 둘 다 통과 시 완성

4. 데이터 모델 (가벼움 — 사람이 쓰는 건 한 줄)

4.1 브랜치 frontmatter governing_docs:

이 브랜치가 구현해야 할 기준 canonical 문서를 명시. tag 추론의 불안정성 제거.

governing_docs: [wiki/projects/ca-tmpl/api-error-envelope-design]
  • 0개 또는 다수 가능.
  • 구현 노트 (2026-06-02): 공유 구조 린터(wiki_structure_lint.py)는 --file 모드에서 is_completeness_checkable 게이트 없이 모든 template fm_key 를 무조건 요구한다. 따라서 governing_docstemplate frontmatter 에 넣으면 기존 80개 노트가 전부 깨진다 → template 에 추가하지 않음. 대신 /coverage 1차 인라인 검사가 ca-tmpl 브랜치 한정으로 존재를 요구(NO_GOVERNING_DOC). 노트에 추가 키로 들어가는 건 린터가 막지 않으므로(required 만 검사, extra 는 허용) per-branch 로 안전하게 부여 가능. 기존 ca-tmpl 노트 backfill 은 점진 마이그레이션(비범위).

4.2 브랜치 노트 ## Coverage / 관심사 커버리지 섹션

coverage-auditor가 생성. 손유지 금지.

관심사 상태 owner 심각도 근거
syntax/shape 검증 covered-here D1
cross-field 검증 delegated feature-boundary-validation-mapping OK §Audit 링크
i18n 메시지 정책 missing (없음) 🔴 Blocking governing doc §X 언급, 결정 없음
  • 상태 3종: covered-here(이 브랜치가 다룸) / delegated(다른 owner) / missing(아무도 안 맡음).

4.3 wiki/projects/ca-tmpl/coverage-matrix.md

프로젝트 모드가 모든 브랜치 ## Coverage에서 생성하는 뷰. 관심사 → owner 브랜치 → status, owner-less(아무 브랜치도 안 맡은 관심사) 강조. 생성물이라 drift 불가.

5. 게이트 로직

5.1 1차 — 결정론 린터 (싸고 빠름)

사람 판단 불요 항목만:

  • governing_docs frontmatter 존재?
  • ## Coverage 섹션 존재?
  • governing_docs 링크가 vault에 실재(깨진 링크 아님)?

심각하게 깨졌으면(필드/섹션 누락) 그것부터 고치도록 안내, 2차 보류 — depth 1차와 동일 정책.

5.2 2차 — coverage-auditor (LLM 의미 감사, 읽기 전용)

브랜치 모드 입력: 브랜치 노트 경로. 다음 셋을 실제로 읽고 비교:

  1. governing_docs 문서 — "있어야 할 관심사" 열거.
  2. 선례(완성) 형제 브랜치 — 이미 누가 무엇을 owner인지.
  3. ca-tmpl 코드(/home/donghyeon/workspace/ca-tmpl/src, docs/registries) — 말로만 있는지 실제 구현인지.

→ governing 문서의 각 관심사를 브랜치 In-scope/결정과 대조해 ## Coverage 표 생성 + 3단계 판정.

프로젝트 모드(--project): 전체 canonical 문서에서 관심사를 열거하고, 각 브랜치 ## Coverage와 cross-ref → owner-less 관심사를 Blocking으로 coverage-matrix.md 생성.

5.3 판정 (3단계 심각도)

신호 의미 트리거
🔴 Blocking (Not-covered) 진짜 빠짐, 아무 브랜치도 안 맡음 governing 문서가 요구하는 관심사가 이 브랜치에도 없고 다른 owner도 없음
🟡 Should-fix 다른 브랜치 owner인데 위임 링크 누락 관심사를 sibling이 소유하나 본 노트 §Audit/§Coverage에 위임 링크 없음
Advisory 있으면 좋음 governing 문서가 권고하나 핵심 아님

Covered = Blocking 0건. Should-fix는 사용자 "감수" 선언 시 통과(리포트 기록) — depth와 동일.

5.4 명명된 실패 모드 (rules/coverage-gate.md)

  • MISSING_CONCERN (Blocking): governing 문서 관심사가 어느 브랜치에도 결정으로 없음.
  • UNLINKED_DELEGATION (Should-fix): owner sibling 있으나 위임 링크 누락.
  • NO_GOVERNING_DOC: governing_docs 미지정 → 기준 부재로 판정 불가(1차에서 차단).
  • STALE_OWNER: §Coverage가 가리키는 owner 브랜치가 실제로 그 관심사를 안 가짐(코드/노트 대조 불일치).

6. 통합 — /branch-spec 흐름

ground truth 읽기 → 결정 추출 → 채움
   → [depth 검사: 적은 게 깊은가]
   → [coverage 검사: 빠뜨린 게 있는가]   ← 신규
        ├─ 둘 다 통과 → 완료 ✅
        └─ depth Not-ready 또는 coverage 🔴 → 다시 branch-spec(보강) → 재검사 (루프)

/coverage는 독립 명령이며 /branch-spec이 끝에서 자동 호출(= /depth 호출 방식과 동일).

6.1 프로젝트 외 브랜치 면제

governing_docs 미지정 + related_projects에 ca-tmpl 없는 브랜치(예: keycloak 학습 노트)는 coverage 면제 — 1차 린터가 프로젝트 소속 여부로 판단.

7. 요구사항 충족 매핑

사용자 요구 충족
깊이 외에 완전성도 검사 DD1~DD4 — 빠진 관심사 3단계 판정
문서를 기준으로 DD2 — governing_docs canonical 문서 1순위
선례 브랜치처럼 조사 + 겹치면 owner 위임 5.2 — 선례 브랜치 읽기 + delegated 상태
branch-spec의 depth 자동실행 구조처럼 DD6 — 맨 끝 자동 호출 + 루프백
별도 명령 .claude/commands/coverage.md

8. 리스크 / 비범위 확인

  • drift 리스크: ## Coverage·matrix를 손유지하면 또 어긋남 → 자동 생성만(DD5). 사람이 쓰는 건 governing_docs 한 줄뿐.
  • governing_docs 오지정 리스크: 사람이 엉뚱한 문서를 적으면 판정 무의미 → 1차 린터가 링크 실재만 확인, 적정성은 2차 auditor가 "이 문서가 이 브랜치 주제와 맞나" 한 줄 코멘트로 surface.
  • canonical 문서 자체가 불완전하면? coverage는 "문서 대비" 완전성만 보장. 문서 자체의 완전성은 별도(후속 — 문서 레벨 critic). 이번 범위 밖.
  • 비용: 프로젝트 모드는 전체 canonical + 전체 브랜치 §Coverage 재독 → 비쌈. 주기적 실행 전제(매 브랜치마다 아님).