# Implementation Report: 사실 인덱스 · 코드 축 — 마일스톤 5a-fix (테스트 축 판정 정본 교정)

**Plan**: `.claude/plans/insuniverse-docs-11-index-code-m5a-fix.plan.md`
**Notes**: `.claude/notes/insuniverse-docs-11-index-code-m5a-fix.md`
**Branch**: `feat/index-code`

## Summary

5b 게이트가 실코드 대조로 재현한 5a 계약 결함 3종을 닫았다.

- **A 앵커** — 검증기에 블록 스칼라 헤더 파서(`readRunBlock`)를 두고, 실행 토큰 검사를 앵커 한 행에서
  **그 `run:` 블록의 본문 span** 으로 넓혔다. 접기는 하지 않는다(`foldBody` 단독 소유). `checkAnchor` 무변경.
- **B 스타일** — wire 스키마를 **늘리지 않고** `rescanInvocations` 독립 재열거 + 레코드 집합 정확 대조로 닫았다.
  스타일 오독 · 명령 바꿔치기 · dispatcher 체인 위조가 **같은 대조 하나**에서 갈린다.
- **C 잔여 결속** — `resolveInvocationContext` 반환을 `{record, typed_residues}` 로 가르고, 잔여를 `bind` 로
  discriminated 했다. 판정식은 `blocks(r, inv)` 하나이고 `governs` 는 제어흐름 경로다. `run_in_ci` 는 호출 단위.

## Assessment vs Reality

| Metric | Predicted (Plan) | Actual |
|---|---|---|
| Complexity | Medium | **High** — 재열거 대조가 저장소 **전체**를 보므로 기존 픽스처 저장소를 재열거와 일치시키는 재구성이 필요했다 |
| Files Changed | 6 (그중 PRD 1건은 계획 시점에 이미 반영) | 5 (구현) + 3 (게이트 산출물) |
| 픽스처 | 12종 신설 | 12종 신설 + 기존 99종 유지 → 111종 |

## Tasks Completed

| # | Task | Status | Notes |
|---|---|---|---|
| 1 | 어휘 확장 (`tests-vocab.mjs`) | 완료 | `unsupported_construct_kind` size **8→10**(손으로 고침) · `residue_bind` 신설 |
| 2 | `resolveInvocationContext` 반환 분할 (`tests-hop.mjs`) | 완료 | `{record, typed_residues}` · `record` 6키 불변 · `CONTRACT_VERSION = 2` |
| 3 | 검증기 — 독립 재열거 + 앵커 span (`verify-tests.mjs`) | 완료 | 아래 「Deviations」의 `governs` 확장 1건 포함 |
| 4 | 픽스처 12종 | 완료 | `F-a1` · `F-r1~F-r5` · `F-c1~F-c6`. **A61 유지** |
| 5 | 5b 가 쓸 capability | 완료 | `CONTRACT_VERSION` + `--selftest-probe` 3종. 5b 계획·receipt 는 **건드리지 않았다** |
| 6 | 어휘 정본 표 · PRD · findings | 완료 | `VOCAB-TABLE` 재생성 · PRD `5a-fix` 행(5a 는 `complete` 그대로) · 발견 38~40 |

## Validation Results

계획 `## Validation` 블록 전항을 그대로 돌렸다.

| Level | Status | Notes |
|---|---|---|
| selftest | PASS | 픽스처 **111건** 실행 (기존 99 + 신설 12) |
| 픽스처 12종 id 확인 | PASS | 개수가 아니라 **id 로** 확인 |
| 어휘 정본 표 동기 | PASS | 계획 마커 ↔ `--print-vocab-table` 정확 일치 |
| capability probe(키) | PASS | `CONTRACT_VERSION >= 2` · `record` 6키 · `typed_residues` 배열 |
| 동작 probe 3종 | PASS | `rescan-catches-style-tamper` · `rescan-catches-residue-omission` · `container-residue-channel-conditional` |
| 회귀 3종 selftest | PASS | `verify-code-index` · `verify-policy-values` · `verify-schema-constraints` |
| 어휘 사본 부재 | PASS | `tests-vocab.{cjs,json}` 0건 |
| doc lint | 기존 위반 1건 | `frontmatter-parse` — **HEAD 에서도 동일**(파일 자체가 잠정 형식). 이 편집이 낸 것이 아니다 |

