# findings · 13-relation-contract

> **형식**: `docs/_meta/findings/README.md` §기록 형식 — 발견 하나가 `## ` 표제 하나이고 그 아래
> 필수 6항목을 `### ` 표제로 순서 그대로 둔다. **판단과 수정 제안은 적지 않는다 — 사실만.**
>
> **`발견 일시` 와 `상태` 는 열거 필드다.** 값 하나만 적는다. 회부의 수신자와 반영 시점은
> `관찰 사실` 에 쓴다 — 그 두 칸에 붙이면 게이트가 정확 일치·1행 규약으로 거부한다.
>
> **조사 기준점**: 동결 SHA `6d177fa`. 아래 근거 앵커의 행 번호는 그 SHA 기준이다.
>
> **심각도 어휘**: `낮` / `중` / `높` — `12-index-runtime.md` 가 쓰는 값과 같다.

---

## F-01 · 우산 §PRD 분할 맵과 `ownership.md` 주 표가 `10-index-git` 행에서 어긋나 있었다

### 발견 일시

2026-08-11

### 관찰 사실

`run_ownership_gate` 검사 1 은 우산 §PRD 분할 맵과 `ownership.md` §PRD별 배타 소유 경로를
행 단위로 대조한다. 두 표의 `insuniverse-docs-10-index-git.prd.md` 행에서 배타 소유 경로 열이
달랐다 — 우산에만 `README.10-index-git.md` · `cross-repo-days.md` · `index-pins.lock` 세 경로가
있고 `ownership.md` 에는 없었다. 나머지 여섯 경로와 선행조건·종료조건 열은 같았다.

이 어긋남은 이 브랜치가 만든 것이 아니다. `git diff origin/main...HEAD` 에서 두 파일이 공집합
이었고, 즉 `origin/main` 내용만으로 이미 게이트가 red 였다.

관측 당시 이 저장소의 `verify.sh --check` 는 검사 1 에 도달하기 전 `run_lint_gate` 에서 먼저
멈춘다 — `docs/` 에 타입 문서가 0건이라 lint 대상이 없다. 검사 1 의 진단은 `--bootstrap` 을
붙여야 관측된다.

### 재현 절차

```bash
git -C . rev-parse HEAD                       # 6d177fa 계열인지 확인
git diff origin/main...HEAD -- docs/_meta/ownership.md \
                               .claude/prds/insuniverse-policy-docs.prd.md   # 공집합
bash docs/_meta/verify/verify.sh --check --bootstrap 2>&1 | tail -5
```

stderr 마지막에 `우산 에만:` 과 `ownership 에만:` 두 행이 나오고 세 경로가 앞쪽에만 있다.

### 근거 앵커

- `docs/_meta/verify/verify.sh:1856-1857` — 검사 1 의 의도 주석(*"선행조건·종료조건 결속 포함"*)
- `docs/_meta/verify/verify.sh:1864` — 실패 문구
- `docs/_meta/verify/verify.sh:2388` · `:2402` — `run_lint_gate` 가 `run_ownership_gate` 보다 앞선다
- `.claude/prds/insuniverse-policy-docs.prd.md` 138행 (드리프트 복구 전 기준)
- `docs/_meta/ownership.md` 22행 (동)

### 심각도

중. 소유권 게이트 전체가 red 라 이 게이트에 의존하는 모든 후속 PRD 의 종료조건이 판정 불가였다.
소유 자체의 오기는 아니다 — 우산 쪽이 정본과 일치했고 승계본만 세 경로를 잃었다.

### 상태

처리 결정됨

## F-02 · 두 소유 표의 상호 대조는 하류 PRD 본문의 선행조건 산문을 강제하지 않는다

### 발견 일시

2026-08-11

### 관찰 사실

검사 1 은 우산 표와 `ownership.md` 주 표 **서로만** 대조한다. 그래서 양쪽에서 같은 PRD 행을
함께 지우면 diff 는 공집합이 되어 통과한다. 선행조건 열은 golden 의 `ownership.paths_sha256` ·
`ownership.prd_count` 어디에도 들어가지 않으므로 golden 도 움직이지 않는다.

선행조건의 실제 소비 지점은 하류 5개 PRD **본문**의 산문인데 게이트는 그것을 보지 않는다.
표에 선행 관계를 적어도 기계로 강제되는 것은 두 표가 서로 같다는 사실뿐이다.

수신자는 `00-protocol`(게이트 소유자)이고, 반영 시점은 이 PRD 의 마일스톤 4·5 — 게이트 갱신을
위임받은 마일스톤이다. 그 전까지 유실 방지책은 이 기록 하나다.

### 재현 절차

```bash
cp docs/_meta/ownership.md /tmp/ow.bak
cp .claude/prds/insuniverse-policy-docs.prd.md /tmp/umb.bak
# 두 파일에서 같은 PRD 행 하나를 함께 지운 뒤
bash docs/_meta/verify/verify.sh --check --bootstrap; echo "EXIT=$?"
# 검사 1 통과. golden 의 paths_sha256 은 그 행이 빠졌으므로 움직이지만,
# 선행조건 열만 고친 경우(행은 남기고 열 값만 변경)에는 golden 조차 불변이다
cp /tmp/ow.bak docs/_meta/ownership.md
cp /tmp/umb.bak .claude/prds/insuniverse-policy-docs.prd.md
```

