# notes · insuniverse-docs-30-contracts-limits — 마일스톤 4

계획서: `.claude/plans/insuniverse-docs-30-contracts-limits-m4.plan.md`
하네스: `.claude/plans/insuniverse-docs-30-contracts-limits-m4.gates.mjs`
산출물: `docs/03-contracts/04-state-transitions.md`

**리뷰 기록은 이 파일이 든다.** 계획 본문에 쓰면 `mccp-plan-codex` receipt 의 `plan_hash` 가
움직여 봉인이 stale 로 떨어진다.

## Codex Implementation Review

- 호출: `node …/scripts/lib/codex-invoke.js adversarial-review` (fail-closed Bash wrapper, v0.2.2)
- 라운드 수: 0
- 합치 결론: **Codex 는 이 게이트에서 발화하지 않았다.** `MCCP_CODEX_DISABLED=1` 이 전역
  `~/.claude/settings.json` 에 박혀 있어 wrapper 가 `classification=disabled` 로 단락했다
  (실측 프로브: `{"ok":true,"stdout":"","stderr":"","durationMs":1,"classification":"disabled","blocking":false,"advisory":false}`).
  지적 0건은 **없다는 관측이 아니라 묻지 못했다는 기록**이다. receipt 의
  `codex_verdict=skipped` 가 그 사실을 든다 — 하류 dedupe 는 `converged` 밖의 값에
  fail-closed 이므로 `/mccp:pr` 시점의 PR-Codex 가 그대로 발화한다.

> Codex skipped per MCCP_CODEX_DISABLED=1

- YAGNI Triage:

  | Finding | Severity | Verdict | Why |
  |---|---|---|---|
  | (없음) | — | — | Codex 미발화. 판정할 지적이 0건이다 |

- Deferred to backlog: 0 → `.claude/plans/codex-findings-backlog.md`
- Open Questions: 계획서 §Open Questions 네 항목이 그대로 열려 있다 — 전건 severity LOW.
  자동 CRITICAL 목록(비밀 노출 · 데이터 손실 · 되돌릴 수 없는 마이그레이션 · 인증 우회 ·
  외부 목적지 변경 · 암호키 취급) 해당 0건.
- Codex session 참조: 없음 (미발화)

### Security Reviewer

이 마일스톤의 산출은 `docs/**` 문서 1건과 `.claude/**` 하네스·기록 3건이다. 인증·암호·비밀·입력
검증·주입·SSRF·경로 순회·권한 상승 어느 축도 건드리지 않으며, 실행 코드 경로를 만들지 않는다.
Phase 2.5.5 의 보안 리뷰 트리거 조건(security-sensitive areas)에 해당하지 않아 호출하지 않았다 —
호출 실패로 인한 auto-fallback 이 아니므로 `security_skipped` 도 세우지 않는다.

### Design Review

`impeccable-detect --mode implement` 가 `design_signal=false` · `silent_skip=true`
(`reason=no-signal`) 를 냈다. 이 마일스톤은 렌더링 표면을 만들지도 고치지도 않는다
(`docs/**` 1건 · `.claude/**` 3건). receipt 에 `impeccable_silent_skip=true` 로 실렸다.

> 계획서 §Design Routing Guide 의 `design_signal=1` 은 **plan 단계 탐지기가 계획서 본문의
> §GROUND G11 앵커(admin 화면 파일 경로)를 UI 표면으로 읽은 오탐**이었다. implement 단계
> 탐지기는 diff 를 보므로 같은 오탐이 서지 않는다 — 두 단계의 신호가 갈리는 것이 정상이다.

### 구현 시점에 새로 선 결정 (2.5.2)

Codex 가 발화했다면 이 목록이 focus 였다. 발화하지 않았으므로 **묻지 못한 결정 목록**으로
남긴다.

