# Milestone Closure — 70-viewer-6

## Milestone

- ID         : 70-viewer-6
- Name       : 빌드 게이트 승격
- PRD        : `.claude/prds/insuniverse-docs-70-viewer.prd.md` (Delivery Milestones 6행)
- Plan       : `.claude/plans/insuniverse-docs-70-viewer-m6.plan.md`
- Status     : done
- Closed at  : 2026-08-31T04:23:09.472Z
- Closed by  : /mccp:milestone-close (run_id=b471d8cf-c305-4147-8b21-f9218d3dc8c9)
- HEAD       : `90a52b82e18fa5e33cf25fd0b57589b6411bb427`

## Acceptance Condition

사용자가 `/goal` 에 넘긴 조건 원문:

> M6 (빌드 게이트 승격) 종료 조건을 확인한다. (1) node .claude/plans/insuniverse-docs-70-viewer-m6.gates.mjs check-all 이 13/13 ok 로 rc 0, (2) bash docs/_meta/verify/verify.sh --check 의 stdout 마지막 줄이 정확히 "check PASS", (3) node .claude/templates/plan-kit/lint-plan.mjs .claude/plans/insuniverse-docs-70-viewer-m6.plan.md 가 rc 0, (4) docs/viewer/gate.mjs · docs/viewer/fail-sites.txt 실재, (5) working tree clean. 전부 초록이면 종료. 하나라도 붉으면 사유 출력하고 종료. 또는 5 turn 후 중단.

## Goal Loop Result

조건 5건 전건 충족. 실측 출력은 아래 §측정 회차.

**(1) `check-all` 13/13 rc 0** — 마지막 줄 원문:

```
check-all ok  완주 13/13 · 실행 집합 == 등록부 집합 == Validation 호출 집합 · 차집합 0 · #11 은 표 현재값 in-progress 로 호출 · 외부 검사는 이 목록 밖 (verify.sh · lint-plan.mjs) · 집계기 자신(check-all)은 실행 목록에서 제외
```

검사별 통과 문면 중 이 마일스톤의 주장을 직접 지는 넷:

```
#4 ok  build rc 0 · 프로브 10건 선행 통과 · anchor-freshness.json 갱신(항목 1417건) · index.html 실재 · 빌드가 받은 --freshness 가 앞단 산출과 같은 파일 · 호출 로그 프로브→anchor → build-docs · 건너뛰기 플래그 0종 · preflight 16878ms · 중간산출 실행별 이름 + 성공 뒤 승격(잔존 0) · 2회 실행 산출 55건 바이트 동일 · 실행 id 문자열 산출 전건 0
#7 ok  probe rc 0 · 프로브 10건 전건 rc≠0 재현 · 기대 출력 조각 일치 10/10 · 사본 1회(트리 32791355 bytes · 263ms) · 프로브 후 복원 171/171 · suite 9675ms · 프로브 호출 전건이 --out 임시 경로(실 docs/viewer/build 바이트 불변 0건 차이) · 임시 트리는 실 문서 사본(픽스처 미커밋) · 앵커 축 프로브가 --docs-root 로 사본을 본다(빼면 이름 있는 실패)
#8 ok  fail 지점 79건 = 덮음 10 + 미덮음 69 + 동적 0 · 미덮음 전건이 행 번호와 메시지 조각으로 출력(69행) · docs/viewer/fail-sites.txt 와 양방향 멀티셋 차집합 0 · 동결 행에 행 번호 0건(형태 <생성기> <sha256>) · 동결 키는 호출 전문 digest · 계수 리터럴 0 · 중복 접두 코호트의 지점 하나를 꺼도 '동결에만 1건' 으로 잡힌다
#13 ok  재생성 전 m2 완주/m3 완주/m4 붉음 1/m5 붉음 1 · gate.mjs build 재생성 후 m2 완주/m3 완주/m4 붉음 1/m5 붉음 1 · 범위 축 0건 · 선재 축 2건 · 의미 축 0
```

**(2) `verify.sh --check`** — rc 0. stdout 136행, 마지막 줄이 정확히 `check PASS`. 진행 로그는
stderr 로 갈리므로 두 스트림을 파일 둘로 나눠 받았다(이어붙이면 마지막 줄이 뒤집힌다).

**(3) `lint-plan.mjs`** — rc 0, 출력 없음.

**(4) 산출물 실재** — `docs/viewer/gate.mjs` 45162 bytes · `docs/viewer/fail-sites.txt` 7064 bytes.

**(5) working tree** — `git status --porcelain` 0행.

## 측정 회차 (스탬프 전)

| 회차 | 시점 | 대상 | 결과 |
|---|---|---|---|
| 1 | 락 진입 전 (HEAD `90a52b8`) | `git status --porcelain` · `git branch --show-current` | clean · `70-viewer` |
| 2 | 락 해제 후 | `lint-plan.mjs <m6 plan>` | rc 0 |
| 3 | 락 해제 후 | `docs/viewer/gate.mjs` · `docs/viewer/fail-sites.txt` 실재 | 둘 다 실재 |
| 4 | 락 해제 후 | `insuniverse-docs-70-viewer-m6.gates.mjs check-all` | rc 0 · 완주 13/13 (`#11` 은 표 현재값 `in-progress` 로 호출) |
| 5 | 락 해제 후 | `docs/_meta/verify/verify.sh --check` | rc 0 · stdout 마지막 줄 `check PASS` |

