# Milestone Closure — 7-relation-axis

## Milestone

- ID         : 7-relation-axis (락 등록 ID `7-관계-축-종료-판정`)
- Name       : 관계 축 종료 판정
- PRD        : `.claude/prds/insuniverse-docs-50-domain.prd.md` (Delivery Milestones 7행)
- Plan       : `.claude/plans/insuniverse-docs-50-domain-m7.plan.md`
- Status     : done
- Closed at  : 2026-08-28T07:07:00.031Z
- Closed by  : /mccp:milestone-close (run_id=ccd423b1-e251-4522-87b2-dd8bfc2dad4c)
- HEAD       : `357fe5d82b2c2a3c4a712042edff19ee841c3def`

## Acceptance Condition

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

> M7 종료 판정 acceptance 확인. 다음을 Read/Grep 으로 대조하고 전부 참이면 종료: (1) .claude/plans/insuniverse-docs-50-domain-m7.gates.mjs 가 존재하고 CHECKS 등록부에 check1~check12·check14 가 전건 등록돼 있다. (2) .claude/notes/insuniverse-docs-50-domain-m7.md 에 지표별 판정 원장이 있고 각 행이 게이트 번호(#N)를 인용한다. (3) --probe=history 가 관계 축을 받지 못한다는 사실이 그 원장에 "(도구 밖)" 으로 남아 있다. (4) .claude/prds/insuniverse-docs-50-domain.prd.md 마일스톤 표 6행이 complete, 7행이 in-progress 이고 7행 Plan 셀이 m7 계획서다. (5) 발신 R-50-4 가 PRD 발신 표와 절 제목 양쪽에 선다. 하나라도 거짓이면 어느 것이 왜 거짓인지 보고하고 계속. 셸 명령은 goal-phase lock 이 막으니 시도하지 말 것. or stop after 12 turns

**이 조건은 실행 검증이 아니라 산출물 대조로 짰다.** `goal-phase-guard.js` 가 락 활성 구간에서
Bash 를 default-deny 로 돌리기 때문이다 — 실측: `cd "…" && sed -n …` 이
`Bash no allowlist match (default-deny during goal-phase) — segment: cd "…"` 로 막혔고, 접두를
떼고 `node …/goal-phase-lock.js exit --run-id …` 한 문장으로 부르면 통과했다. 하네스 실측은
락 안에서 할 수 없으므로 **락 해제 뒤에** 따로 돌렸다(아래 §측정 회차 회차 2).

## Goal Loop Result

5항 전건 충족. 1 turn 에 수렴. 거짓 조건 0건.

| # | 조건 | 관측 | 판정 |
|---|---|---|---|
| 1 | gates.mjs CHECKS 등록부 | `CHECKS.check1`~`check12` + `check14` 전건 등록 (`gates.mjs` 1013 1082 1124 1155 1186 1243 1328 1383 1431 1451 1498 1560 1699행). `check13` 은 설계상 이 목록 밖 — 외부 도구 `lint-plan.mjs` 다 | 참 |
| 2 | 지표별 판정 원장 + 게이트 인용 | `notes` 133~142행 표 8행, 게이트 열 `#3` `#4` `#5` `#6` `#7` `#7` `#8` `#9` | 참 |
| 3 | `(도구 밖)` 기록 | `notes` 138행 측정자 열 `**(도구 밖)** 하네스 독립 재현`, 144~149행에 사유 산문 | 참 |
| 4 | PRD 표 전이 | 6행 `complete` · 7행 `in-progress` · 7행 Plan 셀이 이 계획서 (PRD 221·222행) | 참 |
| 5 | R-50-4 양쪽 | 발신 표 78행 + 절 제목 `### 발신 4건`(71행, 표 행수 4 와 일치). backlog 이월 3행 전건 `id=` 보유 | 참 |

조건 5 의 *"절 제목"* 은 절 제목에 `R-50-4` 라는 문자열이 서는 것이 아니라 **절 제목의 건수와
표 행수가 맞물리는 것**이다. 게이트 `#7` 이 무는 것도 그 자리다 — `PRD 발신 표 4행 == 절 제목 4건`.

### acceptance 가 확인한 것과 하네스가 확인한 것은 다르다

위 5항은 **산출물이 있는가**를 본다. 지표가 실제로 성립하는가는 하네스가 진다. 둘을 나란히 둔다.

## 측정 회차

**회차를 그대로 싣는다. 마지막 초록만 인용하면 이 문서가 봉인하는 것이 실측이 아니라 요약이 된다.**

| 회차 | 시점 | 결과 |
|---|---|---|
| 1 | `/goal` 진입 전 — 구현 창 종결 커밋 `357fe5d` | 구현 창이 진 판정. 이 문서가 인용하지 않는다 |
| 2 | 락 해제 후, 이 문서 작성 전 | `check-all` rc=0 · 12/12 · `--selfprobe` rc=0 · `verify.sh --check` stdout 마지막 줄 `check PASS` · `check FAIL` 0건 · `lint-plan` rc=0. 워킹트리 clean · `HEAD 357fe5d`. **아래 인용은 이 회차** |
| 3 | 이 문서 · PRD 스탬프(잠정 sha) 작성 후 | `check-all` rc=0 · 12/12. 회차 2 와의 유일한 차이는 `#10` 의 `변경 9건` → `변경 10건` (**전건 허용집합 안** 은 그대로) |
| 4 | PRD 스탬프를 최종 sha 로 갈아 끼운 뒤 | `check-all` rc=0 · 12/12 · 실패 0건. `#10` 은 회차 3 과 같은 `변경 10건` (스탬프 값만 바뀌었고 경로 집합은 불변) |

회차 3 의 증분이 **2 가 아니라 1** 인 이유 — PRD 는 기준선 `eeb75d37` 대비 이미 변경 집합
안이었다(구현 창이 `*Status:` 와 표 두 행을 뒤집었다). 새로 든 것은 closure-doc 하나뿐이다.
이 문서의 초고는 증분을 2 로 적었고 회차 3 실측이 그것을 정정했다 — 예측을 지우지 않고 남긴다.

락 안에서 하네스를 돌릴 수 없으므로 Phase 4 순서를 역전시켰다: **락 해제 → 재실측 → 이 문서 작성.**
락 안에서 verdict 만 받으면 봉인되는 증거가 낡는다.

### 회차 2 — `check-all` 12/12 (rc=0)

```
#1 ok  기준선 eeb75d37 (merge-base 유도) · 서브모듈 3/3 동결 일치 · 관계 축 12종 실재 (00-index 트리와 차집합 0 양방향) · docs/10-server 부재 · 마일스톤 6행 in-progress · 7행 pending · *Status: 마일스톤 6 · ownership 수신 행 2건 전건 PRD 판정표 일치 · golden 무변동
     읽은 서브모듈 HEAD — insuniverse-server 4d798f55 · insuniverse-site 767d1e44 · insuniverse-admin fb001e1d
     수신 회부 — R-1 R-2 (발신 13-relation-contract)
     PRD·golden 좌표는 기준선 blob 이다 — 워킹트리 판정은 #10·#11 이 진다
#2 ok  서브커맨드 집합 일치 (--help · --selfprobe · check-all · check1 · check10 · check11 · check12 · check14 · check2 · check3 · check4 · check5 · check6 · check7 · check8 · check9 · freeze) · unknown 거부
     기대 집합은 런타임 등록부가 아니라 계획서 `# 검사 #2:` 마커의 열거에서 유도했다 — 외부 기준이다
#3 ok  00-index 트리 20-site/ 블록 6토큰 == 실제 파일 6건 · 30-admin/ 블록 6토큰 == 실제 파일 6건 (차집합 0 양방향) · 10-server/ 블록 8토큰은 미생성으로 지정
#4 ok  lint-docs --strict-refs 36개 파일 위반 0 · 미해결 참조 0 · 관계 축 12종 포함
     발화 대상 규칙 등록 확인 — flow-exits · ia-exits · flow-refs · history-columns · id-crossref · unresolved-ref
     이 축의 사각지대: 위는 lint-docs.mjs **소스의 문자열 실재**이지 규칙이 발화한다는 증거가 아니다 — 발화 축은 verify.sh --check 의 lint selftest 가 따로 진다
#5 ok  probe=relation rc 0 · 동결 838행 일치 · 계약 부족 0 · unresolved 0 · 동결 재열거 흐름 40건 헤더 계수 == 축별 실제 행수 (policy 11 · surface 236 · edge 169)
     이 검사의 사각지대: surface-edge 382행은 흐름 헤더에 선언 필드가 없어 계수 대조 축이 없다. 동결 전건 문자열 일치(probe rc 0)가 그 축의 유일한 방어다
#6 ok  12종 연혁 행 217건 · matched 200 · orphan 17 · unknown 0 · 인덱스 6190행 (insuniverse-server insuniverse-site insuniverse-admin)
     docs/20-site/00-ia.md rows=90 matched=89 orphan=1 unknown=0
     docs/30-admin/00-ia.md rows=100 matched=95 orphan=5 unknown=0
     docs/30-admin/01-admin-console.md rows=4 matched=2 orphan=2 unknown=0
     docs/30-admin/02-corp-console.md rows=5 matched=3 orphan=2 unknown=0
     docs/30-admin/03-sales-console.md rows=4 matched=2 orphan=2 unknown=0
     docs/30-admin/04-authority-management.md rows=4 matched=1 orphan=3 unknown=0
     docs/30-admin/05-treat-monitoring.md rows=5 matched=3 orphan=2 unknown=0
     (site 흐름 5편은 각 rows=1 matched=1 orphan=0 unknown=0)
     orphan 은 결함이 아니라 질문 대상이라 0 을 요구하지 않는다 — 0 을 요구하면 저자가 연혁 행을 지워 0 을 만든다
     이 검사의 사각지대: rename closure 를 돌리지 않고 앵커 경로 직접 접촉만 본다. 접촉을 덜 세므로 orphan 이 늘 뿐 unknown 은 불변이다
     `--probe=history` 를 부르지 않은 이유는 계획서 GROUND 관측 4 다 (입력 계약이 policy-doc@1)
#7 ok  질문 19건 == 원장 배정 (차집합 0 양방향) · 타 서비스 각론 좌표 0 · 미성립 7건 전건 사유 보유 · PRD 발신 표 4행 == 절 제목 4건 · backlog 신규 3행 전건 id 보유
     질문 집합은 docs/_meta/onboarding-questions.yaml 에서 매 실행 유도했다 — site 5 · admin 14
     발신 — R-50-1 R-50-2 R-50-3 R-50-4
     신규 이월 id — 50m7-probe-history-out-of-range 50m7-relation-freeze-not-repo-gated 50m7-onboarding-unmet-seven
#8 ok  총론 policies[].id 226건 유도 (6디렉터리) · 관계 축 등장 21건 · 참조형 21건 · 재기술 0
     분모 산정 — 총론 문서 24편 스캔 · `policies:` 키 없는 문서 0편. 프론트매터 부재와 키 있는 파싱 실패는 삼키지 않고 죽인다
#9 ok  docs/30-admin/*.md 6편 전건 근거 부재 고지 보유 · docs/20-site 유입 0
     분모는 리터럴이 아니라 glob 유도다 — 마일스톤 8 이 파일을 늘려도 검사가 따라간다
#10 ok  기준선 eeb75d37 대비 변경 9건 전건 허용집합 안 · docs/_meta 변경 0 · 관계 축 밖 docs/ 변경 0 · docs/10-server 부재 · golden 무변동
     기준선은 리터럴이 아니라 git merge-base origin/main HEAD 로 유도했다
     이진 차이는 행 계수가 아니라 버퍼 비교로 갈랐다 — NUL 하나면 diff 행수가 0 이다
     이 검사의 사각지대: 네 축이 중첩이라 `관계 축 밖 docs/ 변경`·`golden 변동` 두 분기는 **도달하지 않는다**. 세 사실은 독립 검증이 아니라 포섭에 의한 참이다
#11 ok  post — 마일스톤 6행 complete · 7행 in-progress + Plan 셀 이 계획서 · *Status: in-progress 가 마일스톤 7 만 지목 (6 미지목)
#12 ok  m6 등록부 13건 == 초록 9 + 붉음 4 (차집합 0 양방향) · 9/9 통과 · 붉은 검사 4건 전건 지정 사유 일치
     check1 은 m6 산출 5편이 병합돼 기준선에 선재 로 exit 1 (지정 사유 일치)
     check10 은 m6 의 term-request 가 병합돼 기준선 안이라 그 창의 요구가 성립하지 않는다 로 exit 1 (지정 사유 일치)
     check11 은 이 창이 6행을 complete 로 뒤집었다 로 exit 1 (지정 사유 일치)
     check12 은 m5 check11 이 보는 m4 범위 요구가 병합으로 해소돼 초록이 됐다 로 exit 1 (지정 사유 일치)
#14 ok  완주 12/12 · 실행 집합 == 등록부 집합 == Validation 호출 집합 · 차집합 0 · 외부 #13 은 이 목록 밖 (lint-plan.mjs)
```

출력 전체에서 `FAIL` 문자열은 1건이며 그것은 `#4` 의 사각지대 산문(`bad-*.md` 픽스처가 지정
규칙으로 FAIL 해야 한다)이지 실패 판정이 아니다.