| # | 결정 | 대안 | 선택 이유 |
|---|---|---|---|
| D1 | 발행 어휘의 분모를 `export enum <이름> {` 선언 블록으로 잡고 멤버를 `<키> = '<값>'` 행으로 정의했다 | 코드 인덱스 `codes/domain_status.yaml` 의 값 목록 | 계획서 G18 이 인덱스 `source_sha` 세 값이 manifest head 와 모두 다름을 실측했고 G13 이 고객사 접두가 인덱스 갈래 정규식에 아예 없음을 실측했다. 인덱스를 분모로 삼으면 `cod_values` 축이 통째로 사라진다. `--selfprobe` 가 대입 형태를 깬 변이에서 0건 거부를 확인한다 |
| D2 | `state_columns` 를 **엔티티의 `@IsEnum(<어휘>)` 속성을 snake 로 바꿔 스키마 컬럼 집합에 실재 확인**하는 방식으로 유도했다 | 컬럼 이름 정규식(`*_state`)으로 스키마를 훑기 | 후자는 이 어휘와 무관한 상태 칸을 함께 집는다(동결 blob 에 `_state`·`_status` 칸이 17개 있고 그중 다섯만 이 문서의 어휘다). 전자는 **어휘에서 칸으로** 되짚으므로 분모가 어휘와 같다. 되짚히지 않는 속성이 하나라도 있으면 FAIL 이라 조용한 축소가 없다 |
| D3 | `odd_final_state` 가 이 집합에 든 것은 규칙의 귀결이지 손으로 더한 것이 아니다 | 계획서 G5 를 근거로 하네스에 리터럴로 박기 | 엔티티가 `oddFinalState` 를 같은 `@IsEnum(OrderDetailState)` 로 선언한다(`order-detail.entity.ts:47`·`:49`). D2 규칙이 그것을 자동으로 집는다 — G5 의 최상위 정책이 리터럴이 아니라 **재유도**로 선다 |
| D4 | 불일치 주장을 **코드값 집합**으로 문서에 싣고 게이트가 양측을 각각 읽어 재구성했다 | 문서에 산문으로만 적기 | 산문만 있으면 층위 2 다 — 주장이 사실이 아니게 되어도 게이트가 침묵한다. 다섯 주장 전부 "차집합이 비면 FAIL" 을 갖는다 |
| D5 | `site-order-detail-type-shape` 만 코드값이 아니라 **모양 이름 두 개**를 토큰으로 썼다 | 이 주장을 검사에서 빼기 | 발행은 코드값, 소비는 업무 이름이라 대조할 코드값 자체가 없다. 모양을 `code`/`label` 로 판정해 두 값이 같아지면 FAIL 한다 — 다섯 주장 중 유일하게 집합이 아닌 축이며 그 사실을 여기 적는다 |
| D6 | 검사 `#12` 를 `--selfprobe` 의 별칭으로 두었다 | `check12` 를 따로 만들기 | 계획서 §Validation 은 `#12` 자리에서 `--selfprobe` 를 부르고 검사 `#2` 는 `check1..check12` 집합 일치를 요구한다. 두 이름이 **같은 본문**을 가리켜야 두 요구가 동시에 성립한다 |
| D7 | 검사 `#1` 을 `--mode baseline|seal` 두 모드로 갈랐다 | m3 처럼 착수와 봉인을 두 검사로 나누기 | 계획서 §Validation 이 `check1 --mode baseline` 과 `check1 --mode seal` 두 자리를 명시한다. 모드 인자가 없으면 rc 64 로 거부한다 — 기본값을 두면 어느 쪽을 돌렸는지 출력만 보고 알 수 없다 |
| D8 | 본문 인용 정규식을 `.ts` 에서 `.tsx` 까지 넓혔다 | m3 의 `.ts` 전용 유지 | 이 문서는 admin 화면 파일(`.tsx`)을 세 자리 인용한다. 넓히지 않으면 그 인용이 **검사 대상에서 조용히 빠진다** — 인용 계수가 61 에서 줄어드는 것으로 확인했다 |
| D9 | `docs/_meta/findings/30-contracts-limits.md` 를 열지 않았다 | 관측 다섯 건을 findings 로 | 계획서 §NOT Building · G21·G22. 관측은 문서 본문과 계획서 §GROUND 에 판단 없이 실렸다. 검사 `#1` 봉인 모드가 미개설을 본다 |
| D10 | 완전성 주장 한 건을 **문서에서 뺐다** | 계획서 G7 문면대로 *"여덟 값 전부 쓰기 자리가 있다"* 를 싣기 | 그 주장을 무는 게이트가 계획서 열두 검사에 없다. CLAUDE.md §Acceptance *"완전성 주장은 그것을 검사하는 코드 없이 쓰지 않는다"* 에 걸린다. 문서는 대신 *"어느 낱말이 실제로 얼마나 쓰이는지는 이 문서가 세지 않는다"* 로 적고 분포 판정을 부록 정책에 넘긴다. 실측 자체는 아래 §관측 잔여에 남긴다 |

