# Milestone Closure — 5-site-ia

## Milestone

- ID         : 5-site-ia
- Name       : site 화면 축
- PRD        : `.claude/prds/insuniverse-docs-50-domain.prd.md` (Delivery Milestones 5행)
- Plan       : `.claude/plans/insuniverse-docs-50-domain-m5.plan.md`
- Status     : done
- Closed at  : 2026-08-27T04:26:28.862Z
- Closed by  : /mccp:milestone-close (run_id=6c7aac68-418f-4402-89ae-90a9e16d2c9f)
- HEAD       : `d368d73d7c85505c82fe3ab9f92eb8763736c2ca`

## Acceptance Condition

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

> `.claude/plans/insuniverse-docs-50-domain-m5.gates.mjs check-all` 이 11/11 통과하고,
> `docs/20-site/00-ia.md` 만 읽고 site 화면 85건의 라우트 좌표와 접힘 12·제외 3 의 사유를
> 답할 수 있으며, 동결 대조 부재 5항이 H1 아래 고지와 backlog 5행으로 명시돼 있다.
> 또는 20 turn 후 중단.

## Goal Loop Result

3항 전건 충족. 1 turn 에 수렴.

### 1) 게이트 11/11 — 통과

`node .claude/plans/insuniverse-docs-50-domain-m5.gates.mjs check-all` 최종 출력 (rc=0):