### 근거 앵커

- `docs/_meta/verify/verify.sh:1862-1864` — 검사 1 의 대조 범위가 두 표뿐이다
- `docs/_meta/verify/verify.sh:1007` — `ow_rows` 가 선행조건 열을 행 결속에 넣는다
- `docs/_meta/verify/verify.sh:1015-1016` — golden 은 `paths_sha256` · `prd_count` 만 emit 한다

### 심각도

중. 소유 관계 자체는 두 표가 지키지만, *어느 PRD 가 어느 PRD 를 기다리는가* 는 정본에 적히기만
하고 검사되지 않는다. 활성 PRD 본문 개정은 우산 제약 6 이 막고(예외는 archived 한정) 게이트
신설은 이 PRD 의 사용자 제약이 막으므로, 현재 마일스톤에서 닫을 수 있는 경로가 없다.

### 상태

미판정

## F-03 · PRD 코드펜스가 선언한 경로 중 `findings` · `term-requests` 밖은 소유 정본과 결속되지 않는다

### 발견 일시

2026-08-11

### 관찰 사실

검사 2d 는 `PRD00` 한 파일만 보고, 검사 2e 는 하류 PRD 코드펜스에서 뽑은 경로 중
`docs/_meta/findings/*.md` 와 `docs/_meta/term-requests/*.md` 만 `ownership.md` 와 대조한다.
그 밖에 PRD 가 §배타 소유 경로 코드펜스에 적은 경로는 `ownership.md` 에 없어도 게이트가 모른다.

실제로 이 PRD 의 `.claude/meta/*.md` 네 경로가 그 상태였고, 어느 표에도 없는 동안에도 게이트는
green 이었다. 두 worktree 가 같은 `.claude/meta/x.md` 를 각자 자기 것이라고 선언해도 아무 데서도
터지지 않는다.

수신자는 `00-protocol`(게이트 소유자)이고, 반영 시점은 이 PRD 의 마일스톤 4·5 다. `docs/_meta/index/**`
계열이 결속 밖인 것은 `ownership.md` 가 이미 사유를 적어 두었으나(표기 정규화 선행), `.claude/meta/**`
는 그 사유에 해당하지 않는다 — 양쪽 다 전 경로 표기다.

### 재현 절차

```bash
grep -n 'docs/_meta/(findings|term-requests)' docs/_meta/verify/verify.sh   # 2011행
sed -n '2001,2013p' docs/_meta/verify/verify.sh                            # 2e 의 유도 범위
sed -n '/배타 소유 경로/,/^\x60\x60\x60$/p' .claude/prds/insuniverse-docs-13-relation-contract.prd.md
grep -c 'claude/meta/05-final-spec' docs/_meta/ownership.md                # 0
bash docs/_meta/verify/verify.sh --check --bootstrap; echo "EXIT=$?"       # 이 사실로는 실패하지 않는다
```

### 근거 앵커

- `docs/_meta/verify/verify.sh:1979-1982` — 검사 2d 가 `PRD00` 만 본다
- `docs/_meta/verify/verify.sh:2011` — 검사 2e 의 유도 정규식이 두 디렉터리로 한정된다
- `docs/_meta/ownership.md` 47행 — `docs/_meta/index/**` 가 결속 밖인 사유

### 심각도

중. 배타 소유의 보증이 경로 종류마다 다르다. 게이트가 보증한다고 읽히는 범위와 실제 범위의 차이가
문서에 적혀 있지 않아, 다음 작업자가 코드펜스 선언만으로 배타 소유가 성립한다고 읽을 수 있다.

### 상태

미판정

## F-04 · `05-final-spec.md` §6-2 전제가 정정된 뒤에도 그것을 인용하는 소유 밖 5자리가 옛 전제를 싣는다

### 발견 일시

2026-08-19

### 관찰 사실

`05-final-spec.md` §6-2 의 권한 DB 전제가 2026-08-12 정정으로 *"미제공 확정"* 에서
*"제공 가능 확정 · 수령 대기"* 로 바뀌었다(`snapshot_state=pending` ·
`receipt_route=ops-40-db-snapshot`). 같은 파일 §0 요약표의 권한 DB 행도 함께 정정됐다.

그 전제를 인용하는 자리가 이 PRD 소유 밖에 다섯 곳 있고, 다섯 곳 모두 정정 전 문면 그대로다.

- `.claude/prds/insuniverse-docs-20-foundation-access.prd.md` 23행 — *"권한 DB 스냅샷 미제공 확정"*
- `.claude/prds/insuniverse-docs-20-foundation-access.prd.md` 115행 — *"스냅샷 미제공 확정"*
- `.claude/prds/insuniverse-policy-docs.prd.md` 101행 — *"미제공 확정"*
- `.claude/prds/insuniverse-policy-docs.prd.md` 194행 — *"미제공 확정, Out of scope로 이동"*
- `.claude/prds/insuniverse-policy-docs.prd.md` 221행 — *"Out of scope 확정"*

`.claude/meta/06-access-model-findings.md` 221행은 이 목록에 없다. 그 행이 적는 것은 2026-08-05
범위 정정(미상은 admin 그룹별 배분에 한정)이며 그 판정은 지금도 유효하다 — 옛 전제의 인용이 아니다.