### 관측 잔여 — 계획서 §GROUND 와 실측의 차이

| 축 | 계획서 §GROUND | 이 구현의 실측 | 판정 |
|---|---|---|---|
| 소비 측 쓰기 자리의 이름 (G10) | *"함수 이름은 분석 실패다"* | 함수 이름은 `updateAuthFailOrderDetail` 로 **발행자와 같은 뜻(인증 실패)** 이고, 그 앞 행의 설명 주석이 `분석 실패 상태 업데이트` 다 | **G10 의 좌표가 한 칸 어긋났다.** 이름과 동작이 갈린다는 관측 자체는 성립하나 갈리는 자리는 식별자가 아니라 **설명 주석**이다. 문서는 실측대로 *"그 자리에 붙은 설명은 분석 실패라고 적는다"* 로 쓴다 |
| 주문상세 사전 불일치 (G9) | 여섯 값에 대해 하나도 일치하지 않는다 | 공통 코드값 여섯 건 전부 이름이 다르다 (`ODD001`~`ODD006`) | 일치 |
| 분석 타입 소비 측 초과 (G12) | 접미 붙은 값 · 서버에서는 주석으로만 등장하는 값 | 소비 측에만 있는 원소 여섯 건: `ANS003A` `ANS003B` `ANS004_2` `ANS004_5` `ANS014` `ANSCAR` | 일치. **덧붙여 발행 측에만 있는 원소가 한 건(`ANS003`) 실재한다** — 계획서가 명명하지 않은 방향이며 문서 기획 절에 *"반대로 발행 쪽에만 있고 화면 쪽에 없는 낱말도 있다"* 로 실었다 |
| admin 구독 라벨 (G11) | 같은 두 코드값에 다른 이름 · 발행자 이름은 필터 쪽과 같다 | `SUB003`·`SUB004` 두 건. 필터 목록이 발행자와 일치 | 일치 |
| 고객사 어휘 (G13) | 다섯 값 · `schema.ts:1110` nullable | `COD001`~`COD005` · 해당 칸 nullable | 일치 |
| 상태 칸 두 개 (G5) | `odd_state` notNull · `odd_final_state` nullable | 동일. 두 칸 모두 같은 `@IsEnum` 어휘로 선언된다 | 일치. D2 규칙이 두 칸을 자동으로 집는다 |
| 정의 앵커 prod 도달 (G20) | 미도달 교집합 0 | 앵커 38종 전건 도달 · `staged-only` 0건 | 일치 |
| 어휘 원소 총수 | (계획서에 없음) | `odd` 8 · `sub` 4 · `pay` 3 · `cod` 5 · `ans` 13 · 상태 칸 5 | **결속 집합이므로 검사 `#8` 이 물지만, 이 수치는 문서 문면에 리터럴로 싣지 않는다** — 문서가 드는 것은 값 집합이고 계수가 아니다(INV4·UI6) |
| 주문상세 낱말 참조 횟수 | G7 *"여덟 값 전부 쓰기 자리가 있고 쓰기 없는 값이 0"* | 동결 blob 의 `apps/**` 에서 멤버별 참조 횟수 6·5·6·8·8·11·7·3 (전건 1 이상) | **참조와 쓰기는 다르다.** 이 계수는 읽기 자리를 포함하며 쓰기만 가려내지 않았다. 어느 게이트도 물지 않으므로 문서 문면에 싣지 않는다(D10) |

### 하네스 자체의 결함 1건 — 봉인 라운드에서 잡혔다

첫 `check-all --expect complete` 가 `#1 FAIL: verify.sh 마지막 줄이 'check PASS' 가 아니다:
  ok  golden 대조 (헤더 + 페이로드)` 로 떨어졌다. **verify.sh 는 rc 0 이었다** — 뒤집은 것은