**스탬프 후 회차는 이 문서에 적지 않는다.** 적는 순간 이 문서의 sha256 이 움직여 PRD 스탬프가
자기를 가리키지 못하고 스탬프를 두 번 갈아야 한다. 아래는 그 회차의 **예측**이며 결과는 이
문서 밖(사용자에게 닫는 보고)에 있다 — 틀리면 그 사실이 여기 남는다.

- 예측 A: PRD 6행 전이 후 `check11 --expect complete` 가 ok. `#11` 은 `--expect` 를 어휘 2종으로
  받고 `check-all` 이 표 현재값에서 expect 를 유도하므로(하네스 1051~1054 행) 전이가 하네스를
  깨지 않는다.
- 예측 B: 이 closure-doc 은 계획서 §Files to Change 8경로 밖이고 `isWorkflowArtifact` 의
  `WF_DIRS` 에도 없다. 따라서 **커밋 전** `#1` 은 범위 밖 미커밋으로 붉다. 커밋 후 미커밋 0 이
  되어 다시 초록. 하네스는 고치지 않는다.
- 예측 C: 커밋 후 `check-all` 재실행이 13/13, `#11` 이 `complete` 로 호출.

## 전이 판정 — 이 축은 표 6행을 종결 커밋에서 뒤집는다

형제 축 `50-domain` 은 행 전이를 **다음 창**으로 미룬다. 그 축의 `check10` 이 `--expect pre|post`
양쪽에서 자기 행의 `in-progress` 를 요구하기 때문이다. **이 축은 다르다.**

- 이 축의 `#11` 은 `--expect in-progress|complete` 두 어휘를 모두 받는다(하네스 851~852 행).
- `check-all` 은 표의 **현재값**을 읽어 expect 로 넘긴다(1051~1054 행). 리터럴 기대가 없다.
- 이 PRD 의 §개정 이력은 마일스톤 2·3·4·5 전건이 *"표 N행과 `*Status:` 두 자리 동시 전이"* 로
  닫혔음을 기록한다. M6 만 착수 전이(`pending`→`in-progress`)까지 하고 멈춰 있었다.

따라서 전이는 이 종결이 진다. **표 6행과 `*Status:` 토큰을 같은 커밋에서 함께** 뒤집는다 —
`#11` 이 두 자리의 일치를 검사하므로 한쪽만 뒤집으면 즉시 붉다.

## 도구 실행 사실

- Phase 1 DETECT 원문:

  ```json
  {"availability":"available","goal_signal":true,"signal_ref":{"row":6,"name":"**빌드 게이트 승격**","plan":".claude/plans/insuniverse-docs-70-viewer-m6.plan.md","status":"in-progress"},"mode":"milestone-close","reason":"ok"}
  ```

- Phase 2 lock enter ok — `run_id=b471d8cf-c305-4147-8b21-f9218d3dc8c9` ·
  `milestone_id=70-viewer-6` · sidecar 는 `<gitdir>/mccp/tmp/` 에 기록.
- **Phase 4 순서를 역전했다.** lock 이 활성인 동안 `goal-phase-guard` 가 Bash 를 default-deny 로
  돌려 acceptance 하네스(`node ... gates.mjs` · `bash verify.sh` · `sed`)가 전건 차단된다. 그 상태로
  verdict 만 받으면 이 문서가 **실측 없이 봉인**된다. 그래서 lock 을 먼저 `exit` 로 풀고
  회차 2~5 를 실측한 뒤 이 문서를 썼다. lock exit 은 `{"ok":true,"cleared":true}`.
- 이 저장소 실측: lock 밑에서는 `cd ... && node ...` 도 세그먼트 불일치로 거부된다. 탈출은
  접두 없는 단일 세그먼트 `node "<절대경로>/goal-phase-lock.js" exit --run-id <id>` 뿐이다.

## Provenance

- Lock run_id        : `b471d8cf-c305-4147-8b21-f9218d3dc8c9`
- Lock owner session : `unknown` (`CLAUDE_SESSION_ID` 미주입 — 도구가 그대로 기록)
- PRD source         : `.claude/prds/insuniverse-docs-70-viewer.prd.md`
- Plan source        : `.claude/plans/insuniverse-docs-70-viewer-m6.plan.md`
- Detection signal   : `{"row":6,"status":"in-progress","reason":"ok"}`
- mccp version       : 1.33.1
- 스탬프 위치        : **PRD** `## Milestone Closure Provenance`. plan body 가 아니다 — plan body 에
  찍으면 `planAwareMarkdownHash` 가 바뀌어 `mccp-plan-codex` · `mccp-implement-codex` 두 receipt 가
  전건 `stale` 로 떨어지고 `/mccp:pr` 이 fail-closed 로 막힌다. PRD 는 `isPlanPath` 밖이다.