### 회차 2 — `--selfprobe` (rc=0)

```
selfprobe ok  실행 (호출부,픽스처) 쌍 51 == 등록부 17 × 픽스처 3 · 차집합 0
     호출부: #1/manifest-repos · #1/ownership-수신 · #1/prd-수신 · #3/트리토큰 · #4/lint요약 · #5/동결 · #5/probe출력 · #6/연혁표 · #6/인덱스 · #7/온보딩 · #7/원장 · #7/prd-발신 · #7/backlog · #8/총론정책 · #11/prd-마일스톤 · #11/prd-status · #12/m6출력
     픽스처: good · empty · mutated (정상 → 행 ≥1 · 빈 입력 → 실패 · 변이 → 다른 결과)
     합성 픽스처를 쓰는 호출부 7종 — 실 문서가 아니다 (Task 1 시점에 입력이 없다)
     등록부 밖 추출기 3종 — docAnchors · planMarkerBlock · verdictCell (계획서 `# 음성:` 마커에 앵커가 없어 등록하지 않았다. 마커를 더하면 plan_hash 가 움직여 영수증이 stale 이 된다)
```

### 회차 2 — `verify.sh --check`

stdout 136행, **마지막 줄 `check PASS`**, `check FAIL` 계수 0, rc=0.

**stdout 만 읽었다.** 이 스크립트는 진행 로그를 stderr 로 내고 `check PASS` 만 stdout 으로 낸다 —
두 스트림을 이어붙이면 마지막 줄이 뒤집힌다. 종료코드만 보지 않는 것은 CLAUDE.md §1 의 직접
요구이고, 이 스크립트가 fork 고갈에서 **빈 출력에 rc 0** 을 낸 선례가 있다(M6 code-review).
이 회차는 136행 정상 출력과 `check PASS` 둘로 선다.

### 회차 2 — `lint-plan.mjs` (검사 `#13`)