하네스 쪽이다.

원인: `verify.sh` 는 진행 `ok` 행을 전부 **stderr** 로 내고(`verify.sh` 2738·2749·2757·3112행)
최종 판정 `check PASS` 만 **stdout** 으로 낸다(3113행). 하네스가 두 스트림을 이어붙여 마지막
행을 봤기 때문에 stdout 뒤에 stderr 가 붙어 **마지막 행이 진행 행**이 됐다. Task 0 의 착수
실측이 통과한 것은 그때 `bash docs/_meta/verify/verify.sh --check` 를 셸에서 직접 돌려 두
스트림이 실시간으로 한 파일에 섞였기 때문이다 — 같은 명령이 두 소비 경로에서 다른 마지막 행을
낸다.

흡수: `runVerify` 가 **stdout 의 마지막 비어 있지 않은 행**만 보고 `check PASS` 와 정확히
같은지 대조하도록 고쳤다. stdout 이 비면 그것도 FAIL 이다 — 판정 행이 사라진 것이지 통과가
아니다.

이 결함은 층위 3(명령 ≠ 게이트)의 변종이다. 출력을 보긴 봤으나 **어느 스트림의 출력인지를
보지 않았다.** 종료코드만 보는 검사와 같은 부류이며, 계획서 §Validation 의 `# 기대:` 가
*"verify.sh 가 `check PASS` 로 끝나고"* 라고만 적어 스트림 축이 문면에 없었다.

### 음성 케이스 실측 (2026-08-27)

계획서 §Validation 의 `# 음성:` 중 `(구현 시 실측)` 으로 남아 있던 항목을 전건 실행했다.
각 프로브는 산출물을 되돌린 뒤 다음으로 넘어갔고, 마지막에 `git status` 로 복원을 확인했다.

| 검사 | 변이 | 관측 출력 | rc |
|---|---|---|---|
| `#3` 대상 집합 | 신설 문서를 lint 대상 밖으로 옮김 | `#3 FAIL: lint 대상 집합에 신설 문서가 없다 1건 — docs/03-contracts/04-state-transitions.md` | 1 |
| `#3` lint | 블록 HTML 주석 1행 추가 | `required-sections  블록 HTML 은 지원 문법 밖이다` + `no-placeholder  자리표시자가 남아 있다` 2건 | 1 |
| `#4` 앵커 | 앵커 행 번호를 파일 길이 밖으로 | `#4 FAIL: 토큰 맵 ↔ 문서 앵커 집합 불일치 — 문서에만: [insuniverse-server/drizzle/schema.ts:999999] / 토큰 맵에만: [insuniverse-server/drizzle/schema.ts:1634]` | 1 |
| `#4` 본문 인용 | 본문 인용 행 번호를 파일 길이 밖으로 | `#4 FAIL: 1건 — 본문 인용 행 초과 insuniverse-server/drizzle/schema.ts:999999 (… 파일 3114행)` | 1 |
| `#5` status | 본문 정책 하나를 `staged-only` 로 | `#5 FAIL: 2건 — 이 마일스톤이 쓰기로 한 status 밖이다 'staged-only' … · staged-only 정책이 1건이다` | 1 |
| `#6` 게이트 이름 | 게이트 이름 한 개 주입 | `#6 FAIL: 게이트 이름 누출 1건 — TREAT_PROVIDER (…:388)` | 1 |
| `#7` 에러 코드 | 오류 코드값 한 개 주입 | `#7 FAIL: 형제 축 값 누출 1건 — 에러 코드 E0304 (…:388)` | 1 |
| `#7` 상수명 | 수치 정책 상수명 한 개 주입 | `#7 FAIL: 형제 축 값 누출 1건 — 상수명 MAX_MONEY_AMOUNT (…:388)` | 1 |
| `#8` 누락 | 결속 집합에서 값 하나 제거 | `#8 FAIL: 1건 — odd_values 문서에 없는 발행값 ODD008` | 1 |
| `#8` 날조 | 결속 집합에 없는 값 하나 추가 | `#8 FAIL: 1건 — pay_values 발행에 없는 문서값 PAY004` | 1 |
| `#9` 누락 | 불일치 주장에서 코드 하나 제거 | `#9 FAIL: 1건 — admin-subscription-label 실측 차집합에 있는데 문서에 없다 SUB004` | 1 |
| `#10` 숫자 | 기획 절 서술에 아라비아 숫자 1건 | `#10 FAIL: 기획 절 코드 심볼 1건 — 숫자 리터럴 "2" (…:121)` | 1 |
| `#10` 코드 심볼 | 기획 절 서술에 코드 스팬 1건 | `#10 FAIL: 기획 절 코드 심볼 1건 — 코드 스팬 "\`odd_state\`" (…:121)` | 1 |
| `#11` 두 자리 | Task 6 이전 상태에서 `--expect complete` | `#11 FAIL: 상태 두 자리 불일치 표=4/in-progress 토큰=3/complete` | 1 |
| `#11` 기대 | Task 6 이후 상태에서 `--expect in-progress` | `#11 FAIL: 상태가 기대와 다르다 기대=in-progress 실측=complete` | 1 |
| `#12` 추출기 | `parseTsEnum` 의 0건 거부를 끔 | `parseTsEnum  good=ok empty=reject mutate=accept` + `--selfprobe FAIL: 1건` | 1 |

