agentleFS
kohj1018kohj1018/agentic-dev-harness/.claude/skills/stabilize-milestone/SKILL.md

stabilize-milestone

Skill2 starsChanged 46 days agoMITView on GitHub

Stabilize a milestone — run E2E + regression + refactoring/ADR review. No code changes, no commits.

The file

Files
SKILL.md

본 skill은 evaluator-optimizer pattern의 evaluator orchestration이다 (ADR-068 D8).

이 skill은 코드 수정·커밋·workitem status 변경을 하지 않는다. 다음 네 종류의 문서 갱신만 정상 책임이다:

  1. docs/40-validation/QA_FINDINGS.md 누적 기록 (결함 — 보고자 무관, ADR-070 D7).
  2. docs/40-validation/IMPROVEMENT_GUIDE.md 누적 기록 (개선 — 보고자 무관 + deterministic preflight 결과).
  3. milestone 문서의 ## 8. 회고 섹션 자동 채움 (ADR-068 graduation contract — status 변경 X, 본문 단락 갱신만).
    • 회고 본문: graduation 줄(YES|PENDING_ACCEPTANCE|NO|BLOCKED (날짜) — 단계 8 판정 영속, ADR-057#amend-1·ADR-068 D4) + open 항목 스냅샷 + post-close 수정 줄(ADR-068 D5) + 4 항목: 목표 달성도 / scope creep / 비목표 위반 / 핵심 학습 3개 이내.
  4. docs/10-charter/DECISION_REGISTER.md append — 점검에서 드러난 기획 결정을 status: open + - 발견: 봉인 후 (M<N>)으로 등재(ADR-060 D11 writer). 기존 항목의 상태는 바꾸지 않는다. 상세는 아래 봉인 후 새 결정 등재 절. milestone 문서 ## 11. 수용 기록은 본 skill의 write 대상이 아니다 — /accept-milestone(마일스톤 스코프) 단독 소유다(ADR-066 D1).

그 외 변경은 금지한다 — milestone 문서의 ## 0. Status / ## 1~7 섹션 / 다른 workitem 문서 / 코드 일체. 후속 작업이 필요하면 /repair-milestone <M>으로 텍스트 제안만 출력한다. inner-loop 4종(/implement-workitem·/validate-workitem·/repair-workitem·/finalize-workitem)의 호출을 권하지 않으며 새 task 자동 추가도 하지 않는다 (ADR-068 D1 / ADR-057#amend-3 결정 6).

실행 single-origin (ADR-054): validate/validate:e2e/npm audit 실행 + QA_FINDINGS/IMPROVEMENT_GUIDE/회고 쓰기는 본 skill(origin)이 한 번만. 같은 checkout에서 stabilize 2개 동시 실행 금지(포트·테스트DB·Playwright outputDir·빌드캐시 충돌 + tracked-doc clobber). 다른 모델 2nd opinion은 읽기 전용 /validate-milestone <M> --reviewer-tag <tag> 병렬 → /repair-milestone이 종합(실행은 origin 1회).

입력:

  • $ARGUMENTS에는 milestone ID(예: M1)가 들어온다. M[0-9]+ 패턴만 허용(미일치 즉시 종료). 다른 인자·플래그는 없다 — 정의되지 않은 플래그를 받으면 안내 후 종료한다.

수행:

  1. milestone 문서를 읽고 포함된 feature/task 목록을 회수한다.

1.0. Deterministic pre-flight (LLM 위임 전 cheap mechanical check)

LLM 호출 전 다음을 순서대로 점검 (모두 deterministic, fail-fast X — 보고만):

  1. docs/ 내부 markdown link 유효성 (기본: 내부 / ADR 참조 / 로컬 파일 만 점검 — 외부 URL 검사는 optional):

    • 기본 (내부 link only — deterministic 보장): markdown-link-check --config <(echo '{"ignorePatterns":[{"pattern":"^https?://"}]}') docs/**/*.md (외부 URL 무시).
      • OS 별 glob 처리:
        • Unix/macOS bash: markdown-link-check docs/**/*.md (bash glob 자동 확장).
        • Windows PowerShell (glob 미확장 안전 패턴): Get-ChildItem docs -Recurse -Filter *.md | ForEach-Object { markdown-link-check $_.FullName }.
        • OS 무관 fallback: repo 의 scripts/verify.{sh,ps1,mjs} 에 한 줄 helper 박거나 npx markdown-link-check 를 각 파일 인자로 직접 호출 — glob npm 패키지 의존 회피.
    • optional (외부 URL 검사 — 네트워크 의존 / flaky): 위 명령에서 ignorePatterns 제거. 단 deterministic preflight 의 기본 단계가 아님 — --with-external-links 플래그로 사용자 명시 발화 시만.
    • 깨진 link 발견 시 IMPROVEMENT_GUIDE.md 에 P1 [Doc-link] <file:line> — <broken link> 라벨 기록.
    • markdown-link-check 미설치 환경은 본 항목만 skip + 출력에 명시 (Doc-link check skipped: markdown-link-check not installed).
  2. ADR 참조 유효성 (ADR-045#d1·#d8):
    • ADR-NNN 참조 → 실제 파일 존재 매칭. 예외(오류 아님): (a) <!-- --> 주석 안 참조, (b) allowlist된 ADR-100/101의 bootstrap 전 미존재, (c) Reserved/Parked/Dropped 표 등재 번호. boilerplate(001~099) 미존재 → P1 [ADR-ref]. 그 외 project ADR(102+) 미존재 → P2 [ADR-ref-project] (무시 X).
    • 앵커 존재 (ADR-045#d2): ADR-NNN#amend-M → 대상 ADR에 ## Amendment M(또는 <a id="adr-NNN-amend-M">) 존재. 누락 시 P1 [Ref-anchor] <file:line>. (#dK는 token-only — 대상 ADR에 "K." 결정 항목 존재는 best-effort, 미존재 의심만 P2.)
    • 내부 anchor 링크 (ADR-045#d9): [label](file.md#anchor)의 anchor가 대상 파일에 <a id> 또는 대응 heading으로 실재. 누락 시 P1 [Link-anchor] <file:line>.
    • Surfaces forward check (ADR-045#d3·#d4): ## Surfaces 블록을 가진 각 ADR에 대해 — 등재 파일이 모두 존재하고 본문에 ADR-NNN 역참조를 갖는가. 누락 시 P1 [Surface-backref] ADR-NNN → <file>. 대상 ADR의 ## Status 본문이 superseded 또는 deprecated로 시작할 때만 forward-check에서 skip한다(아래 «죽은 ADR 인용»과 동일 기준 — accepted (부분 superseded — ...)는 살아 있으므로 skip하지 않는다. 느슨하게 «문자열 포함»으로 읽으면 부분 supersede된 살아있는 ADR의 Surfaces drift가 조용히 검출되지 않는다). live sync 소스만 점검 — 죽은 ADR의 잔존 Surfaces는 별도 [Ref-dead]가 담당. 이 forward 방향만 Phase 4 범위 (역방향은 휴리스틱이라 Phase 5 검토).
    • 죽은 ADR 인용: 인용된 ADR의 ## Status 본문이 superseded 또는 deprecated로 시작할 때만 P2 [Ref-dead] <file:line>. accepted (부분 superseded — ...)로 시작하는 ADR은 살아 있다 — 문자열 superseded가 괄호 안에 있다고 죽은 것으로 세지 않는다(이 구분을 빼면 부분 supersede된 ADR 하나가 100건 단위의 오탐을 만든다). 예외(오탐 아님, ADR-045#amend-2 D10): (a) 같은 줄에 (현재 SSOT:이 병기된 인용(역사 서술 + 현행 포인터를 함께 둔 정본형 — D10의 검사 제외 마커), (b) 그 ADR 자신을 가리키는 인용만 있는 줄(## Status·## Amendment 등), (c) README.md 인덱스 표 행의 supersede 계보 칸, (d) <!-- --> 주석 안. 예외에 해당하면 기록하지 않는다.
    • 인덱스 amend 동기: boilerplate/README.md Amendments 컬럼 amend 수 ↔ 코드펜스(```)·<!-- --> 주석 밖의 본문 ## Amendment N 수 일치(예시·주석 헤딩 제외; 불일치 P1 [ADR-index]). (review-doc과 중복 가능.)
  3. FAC ↔ AC unmapped 검출 (ADR-037#amend-1 영속 SSOT ## 7-1 정합):
    • 본 마일스톤의 모든 feature 문서 ## 7-1. FAC ↔ AC 매핑표에서 unmapped 또는 비어 있음 항목 회수. 우변이 승인 스냅샷 <경로> (manifest: …) 형식인 행은 unmapped 가 아니다(ADR-037#amend-4 — 승인 표면이 검증자다). 우변이 비었거나 (해당 task 없음) 처럼 검증자를 지목하지 않은 행만 센다. ## 7-3 PX↔AC 도 같다(결정 1-b).
    • 발견 시 **QA_FINDINGS.md 본 마일스톤 ### P0**에 P0 [Spec-gap] F-NNN:FAC-N → unmapped(- 출처: preflight)로 등재한다(ADR-073#amend-2 결정 4 / ADR-070 D7 — 계약 결함은 QA 원장, 그래야 졸업 item 5가 센다) + graduation NO 유지 + 사용자 보고. 구현 후에는 plan-workitem으로 task를 자동 추가하지 않으며, 담당 task가 있으면 repair, 없으면 ADR-057#amend-3 결정 6의 사용자 명시 결정 경로를 따른다. 3-1. pattern-scan 범위 밖 잔존 회수 (deterministic): 본 마일스톤 산하 task 문서 ## 8에서 HTML 주석 밖의 - pattern-scan 줄을 회수해 범위 밖 M건이 1 이상인 항목을 모은다. 발견 시 IMPROVEMENT_GUIDE에 아래 스키마로 기록(WORKFLOW 4-A 면제 기록을 stabilize가 회수하는 것과 동형).
      • 폐쇄 후 라운드의 pattern-scan은 task ## 8이 아니라 IMPROVEMENT_GUIDE.md ## 5의 항목 하위 줄에 있다(ADR-066#amend-1). 본 항목은 그 두 위치를 모두 읽는다 — task ## 8은 폐쇄 전 /repair-workitem 라운드분, ## 5는 폐쇄 후 마일스톤 층 라운드분이다.
      • ID는 안정적으로 만든다 — <task-id>-pspread-<패턴 슬러그> (예: T-004-pspread-null-guard). 항목 형식: - **<ID>** | P1 | [관측됨] | linked: <task-id> | status: open + 하위 줄 - [Pattern-spread] <패턴> — 범위 밖 M건 미수정: <경로>.
      • 재등재 금지(dedup): 그 ID가 IMPROVEMENT_GUIDE에 이미 있으면(status가 open이든 resolved든) 다시 등재하지 않는다. - pattern-scan 줄은 task 문서에 영속되므로 이 규칙이 없으면 매 마일스톤 같은 P1이 재생산된다.
      • 예외 — 같은 패턴의 새 출현: 기존 ID가 resolved인데 그 task ## 8에 경로 목록이 다른 - pattern-scan 줄이 새로 append됐으면(두 번째 repair 라운드가 더 찾은 경우) -2·-3 suffix를 붙인 새 ID로 등재한다. 판별 기준은 경로 목록의 차이이며, 같으면 재등재하지 않는다.
      • 후속은 /repair-milestone(cross-cutting) 또는 다음 마일스톤 후보로 라우팅한다. 잔존이 0건이거나 전부 기존 ID면 침묵한다. 3-2. 잠정 해석 회수 (deterministic — ADR-076 D5): 본 마일스톤 산하 task 문서 ## 8(HTML 주석 밖)에서 해석 잠정: 줄 중 같은 AC의 해석 확정: 줄이 없는 것을 모아 IMPROVEMENT_GUIDE.md ## 2. 열린 항목의 ### M<N> 그룹에 기록한다. 사용자 authority 항목이라 6-S 채택 전 검토를 거치지 않고 판정값을 바로 적는다.
    • ID는 그 줄의 확인: IMPROVEMENT_GUIDE <ID>에 적힌 값을 그대로 쓴다(없으면 <task-id>-prov-ac-<N>). 형식: - **<ID>** | P1 | [관측됨] | linked: <task-id> | status: open | decision: needs-confirmation + 하위 줄 - [Provisional-AC] AC-N = <선택> — 대안: <대안> · - 대상: AC-N 해석 / 확인 방법: 사용자 확인 (/repair-milestone) / 막힌 이유: 사용자 authority · - 출처: run-milestone.
    • 재등재 금지: 같은 ID가 IMPROVEMENT_GUIDE나 docs/40-validation/archive/M<N>.md에 이미 있으면(status 무관) 다시 쓰지 않는다.
    • 졸업을 막지 않는다 — IMPROVEMENT_GUIDE P1이라 graduation 판정 입력이 아니다. 대신 아래 «다음 단계»가 확인을 권한다.
    • 회수할 것이 없으면 침묵한다.
  4. 모드 라벨 ↔ 본문 정합 휴리스틱 (ADR-012): 모든 docs/00-meta/ 파일의 > 모드: ... 라벨이 본문과 명백히 어긋나는지 점검 (휴리스틱 한계 명시).
    • mismatch 시 P2 [Doc-mode] <file> 기록.
  5. DESIGN.md + ARCH 7-x cross-surface drift 검출 (ADR-073 D8) — (5-2) 는 정규식 기반 deterministic, (5-3)(5-4) 는 mechanical/best-effort heuristic — 휴리스틱 한계는 항목별 echo:

    5-0. 변경 파일 회수 — git diff 의존 금지: stabilize-milestone 은 정상 lifecycle 에서 /finalize-workitem 으로 이미 커밋된 후 호출되므로 working tree git diff 는 비어 있다. 본 마일스톤 task 의 변경 파일 회수 우선순위:

    • (a) 1차 — task 문서: 본 마일스톤 산하 모든 task (docs/30-workitems/tasks/T-*.md) 의 ## 4-1. 변경 예정 파일/경로 본문 회수. (TASK_TEMPLATE 정합 — finalize 시 --apply 또는 명시 update 로 채워짐)
    • (b) 2차 — commit log fallback: ## 4-1 비어 있거나 git 실제 변경과 어긋난 task 는 git log --grep "Refs: T-NNN" --name-only 로 commit 로그의 변경 파일 회수 (ADR-008#amend-2 Refs footer 정합).
    • (c) 3차 — validation report fallback: 위 둘 다 비어 있는 task 는 docs/40-validation/reports/<task-id>.md 의 diff trace audit 단락 회수.
    • (d) 4차 — 폐쇄 후 수리 기록: IMPROVEMENT_GUIDE.md ## 5의 본 마일스톤 항목 files: 목록(ADR-073#amend-2 결정 3 — 마일스톤 층 수리가 바꾼 파일은 여기에만 있다).
    • (e) 모두 실패 시: 본 task 는 조사 불가 로 표시 + IMPROVEMENT_GUIDE 에 P2 [Stabilize-recovery] T-NNN — 변경 파일 회수 불가 기록 후 다음 task 로 계속.
    • (f) 회수 결과 echo (ADR-073#amend-2 결정 3): 회수 파일 N개 ((a) x · (b) y · (c) z · (d) w). N = 0이면 5-2·5-2b·5-3을 실행하지 않고 P2 [Stabilize-scope-empty] 회수 파일 0건 — 5-x 미실행을 기록한다. 5-2·5-2b·5-3 출력은 대상 K파일 / 위반 M건으로 둘을 함께 적는다.

    5-1. UI 프로젝트 판정 — ADR-073 D9 "UI 판정 다중신호 절차" 적용(부재→비-UI: 5-15-3 skip+사유 echo / status≠draft→UI: 5-15-3 활성 / status=draft+추가신호≥1→UI 의심: IMPROVEMENT_GUIDE에 P1 [Design-draft] DESIGN.md status=draft + UI 신호 감지 — /bootstrap-design 권장 기록 + 5-1~5-3 활성 / 신호 0→silent skip).

    5-2. UI 프로젝트 — raw color grep (정규식 deterministic, 기록 등급 — 진행 차단 안 함): 5-0 에서 회수한 변경 파일 중 아래 두 갈래로 검사한다.

    • 웹 계열 — 확장자 .tsx/.jsx/.ts/.js/.vue/.svelte/.astro/.css/.scss/.html. 단축 hex 는 스타일시트에서만 잡는다(ADR-072#amend-1 결정 3 — design gate 어댑터와 같은 규칙):
      • .css/.scss/.sass/.less: #([0-9A-Fa-f]{8}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{4}|[0-9A-Fa-f]{3})\b(3~8자리 전부)
      • 그 밖의 코드 파일(.tsx·.ts·.vue·.svelte·.astro·.html 등): #([0-9A-Fa-f]{8}|[0-9A-Fa-f]{6})\b(6·8자리만) \b로 더 긴 hex 런의 부분매치를 막는다. 일치 시 P1 [Design-rawhex] <file:line> — DESIGN.md ## 2 token 으로 교체 권장. 왜 갈랐는가: 3~5자리 단축 hex 는 #412 같은 이슈·번호 표기와 구별되지 않아 카피 문자열·테스트 fixture 를 통째로 오탐한다(dogfood Round 11 실측 5/5 오탐 — 전부 「PR #412」). 대가는 «코드에 직접 쓴 #abc 단축 색을 놓친다»이며, 토큰 규율상 코드에 색 리터럴 자체를 두지 않으므로 수용한다.
    • Dart 계열 — 확장자 .dart: ① Color\(0x[0-9A-Fa-f]{6,8}\) 및 Color\.from(ARGB|RGBO)\( → P1 [Design-rawhex] <file:line> ② \b(Colors|CupertinoColors)\.(?!transparent\b)[a-zA-Z]+ (프레임워크 기본 팔레트 사용 — 값을 박은 것은 아니나 프로젝트 토큰을 우회함). Colors.transparent 는 제외한다 — 그것은 색이 아니라 «색을 칠하지 않는다»는 뜻이고 어느 디자인 시스템에서도 토큰화 대상이 아니다(dogfood Round 11 실측 2건 오탐 — 발견 60). 한 낱말 예외라 미탐 위험이 거의 없고, 매번 브리프 ## 14 에 사유 주석을 쓰게 만드는 비용을 없앤다 → P1 [Design-token-grep] <file:line> — 테마에서 가져오도록 교체 권장. 두 라벨은 원인과 수정 방법이 달라 분리한다. [Design-token](접미 없음)은 reviewer 의 LLM 판정 차원이 이미 쓰는 라벨이므로 grep 결정분에는 -grep 접미를 붙인다 — [Design-voice-grep]/[Design-voice] 분리와 같은 규칙이며, 회귀 신호 집계가 라벨 정확 일치로 동작하므로 겹치면 오집계된다.
    • Dart 정의 라인 예외: static +const +(Color +)?[A-Za-z_][A-Za-z0-9_]* *= *Color\( 형태의 줄은 토큰 정의이므로 제외한다(웹의 CSS custom property 정의 라인 예외와 동형). 타입 표기는 선택이다 — static const paper50 = Color(0xFF…) 처럼 중복 타입을 생략하는 것이 Dart 관례이고 dart format·lint 가 그쪽을 민다. 예전 패턴(static +const +Color +…)은 타입을 적은 줄만 잡아 토큰 정의 파일 전건을 오탐했다(dogfood Round 12 실측 — 발견 77).
    • _theme 매니페스트 예외 (발견 77): docs/20-system/prototypes/_theme/manifest.json 의 source[] 에 등록된 파일은 토큰 정의·표시 표면이므로 본 검사 대상이 아니다. R6-1 이 만드는 쇼케이스(theme_gallery.dart·Theme.stories.tsx)는 토큰 값을 라벨로 보여 주는 것이 존재 이유라 hex 문자열이 정상이고, 매 라운드 같은 오탐을 낸다. 파일명 휴리스틱이 아니라 매니페스트를 근거로 삼는다 — 「파일명으로 파일 전체를 빼지 않는다」는 원칙과 충돌하지 않고, 제품 코드의 사용처 위반은 그대로 잡힌다(그 파일들은 source[] 에 없다).
    • 자가 검사 fixture 예외 (발견 77 ③): design gate 자가 검사 fixture 는 색을 의도적으로 박아 둔 입력이다(known-bad 의 2:1 대비 쌍이 그 파일의 존재 이유다). Dart 는 @Tags(['design-gate']) 가 붙은 파일, 웹은 게이트 어댑터 안의 인라인 HTML 이므로 apps/** 밖이다. 태그를 근거로 삼는다 — 그 태그는 이미 --exclude-tags=design-gate 로 통합 validate 에서 그 파일들을 빼는 데 쓰이고 있어 새 표식을 만들지 않는다.
    • 한계(사실 기록): 본 검사는 문자열 검색이라 문법을 이해하지 못한다. 주석 안·문자열 리터럴 안의 색값도 함께 잡는다(실측 확인). 그래서 본 항목은 기록 등급이며 진행을 차단하지 않는다. 문법을 이해하는 검사가 필요하면 Dart 의 공식 analyzer plugin 방식과 별도 패키지인 custom_lint 중 하나를 고른다(둘은 같은 것이 아니다 — ADR-059 D6).

    웹 계열의 제외 (ADR-072 — 정의/사용처 라인 구분): (a) DESIGN.md 자체 파일, (b) CSS custom property 정의 라인(--<name>: #hex 형태 — 토큰 정의는 정상; dogfood src/index.css :root 오탐 해소). 파일명(theme/tokens 등)으로 파일 전체를 빼지 않는다(사용처 위반 은폐 방지 — 정의/사용처는 (b) 라인 형태로만 구분). 검사 대상은 정의 밖 사용처(color:#hex·background:#hex 등) raw hex — 전면 :root 제외 금지.

    5-2b. UI 프로젝트 — voice grep (정규식 deterministic — ADR-073 D6): 5-0 회수 변경 파일 중 UI surface 파일 집합(ADR-073#amend-2 결정 1)의 파일에서, 각 줄의 렌더되는 텍스트 구간 — 따옴표 안 문자열("…"·'…'·`…`) 과 JSX·HTML 텍스트 노드(>와 다음 < 사이) — 에만 (a) placeholder 카피 패턴(lorem ipsum/TODO copy/sample text/여기에 텍스트), (b) DESIGN.md ## 10 "금지 표현"의 [grep 가능] 정규식을 적용한다(ADR-073#amend-2 결정 2 — 식별자·키 이름은 대상이 아니다). 일치 시 P1 [Design-voice-grep] <file:line> — DESIGN.md ## 10 위반(기록 등급 — 차단 아님) 기록. DESIGN.md ## 10 부재 시 (a)만 수행. DESIGN.md 자체는 grep 대상 제외 (규칙 정의 영역 — 5-2와 동형). 출력은 대상 K파일 / 위반 M건.

    5-3. UI 프로젝트 — 컴포넌트 인벤토리 drift (best-effort heuristic): src/components/, app/components/, components/, lib/widgets/, lib/**/widgets/ 중 존재하는 디렉터리의 컴포넌트 파일명 (예: Button.tsx, Card.tsx, primary_button.dart) 목록 ↔ DESIGN.md ## 7. Components 본문에 명시된 컴포넌트 이름 비교. 코드에는 있지만 DESIGN.md 에 없는 컴포넌트 발견 시 P1 [Design-inventory-drift] <component> — DESIGN.md ## 7 등록 권장 기록. 반대 (DESIGN.md 에 있는데 코드에 없음) 는 unimplemented planned component → P2 [Design-inventory-pending] <component> 기록. 휴리스틱 한계 echo 권장 (인벤토리 drift 검출은 free-form 문서 키워드 매칭 — false positive/negative 가능).

    5-4. 7-x Don'ts 위반 grep (best-effort heuristic): ARCH 의 ## 7-1 / ## 7-2 / ## 7-5 의 ### Don'ts 본문에서 명시적 금지 키워드 를 추출 → 5-0 회수 변경 파일에서 해당 키워드 grep. 위반 의심 발견 시 P1 [Arch-iface-violation] <file:line> — ARCH ## 7-N Don'ts 위반 의심: <키워드> 기록 — free-form 키워드 적중은 확정 위반이 아니라 확인 후보이므로 P1 로 적고 /repair-milestone 의 4-판정에서 확인한다(확정 위반과 같은 라벨을 쓰면 라벨을 읽는 쪽이 차단력을 오인한다 — 실측). 휴리스틱 한계 echo 강제 (Don'ts 키워드 추출은 free-form 텍스트 기반 — false negative 多. 본 grep 미작동 시 reviewer 의 design surface 위임이 보조 catch).

    7-3 백엔드 / 7-4 프론트 의 milestone-level deterministic gap 명시: 현 ARCH TEMPLATE 의 ## 7-3 / ## 7-4 는 ### Don'ts 자리가 없어 본 5-4 grep 이 skip 한다(## 7-5는 ### Don'ts를 가지므로 대상이다). 단 이것이 전면 gap 은 아니다 — 7-3/7-4 결정과의 정합은 per-task validate-workitem (validator.md 의 인터페이스 CHECK 규칙 — UI/API/CLI/7-x) 의 CHECK 단계가 task 단위로 점검한다 (DB migration / 인증 / 트랜잭션 / 라우팅 / 상태관리 등). 즉 milestone-level deterministic preflight 에서만 빠지고, task-level validation 에서는 잡힌다. milestone 누적 drift 가 우려되면 stabilize 의 reviewer code surface (Step 5) 가 아키텍처 부채로 추가 catch. 향후 7-3/7-4 에 ### Don'ts 자리를 TEMPLATE 에 추가하면 본 grep 도 확장 가능 (별도 ADR-073 amend 후보).

    5-5. 해당 스택 부재 시 본 항목 skip + skip 사유 echo: [Design/Arch-iface] check skipped: <reason>. 예: [Design] check skipped: docs/20-system/DESIGN.md 부재 (비-UI 프로젝트).

  6. 고-stakes 설계 근거 누락 (ADR-053 backstop, best-effort): ARCHITECTURE_OVERVIEW ## 7의 실제 작성된(HTML 주석 placeholder 제외) 결정 블록에서 필수 칸(옵션≥2/신뢰도/재검토)이 비면 P2 [Design-rationale] <위치> 기록. 한계: 고-stakes 결정을 한 줄 산문으로 쓴 경우는 못 잡음(휴리스틱).
  7. Skill 로스터 fan-out 정합 (cross-doc, deterministic — ADR-010#amend-3 README SSOT + STRUCTURE 로스터 정합 집행):
    • .claude/skills/*/ 디렉터리명 집합 ↔ docs/00-meta/STRUCTURE.md의 Claude skill 본문 행 괄호 목록이 일치하는가. 불일치 시 P1 [Roster-drift] <skill> — STRUCTURE 로스터.
    • README.md/README_ko.md의 자연어 호출 skill 목록 두 곳(정책 요약 문단의 "Remaining skills/나머지 skill" + "For remaining skills/나머지 skill(...)" 명시 목록)이 서로 일치하고, (.claude/skills 집합) − (.agents/skills wrapper 집합)과 같은가. 불일치 시 P1 [Roster-drift] <skill> — README 자연어 목록(<어느 위치>).
    • cross-LLM 리뷰 skill 등재 (D3 재발 지점, deterministic): validate-plan·validate-discovery·validate-milestone 각각이 docs/00-meta/DELEGATION_STRATEGY.md 위임 표에 등장하는가(skill 이름 grep). 미등재 시 P2 [Roster-drift] <skill> — DELEGATION 위임 표.
    • cross-LLM 리뷰 skill wrapper 존재 (ADR-010#amend-4, deterministic): validate-plan·validate-discovery·validate-milestone과 각 repair 짝(repair-plan·repair-discovery·repair-milestone)에 .agents/skills/<name>/SKILL.md가 존재하는가. 부재 시 P1 [Roster-drift] <skill> — Codex wrapper 부재 (ADR-010#amend-4).
    • 발견은 IMPROVEMENT_GUIDE에 기록(보고만 — 차단 X). 한계: WORKFLOW 산문 흐름 등재는 본 grep 범위 밖(reviewer 위임이 보조 catch).
  8. 검증 장치 노후 감지 [Guard-drift] (deterministic — ADR-063 D4): 침묵 우선 — 아래 (a)~(e) 가 전부 정상이면 출력에 한 줄도 남기지 않는다 (skip 사유 echo 도 하지 않는다. 정상 상태를 매번 보고하면 그것이 노이즈이고, 검증 장치가 매 마일스톤 변경되는 것은 정상이 아니다). 단 아래 "선행: 파일 부재 처리" 는 예외다 — 점검을 아예 수행하지 못했다는 사실은 침묵하면 안 된다.
    • 선행: 파일 부재 처리 — docs/00-meta/STACK_SETUP_PLAN.md 는 baseline 이 아니라 /bootstrap-stack 생성물이다. 부재 시 본 항목 전체를 skip 하고 Guard-drift check skipped: STACK_SETUP_PLAN.md 부재 1줄만 남긴다(§1.0 의 markdown-link-check 미설치·원장 부재 선례와 동형).
    • (a) registry 경로 실재 — 대상 절·검사할 열·조건을 아래로 고정한다(deterministic 이려면 같은 입력에 같은 판정이 나야 한다. 절마다 스키마가 다르므로 "registry 행"만으로는 무엇을 볼지 정해지지 않는다). 부재 시 P2 [Guard-drift] <절>:<경로> 부재 — /stack-guard 재실행 권장.

      대상 절검사할 열조건
      ## E2E Smoke Registrysmoke 파일 경로그 행의 status 가 n/a 가 아닐 때
      ## Design Gate Adapteradapter path 만절의 status 가 ready 일 때
      ## Dart Source Roots경로 (pubspec 위치 기준 상대경로)그 절이 존재할 때 (비-Dart 스택은 /bootstrap-stack 이 절을 삭제하므로 대상 0)
      • output path 는 검사하지 않는다 — design-gate-shots/ 는 .gitignore 대상이고 adapter 가 매 실행 통째로 생성·초기화하는 ephemeral 산출물이라 fresh clone·정리 직후 부재가 정상이다. 검사하면 매 마일스톤 오탐이 나 침묵 우선 원칙과 충돌한다.
      • ## Dependency Tools 는 경로 열이 없어 대상이 아니다. status: n/a·미대상 행도 대상이 아니다 — e2e 비대상·비-UI 프로젝트에서 경로가 없는 것은 정상이다.
      • 템플릿 예시 행((예: …))이 남아 있으면 그 경로는 실재하지 않으므로 그대로 P2 가 되며 처방(/stack-guard 재실행)이 정확하다 — 별도 예외를 두지 않는다.
    • (b) design gate copied-from 4방향 판정 (ADR-063#amend-1) — status: ready인 경우에만 세 값을 읽는다: canonical sha C(.claude/skills/stack-guard/assets/design-gate.mjs), registry copied-from R, 사본 sha P(adapter path). (i) P = R, C ≠ R → P2 [Guard-drift] canonical 갱신됨 — /stack-guard 재실행 권장(무수정 사본이라 교체된다) (ii) P ≠ R, C = R → P2 [Guard-drift] 사본 로컬 수정됨 — 재실행해도 덮어쓰지 않음(diff 보고). 수정분을 canonical로 역류할지 검토: IMPROVEMENT_GUIDE [ADR-candidate] (iii) P = C ≠ R → P2 [Guard-drift] registry만 낡음(코드 동일) — copied-from 갱신 권장(/stack-guard 재실행이 갱신) (iv) P ≠ R, C ≠ R, P ≠ C → 둘 다 + 사용자 결정 필요. 전부 읽기 전용 — mtime·날짜 비교 없음; sha256 도구 부재 시 skip + 사유 echo.
    • (c) 등록 밖 소스 디렉터리 — 소스 루트 registry 를 갖는 스택에서만 수행한다. 현재 그 registry 를 갖는 것은 ## Dart Source Roots(Dart/Flutter)뿐이며, 비-Dart 스택에서는 /bootstrap-stack 이 그 절을 삭제하므로 판정 기준이 없다 → 이 항목을 건너뛴다(사유 echo 불요 — 침묵). 기준 없이 "등록 밖"을 판정하면 TS/Python/Go 의 src/·tests/ 가 매 마일스톤 오탐으로 찍혀 침묵 우선 원칙과 정면 충돌한다. Dart 스택에서 발견 시 P2 [Guard-drift] 등록 밖 Dart source root: <경로> — /stack-guard 재실행 권장.
    • (d) probe 판정 기록 — ## 통합 명령 사용법 의 probe smoke: 값으로 판정한다.
      • 정상(무출력): PASS (probe verified, …) 2종 · PROBE OK, PROJECT FAIL. 후자는 probe 전 회차가 기대대로였고 프로젝트 코드만 실패한 상태이므로 검증 장치의 노후가 아니다 — 재실행해도 같은 결과이니 처방이 무의미하고, 그 프로젝트 실패는 졸업 item 2(통합 validate Pass)와 단계 3 이 이미 잡는다.
      • P2 [Guard-drift] validate 판정력 미검증 — /stack-guard 재실행 권장: PROBE FAIL(<단계>) · PARTIAL · SKIPPED (…) · 줄 자체 부재.
      • 여기서 probe 를 다시 돌리지 않는다 — 기록된 문자열만 읽는다(read-only 계약). 이것이 /stack-guard 의 미검증 상태가 조용히 잊히지 않는 유일한 경로다(ADR-063 D3 기록 → D4 회수).
    • (e) visual-QA 전제 기록 (ADR-058#amend-3 결정 5) — ## 통합 명령 사용법의 visual-qa: 값이 PENDING이면 P2 [Guard-drift] visual-QA 전제 미준비 — /plan-workitem 이 전제 line item authoring 후 /stack-guard 재실행 권장. 값이 READY거나, 줄이 없거나(비-UI·비대상), 줄은 있으나 미치환 angle-bracket placeholder면 침묵한다 — 비-UI 프로젝트에는 템플릿 복사분이 그대로 남을 수 있고(/bootstrap-stack은 절 단위로만 비해당 삭제한다) 그 placeholder 문자열 자체에 PENDING이 들어 있어, 명시하지 않으면 deterministic 검사가 오발화한다. 여기서 spec을 실행하지 않는다 — 기록된 문자열만 읽는다((d)와 동형, read-only 계약).
    • validate 4단계 커버리지의 재측정은 본 항목이 아니다 — 실측은 /stack-guard 재실행 시 probe 가 하고, 본 항목은 (d) 로 그 기록만 읽는다(ADR-063 D1·D4 — 중복 회피 + read-only 유지).
    • 회수 경로는 기존과 동일하다 — IMPROVEMENT_GUIDE 에 기록하면 다음 /plan-milestone R0 의 open 항목 회수가 사용자에게 재실행을 안내한다([ADR-candidate]·[Stack-drift] 와 동형, 신설 없음).

본 단계는 모두 보고만 — 발견이 있어도 stabilize 후속 단계 차단 X (LLM 위임 단계로 계속). 후속 처리는 ADR-057#amend-3 결정 6 분기(기존 task 약속 결함=repair, cross-cutting=repair-milestone, 담당 없는 새 범위=사용자 보고+다음 M 후보)를 따른다.

봉인 후 새 결정 등재 (ADR-060 D11): 마일스톤 점검에서 기획 결정(사용자가 정하거나 승인해야 할 것)이 드러나면 docs/10-charter/DECISION_REGISTER.md에 status: open + - 발견: 봉인 후 (M<N>) 줄로 등재한다. QA_FINDINGS/IMPROVEMENT_GUIDE는 결함·개선을 담고 원장은 결정을 담는다(둘 다 해당하면 양쪽에 각자 형식으로). 본 skill의 read-only 계약은 불변 — 원장 등재는 기존 QA_FINDINGS 기록과 동일한 정상 책임 범위다. 원장 파일이 없으면 등재를 건너뛰고 보고만 한다.

review-doc 책임 분담: review-doc은 단일 문서 ad-hoc 검토에 한정. cross-doc / link / FAC↔AC는 본 deterministic preflight가 담당 — review-doc을 --all/--milestone 모드로 확장하지 않는다.

1.5. Graduation 판정 입력 수집 (ADR-068 D3)

MILESTONE 문서의 ## 5. 완료 기준 각 항목을 아래 deterministic 평가로 계산한다(LLM 즉흥 판정 금지). 여기서는 계산만 하고 회고에 기록하지 않는다 — 최종 기록은 단계 8이다.

정적 항목 (본 단계에서 확정하고 이후 재계산하지 않는다) — 본 skill 자신이 단계 4~6에서 문서를 쓰므로, 그 쓰기가 아래 판정에 영향을 주지 않도록 여기서 값을 고정한다.

  • item 1 — 마감 스냅샷 유효: 본 milestone에 속한 모든 task 파일(docs/30-workitems/tasks/T-*.md)에 대해
    1. ## 0. Status 값이 done인가.
    2. ## 8. 메모의 HTML 주석 밖 마지막 - closure 줄이 존재하는가.
    3. 그 줄의 verdict가 Pass 또는 Pending Acceptance인가. Needs Fix는 미충족이다.
    4. 그 줄의 audit가 complete인가. 미완:<축>이면 미충족이며 graduation은 BLOCKED (audit incomplete: <축>)이다.
    • 하나라도 어긋나면 그 task를 미충족 목록에 넣는다(사유를 status / closure 부재 / verdict / audit로 구분해 적는다). ## 0. Status가 done인데 - closure 줄만 없는 task의 처방은 «사용자가 그 task ## 8에 - closure 줄을 직접 기재» 다(ADR-068 D3 item 1). done이 아닌 task에는 이 처방을 내지 않는다 — 그 task는 아직 task 층이고 단계 2가 종료시킨다. /validate-workitem·/finalize-workitem 재실행도 처방하지 않는다 — 전자는 폐쇄 상태에서 종료하고 후자는 done에 read-only no-op이므로 그 처방은 실행 불가다. 수기 기재는 이 개선 이전에 마감된 task에서만 발생한다.
    • 채점표(docs/40-validation/reports/)를 읽지 않는다. 졸업 판정은 커밋된 task 문서만 본다(ADR-068 D2).
  • item 4 — 관측 AC receipt 유효: 각 task ## 6-1에서 modality가 [사용자 관측]·[플랫폼 관측]인 AC를 전수 회수하고, 그 AC마다 task ## 8의 (HTML 주석 밖) 마지막 이벤트가 - ac-acceptance 인가(ADR-065 D3 판독 규칙 2)를 본다. - ac-pending·- invalidated이거나 이벤트가 없으면 미충족. 관측 modality AC가 0건인 task는 해당 없음.
    • - closure의 관측대기= 목록은 회수 편의용 색인일 뿐이다. 그 목록만 읽으면 안 된다 — 수기 기재분이나 구 정의로 쓰인 closure 줄이 목록을 비워 둘 수 있고, 그러면 receipt 없는 관측 AC가 통과한다. 어긋나면 ## 6-1 스캔 결과를 신뢰한다.

동적 항목 (단계 3~6 결과를 반영해 단계 8에서 확정한다)

  • item 2 — 통합 validate Pass: 단계 3에서 실행한 결과의 exit code 0. 마일스톤 층 수리가 추가한 회귀 테스트도 이 명령에 묶여 있으므로 함께 검사된다(ADR-068 D6).
  • item 3 — E2E Pass: 단계 3의 e2e 상태 판정을 그대로 반영(ADR-052#amend-1 5상태).
    • NOT_APPLICABLE (비-UI ∧ item 6에 e2e 미선언) → 해당 없음(통과).
    • PASS → 통과.
    • EMPTY (선언된 e2e 디렉터리 하위에서 실행된 테스트 0개) → 졸업 가능: NO (hard) + Needs E2E Smoke. 프로비저닝 단계와 달리 졸업 시점에는 차단한다(ADR-068 D3 item 3). registry 미등록은 이 상태의 사유가 아니다 — 미등록은 P1 [E2E-registry] 기록 대상일 뿐이다.
    • FAIL → 졸업 가능: NO (hard).
    • BLOCKED_ENV → item 3 미충족 (hard, blocked-on-env). real failure가 아니므로 라벨을 구분해 출력하고 환경 복구를 안내한다. 최종 graduation은 NO가 아니라 단계 8이 확정하는 BLOCKED (e2e blocked-on-env: <target>)이다(ADR-068 D4 — 우선순위 BLOCKED > NO).
  • item 5 — P0 severity finding 0건: docs/40-validation/QA_FINDINGS.md의 본 milestone 헤더(## M-N) 아래 ### P0 섹션에서 status: resolved가 아닌 항목 수 0. «항목» 은 - **<ID>** | 로 시작하는 줄만 센다 — 항목의 하위 산문 줄에도 status: open 같은 문자열이 나올 수 있고(수리 라운드가 «status: open 유지» 라고 적는다), 문자열 grep 으로 세면 계수가 부풀려진다(dogfood Round 11 실측 — 2건이 4건으로). 단계 4의 qa 팬아웃이 새 P0를 등재할 수 있으므로 단계 8에서 확정한다.
  • item 6 — (선택) 본 마일스톤 한정 추가 기준: 본문 텍스트 그대로 평가(사용자가 자유 기재한 영역 — 해당 항목만 LLM 해석 허용).

본 단계의 출력 (판정을 회고에 쓰지 않는다):

  • item 1 미충족 task 목록 (사유별 — status / closure 부재 / verdict / audit)
  • item 4 미충족 <task-id>:AC-N 목록
  • item 1·4가 전부 충족이면 그 사실 한 줄
  • 조기 종료 옵션 (ADR-068 D3): item 1이 미충족이면 그 목록과 함께 조기 종료 옵션을 사용자에게 제시한다(강제 종료 아님 — 계속을 택할 수 있다). item 1이 깨진 상태로 단계 4~6 팬아웃을 끝까지 도는 것은 낭비다. item 4만 미충족인 경우에는 제시하지 않는다 — 결함이 아니라 «사람 확인만 남은» 상태이므로 되돌아가 고칠 것이 없고, 그대로 진행해 단계 8에서 PENDING_ACCEPTANCE를 확정한다.
  1. 각 task의 status를 점검 — done이 아닌 항목이 있으면 명단을 출력하고 종료(완료를 강제하지 않음).
  2. 통합 validate 명령을 실행한다 + e2e 필요성 판정 후 필수 실행(ADR-052 — silent-skip 금지):
    • 3-a. e2e 필요성 판정: 본 마일스톤이 e2e를 필요로 하는가를 deterministic 신호로 결정한다 — (i) UI 프로젝트 (ADR-073 D9 다중신호 UI 판정: DESIGN.md status≠draft, 또는 status=draft+신호≥1) → 필요, (ii) graduation item 6 (선택) 본 마일스톤 한정 추가 기준이 e2e를 명시 선언 → 필요. 둘 다 아니면 불필요 → E2E: 불필요 (비-UI ∧ item 6 미선언) 한 줄 echo 후 통과 처리(이 경우만 skip 허용 — 사유 명시).
    • 3-b. 필요 시 validate:e2e 실행 (silent-skip 금지): e2e가 필요하면 반드시 실행하고 구조화된 러너 출력을 수집해 ADR-052#amend-1의 5상태로 분류한다. exit code만으로 판정하지 않는다.
      • 선행 확인: STACK_SETUP_PLAN.md ## E2E Smoke Registry를 읽어 선언된 runtime target 목록과 각 target의 등록 여부를 회수한다. target이 둘 이상이면 아래 판정을 target마다 따로 내고, 하나라도 PASS가 아니면 졸업은 차단된다. 판정이 target마다 나므로 실행도 target마다 한다 — target이 둘 이상이면 validate:e2e:<target>을 target마다(또는 집계 validate:e2e 1회) 호출하고 target별 구조화 출력으로 각각 판정한다(ADR-059#amend-1). native target의 device id는 scripts/e2e-target.mjs가 registry의 실행 대상 선택 규칙 칸을 flutter devices --machine 출력에 대입해 실행 시점에 얻는다 — 규칙 문자열을 명령에 그대로 넣지 않는다. target이 하나면 1회 호출로 충분하다. 등록이 없는 target도 명령은 실행한다 — 판정은 아래 경로 기준으로 하고 P1 [E2E-registry] <target> — canonical smoke 미등록만 기록한다(ADR-052#amend-1 결정 4).
      • 판정 규칙은 여기서 재서술하지 않는다 — PASS 필요조건 넷과 판정 순서(FAIL(wiring)·BLOCKED_ENV → EMPTY → FAIL(project) → PASS, 먼저 성립하는 상태로 확정)는 ADR-052#amend-1 결정 3이 SSOT다. 그 절을 읽고 그대로 적용한다. 순서를 뒤집으면 기동 불가나 테스트 실패를 EMPTY로 오분류해 "테스트를 쓰라"는 틀린 처방이 나간다. 종료코드가 0이어도 e2e 경로 밖 suite만 돌았으면 EMPTY다.
      • FAIL은 FAIL(wiring)/FAIL(project) 하위 라벨을 구분해 기록하고, BLOCKED_ENV는 real failure와 라벨을 구분한다 — 후속 처리 주체가 다르다(stack-guard 산출물 / 프로젝트 코드 / 환경 복구).
      • host 제약으로 BLOCKED_ENV인 target은 registry의 마지막 PASS(host·날짜·커밋) 칸을 증거로 쓸 수 있다(예: Windows에서 iOS). 유효 조건은 하나 — git diff --name-only <기록 커밋> <판정 커밋> -- . ':(exclude)docs/' ':(exclude)*.md'가 종료코드 0으로 끝나고 출력이 비어 있을 때만(기록과 판정 사이에 문서 밖 변경이 없음) 인정하고 그 target을 PASS로 본다. 출력이 있거나 명령이 실패하면(기록 커밋이 없으면 오류로 끝나도 출력이 비어 있다) BLOCKED_ENV를 유지한다 — 판정은 이 명령 하나이며 "그 사이 앱 코드가 바뀌었는지"를 사람이 판단하지 않는다(ADR-059 D4·#amend-3 — 증거 기록 커밋 자체가 문서 변경이라 이전의 «커밋 동일» 조건은 구성상 충족 불가능했다). 증거를 채택했으면 출력에 <target>: PASS (registry 증거 — <host>·<커밋>)로 근거를 남긴다.
      • 출력 문자열 매칭은 위 판정을 보조하는 용도로만 쓴다.
    • stabilize는 read-only다 — 여기서 e2e/코드를 고치지 않는다. 실패(real/env 무관)는 단계 8의 /repair-milestone 분기로 텍스트 라우팅만 한다. 3-P. (옵션) 탐색적 QA via browser/E2E MCP (ADR-048#d6 registry-driven / ADR-043 보안 — STACK_SETUP_PLAN ## Optional MCP Connectors에 browser/E2E capability MCP가 등재 + agent access 부여 + UI 프로젝트일 때만; 미등재·access 미부여·비-UI는 silent skip + 사유 echo): 실제 앱을 구동해 본 마일스톤 feature의 시나리오(happy/alt/fail) + qa 엣지케이스를 탐색한다(accessibility 트리·클릭/입력·스크린샷·네트워크). 발견한 결함을 docs/40-validation/QA_FINDINGS.md에 기록하고, 재현 케이스를 영속 E2E 테스트(validate:e2e에 묶이는 커밋 가능한 파일)로 남길 것을 권장(자동 커밋 X — stabilize는 코드·커밋 금지, 후속 task 제안). 실패는 Type: bugfix task(ADR-039)로 라우팅. 보안: browser_run_code_unsafe류 RCE급 도구는 사용하지 않는다 — accessibility snapshot·표준 브라우저 조작만. 본 단계는 메인 세션이 직접 수행한다 — 탐색 중 임시 스크립트가 필요하면 메인이 scratch 경로에 두고 경로를 넘긴다(ADR-050#amend-2 결정 2 — 프로젝트 트리에 만들지 않는다). 3-V. 경험 게이트 — 구현 화면 vs 승인 스냅샷 대조 (ADR-072 D7, UI 확정 마일스톤 한정): MCP 불요 체계 감사. 실행 자체는 의무 — silent skip 금지(미실행 사유 echo; 판정은 report-only). 본 단계도 메인 세션이 직접 수행한다 — 렌더·대조에 쓰는 임시 스크립트는 메인이 scratch 경로에 두고 경로를 넘긴다(ADR-050#amend-2 결정 2).
    • (a) docs/20-system/prototypes/M<N>/manifest.json을 읽는다(이 M이 등록한 화면이 있어야 하는데 부재면 blocked-on-env가 아니라 계약 결함 P0 [Experience-contract] 매니페스트 부재. 전 화면이 프로토타입 면제:이거나 이전 M 재사용이면 이 M 파일 부재가 정상이며, 그때는 feature ## 7의 프로토타입: id가 가리키는 M의 매니페스트·스냅샷을 읽는다). 화면마다 두 렌더를 만든다(매니페스트에 없는 UI 화면 — 프로토타입 면제: feature·이전 M 승인본 재사용 — 은 ②만 만들어 (b)의 ② 경로로 대조한다, ADR-072 D7): ① 스토리/위젯 렌더 — validate:design -- --manifest <경로> --snapshot docs/40-validation/visual/M-N/proto/; ② 제품 렌더 — 웹은 dev server 기동(명령은 STACK_SETUP_PLAN·package.json dev/start에서 회수, readiness 대기, 종료 시 kill — 재사용 규칙 기존대로) 후 매니페스트 product_entry(null이면 «제품 진입점 미기록» 사유 echo + ① 대조만)의 라우트를 프로필 뷰포트로 캡처해 docs/40-validation/visual/M-N/app/, Flutter는 통합 테스트 스크린샷이 가능하면 그것, 아니면 blocked-on-env 명시(ADR-059#amend-1 결정 4). blocker가 있어 --snapshot 복사에서 빠진 화면은 design-gate-shots/의 캡처를 ①로 쓴다.
    • (b) 각 화면에 대해 승인 스냅샷(snapshots/) ↔ ① ↔ ②를 Read(멀티모달)로 나란히 대조한다. 앵커 위계: ① 승인 스냅샷(존재 시) ② DESIGN.md §2/§7/§9/§10 파생 체크리스트(면제·부재 화면). 관점: 레이아웃·상태·카피·토큰 준수 — 픽셀 일치가 아니라 경험 계약 준수. ① vs 승인 스냅샷 불일치는 «승인 후 UI 코드 변경»이므로 같은 M 재승인 또는 다음 M supersedes 등재 여부를 함께 본다. 화면의 현재 기준선은 «가장 최근 M의 등록·supersedes»다(ADR-072 D5-5).
    • (c) 불일치는 QA_FINDINGS에 P1 [Experience-drift] <screen> — <1줄> (앵커: 스냅샷|DESIGN 파생 / 렌더: proto|app) report-only. 판독 불확실은 «판독 불확실» 명시. 시각 불일치가 봉인 AC·PX↔AC 위반을 동반하고 재현되면 그것은 별도 P0 결함(재현 줄 포함)으로 등재한다(ADR-070 D1).
    • (d) 단계 8 출력에 갤러리 경로 + «사용자 육안 확인은 /accept-milestone <M>이 수행한다» 1줄. 관측 modality AC가 1건이라도 있으면 사실상 필수 경로(ADR-068 D3).
    • Codex: 캡처까지 수행 + 대조는 «사용자 수동 검토» 안내로 degrade.
  3. 병렬 qa verifier 팬아웃 — 고정 1개가 아니라 필요한 만큼 (feature / user-flow / surface 단위로 분할). 메인 세션이 본 마일스톤의 feature·핵심 시나리오·surface 목록을 회수해 독립 점검 단위로 쪼개고, 각 단위마다 qa agent를 1개씩 병렬 위임한다(회귀·엣지케이스 점검). qa는 보고만 한다(qa.md의 tools에 Write 없음).
    • 위임 시 ADR-046#d3 적용: finding은 cap 때문에 누락하지 말고 전수 반환 — cap은 서술/과정 설명에만.
    • 입력에 «작업 파일을 프로젝트에 만들지 않는다 — scratch 경로: <세션 scratchpad>/stabilize-M<N>/» 한 줄(ADR-050#amend-2).
    • 회수 분할 (ADR-075 D11 (b)): 한 단위의 회수 문서가 10개 이상이면 축·범위를 더 나눠 dispatch 한다 — 한 dispatch 에 전부 싣지 않는다.
    • 입력에 ADR-070 D1 severity 정의표를 그대로 전달한다(기준 전달 — 사전판정 아님). P0 재현 줄 형식도 함께 전달한다.
    • 축 미반환 회수 규율 (ADR-075 D13): qa 단위가 구조화 반환 없이 멈추면 ① 1회 재개(같은 단위·같은 형식, 이미 확립한 finding 전량 포함 명시) → ② 다른 qa에 재위임 → ③ 메인이 그 단위를 직접 감사 → ④ 그래도 불가하면 QA_FINDINGS.md의 본 마일스톤 ### P0에 - **M<N>-audit-<K>** | P0 | [관측됨] | linked: M<N> | status: open + 하위 줄 - 감사 미완(unavailable): <단위> — <4단계 실패 사유>를 등재하고, 단계 8의 graduation을 BLOCKED (audit incomplete: <단위>)로 기록한다(ADR-068 D4). qa 팬아웃은 졸업 predicate ⑤의 유일한 입력이므로, 돌지 않은 감사를 근거로 "P0 0건"을 단정하지 않는다.
    • 다음 라운드에서 그 단위의 감사가 성공하면 본 skill이 그 M<N>-audit-<K> 항목의 status: open을 resolved로 갱신한다(본 skill이 자기가 만든 감사-미완 항목에 한해 status를 닫는 유일한 예외 — 그 밖의 finding status는 /repair-milestone·/repair-acceptance 소유).
    • Codex: 서브에이전트는 GA이나 본 저장소가 Claude persona 위임을 Codex subagent로 아직 매핑하지 않아 순차 단일 실행으로 degrade (동일한 분할 단위를 순차 단일 qa 호출로 한 단위씩 처리, 결과는 동일하게 누적).
  4. 병렬 reviewer verifier 팬아웃 — 필요한 만큼 (리팩토링 후보·아키텍처 부채). 각 reviewer 입력에 Clean Code 6항목 체크리스트(ADR-006) + review surface: code + ADR-046#d3(finding 전수 반환 — report-only) 를 명시 전달한다. UI 프로젝트는 추가로 review surface: design reviewer를 1개 더 팬아웃 — DESIGN.md ## 9. Do's and Don'ts 위반 의심 grep 결과를 입력으로 받아 비판적 검토. reviewer도 보고만 한다. design reviewer 입력에는 grep 결과에 더해 렌더 증거를 주입한다 — §3-V 갤러리 경로(proto/·app/) + 승인 스냅샷 경로(매니페스트) + visual-qa.spec 최근 결과. reviewer는 Read로 이미지를 열람한다(ADR-073 D8). Codex: 경로 echo + 텍스트 결과만 전달로 degrade.
    • 입력에 «작업 파일을 프로젝트에 만들지 않는다 — scratch 경로: <세션 scratchpad>/stabilize-M<N>/» 한 줄(ADR-050#amend-2).
    • 회수 분할 (ADR-075 D11 (b)): 한 단위의 회수 문서가 10개 이상이면 축·범위를 더 나눠 dispatch 한다 — 한 dispatch 에 전부 싣지 않는다.
    • Codex: 서브에이전트는 GA이나 본 저장소가 Claude persona 위임을 Codex subagent로 아직 매핑하지 않아 순차 단일 실행으로 degrade (분할 단위를 순차 reviewer 호출로 처리).
    • 축 미반환 회수 규율: 단계 4와 같은 4단계를 밟는다. 단 ④에 도달해도 판정을 바꾸지 않는다 — reviewer 결과는 졸업 predicate 입력이 아니다(report-only). IMPROVEMENT_GUIDE.md에 P2 [Audit-unavailable] reviewer:<단위> — 감사 미완을 기록하고 단계 8 출력에 사유를 echo한다. 미반환을 P0로 올리면 "결과 없음"이 "결과 있음"(정상 반환한 P1 부채는 졸업을 막지 않는다)보다 강해지는 역전이 생긴다. reviewer가 정상 반환한 결함은 6-S가 QA_FINDINGS로 보내 졸업 입력이 된다(ADR-070 D7). 미반환 자체는 여전히 판정을 바꾸지 않는다. 6-S. 메인 세션 self-synthesis (report-only 계약 유지): 위 4·5의 모든 병렬 verifier가 반환한 보고를 메인 세션이 직접 종합한다.
    • task report 잔여 finding도 이 종합의 입력이다 (ADR-076 D10): 본 마일스톤 산하 done task의 docs/40-validation/reports/<task-id>.md에서 ## 잔여 finding 절의 줄을 4·5의 보고와 함께 받는다. 그 절이 없는 옛 report와 report가 없는 task(checkout-local)는 건너뛰고 건수만 출력한다. 출처 값은 report-residual(<task-id>)다. P0·P1은 아래 채택 전 검토를 똑같이 거치며 등급은 ADR-070 D1 표로 다시 판정한다(validate의 등급과 다르면 판정 근거 한 줄에 적는다). P2는 채택 전 검토 대상이 아니다(ADR-070 D2는 P0·P1) — 성격 라우팅만 거치고, 아래 5-D와 같은 동일성 기준으로 이미 있으면 적지 않는다. report 줄은 과거 시점의 기록이라 verifier 보고와 다른 예외가 둘 있다 — 그 task ## 8에 같은 라벨·위치의 repair Reject-* 결정 줄이 있으면 task 층에서 이미 판정됐으므로 등재하지 않고, P0·P1 중 뒤 task가 이미 고쳐 현재 코드·문서에 근거가 없는 줄도 등재하지 않는다(둘 다 건수만 출력). P2는 해소 여부를 여기서 판정하지 않는다(/repair-milestone이 4-판정으로 닫는다).
    • 성격 기준 라우팅 (ADR-070 D7): 보고자와 무관하게 결함(동작·데이터·보안·계약 위반)은 docs/40-validation/QA_FINDINGS.md, 개선(구조·중복·명명·부채·문서 정합)은 docs/40-validation/IMPROVEMENT_GUIDE.md에 적는다. 항목 하위 줄 - 출처: qa | reviewer(<surface>) | preflight | peer(<tag>) | report-residual(<task-id>)로 보고자를 남긴다.
    • 채택 전 검토 (ADR-070 D2 — 등재 전 1회, P0·P1 전부): 각 항목을 confirmed | rejected-fp | rejected-context | needs-confirmation | unsubstantiated 중 하나로 판정해 decision:에 적는다. P0는 - 재현: 절차를 qa 단발 sub-call(명령 1회면 메인)이 다시 실행해 관측했을 때만 confirmed다. 코드·문서·상태를 바꾸는 재현은 메인이 직접 돌리지 않는다 — 단계 3이 띄운 환경에서 qa로, 불가하면 needs-confirmation(확인 방법 = /repair-milestone). P1은 보고의 재현·근거를 코드·문서로 확인하면 confirmed(재실행 불요). P0인데 재현 줄이 없으면 [Finding-unreproduced]를 붙여 needs-confirmation(하위 줄 - 대상 / 확인 방법 / 막힌 이유 3필드)으로 둔다(ADR-070 D1 — 이 조건은 P0 한정이다. 정적으로 확인되는 P1에 재현을 요구하지 않는다). rejected-*·unsubstantiated는 status: resolved로 등재한다(unsubstantiated는 ### 관찰 메모에 한 줄). 판정 근거 한 줄을 남긴다. 이것은 사후 판정이며 verifier에게 심각도를 미리 지정하는 것이 아니다.
    • 같은 마일스톤의 2회차 이후 stabilize에서 새로 등재하는 P0는 ADR-070 D6의 4가지 사실 줄(이전 감사 범위 / 새 근거 / 종결 항목과 동일성 / 종결을 뒤집는 증거)을 하위에 적는다. 종결 항목과 동일하면 새 ID를 만들지 않는다 — 이번 판정이 confirmed일 때만 그 항목을 status: open으로 재개하고 재개 사유(= 종결을 뒤집는 증거)를 적는다. rejected-*·unsubstantiated로 다시 판정됐으면 종결을 유지하고 그 항목 하위에 - 재보고: <날짜> — 동일 증상, 종결 유지(<decision> 근거 한 줄)만 남긴다(ADR-070 D6 — 근거 없이 재개하면 같은 오탐이 매 라운드 졸업을 막는다).
    • no-cap-drop (ADR-046#d3): 여러 verifier의 finding을 합칠 때도 cap 때문에 누락 금지 — finding은 전수 기록하고, cap은 대화 출력의 서술/과정 요약에만 적용한다.
    • dedup: 분할 단위가 겹쳐 동일 finding이 여러 verifier에서 중복 반환될 수 있다. 동일 <라벨> <file:line> <증상> 항목은 1건으로 병합하되, 서로 다른 단위에서 관측됨은 근거로 보존(병합 시 관측 surface를 한 줄로 합산).
    • reviewer 결과에 구조 변경이 필요해 보이면 메인 세션에 architect 추가 호출을 텍스트로 제안.
    • stabilize는 여전히 read-only다 — self-synthesis는 문서 누적 기록까지만. 코드·커밋·workitem status 변경 없음(도입부 책임 경계 정합). 5-D. 등재 전 dedup (필수 — ADR-070#amend-1 결정 2): 6-S 검토를 통과한 각 P0·P1 을 원장에 적기 전에, 같은 사실이 본 마일스톤 원장에 이미 있는지 본다. 동일성 기준은 «<라벨> <file:line> <증상>»(§1.0 3-1 과 같다)이며 preflight 정규식 발화처럼 file:line 이 여럿인 항목은 경로 집합으로 비교한다. 이미 있으면 status 가 open 이든 resolved 든 새 ID 를 만들지 않는다 — 대신 그 항목에 - 재발화: <YYYY-MM-DD> (stabilize <N>회차) — 판정 유지 한 줄만 붙인다. 경로 집합이 달라졌으면 새 항목이다. 이 규칙이 없으면 preflight 의 구조적 오탐이 매 라운드 새 ID 로 재생산된다(dogfood Round 11 실측 — raw-hex 5건·voice 10건이 3회차 내내 동일하게 재발화).
  5. 미흡한 ADR 후보 제안 — 마일스톤 중에 내려진 결정인데 ADR이 없는 것을 식별하고, IMPROVEMENT_GUIDE 항목 스키마(필수 4필드)로 영속 기록한다: - **M<N>-adrc-<K>** | P2 | [관측됨] | linked: M<N> | status: open + 하위 줄 - [ADR-candidate] <결정 한 줄> — 회수: 다음 /plan-milestone R0 (ADR-000#amend-2 — 기록 전 _ADR_GUIDE의 ADR 대상 기준 self-check, 남발 방지. 후보 ≠ 자동 작성). ADR 후보 기준에 "layer 경계·의존성 규칙 변경"도 포함(ADR-006 정책).
    • ARCHITECTURE_OVERVIEW.md에 비해당 7-x sub-section이 잔존하면 IMPROVEMENT_GUIDE.md에 P2 보고 — "조건부 sub-section 미삭제. /bootstrap-stack 재실행 또는 수동 삭제 권장."
    • layer 경계·의존성 규칙 변경(ARCHITECTURE_OVERVIEW의 ## 3-1)이 마일스톤 중에 발생했으면 ADR 후보로 표시한다(정책: ADR-006).
    • [Stack-drift] ADR-101 staleness 감지 (ADR-055, report-only): 본 마일스톤에서 순증한 dep(산하 task ## 3 install line-item / lockfile diff)을 T2 임계 카테고리(언어/런타임/프레임워크/DB·영속성/인증/배포 토폴로지/핵심 외부 의존, 또는 ARCH §7 결정·charter §7 제약을 뒤엎음 — 개별로 사소해도 cluster로 넘으면 포함)와 대조. 임계를 넘으면 P2 [Stack-drift] ADR-101 stale — 누적 dep가 T2 임계 도달 → /bootstrap-stack --migrate 후보 또는 ADR-101 amend를 IMPROVEMENT_GUIDE에 기록. 임계 미달 누적은 침묵(피로 방지 — ADR-101은 dep 원장이 아님). 휴리스틱 한계 echo(키워드/lockfile diff 기반 — false negative 가능).

6.5. DISCOVERY ↔ Charter staleness 감지 (ADR-035#amend-1)

다음 4 시그널을 점검한다 (보고만, 자동 차단 X — validator 책임 경계 정합).

  1. «Charter 마지막 커밋 이후 DISCOVERY에 Charter 공급 절의 실질 변경이 있는가»(ADR-035#amend-4)로 판정한다. 방법: C=$(git log -1 --format=%H -- docs/10-charter/PROJECT_CHARTER.md); git diff -U0 $C -- docs/10-charter/DISCOVERY.md(워킹트리 변경 포함)의 각 hunk를 **새 파일의 줄 범위(@@ -a,b +c,d @@의 c..c+d)**로 현재 DISCOVERY의 ## N. 헤딩 줄 범위에 대응시켜 절을 정한다(hunk 헤더의 함수명 칸은 markdown에서 절 제목을 보장하지 않으므로 쓰지 않는다). 제외: ## 14·## 15·### Repair history 절의 hunk 전부, 그리고 ## 12 절의 hunk 중 변경 줄이 전부 원장 상호참조 패턴(원장 D-[0-9]{3}·risk-accepted)만 담은 것. ## 12의 그 밖의 변경(가정 추가·결과 변경)은 Charter ## 9의 공급원이므로(ADR-069 D3 전파표) 발화한다. 제외 뒤 남는 hunk가 1개 이상이면 발화. git 이력이 없으면(fresh fork) mtime 규칙으로 degrade + 사유 echo.
  2. DISCOVERY.md ## 12. Assumption Tracker 표에서 "미검증" 결과 항목 수.
  3. PROJECT_CHARTER.md ## 2.1 페르소나 / ## 3.1 핵심 시나리오 / ## 9 핵심 가정 섹션 중 비어 있거나 DISCOVERY.md와 명백히 어긋난 섹션 수.
  4. (ADR-035#amend-2) DISCOVERY.md ## 15. Insight Backlog에서 status=open(미반영) 인사이트 수 — 있으면 "미반영 인사이트 N건 — 다음 /plan-milestone 후보로 회수 권장" P1 보고.

위 1~3 시그널 중 1개라도 stale 의심 판정 시 IMPROVEMENT_GUIDE.md에 P1 보고: "DISCOVERY ↔ Charter drift 의심 — 절 단위 부분 갱신이면 /amend-ssot, 전면 재정의면 /bootstrap-project --apply 권장." (시그널 4는 drift가 아니라 미반영 인사이트 신호 — 위 4번 줄에서 별도 P1 보고하므로 본 집계에 포함하지 않는다.)

  1. ARCHITECTURE_OVERVIEW의 ## 3-1. 레이어 경계 + 의존성 규칙 섹션이 비어 있고 모듈 수가 3개 이상이면 채울 것을 권장 출력한다(정책: ADR-006).

7-T. Telemetry aggregate (ADR-047 D7 deep telemetry + D1 inspectability 정합). 본 마일스톤 산하 task의 이미 수집된 데이터를 수치 dashboard로 echo. 새 데이터 수집 X — surface만.

수집 소스:

  • 본 마일스톤 산하 모든 task의 docs/40-validation/reports/<task-id>.md (존재 시). 부재하면 그 task ## 8의 마지막 - closure 줄에서 기계AC·자동화율을 읽는다(ADR-068 D2 — 새 체크아웃에서 telemetry가 통째로 비는 것을 막는다). 그 줄도 없으면 그 task를 «집계 불가»로 세고 출력에 건수를 남긴다.
  • 검증 레벨 분포는 산하 task의 ## 6-1에서 직접 집계한다 — 채점표에도 - closure에도 그 값이 없으므로(closure는 기계AC·자동화율만 담는다) 커밋된 ## 6-1이 유일한 항구 출처다. 판정 규칙은 /validate-workitem과 같다([자동 테스트] AC만 레벨 대상, 명시 {레벨} 태그 우선, 미기재는 테스트 경로 추론, 나머지는 레벨 비대상).
  • 본 마일스톤 산하 feature의 ## 7-1. FAC ↔ AC 매핑표.
  • docs/40-validation/QA_FINDINGS.md 본 milestone 헤더(## M-N) 아래.
  • docs/40-validation/IMPROVEMENT_GUIDE.md의 ## 2. 열린 항목 안의 본 milestone sub-section (### M-N 그룹) — Cross-stabilize 회귀 신호 grep 대상. ## 5. Repair decision log는 제외 (Step 3 신설 영역, closed records라 open finding 재등장 측정 대상 아님).

집계 항목:

  • Tasks: M done / N total (M/N %)
  • AC↔검증 매핑: 충족 A / 전체 B — 충족률 <%> · 자동화율 <%>
  • AC 검증 레벨 분포: unit N / integration M / contract K / e2e L · 레벨 비대상 P ([자동 테스트] AC만 레벨 대상 — 출처: task ## 6-1. [산출물 검사]·관측 2종은 «레벨 비대상»이며 자동화율 분류와는 별개다 — ADR-065 D4)
  • FAC coverage: C ✅ / D total (C/D %)
  • Evidence Bundle 신뢰도 분포: High K / Medium L / Low J (Step 2 도입 후 채워짐 — 미도입 마일스톤은 "해당없음" 한 줄)
  • Validate exit code (가장 최근 실행): 0 / non-zero / 미설정
  • Findings 분포: P0 X / P1 Y / P2 Z (본 milestone 헤더 산하)
  • Open 전체 스냅샷 — 세 수를 정의대로 센다(겹치지 않게 한다).
    • N = QA_FINDINGS.md의 본 마일스톤 헤더(## M-N) 아래 미해소 항목 수(P0 a / P1 b / P2 c)
    • M = IMPROVEMENT_GUIDE.md의 본 마일스톤 그룹(### M-N) 안 미해소 항목 수(P0 d / P1 e / P2 f). ## 5. Repair decision log는 closed records라 제외.
    • K = 다른(이전) 마일스톤 헤더·그룹의 미해소 P0/P1 수 = carry-over
    • 합계 = N + M + K. 형식: Open 전체: QA_FINDINGS N + IMPROVEMENT_GUIDE M + carry-over(P0/P1) K = (N+M+K)건 — carry-over에 (P0/P1)을 붙여 출력한다. N·M은 전 severity인데 K는 P0/P1만 세므로(다른 마일스톤 항목은 색인 스캔 대상 — /repair-milestone 회수 규율과 동형), 표기하지 않으면 ## 8. 회고에 영속되는 수치를 읽는 사람이 기준을 오독한다.
    • 두 원장을 각각 읽어야만 알 수 있는 수이므로 한 줄로 합산해 남긴다(한쪽만 읽고 남은 항목 수를 오독한 사례가 관측됨). 같은 값을 milestone ## 8. 회고의 open 항목 스냅샷: 줄에도 기록한다(ADR-068 D5).
  • Cross-stabilize 회귀 신호: 이전 모든 milestone들(## M-1 ~ ## M-(N-1))의 P1 라벨 finding이 본 milestone의 QA_FINDINGS(## M-N) 또는 IMPROVEMENT_GUIDE 의 ## 2. 열린 항목 안 ### M-N 두 sub-section에 재등장한 항목 수 (라벨 grep, 휴리스틱 한계 echo — 동의어/오타 false-negative 가능. 본 grep은 정확한 라벨 매칭만 잡음. ## 5. Repair decision log는 closed records라 회귀 신호 대상 아님).
  • 위임 예산 (ADR-074 D11): 턴 소진 0건 보고: N회 — 산하 task 의 report·repair 로그에서 «sub-agent 가 턴 상한에 닿았는데 보고가 0건이었다»고 적힌 건수를 센다(기록이 없으면 0회 (미기록)). 이 실패는 지금까지 사람이 알아채야만 보였다. 1회 이상이면 ADR-074 D14의 slice 강제 조건이 발화한다 — 단계 8 출력에 그 사실을 한 줄로 적는다.
  • 수렴 (ADR-070 D8): round K(IMPROVEMENT_GUIDE ## 5 ### M-N의 - round: 최대값, 없으면 0) / P0 신규 a · 해소 b · 재개 c / P0 재현 첨부율 <%> / needs-confirmation d건

본 단계는 수치 echo만 — IMPROVEMENT_GUIDE / QA_FINDINGS에 새 항목 박지 않음. Cross-stabilize 회귀 신호가 1+ 건이면 단계 8 출력의 "P1 / P2 후속 작업"에 patterned drift 의심 한 줄 추가.

출력 형식 (단계 8의 최종 출력에 Telemetry 단락으로 포함):

Telemetry — M1
- Tasks: 12 / 12 (100%)
- AC↔검증 매핑: 충족 34 / 전체 36 — 충족률 94.4% · 자동화율 88.9%
- AC 검증 레벨 분포: unit 20 / integration 9 / contract 2 / e2e 1 · 레벨 비대상 4
- FAC coverage: 8 / 8 (100%)
- Evidence Bundle 신뢰도: High 9 / Medium 2 / Low 1
- Validate exit code: 0
- Findings: P0 0 / P1 3 / P2 7
- Open 전체: QA_FINDINGS 4 + IMPROVEMENT_GUIDE 6 + carry-over(P0/P1) 1 = 11건
- Cross-stabilize 회귀 신호: 0건
- 위임 예산: 턴 소진 0건 보고 0회
- 수렴: round 2 / P0 신규 1 · 해소 3 · 재개 0 / 재현 첨부율 100% / needs-confirmation 0
  1. 최종 출력:
    • 통합 validate 결과 + E2E 결과 (있으면)
    • P0 / P1 / P2 후속 작업
    • QA_FINDINGS / IMPROVEMENT_GUIDE 갱신 위치
    • 변경한 tracked 파일 목록: QA_FINDINGS.md·IMPROVEMENT_GUIDE.md·마일스톤 문서(## 8 회고)·DECISION_REGISTER.md(등재 시)
    • 커밋 안내: 본 skill은 커밋하지 않는다 — 위 파일을 사용자가 직접 커밋한 뒤 다음 단계로 진행한다(commit owner는 사용자//finalize-workitem). 미커밋으로 두면 후속 task의 /finalize-workitem이 그 파일을 task ## 4-1 밖 변경으로 보고 Needs Review로 멈춘다.
    • 수용 대기 AC (item 4 미충족): <task-id>:AC-N (<modality>) 목록 / 해당없음. /accept-milestone <M> 처방은 최종 판정이 PENDING_ACCEPTANCE일 때만 붙인다 — NO·BLOCKED면 목록만 남기고 처방은 아래 「다음 단계」 분기가 소유한다(한 출력이 두 명령을 지시하면 사용자가 어느 쪽을 칠지 알 수 없다)
    • 다음 마일스톤으로 넘기는 항목
    • (UI) 경험 게이트 결과: [Experience-drift] N건 + 스크린샷 갤러리 경로 (사용자 육안 확인 권장) — 미실행 시 사유 필수 echo (silent skip 금지)
    • architect 호출 권장 (있으면)
    • ADR 후보 (있으면): [ADR-candidate] 라벨 목록 — 다음 /plan-milestone R0가 회수 (ADR-000#amend-2)
    • instruction improvement 후보: 본 마일스톤 동안 builder/validator/reviewer가 반복적으로 막힌 패턴, AGENTS.md 또는 agent/skill body 문구가 비자명하거나 모호했던 지점, 새로 박을 만한 self-check 항목 후보를 IMPROVEMENT_GUIDE.md에 보고. 각 항목에 ADR-022 evidence label 부착. AGENTS.md / agent / skill body는 자동 수정 X — 보고만. 경험·사용 관점 교훈(제품을 실제로 써 본 결과에서 나온 것) 유무를 별도로 확인한다 — 교훈이 검증-정교화 방향으로만 쌓이는 편향 방지([관측됨] 실사용에서 경험 축 교훈 0건).
      • DESIGN.md / ARCH 7-x cross-surface drift 가 본 마일스톤 중에 N회 이상 발견됐다면 ADR-073 D8 적용 본문 이 누락된 fork 인지 점검 권장.
    • Telemetry aggregate (단계 7-T 결과 echo — 수치만, IMPROVEMENT_GUIDE 신규 항목 X).
    • 다음 단계 (WORKFLOW.md "스킬 종료 시 다음 단계 출력 contract" 양식 정합):
      • 졸업 가능 = PENDING_ACCEPTANCE (item 4만 미충족):
        • 유일한 권장: /accept-milestone <M> — 사람이 직접 실행·확인하는 수용 라운드이며(ADR-066 D1), 미발급 receipt는 그 자리에서만 발급된다(사용자 authority — ADR-065 D1). 미발급 AC 목록(<task-id>:AC-N)을 함께 출력한다.
        • 여기서 /validate-workitem·/finalize-workitem 재실행을 권장하지 않는다 — 그 마일스톤은 이미 폐쇄됐고(ADR-068 D1), 졸업 item 4는 task ## 8을 직접 읽으므로 receipt 발급만으로 충족된다.
        • 수용 라운드 뒤에는 그 skill의 출력이 지시하는 순서를 따른다. 코드 변경이 있었으면 /repair-acceptance <M>이 그 자리에서 고치고 회귀 테스트까지 끝낸다 — task를 재개방하지 않으므로 사용자가 돌릴 /validate-workitem·/finalize-workitem은 없다. 사용자는 그 뒤 본 skill을 한 번 더 실행해 YES를 확정한다.
      • 졸업 가능 = YES + P0 후속 0건:
        • (ADR-076 D5) IMPROVEMENT_GUIDE 본 마일스톤 그룹에 status: open인 [Provisional-AC]가 있으면 기본 권장을 /repair-milestone <M> — "잠정 해석 N건 사용자 확인(승인/변경)"으로 두고, 아래 /plan-milestone은 그 뒤 순서로 안내한다.
        • 기본 권장: /plan-milestone — 새 milestone(M-(N+1)) + feature 문서 생성 → contract-ready. 뒤이어 /plan-workitem M-(N+1)(전체 계획 스냅샷, task는 draft) → /seal-milestone M-(N+1)(검사·승인·일괄 ready) 순으로 진행(ADR-057#amend-3 / ADR-060 D7)
        • /accept-milestone <M>은 이 상태에서 선택이다 — YES는 관측 modality AC가 0건이거나 그 receipt가 이미 전부 유효하다는 뜻이므로 receipt로 막힐 것이 없다. 사용자가 경험 확인을 원하면 실행한다. 단 마일스톤 문서 ## 11에 - 판정: 승인이 이미 기록돼 있고 그 뒤 코드·receipt 변경이 없으면 재권장하지 않는다 — 그 상태에서 다시 권장하면 라운드 상한 3이 무의미하게 소모된다.
        • 프롬프트 동봉 권장: 본 라운드 Telemetry 의 신뢰도 분포 + Cross-stabilize 회귀 신호 (다음 milestone 의 우선순위 조정 입력)
      • 졸업 가능 = BLOCKED (평가 실행 불가 — ADR-068 D4). 이 분기가 아래 NO 분기보다 우선한다(우선순위 BLOCKED > NO) — 감사 미완은 M<N>-audit-<K> P0를 등재하므로 «P0 후속 있음»에도 걸리지만, 그 P0의 처방은 repair가 아니다:
        • 감사 미완(BLOCKED (audit incomplete: <단위>)): 처방은 그 축의 재감사다 — 단계 4의 축 미반환 회수 규율 ①~③(1회 재개 → 다른 qa 재위임 → 메인 직접 감사)을 다시 시도하거나 본 skill을 재실행한다. /repair-milestone은 처방이 아니다 — «못 재봤다»는 상태이지 코드 결함이 아니어서 4-판정할 대상이 없다. 등재된 M<N>-audit-<K> P0는 감사가 완료된 뒤 status: resolved로 닫는다.
        • e2e blocked-on-env: 처방은 아래 NO 분기의 «e2e blocked-on-env» 불릿과 같다(환경 복구 후 본 skill 재실행 — real failure가 아니므로 repair 대상이 아니다).
        • BLOCKED은 이전 라운드에 기록된 YES·PENDING_ACCEPTANCE를 덮어쓴다(책임 경계의 회고 기록 규칙) — 낡은 값이 남아 하류가 졸업으로 읽는 것을 막는다.
      • 졸업 가능 = NO 또는 P0 후속 있음 (분기 옵션 ≤3):
        • 수렴 실패 브리프 (ADR-070 D5): 7-T의 round K가 3 이상이고 ### P0에 status: open이 남아 있으면, 판정은 그대로 두고 [Convergence] 라벨로 Decision Brief 6블록(authority: user-choice, 영향: M<N>, DECISION_REGISTER 등재)을 출력한다 — 남은 P0/P1 각각의 decision·근거·영향·수리 범위·보류 가능 여부 + 선택지 A(계속 수리) / B(비차단 항목에 - 수렴-보류: 회수 <시점> | 조건: … 하위 줄을 달아 이번 라운드 대상에서 빼고 차단 항목만 수리 — status는 open 유지, finding 원장에 deferred 상태를 만들지 않는다) / C(NO 유지 + 병렬 Now 승인으로 다음 마일스톤 진행 — carry-over 표시 지속, 해소 후 /repair-milestone M<N>이 원본을 닫고 본 skill 재실행으로 YES). 남은 ### P0 open 항목이 전부 - 판정: Adopt — blocked: 줄을 가지면 선택지 A·B 를 제시하지 않는다(ADR-070#amend-1 결정 3) — 그 상태에서 A(한 라운드 더)의 기대 효과는 0 이고 B(차단 항목만 수리)의 대상도 없다. 그때 선택지는 C 와 «재승인·계약 정정 경로 착수» 둘이며, 브리프에 각 항목의 blocked: 경로를 그대로 옮겨 적는다. 하나라도 blocked 가 아니면 기존대로 셋을 낸다. 판정값 신설·YES 병기·P0의 P1 재분류는 하지 않는다. 항목을 DECISION_REGISTER에 open으로 등재하고(정상 책임 4), 사용자가 같은 세션에서 답하면 그 항목에 한해 closed + 앵커를 쓴다. ## 5의 - convergence-decision: 줄은 답변 시점과 무관하게 후속 skill이 남긴다(A·B → /repair-milestone 1-R, C → /plan-milestone R0 — 본 skill은 ## 5에 쓰지 않는다, ADR-070 D5). ## 5 ### M-N에 - convergence-decision: 줄이 이미 있으면 새 P0 ID가 생겼거나 K − 결정 round ≥ 2일 때만 다시 낸다. BLOCKED 분기에서도 같은 조건(round ≥ 3 + open P0)이면 동일 브리프를 낸다 — 감사 미완·환경 불가와 별개로 남은 P0의 진행 경로를 사용자가 정해야 한다.
        • milestone-level P0/P1 (여러 task 교차) 또는 e2e real failure 있음: /repair-milestone M-N 권장 (ADR-052) — 단일 task로 격리되지 않는 회귀·교차 결함과 실제 e2e 수정은 milestone 단위 repair로 라우팅. stabilize가 read-only로 남기 위한 코드 수정 경로다.
        • [Provisional-AC]가 open이면 같은 /repair-milestone M-N 호출에서 함께 확인한다 (ADR-076 D5).
        • QA_FINDINGS 발견(P0/P1)은 단일 task 격리든 교차든 /repair-milestone M-N 로 회수한다 — repair-milestone이 4-판정 후 per-task 귀속이든 cross-cutting이든 직접 수정하고(재개방·위임 없음 — ADR-068 D1) QA_FINDINGS status를 닫는다.
        • [Spec-gap] finding 있음: 미커버 FAC를 분기 — (i) M-N이 약속한 FAC의 구현 누락·버그이고 담당 task가 있으면 현재 M-N에서 /repair-milestone M-N이 직접 수정(단일 task 귀속이든 교차든 — ADR-068 D1); 담당 task 자체가 없으면(정상적으론 plan-time [Plan-FAC-coverage] 100% 게이트가 막으므로 드묾) 현재 M-N의 미이행 약속으로 graduation NO를 유지하고 사용자에게 보고한다. 현재 M에 새 task를 자동·권장 생성하거나 FAC 취소로 거짓 통과시키지 않는다. 본 계약에 정해진 자동 해소 경로는 없으며 사용자 판단을 기다린다. (ii) 새 기능·기획 변경(M-N 약속 아님)이면 다음 마일스톤(M-(N+1)), (iii) 계획이 근본적으로 잘못됐으면 자동 수정 없이 사용자 중단·보고 (ADR-057#amend-3 결정 6 — F-NNN 재계획 경로 없음)
        • [Doc-link] / [ADR-ref] 등 문서 정합 P0: 사용자 직접 수정 (architect 또는 메인)
        • e2e blocked-on-env (ENVIRONMENT failure): real failure가 아니므로 repair 대상 아님 — 사용자에게 환경 복구(브라우저 설치 / 앱 기동 / E2E MCP 등재·access)를 안내하고 환경 복구 후 /stabilize-milestone M-N 재실행 권장.
      • 공통 프롬프트 동봉 권장:
        • 미해결 P0/P1 라벨 목록 (다음 호출의 우선 처리 대상)
        • Cross-stabilize 회귀 신호 항목 (있으면 — patterned drift 경고)
        • 본 마일스톤의 instruction improvement 후보 (있으면 — 다음 stabilize 라운드에서 회수)

책임 경계:

  • 코드 수정·커밋·workitem status 변경 금지.
  • 누적 문서 갱신 + milestone ## 8. 회고 자동 채움 — 회고의 graduation: 줄은 §1.5의 정적 항목 값(item 1·4)과 단계 3~6의 동적 항목 값(item 2·3·5·6)을 합쳐 단계 8에서 1회만 기록한다(ADR-068 D3·D4). §1.5의 정적 값을 여기서 재계산하지 않는다 — 본 skill이 단계 4~6에서 QA_FINDINGS·IMPROVEMENT_GUIDE를 쓰므로 재계산하면 자기 쓰기가 판정에 섞인다. 값은 YES|PENDING_ACCEPTANCE|NO|BLOCKED+날짜 4종이며 우선순위는 BLOCKED > NO > PENDING_ACCEPTANCE > YES다.
    • item 4만 미충족이고 1·2·3·5가 전부 충족이면 PENDING_ACCEPTANCE (관측 AC 미발급: <task-id>:AC-N 목록) 으로 기록한다 — NO로 쓰지 않는다.
    • 감사 미완이 있으면 BLOCKED (audit incomplete: <축>), e2e 환경 불가면 BLOCKED (e2e blocked-on-env: <target>). 이 값은 이전 라운드의 YES·PENDING_ACCEPTANCE를 덮어쓴다.
    • P0 기준은 QA_FINDINGS.md의 미해소 P0만 반영한다(성격 기준으로 등재된 결함 — 보고자 무관, ADR-070 D7).
    • 회고의 open 항목 스냅샷: 줄도 여기서 채운다(ADR-068 D5).
    • 회고의 post-close 수정: 줄도 여기서 채운다 (ADR-068 D5) — IMPROVEMENT_GUIDE.md ## 5. Repair decision log의 본 마일스톤 ### M-N 그룹 항목 수를 세고 각 항목의 scope: 값으로 in-AC/out-of-AC를 분해한다. 그룹이 없으면 없음.
    • 로드맵 파일은 안 건드린다(다음 plan-milestone R0가 이 줄을 읽어 재조정).
  • 상세 SSOT 는 본 skill 도입부 책임 경계 단락 — 본 단락은 단순 재확인.

E2E는 단계 3-a의 필요성 판정으로 결정한다 — e2e 불필요(비-UI ∧ graduation item 6 미선언) 마일스톤만 통합 validate만 돌리고 e2e를 skip한다(사유 출력 명시). e2e 필요 마일스톤은 silent-skip 금지 — validate:e2e를 반드시 실행하고, 미통과(real) 시 졸업 hard-block, 실행 불가(env) 시 사용자 환경 복구 안내(ADR-052).

Dependency hygiene

실행 시점: 단계 4~5(qa·reviewer 위임)와 함께 수행하고 결과를 단계 8 최종 출력 전에 IMPROVEMENT_GUIDE 에 기록한다 — 본 섹션이 문서 끝에 있다고 마지막에 실행하는 것이 아니다.

  • npm audit / pip-audit (스택별 대응) 1회 실행. Dart/Flutter 는 audit 에 정확히 대응하는 명령이 없어 아래 셋으로 나뉜다 — 목적이 서로 달라 하나로 묶어 보고하지 않는다. 셋 다 읽기 전용 경로만 쓰고, 도구를 설치하지 않는다(본 skill 은 파일을 고치지 않는다). 미설치 도구는 그 항목만 skip 하고 사유를 출력에 명시한다(Doc-link check skipped 와 동형).
    • 갱신 가능 여부: flutter pub outdated — 내장이고 pubspec.lock 을 바꾸지 않는다.
    • 미선언·미사용 의존: dart pub global run dependency_validator. 미활성이면 skip + dep hygiene skipped: dependency_validator not activated (dart pub global activate dependency_validator — 사용자/stack-guard 소관).
    • 취약점: pubspec.lock 을 대상으로 osv-scanner 실행. 미설치면 skip + 사유 명시. dart pub get 의 advisory 출력을 쓰려면 반드시 --enforce-lockfile 을 붙인다 — 플래그 없는 pub get 은 해결 결과를 pubspec.lock 에 쓰므로 read-only 계약을 깨뜨린다. 플래그를 못 쓰는 환경이면 이 경로를 생략하고 osv-scanner 결과만 쓴다.
  • 결과를 IMPROVEMENT_GUIDE.md에 P1 severity로 보고.
  • 6개월 unused deps는 P2로 자동 등록.

Context 정책 (ADR-019)

반드시 먼저 읽을 파일은 최소 충분. 추가 ADR/architecture 섹션은 task 본문에서 발화 시 인용 — 사전 fork-load 금지. fan-out 병렬 오케스트레이션 정책은 ADR-075 D2 정합.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.