`node .claude/templates/plan-kit/lint-plan.mjs .claude/plans/insuniverse-docs-50-domain-m7.plan.md`
→ 출력 없음, rc=0. `check-all` 밖의 외부 도구다.

## 닫히지 않은 것

acceptance 는 충족됐다. 그것이 아래를 닫지 않는다.

| 결손 | 무엇이 안 잡히는가 | 이월 |
|---|---|---|
| **단독 온보딩 성립 — 답 실재가 미성립** | 질문 19건 중 7건(`Q36` `Q46` `Q49` `Q50` `Q51` `Q53` `Q55`)이 자기 각론 안에서도 답이 없다. 전건 문서가 스스로 `답하지 못한다`·`확정하지 못했다`·`판정하지 않는다`·`알지 못한다` 로 판정을 유보한 자리다. 타 서비스 각론 의존 축은 19/19 성립이므로 두 축을 섞지 않는다 | backlog `50m7-onboarding-unmet-seven` — 해소에 서브모듈 소스 재정독이 필요하며 이 창의 계획된 작업이 아니다. 추측으로 메우는 것은 문서가 스스로 거부한 것이다 |
| PRD 가 지목한 연혁 측정자가 관계 축에서 안 돈다 | `--probe=history` 의 입력 계약이 `policy-doc@1` 뿐이라 12종(`flow-doc@1` 10 · `ia-doc@1` 2)을 받지 못한다. 하네스가 조인을 독립 재현해 지표를 실측했으나(`unknown` 0) **우회이지 해소가 아니다** | 발신 `R-50-4` (2) · backlog `50m7-probe-history-out-of-range`. 마일스톤 8 이 server 각론에서 같은 자리를 다시 만난다 |
| 관계 축 동결이 저장소 상시 게이트가 아니다 | `--probe=relation` 동결 838행을 `verify.sh --check` 가 읽지 않는다. 무는 것은 이 창의 `#5` 뿐이고 이 계획서가 아카이브되면 관계 계산 가능성의 재검증 경로가 사라진다 | 발신 `R-50-4` (1) · backlog `50m7-relation-freeze-not-repo-gated`. `R-50-2` 와 같은 뿌리 — `docs/_meta/verify/**` 개정 위임 부재 |
| `orphan` 17건 미정정 | 조인은 대조이지 정정이 아니다. rename closure 를 돌리지 않아 접촉을 덜 세므로 orphan 이 부풀 수 있다 | `#6` 이 매 실행 이름으로 낸다. 정정은 질문 대상 |
| `surface-edge` 382행 계수 대조 축 없음 | 흐름 헤더에 선언 필드가 없어 헤더 계수와 대조할 상대가 없다. 동결 전건 문자열 일치가 유일한 방어다 | `#5` 가 매 실행 사각지대로 출력 |
| `#10` 두 분기 미도달 | 네 축이 중첩(golden ⊂ docs/_meta ⊂ 관계 축 밖 docs/ ⊂ 허용집합 밖)이라 바깥 축이 먼저 죽는다. `관계 축 밖 docs/ 변경`·`golden 변동` 두 분기는 반사실을 잰 적이 없다 | 허용집합을 넓히는 창이 그 줄을 보고 반사실을 다시 잰다 |
| `#4` 발화 축 부재 | lint 규칙 6종의 확인이 **소스 문자열 실재**이지 규칙이 실제로 발화한다는 증거가 아니다 | `verify.sh --check` 의 lint selftest(`bad-*.md` 픽스처)가 그 축을 따로 진다 |
| `#12` 사각지대 | m6 하네스의 `check-all`·`--selfprobe` 는 부르지 않는다 — 개별 검사만 회귀 대조한다 | 구조적. m6 창이 그 둘의 판정을 이미 졌다 |
| `actor` 축 미해소 | 링크 코드만 갖고 흐름을 걷는 비로그인 보행자를 담을 값이 `config.actors` 에 없고, 그 키는 lint 규칙 전수에 대응 축이 없어 **어떤 값을 써도 통과한다** | 발신 `R-50-3` · `docs/_meta/term-requests/50-domain.md`. 이 창이 다시 만났고 다시 우회로 멈췄다 |
| 리뷰 라운드 수렴 | 이 창은 문서를 새로 쓰지 않았으므로 담당자 리뷰 축이 없다. `(미검증)` | 계획서 Acceptance `(미검증)` 2행 |

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