**`#4` 앵커 축의 출력이 계획서 예상과 다르다.** 계획서는 `#4 FAIL: 앵커 행 초과 …` 를 예상했으나
실제로는 **토큰 맵 양방향 결박이 먼저 터진다** — 토큰 맵의 키가 `<앵커>:<행>` 이라 행 번호를
바꾸면 집합이 먼저 어긋난다. 행 초과 분기는 토큰 맵 밖에 사는 **본문 인용**에서 도달하며 그
경로를 따로 실측했다(위 넷째 행). 두 분기가 다른 입력에서 각각 산다는 사실이 관측이다.

**`#11` 은 Task 6 전에 통과할 수 있는 상태가 없다.** 표 4행과 토큰이 함께 뒤집히기 전에는 두
자리가 정의상 어긋나 있다(표 = 마일스톤 4, 토큰 = 마일스톤 3). 계획서 §Validation 의 *"Task 6
전에는 `in-progress`"* 는 그래서 성립하지 않으며, 이 검사는 봉인 시점에 `--expect complete`
하나로만 돈다. 마일스톤 3 도 같은 형태였다.

### 리뷰 흡수 라운드 1 — `/mccp:code-review` (Local Review Mode, 2026-08-27)

봉인 뒤 미커밋 상태에서 돈 자문 리뷰다. 지적 10건 전건 수용했다. **계획서 본문은 고치지
않는다** — `mccp-plan-codex` receipt 의 `plan_hash` 가 그 본문에 결박돼 있어 흡수가 봉인을
stale 로 떨어뜨린다. 신설 검사 `#13`~`#15` 의 정본은 이 절이다.

| 라운드 | A | B | 층위 | 흡수 | 기각 |
|---|---|---|---|---|---|
| 1 | code-review(local) | — | 2 · 3 | 10 | 0 |

| # | 지적 | 층위 | 판정 | 반사실 |
|---|---|---|---|---|
| H1 | `적용 범위` 표 `state:analysis-type-is-not-a-state` × admin 이 `—` 인데 admin 이 조회 요청에 그 갈래를 실어 보낸다 | 2 | ABSORBED | `#13` 신설 · 셀 정정 |
| H2 | 같은 표 `state:external-projection-separate-vocabulary` × admin 이 `—` 인데 admin 이 대외 낱말을 코드값 그대로 읽는다 | 2 | ABSORBED | `#13` 신설 · 셀 정정 |
| M1 | 같은 표 site `—` 두 칸이 라벨 어휘 소비 자리를 놓친다 | 2 | ABSORBED | `#13` 신설 · 셀 정정 |
| M2 | 서비스 3열 27칸을 무는 게이트가 0건 | 2 | ABSORBED | `#13` 신설 |
| M3 | 산문의 완전성 주장 2건에 게이트가 없다 (D10 이 같은 부류를 뺀 뒤에도 남았다) | 2 | ABSORBED | `#14` 신설 |
| L1 | `연혁` 8행의 SHA·날짜를 어느 게이트도 실재에 대지 않는다 | 2 | ABSORBED | `#15` 신설 |
| L2 | `last_verified` 를 manifest head 와 대조하는 검사가 없다 | 2 | ABSORBED | `#15` 신설 |
| L3 | `claimEvidence` 가 사전 주석의 행 번호를 하드코딩해 토큰 맵과 정본이 둘이다 | 3 | ABSORBED | `tokenMapLine()` 도입 |
| L4 | `check-all` 이 `--expect` 없으면 rc 64 인데 `--help` 가 그 인자를 안 적는다 | 3 | ABSORBED | HELP 행 정정 |
| L5 | 리포트 §Assessment 의 `Files Changed` 실측이 5 인데 아래 표는 6행 | 1 | ABSORBED | 리포트 정정 |