### 반증 변이 시험 — 픽스처가 공허하지 않다는 증거

가드를 하나씩 지우고 selftest 를 돌려 **정확히 그 픽스처만** 붉어지는지 봤다. 가드만 넣고 픽스처가
공허하면 다음 편집이 그것을 조용히 되돌린다 — 이 파일이 반복해서 밟은 자리다.

| 변이 | 붉어진 픽스처 |
|---|---|
| 블록 span → 앵커 한 행 (옛 동작) | `F-a1` **하나만** — 인라인 경로 무회귀가 여기서 증명된다 |
| `governs` → 항상 참 (파일 공존 기준) | `A1` · `F-c4` · `F-c6` |
| `run_in_ci` → 저장소 단위 거부 (옛 동작) | `F-c1` · `F-c2` 포함 39건 |
| 잔여 집합 대조 제거 | `F-r5` **하나만** |
| 레코드 6키 대조 → id 존재만 (부분집합) | `F-r2` · `F-r3` · `F-r4` — 위조 셋이 한 대조에 걸려 있다 |
| kind→허용 bind 표 무력화 | `F-c5` |
| container 예외 → 무조건 면제 | `F-c3` |
| orphan `invocation_id` 검사 제거 | `F-c5` |

## Files Changed

| File | Action | Notes |
|---|---|---|
| `docs/_meta/verify/tests-vocab.mjs` | UPDATED | 어휘 2값 + 어휘 1종 |
| `docs/_meta/verify/tests-hop.mjs` | UPDATED | 반환 분할 · `CONTRACT_VERSION` |
| `docs/_meta/verify/verify-tests.mjs` | UPDATED | 파서 · 재열거 · 결속 판정 · probe · 픽스처 |
| `docs/_meta/findings/11-index-code.md` | UPDATED | 발견 38~40 |
| `.claude/plans/insuniverse-docs-11-index-code-m5a-fix.plan.md` | UPDATED | `VOCAB-TABLE` 블록만 |
| `.claude/notes/insuniverse-docs-11-index-code-m5a-fix.md` | CREATED | 게이트 리뷰 기록 |
| `.claude/plans/codex-findings-backlog.md` | UPDATED | 이월 3건 |
| `.claude/receipts/mccp-implement-codex/…json` | CREATED | 게이트 receipt |

**건드리지 않았다**: `verify-code-index.mjs`(`checkAnchor`) · `jsonl-doc.mjs` · `m5a-r2.plan.md` ·
`m5b-r2.plan.md` 와 그 receipt · `extraction-manifest.yaml` · 3저장소.

## Deviations from Plan

1. **`governs` 에 `needs:` 전이 선행 job 을 더했다** (Implement-Codex R1 F3 흡수). 계획 112행은 "다른 job
   이면 거짓" 이라고만 적었는데, `A2~A4` 가 계약으로 적어 둔 "`needs:` 로 닿는 job" 의 미해석 선행이 그
   문장으로 통째로 면제됐다 — 상류 불확실성을 버리고 하류 호출을 확정하는 경로다. Acceptance 가 FAIL
   로 못박은 셋(step 내부 면제 · 파일 공존 · 호출 뒤 차단)은 어느 것도 건드리지 않는다.
2. **`source` 잔여 앵커의 토큰을 kind 별 표로 뒀다**(`RESIDUE_ANCHOR_TOKENS`). 계획은 "`anchorCheck` 를
   통과" 라고만 적고 토큰을 지정하지 않았다. 호출 토큰(`run`/`uses`/`test`)을 요구하면 Dockerfile `FROM`
   위의 정직한 container 잔여가 거부된다. 기호 토큰(`&`)은 단어 경계 대조에 안 걸려 **거부**되는데,
   거짓 수용보다 거짓 거부가 낫다는 방향을 택했다.