```
#1 ok  서브모듈 3/3 동결 일치 · 기준선 7237ff13 에 docs/20-site 부재 · 기준선 마일스톤 4행 in-progress · 기준선 *Status: 마일스톤 4 · doc lint 18개 파일 위반 0 · plan-kit 18건 mismatch 0 · golden 무변동
     읽은 서브모듈 HEAD — insuniverse-server 4d798f55 · insuniverse-site 767d1e44 · insuniverse-admin fb001e1d
     현재 워킹트리 docs/20-site: 00-ia.md — 이 자리의 판정은 #9·#10 이 진다
#2 ok  서브커맨드 집합 일치 (--help · --selfprobe · check-all · check1 · check10 · check11 · check13 · check2 · check3 · check4 · check5 · check6 · check7 · check8 · check9) · unknown 거부
#3 ok  App.tsx 태그 117 == 잎 100 + 비잎 17 · 2회 실행 집합 sha256 동일 c3f6d067ccbb6111 · <Routes> 담는 파일 2건 중 라우트 등록부는 front/src/App.tsx 1건
     판독 원본 — insuniverse-site@767d1e44:front/src/App.tsx (워킹트리 아님)
     <Routes> 담는 파일 전수: front/src/App.tsx · front/src/pages/analysis/analyze/AnalyzePage.test.tsx (테스트 래퍼)
     이 sha256 은 저장소 골든에 없다 — 대조 대상이 같은 창의 추출기뿐이라는 것이 이 마일스톤의 결손이다 (회부 R-50-2)
     스캐너 사각지대 — 주석(`{/* … */}`) 안의 `<Route` 문자열과 자기닫힘 없는 변형 문법은 가르지 못한다
#4 ok  잎 100 == 화면 85 + 접힘 12 + 제외 3 · surfaces[].path ⊆ 유도집합 · 유도집합 ⊆ 세 부류 합집합 · 중복 배정 0 · 사유 없는 제외 0 · 중복 id 0
     화면 내역 — 비param 잎 56 · 고아 param 잎 29 (고아는 제외가 아니라 화면이다)
     제외: 440행 {process.env.REACT_APP_TOSS_SUCCESS_URL ?? ""} — 경로가 빌드 환경변수 식이라 동결 트리만으로 값을 알 수 없다
     제외: 441행 {process.env.REACT_APP_TOSS_FAIL_URL ?? ""} — 경로가 빌드 환경변수 식이라 동결 트리만으로 값을 알 수 없다
     제외: 443행 * — catch-all 라우트이며 element 가 빈 조각이라 렌더 대상이 없다
#5 ok  접힘 12건 전건이 부모 ### 블록 본문에 등장 · 부모 6개 · 고아 부모 0
#6 ok  surfaces 85건 · evidence S-route+S-component 동시보유 84건 · 예외 1건은 limitations 보유 · S-test 보유 5건 · anchors 175건 전건 동결 트리 실재 · 파일없음 0 · 행초과 0 · status 어휘 밖 0 · unknown 계열 0건 전건 unknown_reason 보유
     anchors 해석 기준 — insuniverse-site@767d1e44 동결 트리 (워킹트리 실재가 아니다) · last_verified 767d1e44
#7 ok  00-ia H1 아래 고지 문단이 동결 인벤토리 부재·일회용 하네스·배포 접두 basename·식 경로·exits 페이지 파일 한 겹 5항을 담는다 · PRD 발신 표에 R-50-2 행 (표 2행 == 절 제목 2건) · backlog 이월 5행 전건 표 형태 · admin 전용 테스트 부재 고지 유입 0
     id=50m5-dangling-navigate-targets
     id=50m5-site-inventory-not-frozen
     id=50m5-env-dependent-routes
     id=50m5-prev-harness-scope-set-stale
     id=50m5-exits-page-file-scoped
     리터럴 navigate 대상 재유도 49건 (정확 34 · :param 2 · 접두 8 · 상대 1 · dangling 4) — 대조 기준은 리터럴 라우트 경로 전수 111건(잎·비잎 포함)이며 계획서 관측 7 의 비param 화면 집합과 다르다
     backlog id=50m5-dangling-navigate-targets 의 고유 49건 · 남은 4건 == 재유도 · dangling 집합 차집합 0
     dangling /account/signin → limitations 보유 화면 site-payment
     dangling /join → limitations 보유 화면 site-auth-find
     dangling /mypage/money/auto-charge → limitations 보유 화면 site-payment
     dangling /step-fail/b2c → limitations 보유 화면 site-step-three-b2c-param
     상대 이동(절대경로 아님, dangling 으로 세지 않는다): select-payment-card
     exits 유도 범위 밖 — 리터럴 navigate 보유 파일 51건 중 문서 anchors 밖 26건 · 그 파일에만 등장하는 이동 대상 20건 (귀속은 import 그래프 필요 — id=50m5-exits-page-file-scoped)
     backlog 4열 아님으로 건너뛴 행 29건: 11행(5열) 12행(5열) 23행(6열) 26행(6열) 31행(6열) 32행(6열) 33행(6열) 36행(7열) 44행(5열) 60행(5열) 90행(8열) 95행(9열) 105행(5열) 115행(5열) 171행(7열) 172행(9열) 173행(20열) 174행(8열) 177행(5열) 184행(7열) 209행(5열) 211행(6열) 214행(6열) 216행(10열) 228행(9열) 242행(5열) 295행(5열) 311행(3열) 312행(3열) — 이 창의 행은 그중 0건 (다출처 장부라 남의 행에 결박하지 않는다)
#8 ok  lint-docs --strict-refs 18개 파일 위반 0 · 미해결 참조 0 · 독립 확장기 차집합 0 · docs/20-site/00-ia.md 포함
     발화 대상 규칙 등록 확인 — ia-exits · id-crossref · history-columns · required-sections · no-placeholder
     OK — 18개 파일, 위반 0 (--strict-refs)
#9 ok  기준선 7237ff13 대비 변경 10건 전건 허용집합 안 · docs/_meta 변경 0 · docs/30-admin/*.md 바이트 동일 6건 · docs/10-server 부재 · golden 무변동
     허용: .claude/PRPs/reports/insuniverse-docs-50-domain-m5-report.md
     허용: .claude/milestone-closures/5-site-ia.md
     허용: .claude/notes/insuniverse-docs-50-domain-m5.md
     허용: .claude/plans/codex-findings-backlog.md
     허용: .claude/plans/insuniverse-docs-50-domain-m5.gates.mjs
     허용: .claude/plans/insuniverse-docs-50-domain-m5.plan.md
     허용: .claude/prds/insuniverse-docs-50-domain.prd.md
     허용: .claude/receipts/mccp-implement-codex/insuniverse-docs-50-domain-m5.json
     허용: .claude/receipts/mccp-plan-codex/insuniverse-docs-50-domain-m5.json
     허용: docs/20-site/00-ia.md
#10 ok  post — 마일스톤 4행 complete · 5행 in-progress + Plan 셀 이 계획서 · *Status: in-progress 가 마일스톤 5 만 지목 (4 미지목)
#11 ok  post — m4 check1~check11·check13 12/12 통과 · check12 는 마일스톤 4행 complete 로 exit 1 (지정 사유 일치)
#13 ok  완주 11/11 · 실행 집합 == 등록부 집합 == Validation 호출 집합 · 차집합 0 · #10 은 표 현재값 post 로 호출 · 외부 #12 는 이 목록 밖 (lint-plan.mjs)
```

**측정을 세 번 했고 가운데 한 번이 붉었다. 숨기지 않는다.**