#### `#13` 이 문 것 — 표의 `—` 아홉 칸이 전건 거짓이었다

리뷰가 지목한 넷(H1·H2·M1)보다 많다. 검사가 27칸을 돌자 `—` 로 적힌 **아홉 칸 전부**가
동결 트리에 반증됐다.

| 정책 | 열 | 문서 | 실측 |
|---|---|---|---|
| state:elapsed-time-forces-outcome | site · admin | `—` · `—` | 20파일 · 13파일 |
| state:subscription-lifecycle | site | `—` | 8파일 |
| state:payment-outcome-decided-outside | site | `—` | 4파일 |
| state:analysis-type-is-not-a-state | admin | `—` | 63파일 |
| state:external-projection-separate-vocabulary | site · admin | `—` · `—` | 3파일 · 7파일 |
| state:stored-distribution-unknown | site · admin | `—` · `—` | 21파일 · 13파일 |

**서비스 3열은 상수다.** 세 저장소가 다섯 어휘를 전부 만진다. 상수 열은 정보를 안 나르지만
거짓 `—` 보다는 낫고, 이제 게이트가 그 상수를 붙든다. 계층별 차이는 강제 지점 절이 든다.
가장 무거운 관측 하나는 site 가 대외 상태 칸을 읽어 **내부 진행 칸의 이름을 가진 자리에
넣는다**는 것이다 — 문서가 경고한 어휘 혼동이 코드에 실재한다. 기획 절에 판정 없이 실었다.

#### `#14` 의 첫 판정 규칙이 틀렸다 — 데코레이터 등장 ≠ 저장 칸

*"저장 정의 전체에서 이 종류 낱말을 담는 칸이 없다"* 를 `@IsEnum(ans*)` 등장 0건으로 물었더니
6건이 나왔다. 여섯은 **전부 조회 요청 DTO 의 파라미터 검증**(`analyze.dto.ts` 95·134·154행 ·
`client-analyze-admin.dto.ts` 90·129·148행)이고 저장 칸이 아니다.

되짚기 경로를 `stateColumns()` 와 **같게** 고쳤다 — 속성을 snake 로 바꿔 스키마 컬럼 집합에
실재하는지 본다. 결박 속성 6건 중 스키마 칸 0건이 실측이고 그것이 문서 주장과 같다. 층위 6
(게이트가 보는 대상)의 자기 사례이며, 검사를 먼저 돌리지 않았으면 문서 문면을 잘못 고쳤다.

#### 음성 케이스 실측 (2026-08-27)

| 검사 | 변이 | 관측 출력 | rc |
|---|---|---|---|
| `#13` | `소비` 한 칸을 `—` 로 | `#13 FAIL: 1건 — state:subscription-lifecycle × site '—' — 실측은 '소비' 다 (동결 트리 8파일, 행 323)` | 1 |
| `#13` | 프론트매터에 없는 표 행 1개 추가 | `#13 FAIL: 2건 — 프론트매터에 없는 표 행 state:fabricated-row · 정책 state:fabricated-row 의 어휘 축이 하네스에 없다` | 1 |
| `#14` | 완전성 주장 문장을 완화 | `#14 FAIL: 1건 — 문서에 '진입 유일성' 주장이 없다 — 검사가 대표할 문장이 사라졌다` | 1 |
| `#15` | 연혁 날짜 1행 변조 | `#15 FAIL: 1건 — 12bc68b7 의 날짜가 2024-12-03 인데 표는 2024-12-04 다 (insuniverse-server, 행 397)` | 1 |
| `#15` | `last_verified` 변조 | `#15 FAIL: 1건 — last_verified '0000000' 가 manifest head 0건에 걸린다 — 1건이어야 한다` | 1 |