`docs/_meta/ownership.md` §개정 위임 표의 어느 행도 이 다섯 자리를 이 PRD 에 위임하지 않는다.
우산 PRD 의 위임 사유는 *제약 #6 예외 · 분할 맵 10행 · 선행조건 열* 셋이고 권한 DB 전제는
거기 없다.

### 재현 절차

```bash
sed -n '19p;493,520p' .claude/meta/05-final-spec.md          # 정정된 두 자리
sed -n '23p;115p' .claude/prds/insuniverse-docs-20-foundation-access.prd.md
sed -n '101p;194p;221p' .claude/prds/insuniverse-policy-docs.prd.md
grep -n '개정 위임' -A 20 docs/_meta/ownership.md            # 위임 사유에 권한 DB 전제가 없다
```

### 근거 앵커

- `.claude/meta/05-final-spec.md` 19행 — §0 요약표 권한 DB 행 (정정 후)
- `.claude/meta/05-final-spec.md` 493행 — `### 6-2. 권한 DB — 미제공 확정` 절 제목 (원문 보존)
- `.claude/prds/insuniverse-docs-20-foundation-access.prd.md` 23행 · 115행
- `.claude/prds/insuniverse-policy-docs.prd.md` 101행 · 194행 · 221행
- `docs/_meta/ownership.md` 106행 — §개정 위임 표의 범위

### 심각도

중. 저장소가 같은 전제에 대해 두 문면을 동시에 싣는다. 정본은 `05-final-spec.md` 이고 나머지
다섯은 그것을 인용하는 자리다.

### 상태

미판정

## F-05 · backlog 3건이 이 마일스톤에서 해소됐다 — 관계 축 엣지 튜플 · `..` 탈출 · ownership 메시지

### 발견 일시

2026-08-19

### 관찰 사실

`.claude/plans/codex-findings-backlog.md` 의 세 항목이 인수처를 이 마일스톤으로 지목했고 M5 가
같은 코드 경로를 다시 열면서 셋 다 닫혔다.

`2026-08-18 HIGH` — `--probe=relation` 의 엣지 출력 계약이 `<flow> edge <target> | <condition>`
이라 `실패·이탈` 표의 `지점` 열을 담지 않았다. 조건과 대상이 같은 엣지를 다른 단계로 옮기면
흐름 위상이 바뀌었는데도 동결이 그대로라 exit 0 이 났다. 출력 계약을
`<flow> edge <point> -> <target> | <condition>` 으로 넓히고 `probe-expected.relation.yaml` 을
재생성했다 — 재생성 diff 는 14행 삽입 · 14행 삭제이고 그중 13행이 엣지 행, 1행이 머리 주석이다.

`2026-08-18 HIGH` — `isRelativeRef` 가 절대경로 · URI scheme · rooted-backslash · UNC 는 거부하되
`../` 상향 탈출은 통과시켰고 `resolveRefItem` 의 `path.resolve` 에도 경계가 없었다. 참조를
해석하는 모든 CLI 모드에서 `--root` 를 필수로 만들고, realpath 로 정규화한 containment 함수
하나가 참조와 `config:` 를 함께 통과하도록 바꿨다. 대상이 아직 없는 경우는 가장 가까운 존재하는
상위를 정규화해 판정한다.

`2026-08-14 MEDIUM` — `verify.sh` 의 ownership 게이트 성공 메시지가 `PRD 9행 결속` 을 리터럴로
찍는데 golden `ownership.prd_count` 는 M1 이후 `10` 이었다. 메시지에서 수를 없앴다. 계수를
golden 에서 읽어 찍는 대신 메시지가 수를 자칭하지 않게 한 것은 같은 결함의 재발을 막는 쪽을
고른 것이다.

### 재현 절차

```bash
node .claude/plans/insuniverse-docs-13-relation-contract-m5.gates.mjs check9    # 엣지 튜플
node .claude/plans/insuniverse-docs-13-relation-contract-m5.gates.mjs check10   # 루트 경계
node .claude/plans/insuniverse-docs-13-relation-contract-m5.gates.mjs check12   # ownership 메시지
grep -n 'ok  ownership 게이트' docs/_meta/verify/verify.sh
```

### 근거 앵커

- `.claude/plans/codex-findings-backlog.md` — `2026-08-18 HIGH` 2행 · `2026-08-14 MEDIUM` 1행
- `.claude/templates/doc-kit/lint-docs.mjs` — `insideRoot` · `resolveInRoot` · `probeRelation` 의 엣지 튜플
- `docs/_meta/verify/verify.sh` — ownership 게이트 성공 메시지
- `.claude/templates/doc-kit/examples/probe-expected.relation.yaml` — 재생성본

### 심각도

중. 셋 다 게이트가 통과하는데 대상 성질이 검사되지 않던 자리이며, 조용한 거짓 통과였다.

### 상태

처리 결정됨


## F-06 · 시간 축 계약이 남긴 두 노출 — 0건 사유 (i)/(ii) 미분리와 R-6 미수용

### 발견 일시

2026-08-19

### 관찰 사실