| 회차 | 시점 | 결과 |
|---|---|---|
| 1 | `/goal` 진입 전 (락 밖) | rc=0 · 11/11 |
| 2 | 락 해제 후, closure-doc 작성 전 | rc=0 · 11/11 (워킹트리 무변동, HEAD 동일) |
| 3 | closure-doc · PRD 스탬프 작성 후 | **rc=1 · 10/11** — `#9 FAIL: 허용 집합 밖 변경 1건 — .claude/milestone-closures/5-site-ia.md` |
| 4 | `#9` 허용 접두에 `.claude/milestone-closures/` 를 더한 뒤 | rc=0 · 11/11 (위 인용은 이 회차) |

회차 1·2 가 갈린 이유는 `goal-phase-guard.js` 가 락 활성 구간에서 Bash 를 default-deny 로 돌려
이 하네스를 **락 안에서는 실행할 수 없기** 때문이다 — 락 안에서 verdict 만 받으면 봉인되는
증거가 낡는다. 그래서 Phase 4 순서를 역전시켰다: 락 해제 → 재실측 → 이 문서 작성.

회차 3 의 붉음은 오탐이 아니라 **참인 지적이 창을 잘못 짚은 것**이다. `#9` 의 허용 집합은
구현 창 저작 시점의 것이고 closure-doc 은 그 창이 닫힌 **뒤**에 나온다. 앞 창의 집합이 뒤 창
산출을 모르는 것(backlog `50m5-prev-harness-scope-set-stale`)과 같은 부류이되, 이쪽은 **같은
창**의 종결 기록이므로 귀속처가 이 집합이다. 그래서 접두 한 줄을 더했다 —
`.claude/plans/insuniverse-docs-50-domain-m5.gates.mjs` 는 `#9` 자신의 `ALLOWED_EXACT` 안이라
이 수정은 창 안이고, 계획서 본문은 허용 경로를 열거하지 않으므로(*"허용 집합 안"* 이라고만
쓴다) 계획서↔하네스 표류도 생기지 않는다. `plan_hash` 는 건드리지 않았다.

### 2) `00-ia.md` 단독 답변 — 통과

락 활성 구간에서는 `Read`/`Grep` 툴만 통과하므로 그 둘로만 판독했다.

| 조건 항목 | 좌표 | 관측 |
|---|---|---|
| 화면 85건 | `docs/20-site/00-ia.md` 1073~1157행 `## 화면 목록` 표 | 85행 (id · 경로 · 컴포넌트 · 레이아웃 · status) |
| 라우트 좌표 85건 | `## 화면별 구성` 각 블록의 `- 라우트:` 행 | grep 계수 85. 좌표가 `insuniverse-site/front/src/App.tsx:NNN` 의 `path` 리터럴까지 지목 |
| 접힘 12 | `- 접힌 상세 라우트:` 비-`없음` 6블록 | 6+1+1+2+1+1 = 12건. 부모 6개 — `site-analysis` · `site-analysis-loss` · `site-invoices-list` · `site-loss-add` · `site-mypage` · `site-mypage-subscription-change` |
| 접힘 사유 | 1043행 분할 규칙 | 최장 접두 부모로 접고, 접두가 하나도 없는 잎은 접을 곳이 없어 그 자체로 화면 |
| 제외 3 사유 | 1065행 진입점 표 · 1038행 고지 | 와일드카드 1건(`<></>` 렌더라 화면 아님) · 식 경로 2건(`basename` 이 `REACT_APP_PUBLIC_PATH` 에서 와 동결 트리로 해석 불가) |

**계수 12·3 자체는 문서에 리터럴로 없다.** 1045행이 *계수는 이 문서에 적지 않는다* 를 규약으로
박았고 부류별 크기는 게이트 `#4`·`#5` 가 매 실행 유도한다. acceptance 가 물은 것은 **사유**이며
사유는 문서 안에 있다. 이 구별을 지우지 않는다 — 문서만으로 답할 수 있는 것은 사유이고, 수는
문서가 아니라 하네스가 진다.

### 3) 동결 대조 부재 5항 — 통과

H1(1036행)과 첫 `## `(1053행) 사이 인용 문단 2행:

- 1038행 — 1) `../_meta/extraction-manifest.yaml` `screen_codes` 에 site 대응 키 부재
  2) 재검증이 저장소 상시 게이트가 아니라 이 마일스톤의 일회용 하네스뿐이며 집합 sha256 이
  `../_meta/verify/golden.txt` 에 미등재 3) 배포 접두 `basename` 미해결 4) 식 경로 2건 미해결