`Delivery Milestones` 7행은 `in-progress` 로 둔다. 이 PRD 축에서 행 전이는 **다음 창의 구현
커밋**이 한다 — 실측: 4행을 `complete` 로 뒤집은 것은 m4 의 종결이 아니라 M5 구현 커밋
`d368d73` 이고, 6행을 뒤집은 것은 이 창(M7)의 구현 커밋 `357fe5d` 다.

지금 7행을 뒤집으면 이 창의 `check11` 이 죽는다 — `check11` 은 `--expect pre|post` **두 모드
모두에서** 7행 `in-progress` 와 7행 Plan 셀의 이 계획서 지목, `*Status: in-progress` 의 마일스톤 7
단독 지목을 요구한다(`pre`/`post` 가 가르는 것은 앞 행 6뿐이다). 그 붉음을 지정 사유로 받아 주는
후속 하네스(m8 의 회귀 자리)가 아직 없으므로, 지금의 전이는 귀속처가 없는 붉음이다.

## 꼬리를 여기서 끊는다

마지막 회차 뒤에 남는 편집은 둘뿐이다 — 위 §측정 회차 표에 회차 4 행을 적는 것과 PRD 스탬프의
sha256 을 그에 맞춰 갈아 끼우는 것. 그 두 자리가 게이트 `#10` 허용 집합 안임은 측정이 아니라
**경로로** 판정된다: `.claude/milestone-closures/` 는 `ALLOWED_PREFIX` 98행,
`.claude/prds/insuniverse-docs-50-domain.prd.md` 는 `ALLOWED_EXACT`(88행 `PRD`). `#10` 이 보는
것은 경로 집합이고 내용이 아니므로 이 두 편집이 그 검사를 뒤집을 수 있는 경로가 없다.
무한히 재측정하지 않고 끊는다는 사실을 감추지 않는다.