`--probe=history` 는 이벤트가 0건인 앵커에 사유를 붙인다. 분류는 셋이다 — (i) 기준 HEAD 이후에
생긴 경로 · (ii) 경로가 없다 · (iii) 변경이 없었다. 이 실행 환경에서 (i)과 (ii)는 **같은
관측값**을 낸다. 이 워크트리의 서브모듈 3종이 manifest `repos[].head` 그 자체이기 때문이다
(`git -C insuniverse-server rev-parse HEAD` = `4d798f55…`, site = `767d1e44…`, admin =
`fb001e1d…`). 기준 HEAD 이후에 생긴 경로를 만들 수단이 없으므로 둘 다 "인덱스에도 트리에도
없다" 로 관측된다. 합쳐 `미상 — 인덱스 범위 밖이거나 경로 없음` 으로 내고 (iii)과만 가른다.

`docs/_meta/index/index-pins.lock` 은 manifest HEAD 를 잠그지 않는다 — `[prod_tip]` 3건과
`[classifier]` 뿐이다. 회부 R-6(인덱스 생산자 stamp)이 수용되기 전까지 `--probe=history` 의
신선도 판정은 세 조건(동결 머리 = manifest · 인덱스 digest·행 수 · 인덱스 최신 행이 HEAD 의
조상)에만 기댄다. 그 셋을 전부 통과하면서 인덱스가 낡을 수 있는 구간이 하나 남는다 — `src_roots`
안에 커밋을 더하지 않는 HEAD 이동(빈 커밋)이며, 그 경우 정당한 재생성인데도 `--refreeze` 의
재현 대조는 통과한다. 반대로 추출기 결정성이 깨진 환경에서는 정당한 재생성이 거부된다 —
**막는 방향의 오거부**다.

`--refreeze` 는 digest 변동 여부와 무관하게 **언제나** `extract-commits.mjs` 를 임시 출력으로 다시
돌려 커밋된 JSONL 과 바이트 대조한다. 앞선 판(digest 불변이면 재현 생략)은 판정의 두 입력이 모두
가변이라 — 현재 인덱스의 digest 와 동결 파일 머리에 적힌 digest — 둘을 함께 고치면 손상된
인덱스가 재현 없이 봉인됐다.

### 재현 절차

```bash
git -C insuniverse-server rev-parse HEAD    # manifest repos[].head 와 같다
grep -n 'prod_tip\|classifier' docs/_meta/index/index-pins.lock
node .claude/plans/insuniverse-docs-13-relation-contract-m5.gates.mjs check8
```

### 근거 앵커

- `docs/_meta/extraction-manifest.yaml` — `repos[].head` 3건
- `docs/_meta/index/index-pins.lock` — `[prod_tip]` · `[classifier]`
- `.claude/templates/doc-kit/lint-docs.mjs` — `probeHistory` 의 stale 3조건 · `refreezeHistory`
- `.claude/meta/12-flow-centric-restructure.md` §3-6 — 0건 사유 3분류 표

### 심각도

중. 선언된 사각지대이며 게이트 출력과 분석 정본 양쪽에 적혀 있다. 해소 주체는 `10-index-git` 이다.

### 상태

미판정


## F-07 · M5 계획서 §GROUND 의 두 진술이 실측과 어긋났다

### 발견 일시

2026-08-19

### 관찰 사실

계획서 `.claude/plans/insuniverse-docs-13-relation-contract-m5.plan.md` §GROUND 는
*"템플릿 3종에는 표 실물이 없다 — `## 연혁` 아래가 TEMPLATE 주석 한 덩이뿐이고 헤더 행이 없다"*
고 적었다. 실측은 반대다. `policy-doc.template.md` 120~122행 · `ia-doc.template.md` 107~109행 ·
`flow-doc.template.md` 139~141행이 헤더 행 · 구분선 · 자리표시자 본문 행 1개를 이미 갖는다.
자리표시자 행은 같은 파일의 다른 표(75행 · 88행)와 같은 규약이므로 지우지 않았다. 그 결과
계획 Task 0b 는 실질 무작업이고, 게이트 `#1` 은 기준점 7자리의 헤더 행 일치만 보므로 그대로
판정된다.

같은 절의 조인 실측표는 `corpAnalysisViewLevel` 의 `문서 표 기록` 을 1, `미기록` 을 13 으로
적었다. 구현이 낸 값은 2 와 12 다. 원인은 `f0038eb9` 한 커밋이 `admin-view-token.guard.ts` 와
`analyze-admin.controller.ts` 를 **함께** 만진다는 것이며, 정책별 이벤트 집합은 서로 배타가
아니다. 계획의 표는 문서 표의 각 행을 한 정책에만 배정한 계수다. 이벤트 수(3 · 48 · 14)와
최초·최종 SHA 는 계획과 일치한다.

문서 단위 계수는 **행 단위**로 센다 — 정책별 `recorded` 를 더하면 문서 행 수를 넘는다.

### 재현 절차

```bash
sed -n '113,122p' .claude/templates/doc-kit/policy-doc.template.md
node .claude/templates/doc-kit/lint-docs.mjs --probe=history --root . \
  --index-dir docs/_meta/index --manifest docs/_meta/extraction-manifest.yaml \
  --repos-dir . --expected .claude/templates/doc-kit/examples/probe-expected.history.yaml \
  .claude/templates/doc-kit/examples/policy-example.md
```

### 근거 앵커

- `.claude/templates/doc-kit/policy-doc.template.md` 120행 — 연혁 표 헤더 (M5 이전부터 존재)
- `.claude/templates/doc-kit/examples/probe-expected.history.yaml` — `corpAnalysisViewLevel policy … recorded=2 unrecorded=12`
- `docs/_meta/index/commits.server.jsonl` — `f0038eb9` 행의 `files[]`