각 프로브는 산출물을 되돌린 뒤 다음으로 넘어갔고 `git diff --stat` 으로 복원을 확인했다.

#### 남은 사각지대 — 출력에 드러낸다

- `적용 범위` 표의 **actor 5열**은 여전히 미검증이다. 요청 주체의 권한 모델을 동결 트리에서
  되짚는 경로가 이 조사에 없다. `#13` 의 출력이 그 사실을 매번 찍는다.
- 관리자 화면 쪽 분석 종류 목록이 발행 쪽과 어떻게 다른지는 되짚지 않았다. `#13` 은 등장
  여부만 보고 차집합은 만들지 않는다. 문서 기획 절에 그 한계를 적었다.
- **`check1` 서브커맨드 자체는 이 세션에서 완주시키지 못했고, 세 축은 각각 확인했다.**
  `check1 --mode seal` 이 두 번 잘렸다 — 10분 타임아웃 · rc `4294967295`(프로세스 킬).
  양성 프로브(`bash verify.sh --help` → rc 2 + usage)로 도구 부재가 아님을 갈랐다. 원인은
  이 세션의 부하(node 103 · bash 27 프로세스)이며 `verify.sh --check` 한 번이 40분 가까이
  걸렸다.

  | `#1` 의 축 | 확인 수단 | 결과 |
  |---|---|---|
  | 서브모듈 3종 동결 ↔ manifest ↔ golden | 하네스 `parseManifestHeads` · `parseGolden` 으로 재유도 | 3/3 일치 |
  | golden 바이트 ↔ 착수 스냅샷 | `cmp` | 동일 (105행) |
  | findings 미개설 | `test -e` | 미개설 |
  | `verify.sh --check` | 직접 실행 (분리 로그) | **rc 0 · stdout 마지막 판정 행 `check PASS`** |

  **한 번 오독했다.** 실행 직후 출력 파일이 0바이트인 것을 보고 "세 번 다 잘렸다" 로 적었다.
  파일은 그때 막 열려 비어 있었을 뿐이고 40분 뒤 `check PASS` 로 끝났다. 진행 중인 로그의
  크기 0 은 실패의 증거가 아니다 — 종료 알림을 받고 읽어야 한다.

  세 축을 각각 확인한 것과 `check1 --mode seal` 한 명령이 통과하는 것은 **같지 않다.** 축의
  합성(순서·조기 반환)은 그 명령 안에만 있다. 다음 세션에서 부하가 낮을 때 한 번 돌린다.

### 게이트 실행 기록

| 시점 | 명령 | 결과 |
|---|---|---|
| 착수 | `bash docs/_meta/verify/verify.sh --check` | rc 0 · 마지막 줄 `check PASS` (셸 직접 실행 — 두 스트림이 섞인 로그) |
| 착수 | `cp docs/_meta/verify/golden.txt .claude/notes/…m4.golden-baseline.txt` | 105행 스냅샷 |
| 저작 후 | `check2` · `check12` | 서브커맨드 집합 일치 · 추출기 21종 전건 거부 |
| 저작 후 | `check3`~`check10` | 전건 ok |
| Task 6 후 | `check11 --expect complete` | `마일스톤 4 = complete · 상태 토큰 = 4/complete` |
| 봉인 1회차 | `check-all --expect complete` | **`#1 FAIL`** — 하네스의 스트림 오독 (위 §하네스 자체의 결함) |
| 봉인 2회차 | `check1 --mode baseline` · `check-all --expect complete` | 아래 §최종 출력 |
| 리뷰 흡수 | `check2`~`check11` · `check13`~`check15` · `--selfprobe` | 전건 rc 0 · 추출기 23종 |
| 리뷰 흡수 | 음성 5건 (`#13`×2 · `#14` · `#15`×2) | 전건 rc 1 · 산출물 바이트 복원 확인(`cmp`) |
| 리뷰 흡수 | `check1 --mode seal` | 서브커맨드 미완주 (부하로 2회 잘림) — 세 축은 각각 확인. 세부는 위 §남은 사각지대 |
| 리뷰 흡수 | `bash docs/_meta/verify/verify.sh --check` | rc 0 · stdout 마지막 판정 행 `check PASS` (약 40분) |