앞 창(5-site-ia)에서 이 자리가 붉었던 것과 다르다. M5 는 `#9` 허용 집합에 closure-doc 경로가
없어 회차 3 이 `10/11` 로 떨어졌고 접두 한 줄을 더해 닫았다. 이 창의 하네스는 그 수정을 이미
승계해 `ALLOWED_PREFIX` 에 `.claude/milestone-closures/` 를 갖는다(`gates.mjs` 98행).

## Provenance

- Lock run_id        : `ccd423b1-e251-4522-87b2-dd8bfc2dad4c`
- Lock owner session : `unknown` (`CLAUDE_SESSION_ID` 미설정 — 셸 환경에 노출되지 않는다)
- Sidecar            : `<gitdir>/mccp/tmp/goal-token-ccd423b1-e251-4522-87b2-dd8bfc2dad4c.dat` (exit 시 `cleared: true`)
- Detection signal   : `{"availability":"available","goal_signal":true,"signal_ref":{"row":7,"name":"관계 축 종료 판정","plan":".claude/plans/insuniverse-docs-50-domain-m7.plan.md","status":"in-progress"},"mode":"milestone-close","reason":"ok"}`
- mccp version       : 1.32.6

### 이 문서는 계획서 본문을 건드리지 않았다

provenance 를 계획서가 아니라 **PRD** `## Milestone Closure Provenance` 표에 싣는다. 계획서
본문은 `mccp-plan-codex` · `mccp-implement-codex` 두 receipt 의 `plan_hash` 앵커이고, 거기에
절을 덧붙이면 두 게이트가 동시에 stale 로 떨어진다. PRD 는 `isPlanPath` 밖이라 어떤 게이트
해시에도 안 걸린다.

### receipt 체인은 이 회차에 초록이다

락 해제 직후, 이 문서를 쓰기 **전에** 실측했다. 워킹트리 clean · `HEAD 357fe5d`:

```
$ node .../receipt/cli.js validate --command "mccp:pr" \
    --decision insuniverse-docs-50-domain-m7 \
    --plan .claude/plans/insuniverse-docs-50-domain-m7.plan.md
{ "ok": true, "missing": [], "stale": [], "blocking": [], "open_critical": [] }
```

경고 2건이 남는다 — `mccp-plan-codex` · `mccp-implement-codex` 의
`meta.impeccable_silent_skip=true` (`silent_skip_reason: no-signal`). 관찰용이며 현재 차단하지
않는다. 앞 창(6-site-flows)이 진입 시점에 두 receipt 가 이미 `stale` 이던 것과 다르다.

**이 문서와 PRD 스탬프는 그 상태를 바꾸지 않는다** — 둘 다 `isPlanPath` 밖이다. 다음 `/mccp:pr`
는 이 체인 위에서 진입한다.