### 심각도

낮. 계획서의 진술이며 산출물의 결함이 아니다. 게이트는 어느 쪽 값도 리터럴로 담지 않는다.

### 상태

처리 결정됨

## F-08 · 문서 트리 계수를 말하는 산문 3자리가 golden 과 대조되지 않은 채로 있었다

### 발견 일시

2026-08-19

### 관찰 사실

`docs/00-index.md` 와 `.claude/meta/12-flow-centric-restructure.md` 는 문서 트리의 두 계수를
값과 함께 산문으로 말한다. 세 자리다 — 사본 12행(전수) · 13행(자기 참조 1건을 뺀 값) ·
분석 정본 400행(게이트 계약 표의 "불가" 사유). 세 자리 모두 `51` 과 `50` 을 리터럴로 담고 있었다.

`docs/_meta/verify/verify.sh` 의 `run_index_gate` 는 코드펜스가 담은 경로 집합과 정본 §4 의
집합을 exact-diff 로 대조하고 그 계수를 `golden.txt` 에 동결한다. 그 검사는 **코드펜스 안만**
본다. 코드펜스 밖 산문의 리터럴을 golden 이나 코드펜스와 대조하는 검사는 저장소 어디에도 없다.
`grep -rn 'entry_count' docs/_meta/verify/verify.sh` 로 확인한 결과 산문 구간을 표본으로 삼는
호출이 없다.

M6 이 트리에 IA 문서 2건을 얹어 동결값이 `index.entry_count` 53 · `index.doc_count` 52 로
움직였다. 이 마일스톤 전이라면 세 자리를 고치지 않아도 `verify.sh --check` 는 통과했다.

M6 계획서 `.claude/plans/insuniverse-docs-13-relation-contract-m6.plan.md` §Validation 의
검사 `#3` 이 세 자리를 문면 재열거와 대조하고 `#5` 가 재열거·golden·PRD 지표 행을 묶는다.
**두 검사는 그 계획서의 블록 안에만 있다** — `verify.sh` 나 재사용 검증기로 승격되지 않았고,
따라서 M6 이후의 트리 개정에는 자동으로 걸리지 않는다.

### 재현 절차

```bash
# 이 마일스톤 이전 상태에서 산문만 낡힌 채 게이트가 통과함을 본다
git stash && git checkout 5966e11 -- docs/00-index.md
bash docs/_meta/verify/verify.sh --check --bootstrap   # exit 1 — 트리 자체가 되돌아갔기 때문
# 산문만 되돌리는 경우: 사본 12·13행의 값만 51/50 으로 바꾸고 코드펜스는 그대로 둔다
bash docs/_meta/verify/verify.sh --check --bootstrap   # exit 0 · check PASS
```

### 근거 앵커

- `docs/00-index.md` 12행 · 13행 — 동결 SHA `5966e11e03d4c5c2b7c145a24211fbbfa7cc6562`
- `.claude/meta/12-flow-centric-restructure.md` 400행 — 같은 SHA
- `docs/_meta/verify/golden.pre-m6.txt` 80~82행 — 착수 시점 동결값
- `docs/_meta/verify/golden.txt` 80~82행 — 재동결 후 동결값

### 심각도

오동작. 범위는 트리 계수를 말하는 산문 3자리이며, 그 값을 읽는 독자와 그 값을 인용하는
하류 문서까지다. 노출이나 데이터 손실은 없다. 자동 검사의 사각지대이며 M6 계획 블록 밖에서는
지금도 사각지대다.

### 상태

처리 결정됨

## F-09 · 회부 8건이 수신 PRD 세 종 본문 어디에서도 참조되지 않았고 형제 findings 회수를 계약한 것은 1/3 이었다

### 발견 일시

2026-08-20

### 관찰 사실

`.claude/prds/insuniverse-docs-13-relation-contract.prd.md` §회부 8건 은 R-1~R-8 을 수신 PRD 다섯
곳으로 보낸다. 표의 (번호, 수신, 회부 요지)는 아래와 같다.

| # | 수신 | 회부 요지 |
|---|---|---|
| R-1 | `50-domain` | IA 문서 2건(`docs/20-site/00-ia.md` · `docs/30-admin/00-ia.md`) 수용 |
| R-2 | `50-domain` | 마일스톤 순서 역전 — 흐름 5 + 콘솔 5 + IA 2 를 앞에, `10-server/` 8 을 뒤로 |
| R-3 | `70-viewer` | 표면·계약 요청 (기존) |
| R-4 | `60-history-deprecated` | `docs/99-deprecated/**` 에 `template:` 없이 프론트매터만 얹기 — `deprecated: [{id, at, sha, reason}]` |
| R-5 | `70-viewer` | 계약 요청 #4(`## 연혁` 의 기계 접근 경로) 재판정 |
| R-6 | `10-index-git` | `commits.<repo>.jsonl` 에 생성 기준 `repos[].head` 기록 (또는 `index-pins.lock` 에 manifest HEAD 핀 추가) |
| R-7 | `ops-doc-reconcile` | `target.kind: doc` 앵커를 heading slug 가 아니라 `<경로>.md#<policies[].id>` 로 · id 실재 확인까지 요구 |
| R-8 | `60-history-deprecated` | `docs/90-history/` 에 등급 O(ops 원장 판독) 기록이 앉을 자리 신설 |

