Skip to content
Back to skills

Validate Workitem

ASecurity

Validate whether a completed workitem implementation matches its documented scope and is ready for the next step.

  • 2 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 29, 2026
ai-agentsbashgitapibackend

Works with

  • cli
  • api
  • mcp

Security analysis

A100/100

Scanned September 29, 2026

npx -y skills add kohj1018/agentic-dev-harness --skill validate-workitem --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Validate Workitem?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Validate Workitem
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/kohj1018-validate-workitem-agentic-dev-harness/badge)](https://www.skillsdirectory.com/skills/kohj1018-validate-workitem-agentic-dev-harness)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: validate-workitem
description: Validate whether a completed workitem implementation matches its documented scope and is ready for the next step.
argument-hint: "[task identifier]"
allowed-tools: Read Glob Grep Write Agent Bash(pnpm validate) Bash(pnpm validate *) Bash(npm run validate) Bash(npm run validate *) Bash(make validate) Bash(make validate *) Bash(task validate) Bash(task validate *) Bash(pnpm validate:design*) Bash(npm run validate:design*) Bash(yarn validate:design*) Bash(bun run validate:design*) Bash(git diff *) Bash(git log *) Bash(git status *) Bash(git -c core.quotePath=false status *) Bash(wc *)
---

이 skill은 **판정 + report 기록 전용**이다. status 변경, 코드 수정, 커밋은 하지 않는다.

너의 역할은 지정된 workitem 구현 결과를 검증하고 표준 양식의 report를 기록하는 것이다.
큰 diff에서는 **메인 세션이 감사 축(audit AXIS)별 validator를 병렬 팬아웃**하고(아래 0단계),
각 validator가 반환한 **partial verdict**(findings + 그 축의 evidence)를 *메인이 집계해
단일 report 1개를 작성*한다. **report 작성과 confidence 산정은 집계자(메인 세션) 책임이다 —
validator는 report 파일을 쓰지 않는다**(clobber 방지: report 경로는 `<task-id>.md` 단일 파일).

입력:
- `$ARGUMENTS`에는 task ID가 들어온다 (feature 단위 검토는 `/validate-plan` 책임). FAC↔AC spec coverage 점검 시 본 task 의 상위 feature 문서를 *참조로* 읽는다.

반드시 먼저 할 일:
0-G. **폐쇄 가드 (ADR-068 D1)**: 대상 task의 `## 0. Status`가 `done`이고 그 마일스톤 산하 **모든** task가 `done`이면, 그 마일스톤은 마일스톤 층이다 — 새 채점표를 만들지 않고 종료한다. 안내: *"이 마일스톤은 전 task가 `done`이라 마일스톤 층입니다. 졸업 판정은 task `## 8`의 `- closure`를 읽으므로 재validate가 필요하지 않습니다. 검증은 `/stabilize-milestone <M>`이 수행합니다."* 산하에 `done`이 아닌 task가 하나라도 있으면 통상 진행한다.
0. **감사 축 분할 + 병렬 validator 팬아웃 (orchestration)** — diff 규모로 분기한다.
   - **diff가 작으면 (cost guard)**: 팬아웃하지 않고 메인 세션이 직접 단일 inline validator로 1~5단계를 그대로 수행한다(아래 fallback 기준).
   - **diff가 크면**: 메인 세션이 아래 **감사 축**을 독립 sub-task로 분할하고, [DELEGATION 병렬 패턴 #1](../../../docs/00-meta/DELEGATION_STRATEGY.md#병렬-패턴-3종)(한 turn에 `validator` sub-agent 다중 호출)로 *한 turn에* 팬아웃한다. 각 validator는 **자기 축 하나만** scoped로 받고 **partial verdict만 반환**한다(report 작성 금지). 입력에 «작업 파일을 프로젝트에 만들지 않는다 — scratch 경로: <세션 scratchpad>/validate-<task-id>/» 한 줄(ADR-050#amend-2).
     - 축 목록 (1축 = 1 validator sub-task):
       1. AC ↔ 검증 매핑 (modality별 증거 판정 — ADR-065 D1 + 테스트 선행 휴리스틱 + `[verify-placeholder]` / `[test-id-missing]` + 충족률·자동화율 산정)
       2. 범위 밖 변경 + diff trace audit (ADR-006#amend-1)
       3. FAC → AC spec coverage audit (ADR-037)
       4. Arch-iface 7-1/7-2/7-3/7-4/7-5 audit (API/CLI/백엔드/프론트/모바일)
       5. UI Design inventory audit (ADR-073 D8) — diff에 UI surface 파일이 있을 때만 spawn (ADR-075 D12)
       6. MCP 사용 audit (ADR-048#d5)
       7. Evidence Bundle 축(통합 명령 실행 결과 + oracle gap surface 점검 + ADR-064 receipt 판정 — 실행 증거/판정력/미실측 잔존, 전부 P1 기록 등급. 별도 축을 만들지 않는다)
       8. Cross-task seam 축 (feature `## 7-2`가 실재하고 "(해당 없음)"이 아닐 때만 spawn — ADR-057 결정 12)
     - **신호 기반 조건부 spawn (cost guard 확장)**: 축 3(FAC spec)·4(Arch-iface)·5(UI)·6(MCP)·8(seam — feature `## 7-2` 실재)는 *해당 신호가 있을 때만* spawn한다 — 3 = task가 feature에 연결(`## 7 Feature` 링크), 4 = API/CLI/백엔드/프론트 신호(7-x 키워드·path), 5 = diff에 UI surface 파일 집합(정의: ADR-073#amend-2 결정 1)의 파일 1개 이상(ADR-075 D12 — UI 프로젝트라도 파일이 없으면 spawn하지 않고 «해당없음» 인라인 기록), 6 = task `## 3`에 MCP 사용 line item, 8 = feature `## 7-2` 실재. 신호 없는 축은 spawn하지 않고 메인이 "해당없음"으로 인라인 기록한다(중간 크기 task의 과다 팬아웃 방지). 축 1(AC↔검증)·2(diff-trace)·7(Evidence Bundle)은 항상 해당. **한 dispatch에 두 축을 합치지 않는다(1축 = 1 validator — ADR-075 D11).**
     - **통합 검증 명령(1단계)은 메인 세션이 1회만 실행**하고 그 결과(exit code + stdout/stderr 요약)를 7번 축 validator와 집계에 공유한다 — N개 validator가 `pnpm validate`를 중복 실행하지 않는다.
     - **공통 팩 주입 (ADR-076 D13)**: 메인이 이미 1회 계산하는 아래 셋을 **모든 축 프롬프트에 같은 팩으로** 넣는다 — ① 아래 small-diff 계산의 F·L_impl·L_test·L_docs와 변경 파일 목록(`git -c core.quotePath=false status --porcelain -uall`로 뽑는다 — 검증자는 팩을 다시 계산하지 않으므로 8진수로 바뀐 한글 경로가 넘어가면 그 파일을 열지 못한다) ② 1단계 통합 명령의 exit code + 실패 요약(최대 20줄 — 7번 축만이 아니라 모든 축에) ③ 축별로 읽을 문서 경로·앵커(task 문서, feature `## 7`·`## 7-1`·`## 7-2`, ARCH `## 7-x`, DESIGN 절). 팩은 **기계적 결과와 경로만** 담는다 — task·문서 내용은 검증자가 원본에서 직접 읽고, 무엇을 지적하지 말라거나 심각도를 미리 정하는 문구를 넣지 않는다(ADR-050#amend-1). 위 scratch 경로 한 줄과 함께 넣는다. 턴 수는 적지 않는다(ADR-074 D9).
     - **small-diff fallback 기준 — 계산이 먼저, 초과 시 재량 0** (cost guard, ADR-075 D11): dispatch 전에 크기를 *결정적 명령으로 계산한다*. 파일을 «테스트 파일 집합»(test/**, tests/**, __tests__/**, e2e/**, integration_test/**, **/*.test.*, **/*.spec.*, **/*_test.dart)·«문서 집합»(docs/**)·구현 파일 셋으로 분류하고 각각 줄 수를 합산한다. **tracked 줄 변경** = `git diff HEAD --numstat` 각 행의 (added+deleted)를 그 파일의 분류에 더한다(**binary 파일은 numstat이 `-\t-`로 표기 → 0으로 취급**; rename 행 `{old => new}`도 숫자 열은 그대로라 합산 정상); **untracked 신규** = `git status --porcelain --untracked-files=all`(= `-uall`)의 `??` 항목 각 *파일* 줄 수(`wc -l`)를 같은 분류로 합산. **`-uall`이 핵심** — 기본 `git status --porcelain`은 untracked 디렉터리를 `?? dir/` 한 줄로 접어 파일 수를 놓치고 `wc -l`을 디렉터리에 돌리면 깨진다(예: untracked 대량 디렉터리가 1로 오계산). **L_impl = 구현 파일 합, L_test = 테스트 파일 집합 합, L_docs = 문서 집합 합, F = numstat 행 수 + untracked 파일 수(전체).** **기준은 working tree 전체(HEAD 대비)** — 정상 lifecycle은 직전 task가 finalize로 커밋돼 tree엔 본 task 변경분만 남으므로 별도 '관련 파일' 선별이 불요하다. **over-count는 안전하다**(크게 세면 fan-out으로 기울 뿐 — 검증을 *더* 하는 쪽). 그래서 무관한 dirty/untracked가 섞여도 **임의 제외하지 말고**(제외가 재량 우회 창구가 된다) 전부 센 뒤 `## Orchestration`에 "오염 tree(무관 파일 포함 가능)" 사유만 적는다. 정확한 수가 필요하면 무관분을 stash 후 재계산해도 되지만 필수 아님 — **공유 worktree에서 사용자 변경을 강제 커밋/stash하지 않는다**. inline 허용은 **(L_impl ≤ 50) 또는 (F ≤ 2 이고 L_impl ≤ 200)** … (ADR-075 D11 — L_impl은 테스트 파일 집합과 docs/**를 제외한 변경 줄 합), *그리고* UI/Arch-iface/MCP/spec-coverage 중 둘 이상이 명백히 해당없음 — **셋 다 충족일 때만**. 하나라도 미충족이면 **fan-out 필수 — inline 선택 불가(재량 0)**. 조건 충족이어도 "vertical slice라 하나로 본다" 류 사유로 inline을 택하려면 `## Orchestration`의 fallback 사유에 계산한 F·L_impl·L_test·L_docs + "임계 미달"을 명시 기록한다. **임계 초과인데 inline이면 규칙 위반**(산출물로 반증 가능 — SIMULATION_RUN Round 4 T-002 우회 재발 방지). 경계값(50/200)은 Round 11 실측으로 재보정됐다(ADR-075 D11). 다음 재보정 창구는 ADR-075 재검토 트리거다. 어느 경로를 탔든 report `## Orchestration` 기록은 의무다.
     - **축 미반환 회수 규율 (ADR-075 D13)**: 위임한 validator가 구조화 partial verdict 없이 멈추면 ① 1회 재개(같은 축·같은 형식 명세로 재요청, 이미 확립한 finding 전량 포함을 명시) → ② 그래도 미반환이면 다른 validator에 재위임 → ③ 그래도 불가하면 메인이 그 축을 직접 감사 → ④ 그래도 불가하면 **`감사 미완(unavailable): <축>`으로 기록한다.** "결과 없음"을 조용히 통과시키지 않는다.
     - **④에 도달한 축이 하나라도 있으면 `Pass`를 낼 수 없다** (근거: ADR-068 D4 평가 규칙 — 미실행 감사가 입력을 주는 판정을 충족으로 단정하지 않는다). report `## 실패 항목`에 `[P0] 감사 미완(unavailable): <축> — 재검증 필요(수정 대상 아님)`을 적고 combined verdict는 `Needs Fix`로 낸다. 단 **후속 라우팅은 `/repair-workitem`이 아니라 `/validate-workitem` 재실행**이다(고칠 코드가 없다) — report `## 다음 권장 액션`에 그렇게 적고 자동 후속 호출을 하지 않는다(`[Spec-gap]`의 사용자 보고 라우팅과 동형). 이 축의 존재는 `## Orchestration`에도 남고, `/finalize-workitem`이 그것을 `- closure`의 `audit=` 칸으로 옮겨 적으므로 졸업 item 1이 읽는다(ADR-068 D2·D3 item 1).
     - **Codex: 서브에이전트는 GA이나 본 저장소가 Claude persona 위임을 Codex subagent로 아직 매핑하지 않아 순차 단일 실행으로 degrade** — 이 매핑이 없으므로(ADR-010) 위 축을 순차로 단일 실행해 같은 partial들을 모은 뒤 동일하게 메인이 집계·작성한다.
1. 통합 검증 명령(`pnpm validate` / `npm run validate` / `make validate` / `task validate` 중 하나)이 있으면 **항상 실행**하고 stdout/stderr를 수집한다 (메인 세션 연쇄 실행이라도 implement 이후 코드 상태가 바뀌었으므로 직전 결과를 재사용하지 않는다).
   - **명령이 없을 때 (ADR-007#amend-3)**: `docs/00-meta/STACK_SETUP_PLAN.md`가 *존재*하면(스택 확정) skip하지 않고 **`Needs Stack Guard`로 종료** + `/stack-guard` 실행 안내. STACK_SETUP_PLAN.md가 *없으면*(스택 미정) 기존대로 이 단계 skip하고 정적 판정만 한다.
   - 다른 빌더(`bun validate`, `mise run validate`, `just validate` 등)를 쓰는 스택은 본 skill의 `allowed-tools`에 해당 패턴(`Bash(bun validate)` 등)을 추가해야 자동 실행된다.
2. 관련 workitem 문서를 읽는다 — **메인 세션 연쇄 실행으로 직전 단계가 이미 같은 task 문서를 메인 컨텍스트에 올렸고 그 뒤 문서가 갱신되지 않았으면 재독을 생략**하고, 없거나 갱신됐으면 읽는다 (ADR-019 minimal sufficiency).
3. 필요한 상위 문서를 읽는다 (사전 fork-load 금지 — task 본문에서 발화 시 인용).
4. 최근 변경 파일 또는 diff를 기준으로 구현 결과를 본다 — **직전 단계 이후 코드/diff가 바뀌었으므로 diff는 항상 새로 확인**한다.

검증 기준:
- 문서 범위와 구현이 일치하는가
- 범위 밖 변경 + diff trace audit (ADR-006#amend-1):
  변경 파일 회수를 `git status --porcelain`(untracked 신규 파일 포함) 기준으로 한다 — tracked 변경은 `git diff HEAD`의 각 줄로(staged+unstaged 모두 — plain `git diff`는 staged를 놓침), untracked 신규 파일은 파일 전체 내용을 대상으로, 각각이 task의 AC-N 또는 명시 요청으로
  거꾸로 추적 가능한지 감사한다(신규 파일이 감사에서 누락되지 않게 — finalize의 `git status` 방식 정합). **원장(`DECISION_REGISTER.md`)의 `status: closed` + `authority: user-*` 항목(`D-NNN`) 을 이행해 추가된 줄은 대응 AC 가 없어도 "명시 요청"으로 보아 *추적 가능*으로 분류하고, 근거를 `D-NNN` + 7-x 앵커로 적는다 (ADR-061 D2 — ADR-006#amend-1 문구의 해석 고정).** 추적 불가 줄은 다음 카테고리 중 하나로 분류 보고.

  Needs Fix 트리거 (강 constraint, P0 라벨):
    (c) pre-existing dead code 삭제 — task 범위 밖 *파괴적 변경*. Pass 차단.

  Report only + reviewer 라벨 권장 (약 enabling, P1/P2 라벨):
    (a) 인접 코드 포맷팅/주석 정리 — P1
    (b) 무관 리팩토링 (행동 미변경 코드 구조 변경) — P1
    (d) 스타일 변경 (semicolon, quote, indent 등) — P2

  의도적 (c)는 task 문서에 명시 요청으로 박혀 있을 때만 Pass 통과.
- 빠진 검증 포인트가 있는가
- obvious regression risk가 있는가
- 통합 검증 명령(있으면) 결과는 통과인가
- AC ↔ 검증 매핑 (ADR-065 D1) — task `## 6-1`의 AC마다 `[modality]`를 읽고 그 modality가 요구하는 증거가 실재하는지 판정한다: `[자동 테스트]`=대응 테스트 실재(자연어 매칭 휴리스틱 또는 `AC_N` 식별자 매칭), `[산출물 검사]`=`## 6-1`에 기록된 검사 수단이 **통합 `validate`에 묶여 있고 그 실행이 통과**했는가(1단계에서 수집한 결과로 판정 — 검사 명령을 여기서 실행하지 않는다). 묶이지 않은 검사 수단은 충족 근거가 아니며 `P1 [Artifact-check-unbound] AC-N`으로 기록하고 그 AC는 미충족, `[사용자 관측]`·`[플랫폼 관측]`=task `## 8`에서 **그 AC의 마지막 이벤트가 `- ac-acceptance`**(ADR-065 D3 판독 규칙 2 — 마지막이 `- invalidated`면 미충족. HTML 주석 밖의 줄만 센다). **modality 표기가 없으면 `[자동 테스트]`로 간주해 판정한다(legacy 호환 — 아래 둘째 불릿)**. `## 6-2. TDD opt-out`은 충족의 예외가 아니다(ADR-065 D2 — 이 예외를 두면 `## 6-2` 두 줄로 AC 게이트가 사라진다). **`## 6-1`의 `VC-N` 행은 AC 행동으로 귀속되지 않는 판정력 확인용(positive control 등)이므로 본 매핑의 분자·분모 어디에도 넣지 않는다 (ADR-064 D2)** — 자동화율이 아래 confidence ladder의 입력이라 섞이면 등급이 이동한다. 대신 `VC-N`이 가리키는 테스트 줄은 diff trace audit에서 *추적 가능*으로 분류한다(추적 근거는 `AC-N | 명시 요청 | VC-N` 셋이다 — ADR-006#amend-1 문구의 해석 확장). **미충족 표현의 정본형 (중요)**: 어떤 modality든 미충족일 때 **`[modality]` 표기를 결과 라벨로 덮어쓰지 않는다.** `[사용자 관측]`·`[플랫폼 관측]`이 미충족이면 `- AC-N: ❌ [사용자 관측] receipt 대기 — `## 8`에 유효한 `- ac-acceptance` 없음` 형태로 적는다. **`[미관측]`은 «표기 부재 + 대응 테스트 없음»(legacy) 한 경우에만 쓴다**(ADR-065 D1). modality를 지우면 판정값(D6) 산출과 `/finalize-workitem` 분기가 «코드로 고칠 것»과 «사람이 볼 것»을 구분할 수 없다. **관측 AC의 미충족은 `## 실패 항목`에 적지 않는다** — 그 섹션은 `Needs Fix`일 때만 존재하고 이 AC는 판정을 `Needs Fix`로 만들지 않는다. 대신 `## Evidence Bundle`의 «검증하지 못한 것(oracle gap)» 하단에 `- receipt 대기: AC-N [<modality>] — 마일스톤 수용 라운드에서 발급` 한 줄을 남긴다.
- **modality 표기 부재 (ADR-065 D1 legacy 규칙)**: 표기가 없는 AC는 **`[자동 테스트]`로 간주**한다(기존 fork 호환 — 판정이 현행과 동일해진다). 그 AC에 대응 테스트가 없으면 기존과 같이 미충족이다. 표기 부재 자체는 `P2 [Modality-missing] AC-N`으로 기록만 한다(차단 X).
- **AC 해석 기록 (ADR-076 D5)**: task `## 8`(HTML 주석 밖의 줄만)에 그 AC의 `해석 확정:`(없으면 `해석 잠정:`)이 있으면 그 해석을 기준으로 충족을 판정한다. 잠정 해석 자체는 finding이 아니다.
- **두 수치 (ADR-065 D4)**: `충족률`(전 modality)과 `자동화율`(`[자동 테스트]`+`[산출물 검사]`)을 따로 계산해 report에 적는다. **confidence ladder의 입력은 자동화율이다** — 사람·플랫폼 관측이 많은 task가 자동으로 High가 되지 않게 한다. 자동화율의 분모는 **AC 수**이지 `## 6-1` 행 수가 아니다 — 한 AC가 두 modality 행으로 존재하면 계획 오류이며(ADR-065 D1 «정확히 하나»), `P2 [Modality-split-needed] AC-N`으로 기록하고 분모는 AC 수로 센다(Round 12 발견 30).
- **confidence 임계값 (본문 SSOT — 아래 report 양식의 주석은 이 값의 사본이다)**: 평가 순서는 Low → Medium → High이며 **첫 매치로 확정**한다.
  - **Low** (하나라도 매치): 통합 명령 미통과 / oracle gap 카테고리 미명시(누락 ≥2) / **자동화율 < 70%** / **미충족 «기계 검증» AC 있음**
  - **Medium** (잔여 등급 — Low도 High도 아닌 전부): Low 조건 모두 불일치 + High 조건을 전부 충족하지는 못함(예: 자동화율 70~89% / oracle gap 1개 누락 / diff trace audit 미통과). **미달 개수에 상한을 두지 않는다** — 상한을 두면 «Low 아님 + High 아님 + 3개 미달»이 어느 등급에도 들어가지 못해 아래 self-check ④가 만족 불가능해진다(`out-of-AC` 직접 수정분의 재validate가 diff trace 미통과 + 자동화율 하락을 동시에 만들므로 실제로 도달하는 조합이다).
  - **High**: 통합 명령 통과 + **자동화율 ≥ 90%** + diff trace audit 통과 + oracle gap 카테고리 전부 명시
  - **Low 조건의 «미충족 AC 있음»을 «기계 검증 AC 한정»으로 읽는 이유**: 사람·플랫폼 관측 비중은 자동화율 <70%가 이미 잡는다. 관측 AC의 receipt 미발급까지 세면 이중으로 깎여 정상 `Pending Acceptance` task가 무조건 Low가 된다(ADR-065 D6).
- **report 저장 전 self-check (5항목 — 하나라도 어긋나면 저장하지 않고 재계산한다)**: ① 관측 AC의 receipt 판독이 `## 8`의 «마지막 이벤트» 규칙대로인가 ② 판정값이 D6 우선순위의 첫 매치인가 ③ 충족률·자동화율의 분자·분모가 AC 행과 일치하는가(`VC-N` 제외) ④ confidence가 위 임계값의 첫 매치인가 ⑤ `## 다음 권장 액션`이 판정값과 일치하는가(`Pass`·`Pending Acceptance` → finalize / 감사 미완 → 재validate / **`P0 [Spec-gap]` 있음 → 사용자 보고**(아래 spec coverage audit의 «task 자동 추가 금지»가 일반 repair 안내보다 우선한다 — 계획 누락은 코드 수리로 해소되지 않는다) / 그 외 `Needs Fix` → repair).
  - `## 6-1. 테스트 시나리오` 항목이 `→ <runner>::<file>::<test-id>` 형식이고 *값에 angle-bracket placeholder(`<...>`)가 포함되지 않으면* path 우선 resolve (deterministic, ADR-047 D6 contract formation + D1 inspectability 정합, ADR-009).
  - 값에 `<runner>` / `<file>` / `<test-id>` 같은 angle-bracket placeholder가 잔존하면 *미설정*으로 간주 + 본 report에 P2 `[verify-placeholder]` 라벨로 기록 — 기록 위치: *Needs Fix 판정 시* `## 실패 항목` 하단에 한 줄, *`Pass`·`Pending Acceptance` 판정 시* `## Evidence Bundle` 의 *검증된 것* sub-section 하단에 한 줄(`## 실패 항목`은 Needs Fix일 때만 존재하므로). 자연어 매칭 fallback으로 계속 진행 (validate-workitem 책임 경계 정합 — IMPROVEMENT_GUIDE 직접 append는 stabilize-milestone이 reviewer 결과 받아 적는 영역).
- 테스트 선행 휴리스틱 — git log에서 동일 task 범위의 테스트 파일 추가/수정이 구현 파일보다 먼저(또는 동일 커밋) 들어왔는지. 단순 경고로만 보고하고 강제 종료하지 않는다(소규모 작업이 한 커밋에 묶이는 경우 정상).
- FAC → AC spec coverage audit ([ADR-037](../../../docs/90-decisions/boilerplate/ADR-037-spec-coverage-audit.md)#amend-3):
  feature `## 7 FAC`의 각 항목이 본 task의 `## 6 AC` 또는 *연관 task의 AC*에
  매핑되는가? 매핑 안 된 FAC가 있으면 report의 "Spec coverage" 섹션에
  `P0 [Spec-gap] FAC-N → unmapped — 계획 누락, 사용자 결정 필요`로 기록한다. 우변이 `승인 스냅샷 <경로> (manifest: …)` 형식인 행은 unmapped 가 아니다(ADR-037#amend-4).
  **task 자동 추가 금지** — P0라 combined verdict는 Needs Fix, 집계자는 이 라벨이 있으면 일반 `/repair-workitem` 안내보다 우선해 자동 후속 호출 없이 사용자 보고로 라우팅한다. legacy fallback은 plan-workitem SKILL.md의 "task 분해 + ## 7-1 AC 측 채움" 섹션 **Legacy fallback** 단락 참조.
  - **계측 속성 도메인 관찰(기록 등급)**: task `## 3`의 계측 이벤트 속성이 승인 UI·도메인에서 산출 가능한 값인지 diff로 본다. 불가하면 `P2 [Instrumentation-domain] <이벤트.속성>`(Round 12 발견 31 — 계획 시점 3-S (b)는 콜백 유무까지만 본다).
- **UI 프로젝트 — Design inventory audit** (ADR-073 D8): 본 task 가 새 컴포넌트를 추가했는데 task `## 3. 구현 항목` 의 *등록 line item* (plan authoring) 이 실행 누락이면 `P1 [Design-inventory]`. 등록 line item 자체가 부재한데 신규 컴포넌트 출현이면 `P1 [Design-inventory-planless]` 기록하고 분기: 기존 task AC에 필요한 컴포넌트면 repair-workitem이 구현 또는 DESIGN 등록 누락을 고치고, 불필요하면 제거, 새 디자인 범위면 사용자 보고 + 다음 M 후보(ADR-057#amend-3 결정 6). **승인 UI 재사용 diff 점검**: task `## 3`에 `승인 UI 재사용` line item이 있고 diff가 배선 범위를 넘으면 `P1 [Design-reuse-drift]`(ADR-072 D5-4) — 검증기준은 validator.md와 동일. task `## 3`에 `승인 UI 재사용` line item이 있고 diff가 그 화면의 매니페스트 `source[]`를 건드릴 때만 `validate:design -- --manifest <M> --only <screen id>` 실행(allowed-tools에 `Bash(npm run validate:design*)` 등 4 PM 변형 추가 — 없으면 추가). 그 외 task는 게이트를 돌리지 않는다(task마다 Storybook 재빌드 비용). 행동 변경 고지 누락은 `P2 [Design-behavior-drift]`(ADR-072#amend-5 결정 5).
- **MCP 사용 audit** (ADR-048#d5): task `## 3. 구현 항목`에 `<capability> 작업 시 <mcp-name> MCP 사용` line item(plan authoring)이 있었는데 실행 흔적(diff / test / 출력)이 없으면 report에 `P2 [MCP-unused] <mcp-name> — plan이 박은 MCP 사용 line item 미실행` 기록. implement가 `Needs MCP Access`로 멈춘 경우(권한 미부여)는 `P2 [MCP-access] <mcp-name> — agent access 미부여(연결 절차 (e))`로 구분 기록. 자동 차단 X(report 신뢰 등급만 영향).
- **API/CLI/백엔드/프론트/모바일 — Arch-iface audit**: 본 task 가 ARCH `## 7-1`/`## 7-2`/`## 7-3`/`## 7-4` / `## 7-5` 의 기존 결정을 위반했거나, 신규 결정을 *7-x 본문 갱신 없이* 도입했으면 report 에 `[Arch-iface-7-N]` 기록 + 7-x 본문 갱신 권장 또는 ADR 후보 표시. **등급 분기 (ADR-061 D1)**: 위반된 7-x 항목이 [DECISION_REGISTER.md](../../../docs/10-charter/DECISION_REGISTER.md) 의 `status: closed` + `authority: user-choice|user-approval` 항목(그 항목의 `정본:` 앵커가 이 7-x 를 가리킴)으로 추적되거나, 그 7-x 의 `### Don'ts` 를 위반하면 **`P0 [Arch-iface-7-N]`** — Needs Fix 트리거다(사용자가 승인해 닫은 결정을 구현이 뒤집은 것을 보고만으로 통과시키지 않는다). **`Don'ts` 위반은 authority 와 무관하게 P0 다** — 금지 규정은 성질상 AC 로 회수될 수 없어 구현 시점 외에 검출 지점이 없다(ADR-060 D9 상 `Don'ts` 소항목 자체는 `agent-delegated` 이지만, 아래 P1 규칙보다 본 분기가 우선한다). 그 외(agent-delegated 컨벤션 불일치·7-x 본문 문구 미갱신 등)는 기존대로 **`P1`**. 원장 조회는 `## 결정 항목` 아래의 실제 `D-NNN` 항목만 대상으로 한다(설명 섹션의 형식 예시는 항목이 아니다 — ADR-019 색인 회수). 원장 파일이 없거나 해당 앵커 항목을 찾지 못하면 P1 로 두고 그 사실을 report 에 한 줄 기록한다.
- **Cross-task seam audit** (feature `## 7-2`가 실재하고 "(해당 없음)"이 아닐 때만 — ADR-057 결정 12): 본 task 구현이 관련 INV-N을 위반하는가(상태 역방향 write / 멱등 미보장 / 2차-write 누락)? INV가 테스트로 커버되는가? 위반·미커버 시 `P1 [Seam] INV-N — <증상>`. §7-2가 참조 링크형이면 canonical feature 의 표를 따라 읽는다. (inline·fan-out 축 8 동일 기준 — small-diff inline 경로에서도 누락 없이 점검.)
- **Evidence Bundle 양식 강제** (ADR-047 D8 oracle adequacy + D1 inspectability 정합): 위 양식의 "검증된 것 / 검증하지 못한 것 / 신뢰도" 3 sub-section을 *모두* 채운다. Pass 판정이라도 oracle gap이 명시 안 되면 *신뢰도: Low*로 강등 (자동 차단 X — report 신뢰 등급만 영향).
- **아래 세 판정의 공통 판독 규칙 (ADR-064 D4)**: `- 외부 경계:` · `[미실측]` · `- exec-evidence`/`- verify-power` 를 찾을 때는 **HTML 주석(`<!-- ... -->`) 밖의 줄만** 센다. TASK_TEMPLATE 주석에 같은 형식의 예시가 들어 있어, 주석까지 세면 앞의 둘은 모든 task에서 오탐이 나고 `- exec-evidence`는 항상 존재로 보여 검사가 조용히 죽는다(원장 조회의 "설명 섹션의 형식 예시는 항목이 아니다"와 동형).
- **실행 증거 판정** (ADR-064 D1/D7 — 본 skill은 실행하지 않고 *기록만 읽는다*): 본 task가 외부 경계를 건드렸는가를 diff와 task `## 2`의 `- 외부 경계:` 표시로 판정한다((a) 영속 저장소 쓰기 / (b) **외부** 네트워크 호출 — 같은 배포 단위 안의 서비스 간 호출은 제외 / (c) 실행 진입점). 해당하는 **경계 종류마다** task `## 8`에 `- exec-evidence` 줄이 있어야 한다. 없으면 `P1 [Exec-evidence-missing] <경계 종류>`. 사용자 waiver로 기록된 줄은 충족으로 보고 사유를 report에 인용한다. **줄의 존재 여부만 본다 — 신선도는 판정하지 않는다**(digest·커밋 비교는 도구가 없고, 줄 순서 기반 판정은 정상 repair 라운드에서 오탐이 난다. 근거는 ADR-064 D4). 증거 갱신은 코드를 고친 `/repair-workitem`의 책임이다. **본 항목은 기록 등급이며 Needs Fix를 트리거하지 않는다** — 실질 차단은 `/implement-workitem`의 `Needs Execution Evidence` 정지가 담당한다(ADR-064 D7). 경계 종류의 **마지막** `- exec-evidence` 줄이 `미확보`이면 `P1 [Exec-evidence-stale] <경계 종류> — repair가 재확보하지 못함`으로 기록한다(ADR-064 D4 «고친 주체가 갱신» 원칙 — 미확보도 갱신이다).
- **판정력 판정** (ADR-064 D2/D7): **`[사용자 관측]`·`[플랫폼 관측]` modality AC는 대상에서 제외한다**(Red가 성립하지 않으므로 `- verify-power` 줄이 없는 것이 정상 — ADR-065 D1). 나머지 각 AC에 대해 task `## 8`에 `- verify-power` 줄이 있고 `red=` 값이 `observed|opt-out(사유)|characterization(사유)|unrecoverable(사유)` 중 하나인가. 없거나 값이 비면 `P1 [Verify-power-missing] AC-N`. **`opt-out`·`characterization`은 정상이며 결함이 아니다**(정당한 TDD opt-out·`Type: research-spike`·`Type: refactor`). `mutation=미승격`도 정상이다. 기록 등급 — Needs Fix를 트리거하지 않는다.
- **미실측 잔존 판정** (ADR-064 D3): task `## 3`에 `[미실측]` 표기가 남아 있으면 `P1 [Unmeasured-fact] <무엇> — 구현 시 해소되지 않음`. 기록 등급.

마지막 단계 — partial 집계 + report 파일 작성 (집계자=메인 세션 단독):
0단계에서 팬아웃했으면 각 validator가 반환한 partial verdict(축별 findings + 그 축의 evidence)를
*메인 세션이* 모아 아래 양식의 report 1개를 `docs/40-validation/reports/<task-id>.md`에 기록한다(이미 있으면 덮어쓴다).
validator는 이 파일을 쓰지 않는다(clobber 방지). inline fallback이면 메인 세션이 자기 판정을 그대로 기록한다.

집계 규칙 (combined verdict):
- **판정값 3종 (ADR-065 D6) — 우선순위 `Needs Fix` > `Pending Acceptance` > `Pass`, 먼저 성립하는 값으로 확정한다.**
  - **`Needs Fix`**: 어느 한 축이라도 P0 finding이 있거나 / 통합 검증 명령이 exit≠0이거나(통합 명령 부재 스택은 해당 없음) / **`[사용자 관측]`·`[플랫폼 관측]`이 아닌 미충족 AC**가 하나라도 있으면(`미관측` 포함).
  - **`Pending Acceptance`**: 위가 전부 아니고, **`[사용자 관측]`·`[플랫폼 관측]` AC의 receipt만 미발급**일 때. 이 AC에는 고칠 코드가 없다(receipt는 사용자만 발급한다 — ADR-065 D1).
  - **`Pass`**: 미충족 AC 0건.
  - P1/P2 라벨만 있는 것은 판정을 바꾸지 않는다(라벨은 report에 전수 기록).
  - **`감사 미완(unavailable)`은 `Pending Acceptance`가 아니다** — P0이므로 `Needs Fix`다. 고칠 것은 없지만 *판정할 수 없는* 상태이므로 `Pass` 계열을 낼 수 없다(ADR-068 D4와 동일 원리).
  - **하류가 이 값으로 갈린다**: `/finalize-workitem`은 `Pass`·`Pending Acceptance`를 통과시키고 `Needs Fix`를 차단한다. `/repair-workitem`은 `Pass`·`Pending Acceptance`면 종료한다. 졸업 item 1은 이 판정값을 task `## 8`의 `- closure` 줄에서 읽는다(ADR-068 D3).
- 각 축의 partial findings(P0/P1/P2)·`[verify-placeholder]`·`[test-id-missing]`·`Spec Gap`·`[Design-inventory*]`·`[MCP-*]`·`[Arch-iface-7-N]`를 누락 없이 해당 report 섹션에 전수 합친다(ADR-046#d3 — cap 때문에 finding 누락 금지).
- **confidence는 메인 세션이 *집계 후* 재계산**한다(개별 validator의 신뢰도 추정을 그대로 신뢰하지 않는다). 아래 confidence ladder의 입력(통합 명령 통과 여부 / 자동화율 / diff trace 통과 / oracle gap 카테고리 명시 여부)을 *집계된 전체*에서 평가해 Low→Medium→High 첫 매치로 확정한다.
- **잔여 finding (ADR-076 D10)**: 판정이 `Pass`·`Pending Acceptance`면 모든 축의 P1·P2를 원래 등급·라벨·위치(파일:라인 또는 AC-N) 그대로 `## 잔여 finding`에 전수 적는다(다른 섹션에 이미 적힌 것도 여기에 한 번 더 — `/stabilize-milestone`의 회수 입력).

```markdown
# Validation Report: <task-id>

- 검증 시각: <ISO 8601 타임스탬프>
- task-id: <task-id>
- 판정: Pass | Pending Acceptance | Needs Fix

## Orchestration (ADR-075 D10)
<!-- 5줄 이내. 팬아웃/inline 여부를 산출물로 검증 가능하게 하는 관측 섹션 -->
- 모드: fan-out N축 | inline fallback | Codex 순차 degrade
- spawn된 축: <번호·이름 목록 (예: 1 AC↔검증, 2 diff-trace, 7 Evidence)>
- 회수된 축: <번호 목록> / 재개 1회로 회수: <번호 목록 또는 없음>
- 감사 미완(unavailable): <축 — 4단계 회수 전부 실패 사유 / 없음>  ← 1건 이상이면 판정은 Pass 불가
- skip된 축: <축 — 사유 (신호 없음 / 해당없음)>
- 크기 측정 (**모드 무관 필수** — ADR-075 D11): 파일 F개 · 구현 줄 L_impl · 테스트 줄 L_test · 문서 줄 L_docs (`git status --porcelain` 기준 — tracked=`git diff HEAD`, untracked=파일 전체) + 판정 근거 한 줄. 임계 미달이면 **inline 정당 근거**이고, **임계 초과면 inline 불가(fan-out 필수)** — "임계 초과 예외 inline"은 없다(재량 0). **fan-out 모드에서도 네 값과 근거를 비우지 않는다** — 판정이 산출물로 검증 가능해야 한다.

## 통합 명령 실행 결과
<있으면 명령어와 stdout/stderr 요약, 없으면 "통합 명령 미설정 — 정적 판정만 수행">

## 실패 항목 (Needs Fix일 때만)
- [P0] <짧은 설명> — <관련 파일:라인>
- [P1] <...>
- [P2] <...>

## Diff trace audit (ADR-006#amend-1)
- 추적 가능 변경 줄: N개 (AC-1: M개, AC-2: ...)
- 추적 불가 변경 줄: K개
  - (a) 인접 포맷팅/주석: <file:line> ... [P1]
  - (b) 무관 리팩토링: ... [P1]
  - (c) pre-existing dead code 삭제: ... [P0 — Needs Fix 트리거]
  - (d) 스타일 변경: ... [P2]
- 판정 영향: <판정 유지 / Needs Fix 트리거 (오직 (c) 의도 외 발견 시)>

## AC ↔ 검증 매핑 (ADR-065)
- AC-1: ✅ [자동 테스트] tests/foo.spec.ts > test_AC_1_xxx
- AC-2: ✅ [산출물 검사] validate 통과 — insights 노트 필수 섹션 3개 검사(`scripts/verify` 내 docs 검사 단계)
- AC-3: ✅ [사용자 관측] ac-acceptance 2026-08-09 / authority: 사용자 / 환경: Chrome 128·로컬
- AC-4: ✅ [플랫폼 관측] ac-acceptance 2026-08-09 / authority: 사용자 / source: GH Actions run 12345
- AC-4b: ❌ [사용자 관측] receipt 대기 — `## 8`에 유효한 `- ac-acceptance` 없음 (수용 라운드에서 발급 — 판정은 `Pending Acceptance`)
- AC-5: ❌ [미관측] 표기 없음 → 자동 테스트 간주(legacy) — 대응 테스트 없음. `P2 [Modality-missing] AC-5` 병기
- **충족률: 4/6 (67%) · 자동화율: 2/6 (33%)**
- **검증 레벨 분포: unit N / integration M / contract K / e2e L · 레벨 비대상 P** — **`[자동 테스트]` AC만 레벨 분포 대상**(명시 `{레벨}` 태그 우선, 미기재는 테스트 경로 추론). `[산출물 검사]`와 관측 2종은 테스트 경로가 없어 `레벨 비대상`으로 센다 — **«비자동»이라 부르지 않는다**: `[산출물 검사]`는 자동화율의 분자에 들어가므로(ADR-065 D4) 같은 AC가 두 수치에서 반대로 분류된다. 레벨 4종의 합 = `[자동 테스트]` AC 수, `+ 레벨 비대상` = 전체 AC 수 (기록 등급)

## Spec coverage (FAC ↔ AC, ADR-037)
- FAC-1: ✅ T-001:AC-1
- FAC-2: ✅ T-001:AC-2
- FAC-3: ❌ `P0 [Spec-gap]` unmapped — 계획 누락, 사용자 결정 필요(task 자동 추가 금지)

## 실행 증거 · 판정력 (ADR-064 — 전부 기록 등급, Needs Fix 미트리거)
- 외부 경계: 해당(a 영속 저장소 / b 외부 네트워크 / c 진입점) | 해당없음
- exec-evidence: (a) ✅ 등급1 재실행 가능 / (b) ❌ `P1 [Exec-evidence-missing]` / waiver(<사유>) | 해당없음
- verify-power: AC-1 ✅ observed / AC-2 ✅ opt-out(spike) / AC-3 ❌ `P1 [Verify-power-missing]` / AC-4 해당없음(사용자 관측)
- VC-N: <등재 목록 또는 없음> (충족률·자동화율 집계 제외)
- 미실측 잔존: 0건 | `P1 [Unmeasured-fact] <무엇>`

## Evidence Bundle (ADR-047 D8 oracle adequacy 정합)
<!-- 본 검증 라운드가 *무엇을 봤고 무엇을 못 봤는지* 명시. green test가 곧 충분한 검증이라는 착각을 줄인다. -->

### 검증된 것 (verified)
- 통합 명령 exit code: <0 / non-zero / 미설정>
- AC↔검증 매핑: 충족 M개 / 미충족 K개 — 충족률 <%> · 자동화율 <%> (modality별 내역은 `## AC ↔ 검증 매핑`)
- diff trace audit: 추적 가능 N줄, 추적 불가 K줄(카테고리별)
- FAC↔AC spec coverage: <% / 부재>
- 기타 deterministic 점검: <markdown-link-check / static analysis 등 / 해당없음>

### 검증하지 못한 것 (oracle gap)
<!-- 다음 카테고리 중 *본 task의 surface area에 해당하는 것만* 명시. 해당없으면 "해당없음" 한 줄.
     UI 외에도 backend API에 i18n / 접근성 응답이 있으면 본 카테고리도 surface로 본다. -->
- 동시성·race condition 시나리오: <검증 가능 여부 / 가능 시 도구>
- 운영 환경 부하·성능: <검증 가능 여부>
- 외부 서비스 실패·timeout: <mocked / not covered>
- 보안 (인증 우회·권한 escalation·인젝션): <not covered / partial / not applicable>
- 접근성·국제화 (task surface가 해당하면): <not covered / partial / not applicable>
- 회귀: 이전 milestone의 어떤 시나리오를 본 변경이 깰 위험이 있나 — <명시 또는 "관련 없음">

### 신뢰도 (confidence)
<!-- 기준 (정의 — 같은 입력에 같은 판정 보장. 평가 순서: Low → Medium → High 의 *첫 매치* 등급으로 확정):
     - Low (어느 하나라도 매치): 통합 명령 미통과, 또는 oracle gap 카테고리 미명시(누락 카테고리 ≥2), 또는 **자동화율 <70%**, 또는 **미충족 «기계 검증» AC 있음**(`[자동 테스트]`·`[산출물 검사]`·표기 부재 한정 — 관측 modality의 receipt 미발급은 세지 않는다. 사람·플랫폼 관측 비중은 자동화율 <70%가 이미 잡으므로 이중으로 깎으면 정상 `Pending Acceptance` task가 무조건 Low가 된다. 본 조건의 SSOT는 skill 본문의 confidence 임계값이며 이 주석은 그 사본이다 — ADR-065 D6)
     - Medium (잔여 등급 — Low도 High도 아닌 전부): Low 조건 모두 불일치 + High 조건을 전부 충족하지는 못함 (예: 자동화율 70~89% / oracle gap 카테고리 1개 누락 / diff trace audit 미통과). 미달 개수에 상한을 두지 않는다 — 본 조건의 SSOT는 skill 본문의 confidence 임계값이며 이 주석은 그 사본이다
     - High: 통합 명령 통과 + **자동화율 ≥90%** + diff trace audit 통과 + oracle gap 카테고리 모두 명시(해당없음 포함)
     자동화율(ADR-065 D4)을 쓰는 이유: 충족률로 계산하면 사람·플랫폼 관측만으로 채운 task가 High가 된다. -->
- 본 판정의 신뢰도: <High / Medium / Low> — <한 줄 근거 (예: "통합 명령 + 자동화율 100% + diff trace 통과 + 외부 서비스 의존 없음" / "통합 명령만 통과, 동시성·외부 의존 미검증")>

## 잔여 finding (Pass·Pending Acceptance일 때 — ADR-076 D10)
<!-- Needs Fix면 ## 실패 항목이 대신한다. 남은 P1·P2를 원래 등급·라벨·위치 그대로 한 줄씩. 없으면 "없음". -->
- [P1] [<라벨>] <파일:라인 | AC-N> — <요약>

## 다음 권장 액션
- Pass: `/finalize-workitem <task-id>` (메인 세션이 이어서 직접 발화하거나 사용자가 발화 — ADR-050)
- Needs Fix: `/repair-workitem <task-id>` (메인 세션이 이어서 직접 발화하거나 사용자가 발화 — ADR-050)
- Pending Acceptance: **`/finalize-workitem <task-id>`** — 이 modality는 마감을 막지 않는다(ADR-065 D1·D6). receipt는 마일스톤 수용 라운드(`/accept-milestone <M>` — ADR-066 D1)에서 발급되고 미발급은 졸업 item 4가 잡는다(ADR-068 D3). **`/repair-workitem`으로 보내지 않는다**(고칠 코드가 없어 순환에 빠진다)
- `감사 미완(unavailable)` 축 있음: `/validate-workitem <task-id>` 재실행 (수정 대상 아님)
```

마지막 출력 (메인 세션에 텍스트로):
- Pass / Pending Acceptance / Needs Fix
- 핵심 문제 최대 5개
- report 파일 경로
- orchestration 모드 1줄 (예: "fan-out 4축" / "inline fallback — 1파일 12줄")
- 다음 추천 단계 (텍스트 제안임을 명시)

## Context 정책 (ADR-019)
`반드시 먼저 읽을 파일`은 *최소 충분*. 추가 ADR/architecture 섹션은 task 본문에서 발화 시 인용 — 사전 fork-load 금지.
메인 세션 연쇄 실행(implement→validate→repair, ADR-050) 시 직전 단계가 메인 컨텍스트에 올린 task 문서는 *갱신되지 않았으면 재독 생략*(ADR-075 D8 + ADR-019#amend-1 정합). 단 통합 검증 명령 재실행·diff 재확인·report 신규 작성은 항상 수행(코드 상태/산출물이 매 phase 변한다).

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.