3. **재열거는 source 결속 잔여 중 `preceding_action_unresolved` 만 낸다.** `yaml_anchor`·`yaml_alias` 는 이
   행 스캐너의 자기 사각이고(이월), `matrix_expansion`·`expression_interpolation` 은 `literalDir`·
   `classifyStepCondition` 이 이미 **호출 결속**으로 같은 결손을 내므로 source 로 또 내면 두 번 실린다.
4. **selftest 픽스처 저장소를 재구성했다.** 재열거 대조가 저장소 전체를 보므로 기본 문서가 재열거
   결과와 글자 그대로 같아야 한다 — `package.json` 2개 추가(dispatcher 체인 종결) · 미끼 워크플로를
   `.github/samples/` 로 이동 · 기본 증거를 호출 2건으로 · CI 구조 픽스처(`A1~A4`·`A27`·`A28`·`F-*`)는
   **자기 저장소를 짓는다**. `A2~A4` 는 앞판에서 **같은 문서**를 라벨만 셋으로 갈라 돌리고 있었다 —
   이제 워크플로 구조가 답을 가른다.
5. **`F-b2`·`F-b3` 는 만들지 않았다.** 계획 `Risks` 표가 그 둘을 언급하지만 `Tasks`·`Acceptance` 가
   요구하는 12종 목록(`F-a1`·`F-r1~F-r5`·`F-c1~F-c6`)에 없다 — R4 설계 전환 전 초안의 잔존 참조다.

## Issues Encountered

- **`plan-conflict-detector` 가 오탐을 낸다.** `file-expansion` 으로 `conflict:true` 가 나왔으나, 원인은 계획
  `Files to Change` 표 셀의 **백틱을 안 벗기는** 것이다 — 같은 입력에 백틱을 붙여 넘기면 `conflict:false`.
  실제 파일 확장은 **0건**이고 변경 파일 전부가 계획 표 안이다. 모듈 자체 주석이 "오탐이 정당한 작업을
  멈춘다" 며 보수적 판정을 원칙으로 적고 있으므로 escalate 하지 않고 backlog 로 올렸다.
- **`security-reviewer` 미가동.** 계획 UI7 과 세션 규칙이 Agent 도구를 금지한다. receipt 를
  `security_skipped=true` 로 봉인했고, 그 결과 이 receipt 는 `/mccp:pr` 에서 **non-approving** 이다.

## Tests Written

별도 러너를 들이지 않는다 — 전부 `verify-tests.mjs --selftest` 인라인 픽스처다(Mirror 규율).

| 위치 | 픽스처 | 덮는 것 |
|---|---|---|
| `verify-tests.mjs --selftest` | `F-a1` | 결함 A — 앵커 span (재열거와 독립) |
| 〃 | `F-r1~F-r5` | 재열거 정확 대조 — 거짓 양성 0 · 스타일/명령/체인 위조 · 잔여 누락 |
| 〃 | `F-c1~F-c6` | 결함 C — 호출 단위 양화 · container 채널 조건부 · `governs` 경로 대칭 · `bind` 결속 검증 |
| `verify-tests.mjs --selftest-probe` | 3종 | 종료 코드로 **동작**을 증명 (상수만 올린 부분 구현 차단) |

## Next Steps

- [ ] **`/mccp:santa-loop`** — `STATE.md` 의 escalation 과 `fix-task` 가 대기 중이고, Implement-Codex verdict 도
      `divergent` 다. 이 교정을 봉인하려면 그 이중 리뷰를 거쳐야 한다
- [ ] 5b 소유 **후속 계획** — `0-e` preflight 가 `CONTRACT_VERSION >= 2` · 픽스처 id 12종 · probe 3종을
      fail-closed 로 물게 하고, 재사용 워크플로 id 충돌(이월 HIGH)을 **필수 선행**으로 닫는다
- [ ] PRD `5a-fix` 행은 **`in-progress` 로 남겼다** — escalation 이 열려 있는 동안 `complete` 를 찍지 않는다
- [ ] 계획은 **아카이브하지 않았다** — 두 receipt 가 그 경로의 `plan_hash` 에 결속돼 있고 Validation 블록도
      그 경로를 인용한다. 옮기면 완료 증거가 끊긴다