**수신 PRD 3종 본문에 이 PRD 를 가리키는 참조가 0건이었다.** `50-domain` · `70-viewer` ·
`60-history-deprecated` 세 파일에서 `13-relation` · `relation-contract` · `회부` · `인계` 네 토큰을
합쳐 세면 각각 0 이다. 즉 회부 사실이 발신 측 파일 하나(그 PRD 본문)에만 있었고, 수신자가 자기
파일만 읽으면 도달하지 않았다.

**형제 `findings/` 회수를 계약한 것은 세 수신 중 하나뿐이었다.** `60-history-deprecated` 는
*"형제가 `dead-code-candidate` 를 발견하면 `docs/_meta/findings/<prd-id>.md` 에 기록 → 이 PRD가
회수해 판정"* 을 선언하고(87행) `docs/_meta/findings/**` 를 형제 보고 회수용 **읽기** 경로로
명시하며(105행) 마일스톤 5 를 *"형제 findings 회수 + 재판정"* 으로 둔다(125행). `50-domain` 과
`70-viewer` 는 자기 파일 쓰기만 선언한다 — `50-domain` 98행 · 106행, `70-viewer` 85행 · 95행 ·
228행 어디에도 형제 파일을 읽는다는 문장이 없다.

**`docs/_meta/findings/13-relation-contract.md` 자신도 회부를 열거하지 않았다.** 이 기록 이전
발견 8건(F-01~F-08) 중 회부 id 를 표로 담은 항목은 0건이고, F-06 이 본문에서 R-6 을 한 번
언급하는 것이 전부였다.

수신자별 미도달 건수는 `50-domain` 2 · `70-viewer` 2 · `60-history-deprecated` 2 ·
`10-index-git` 1 · `ops-doc-reconcile` 1 이다. 이 마일스톤(M7)이 `docs/_meta/ownership.md` 에
`## 회부 인계` 절을 신설해 8행 전사를 앉혔고, 그 파일은 모든 PRD 가 읽는 소유 정본이다.
반영 시점은 각 대상 PRD 착수 시점이며 이 PRD 가 대신 수용하지 않는다.

### 재현 절차

```bash
# 착수 커밋 6301864 기준. 수신 PRD 3종 본문의 역참조 계수
for p in 50-domain 70-viewer 60-history-deprecated; do
  printf '%-24s %s\n' "$p" \
    "$(git show 6301864:.claude/prds/insuniverse-docs-$p.prd.md \
       | grep -c -E '13-relation|relation-contract|회부|인계')"
done                       # 세 줄 전부 0

# 형제 findings 회수 계약 유무
git show 6301864:.claude/prds/insuniverse-docs-60-history-deprecated.prd.md | grep -n 'findings'
git show 6301864:.claude/prds/insuniverse-docs-50-domain.prd.md            | grep -n 'findings'
git show 6301864:.claude/prds/insuniverse-docs-70-viewer.prd.md            | grep -n 'findings'
# 60 만 '회수' 문장을 갖는다. 나머지 둘은 '기록만' 이다

# 이 파일 자신의 회부 열거 계수 (이 기록 이전)
git show 6301864:docs/_meta/findings/13-relation-contract.md | grep -c '| R-[0-9] |'   # 0
```

### 근거 앵커

- `.claude/prds/insuniverse-docs-13-relation-contract.prd.md` 145 행 §회부 8건 표 — 동결 SHA `6301864b731b6fd75a6b81eab83be529c8464691`
- `.claude/prds/insuniverse-docs-60-history-deprecated.prd.md` 87 행 · 105 행 · 125 행 — 같은 SHA
- `.claude/prds/insuniverse-docs-50-domain.prd.md` 98 행 · 106 행 — 같은 SHA
- `.claude/prds/insuniverse-docs-70-viewer.prd.md` 85 행 · 95 행 · 228 행 — 같은 SHA
- `docs/_meta/ownership.md` §회부 인계 — M7 이 신설한 도달 경로

### 심각도

유실. 범위는 회부 8건 전부와 그 수신 PRD 5종이다. 노출이나 데이터 손실은 아니며, 회부가 수신자의
착수 입력에 나타나지 않아 **판정 없이 잊히는** 형태다. `60-history-deprecated` 로 가는 2건(R-4 ·
R-8)은 그 PRD 의 회수 계약이 덮지만, `50-domain` 2건과 `70-viewer` 2건은 M7 이 신설한
`ownership.md` §회부 인계 가 유일한 도달 경로다. `10-index-git`(R-6)과 `ops-doc-reconcile`(R-7)은
우산 밖이라 그 두 우산의 자기 창에서만 회수된다.

### 상태

처리 결정됨

## F-10 · 착수 시점 실측 9건 — 이월 원장의 두 진술이 거짓이었고, 같은 사각을 세 계획서가 각자 재생산했다

### 발견 일시

2026-08-20

### 관찰 사실

**(1) EOL 측정 관용구 중 blind 는 gawk 하나다.** 이월 원장의 `2026-08-20 | HIGH | docs/_meta/verify/verify.sh · …-m7.plan.md` 행은
`awk '/\r$/'` 과 `grep -c $'\r'` 이 *"둘 다 0"* 을 낸다고 적었다. `docs/00-index.md`(바이트 계수 CRLF 163행)에서 재측정한 값은
아래와 같다.