- 1039행 — 5) exits 는 각 화면의 페이지 컴포넌트 **파일 한 겹**에서만 유도

backlog 이월 `.claude/plans/codex-findings-backlog.md` 334~338행 5건:
`50m5-dangling-navigate-targets` · `50m5-site-inventory-not-frozen` ·
`50m5-env-dependent-routes` · `50m5-prev-harness-scope-set-stale` · `50m5-exits-page-file-scoped`

## 닫히지 않은 것

acceptance 는 충족됐다. 그것이 아래를 닫지 않는다 — 이 창이 산출로 낸 결손이다.

| 결손 | 무엇이 안 잡히는가 | 이월 |
|---|---|---|
| 저장소 동결 대조 부재 | 화면 집합 sha256 이 골든에 없어 **비교 대상이 같은 창의 추출기**다. 추출기가 틀리면 문서와 추출기가 함께 틀리고 게이트는 초록이다 | 회부 `R-50-2` · backlog `50m5-site-inventory-not-frozen` |
| exits 한 겹 | 페이지가 렌더하는 feature 컴포넌트 안의 `navigate` 는 세지 않았다. 실재 이탈이 `exits` 에서 빠져 있을 수 있다 | backlog `50m5-exits-page-file-scoped` — 귀속에 import 그래프 필요 |
| 배포 접두·식 경로 | `basename` 이 `REACT_APP_PUBLIC_PATH` 에서 오고 라우트 2건 경로가 환경변수 식이라 라우트 전수가 빌드 환경에 의존하는 구간을 갖는다 | backlog `50m5-env-dependent-routes` |
| dangling 4건 | 어느 라우트로도 해석되지 않는 이동 대상. 문서는 `limitations` 에 적었을 뿐 고치지 않았다 | backlog `50m5-dangling-navigate-targets` |
| 앞 창 허용 집합 stale | m4 하네스 `check12` 가 이 창의 산출(`docs/20-site/`)을 자기 허용 집합 밖으로 본다 | backlog `50m5-prev-harness-scope-set-stale` |
| 스캐너 사각 | 주석 안 `<Route` 문자열과 자기닫힘 없는 변형 문법은 가르지 못한다 (`#3` 이 출력에 낸다) | (미검증) |
| 화면 렌더 내용 | `주요 영역·액션` 은 전건 `미검증` 이다. 라우트 등록과 컴포넌트 실존만으로는 판정되지 않는다 | (미검증) |

## 마일스톤 표 전이는 이 문서가 하지 않는다

`Delivery Milestones` 5행은 `in-progress` 로 둔다. 이 PRD 축에서 행 전이는 **다음 창의 구현
커밋**이 한다 — 실측: 4행을 `complete` 로 뒤집은 것은 m4 의 종결이 아니라 M5 구현 커밋
`d368d73` 이고, 기준선 `7237ff13` 에서는 4행이 `in-progress` 였다(게이트 `#1` 출력).

지금 5행을 뒤집으면 이 창의 `check10` 이 죽는다 — `check10` 은 `pre`·`post` 두 모드 모두에서
5행 `in-progress` 와 `*Status: in-progress` 의 마일스톤 5 지목을 요구한다. 그 붉음을 지정
사유로 받아 주는 후속 하네스(m6 의 `check11` 자리)가 아직 없으므로, 지금의 전이는 붉음의
귀속처가 없는 붉음이다.

## Provenance

- Lock run_id        : `6c7aac68-418f-4402-89ae-90a9e16d2c9f`
- Lock owner session : `79554286-26fb-4d80-ac35-1fbbbe81c093`
- Detection signal   : `{"availability":"available","goal_signal":true,"signal_ref":{"row":5,"name":"site 화면 축","plan":".claude/plans/insuniverse-docs-50-domain-m5.plan.md","status":"in-progress"},"mode":"milestone-close","reason":"ok"}`
- mccp version       : 1.32.6
- plan_hash 무변동   : `hash-plan` 재계산 `sha256:8e8ccd0e0a923a679fc2f23dae1f807936443293d2b3aa80ee37435c2b046637` 이 `mccp-plan-codex` · `mccp-implement-codex` 두 receipt 의 `plan_hash` 와 같다. 이 문서의 provenance 를 계획서 본문이 아니라 PRD 에 싣는 이유가 그것이다 — 계획서에 절을 덧붙이면 두 receipt 가 동시에 `stale` 로 떨어지고 `stale` 에는 우회 env 가 없다