**`check1 --mode baseline` 은 봉인 2회차에서 처음 돌았다.** 착수 시점의 기준선 실측은 셸에서
`verify.sh --check` 를 직접 돌리고 golden 을 손으로 스냅샷하는 형태였다 — 하네스의 baseline
모드는 그 시점에 존재하지 않았다(Task 1 이 Task 0 뒤다). 두 모드가 같은 판정을 낸다는 사실은
2회차에서 확인한다.

### 최종 출력

`check1 --mode baseline` 과 `check-all --expect complete` 의 출력은 이 절 아래에 그대로 옮긴다.

```
### baseline
#1 ok  서브모듈 3/3 동결 일치 · lint glob .md 19건 · golden 스냅샷 105행 보유 · check PASS
BASELINE_RC=0
### check-all
#1 ok  서브모듈 3/3 동결 일치 · lint glob .md 19건 · golden 무변동 · findings 30-contracts-limits 미개설 · check PASS
#2 ok  서브커맨드 집합 일치 (--help · check1..check12 · check-all · --selfprobe) · unknown 거부
#3 ok  lint 대상 19건에 신설 1건 포함 · 위반 0
#4 ok  앵커 43건 전건 해석 (server 4d798f5 · site 767d1e4 · admin fb001e1) · 고유 38건 토큰 맵 전건 일치 · 본문 인용 61건 (고유 위치 38) 전건 해석
#5 ok  active-prod 8건 전건 도달 · data-dependent-unknown 1건 사유 보유 · staged-only 0건
#6 ok  known_gates 15종 재열거 · 신설 문서 1건 등장 0
#7 ok  상수명 54종 재열거 등장 0 · 에러 코드 패턴 ^E[0-9]{4}$ 매치 0
#8 ok  어휘 6축 집합 일치 (원소 38건 · 출처 동결 blob · 인덱스 미독)
#9 ok  불일치 주장 5건 양측 실측 일치 (원소 18건 · 발행≠소비 확인)
#10 ok  정책 (기획)·부록 서술 코드 심볼 0 · 아라비아 숫자 0 (서술 78행)
#11 ok  마일스톤 4 = complete · 상태 토큰 = 4/complete
--selfprobe 추출기 호출부
  parseGolden              good=ok empty=reject mutate=reject
  parseManifestHeads       good=ok empty=reject mutate=reject
  parseUnreached           good=ok empty=reject mutate=reject
  parseKnownGates          good=ok empty=reject mutate=reject
  parseConstantNames       good=ok empty=reject mutate=reject
  parseErrorPattern        good=ok empty=reject mutate=reject
  parseStatusPlacement     good=ok empty=reject mutate=reject
  parseTsEnum              good=ok empty=reject mutate=reject
  parseTsUnionType         good=ok empty=reject mutate=reject
  parsePropUnion           good=ok empty=reject mutate=reject
  parseNameCodeMap         good=ok empty=reject mutate=reject
  parseCaseReturnMap       good=ok empty=reject mutate=reject
  parseOptionValueMap      good=ok empty=reject mutate=reject
  parseIsEnumProps         good=ok empty=reject mutate=reject
  parseSchemaColumnNames   good=ok empty=reject mutate=reject
  parsePolicies            good=ok empty=reject mutate=reject
  parseSections            good=ok empty=reject mutate=reject
  parseMilestoneStatus     good=ok empty=reject mutate=reject
  parseStatusToken         good=ok empty=reject mutate=reject
  parseStatusTokenMilestone good=ok empty=reject mutate=reject
  parseLintGlobs           good=ok empty=reject mutate=reject
--selfprobe ok  추출기 21종 · empty=reject mutate=reject 전건
RC=0
```