| 측정 | 결과 |
|---|---|
| `awk '/\r$/' f \| wc -l` (GNU Awk 5.4.0) | 0 |
| `awk '{if(index($0,"\r"))n++}END{print n+0}' f` | 0 |
| `awk -v BINMODE=r '/\r$/' f \| wc -l` | 163 |
| `grep -c $'\r' f` (GNU grep 3.0) | 163 |
| `grep -cU $'\r' f` | 163 |
| `sed -n $'/\r$/p' f \| wc -l` | 163 |
| `tr -d '\r' < f \| wc -c` 바이트 delta | 163 |
| `git ls-files --eol f` | `i/lf w/crlf` |

같은 파일에서 gawk 는 정규식으로도 `index()` 로도 CR 을 보지 못하고, grep·sed·tr 은 본다. 같은 창에서 원장의
`2026-08-20 | MEDIUM | …-m6.plan.md` 행(M6 사각 3건 재확인)도 *"`awk '/\r$/'` 도 `grep -c $'\r'` 도 0 을 낸다"* 를 담고 있다.

**(2) 이월 원장의 스키마 문면 반증 항목은 지금 성립하지 않는다.** 원장의 `deferred_ref_targets` 항목은 *"스키마에는 참조 문서 기준으로
적혀 구현과 반대"* 라고 적었다. 실제 `.claude/templates/doc-kit/template-config.schema.md` 103 행은 **"여기의 상대경로는 이 config
파일 기준이다"** 이고 `lint-docs.mjs` 757 행 `ctx.configDir = path.dirname(abs)` 와 방향이 같다. `git blame` 은 그 행을 M5·M6 커밋
`6301864` 로 짚는다.

**(3) findings 항목 **존재** 판정은 이미 있고, **신규 항목 요구**는 없다.** 원장의 `…-m6.plan.md` R1 F4 항목은 *"findings 신규 항목을
요구하는 검사가 어디에도 없다 — 이미 있는 항목의 6항목 구조만 보므로 기록을 아예 빼도 마일스톤이 complete 가 된다"* 로 적었다.
착수 시점(`9f1e09a`) 실측: `docs/_meta/verify/verify.sh:2551` 의 `if (nfound == 0) { … F = 1 }` 이 `## ` 표제 0개 파일을 이미
exit 1 로 거부한다(커밋 `2f57448` 이 넣었다). 표제 0개 파일을 그 함수에 직접 넣어 확인했다 — `rc=1`. 남아 있는 것은 **파일은 두고
항목만 지우는** 경로이며, `golden.txt` 는 `findings.files`(파일 목록)만 동결하고 파일별 항목 수는 담지 않았다.

**(4) 투영 검사가 파일명 부분문자열만 보는 축이 3회차다.** `…-m6.plan.md` 384 행과 `…-m7.plan.md` 421~425 행이 같은 형태다 —
`KEYS` 3개를 `grep -qF` 로 backlog 와 투영 양쪽에서 찾는다. 세 이름을 한 문장에 몰아넣은 파일이 통과하고 항목 수·날짜·심각도·
인수처는 어느 것도 대조되지 않는다. 원장의 `…-m7.plan.md` R1 F4 행이 *"같은 축 3회차면 개별 계획서 흡수가 아니라 재사용 생성기로
승격한다"* 를 이미 적어 두었다.

**(5) 이월 규모는 파싱 방식에 따라 갈린다.** `^<날짜> \| <심각도> \| <source> \| <finding>$` 를 필드 정확히 4개로 요구하면 원장 전체가
140행이고, source 만 `|` 를 금지하고 본문에는 허용하면 154행이다(착수 커밋 `9f1e09a` 기준). 후자에서 `13-relation-contract` 를
source 또는 finding 에 담은 행은 35행이다. 전자의 파싱은 본문에 `|` 가 있는 14행을 행으로 세지 않는다.

**(6) 동결된 계획서 게이트 다섯이 이 원장의 대상이다.** M6 `#1`(트리 행 설명 열) · M6 `#2`(`cr == 0` 성공 분기) · M6 `#6`(투영
부분문자열) · M7 `#2`(소절 계수) · M7 `#8`(투영 부분문자열). 다섯 다 각 계획서 §Validation 블록 안이고 그 블록은 해당
`mccp-plan-codex` receipt 의 `plan_hash` 에 결박돼 있다.

**(7) 착수 시점 행 집합을 실행 시점에 다시 유도하면 삭제가 관측되지 않는다.** 판정 커버리지를 *"미판정 0"* 으로 재는 검사에서 분모를
실행 시점 원장에서 유도하면, 대상 행을 지우거나 `13-relation-contract` 문자열을 떼는 순간 분모와 분자가 함께 줄어 값이 유지된다.

**(8) `.claude/state/` 는 gitignore 대상이다.** `git check-ignore -v .claude/state/fix-task.d/insuniverse-docs-13-relation-contract-m7.md`
가 `.gitignore` 규칙을 짚는다. 따라서 매칭 행이 있는 clean checkout 에는 투영 파일이 없다.

**(9) `## 흐름으로 읽기` 는 사본의 h2 이고 정본은 spec 의 h3 다.** `docs/00-index.md:54` 가 `## 흐름으로 읽기` 이고
`.claude/meta/05-final-spec.md` 402 행이 `### 읽기 축 2 — 흐름 진입` 이다. M7 게이트 `#2`(`…-m7.plan.md` 289 행)는
`grep -c '^### 읽기 축 2 — 흐름 진입$' "$SPEC"` 로 정본 파일 **전역**을 센다 — §4 슬라이스 안인지, 소절 본문이 있는지는 그 계수와
무관하다.

### 재현 절차

```bash
# 착수 커밋 9f1e09a 기준. (1) EOL 측정 8경로
f=docs/00-index.md
printf 'awk       %s\n' "$(awk '/\r$/' "$f" | wc -l)"
printf 'awk index %s\n' "$(awk '{if(index($0,"\r"))n++}END{print n+0}' "$f")"
printf 'binmode   %s\n' "$(awk -v BINMODE=r '/\r$/' "$f" | wc -l)"
printf 'grep      %s\n' "$(grep -c $'\r' "$f" || true)"
printf 'sed       %s\n' "$(sed -n $'/\r$/p' "$f" | wc -l)"
printf 'byte      %s\n' "$(( $(wc -c < "$f") - $(tr -d '\r' < "$f" | wc -c) ))"
git ls-files --eol "$f"

# (2) 스키마 문면 방향
git show 9f1e09a:.claude/templates/doc-kit/template-config.schema.md | sed -n '103p'
git show 9f1e09a:.claude/templates/doc-kit/lint-docs.mjs             | sed -n '757p'

# (3) findings 표제 0개 파일이 이미 거부되는가
T=$(mktemp -d)
printf '발견 일시\n관찰 사실\n' > "$T/items.txt"
printf '# 표제 없음\n\n본문만 있다.\n'  > "$T/empty.md"
git show 9f1e09a:docs/_meta/verify/verify.sh \
  | sed -n '/^findings_structure_ok() {/,/^}$/p' > "$T/fn.sh"
bash -c 'source "$1/fn.sh"; findings_structure_ok "$1/items.txt" "$1/empty.md" \
  "미판정,사용자 통보,처리 결정됨" "발견 일시" "상태"; echo "rc=$?"' _ "$T"
# -> '`## ` 발견이 0건이다' + rc=1

# (4) 투영 검사의 형태
git show 9f1e09a:.claude/plans/insuniverse-docs-13-relation-contract-m6.plan.md | sed -n '378,386p'
git show 9f1e09a:.claude/plans/insuniverse-docs-13-relation-contract-m7.plan.md | sed -n '417,426p'

# (5) 파싱 방식별 행 수
git show 9f1e09a:.claude/plans/codex-findings-backlog.md \
  | grep -cE '^[0-9]{4}-[0-9]{2}-[0-9]{2} \| [A-Z]+ \| [^|]+ \| [^|]+$'   # 140
git show 9f1e09a:.claude/plans/codex-findings-backlog.md \
  | grep -cE '^[0-9]{4}-[0-9]{2}-[0-9]{2} \| [A-Z]+ \| [^|]+ \| '          # 154

# (8) 투영 경로의 gitignore 여부
git check-ignore -v .claude/state/fix-task.d/insuniverse-docs-13-relation-contract-m7.md

# (9) 정본과 사본의 자리
git show 9f1e09a:docs/00-index.md          | sed -n '54p'
git show 9f1e09a:.claude/meta/05-final-spec.md | sed -n '402p'
git show 9f1e09a:.claude/plans/insuniverse-docs-13-relation-contract-m7.plan.md | sed -n '289p'
```

### 근거 앵커

동결 SHA `9f1e09a606c14b5cecbe783e64fc53debb328364` 기준.

- `docs/_meta/verify/verify.sh:2484` `findings_structure_ok()` · `docs/_meta/verify/verify.sh:2551` `if (nfound == 0)`
- `docs/00-index.md:54` `## 흐름으로 읽기` (사본의 h2)
- `.claude/meta/05-final-spec.md` 402 행 `### 읽기 축 2 — 흐름 진입` (정본의 h3)
- `.claude/templates/doc-kit/template-config.schema.md` 103 행 · `.claude/templates/doc-kit/lint-docs.mjs` 757 행
- `.claude/plans/insuniverse-docs-13-relation-contract-m6.plan.md` 212 행 `tree_of()` · 378~386 행 게이트 `#6`
- `.claude/plans/insuniverse-docs-13-relation-contract-m7.plan.md` 289 행 게이트 `#2` · 417~426 행 게이트 `#8`
- `.claude/plans/codex-findings-backlog.md` — EOL 행과 M6 사각 3건 재확인 행 (둘 다 `2026-08-20`)
- 커밋 `2f57448` — `nfound == 0` 판정을 넣은 커밋

### 심각도

오동작. 범위는 게이트의 관측 능력이다 — (1)·(9) 는 게이트가 대상을 못 보는 상태이고, (3)·(4)·(7) 은 값이 사라져도 게이트가
초록을 내는 상태다. 산출 문서의 내용에는 영향이 없다. (2)·(5) 는 원장·계획서 문면과 실측의 불일치이며 그 자체가 후속 창의
입력을 오염시킨다.

### 상태

처리 결정됨
