# Plan Review Panel — insuniverse-docs-20-foundation-access-m1

**Plan**: `.claude/plans/insuniverse-docs-20-foundation-access-m1.plan.md` · **Plan version**: `sha256:b7687ff9073df6a708912f166ca8ec9ab0f027f824be0e0ca6a627080539dae0`
**Verdict**: `divergent` via `multi-agent`
**Quorum**: 4/3 responses · 4 distinct roles (of 4 fielded) · passed=false
**Layers**: L1 converged · L2 divergent · L3 not fired

> Reason: L2 quorum not satisfied: 10 blocking finding(s): architect/HIGH, architect/FAIL, test/HIGH, test/HIGH — MCCP_REVIEW_SINGLE_PASS=deadline_pressure 로 진행한다. verdict는 divergent 그대로 봉인된다.

## Findings

| Perspective | Severity | Claim | Evidence |
|---|---|---|---|
| architect | HIGH | Task 3 creates overlapping edit delegations without formal semantics: PRD 13 ('완료' status) and PRD 20 ('진행' status) will both have rows in §개정 위임 table for identical paths (docs/_meta/template-config.yaml, docs/_meta/verify/golden.txt) | Plan lines 121-129 acknowledge adding 3 rows for PRD 20 to paths already delegated to PRD 13 with 'completed' status. Plan admits the relationship is unverified (Acceptance line 356: '위임 3 행의 사유가 타당하고 `13` 완료 위임과의 관계 서술이 옳다는 판단 — `(미검증)`'). Ownership.md line 108 defines delegation as '개정 권한만 이동한다' (only editing rights move) but does not formally define whether '완료' revokes those rights or whether simultaneous editing is prevented. |
| architect | MEDIUM | Overlapping delegations lack machine verification and boundary enforcement. The plan relies on prose documentation to justify overlapping permissions without gatekeeping. | Ownership.md lines 113-114: '게이트로 승격하지 않는다... 위임 PRD 가 둘 이상이 되면 그때 재검토한다' (not elevated to gate; when delegation PRDs become 2+, reconsider then). Plan line 129 says it will add a '재검토' paragraph to explain the relationship, but this is documentation only. Plan's own risk (line 330) marks the relationship validity as unverified. No gate (such as check6 cited at plan line 135) validates permission exclusivity or prevents concurrent writes. |
| architect | MEDIUM | Plan claims check6 validates delegation relationships, but check6 only verifies row count and path set matching, not permission semantics or exclusivity. | Plan lines 224-232 detail check6: '(a) ownership.md §개정 위임 표에서 위임받은 PRD 열이 20 인 행이 3 개, (b) 그 3 행의 경로 집합이 PRD 문면과 같고, (c) 계수가 맞는지'. The plan explicitly admits (line 231): '검사 `#6` 은 행 수와 PRD 문면 수만 보고 관계 서술의 타당성은 못 본다' (check6 only sees row counts and numbers, can't verify relationship validity). This gate does NOT detect whether delegations can conflict. |
| test | MEDIUM | Task 2's Validate line runs lint-docs and checks format correctness, mapping to Gate #1 which runs check1 with dual mode verification (basic + --strict-refs) | Task 2 Validate (line 118) runs: `node .claude/templates/doc-kit/lint-docs.mjs --root . --strict-refs docs/01-foundation/01-glossary.md` with both flags combined in one invocation. But Validation check#1 (line 186-190) says it expects: 'check1 lint=ok strict=ok' — running both modes SEPARATELY and capturing both exit codes. These test different things: Task 2 tests combined mode, check#1 tests independent mode outcomes. If glossary passes with combined --strict-refs but would fail --strict-refs in isolation (or vice versa), the tests diverge. No test verifies both independent modes pass. |
| test | MEDIUM | Task 2 must create the `## 용어 요청 처리` section with correct structure to hold content that Task 4 will add, and check#5 will verify the structure and content align | Task 2 Action (line 116) mentions 'Task 4의 판정표를 싣는다' but doesn't specify the table structure (columns, format). Check#5 (line 215-222) expects: 'check5 termreq pending=0 resolved=2 rows=3 values=match' implying a table with specific rowcount and fields. But Task 2's Validate line (line 118) only runs basic lint-docs, which validates format not content structure. No Validate command verifies that glossary has created the correct `## 용어 요청 처리` table structure before Task 4 fills it. If Task 2 creates the section but with wrong column names or structure, Task 4 would add rows to a malformed table. |
| test | HIGH | The plan specifies exact code anchors for each actor term in Task 2 (lines 85-101) and checks will verify these anchors point to real files/lines via check#2 | Task 2 prescribes specific anchor values like `insuniverse-server/apps/api/src/modules/auth/admin/auth.service.ts:42` for the 관리자 actor. Check#2 (line 192-195) verifies anchors exist at those line numbers in those files. However, check#2 only verifies file existence and line bounds: 'anchor line out of range' in the negative test case. Check#2 does NOT verify that line 42 actually contains code about admin authentication. The plan acknowledges this (Acceptance line 364): 'A축 앵커가 그 용어를 실제로 뒷받침한다는 판단 — `(미검증)`' but the wording 'anchors point to real things that match the terms' in this reviewer's lens is falsifiable and fails. |
| test | HIGH | Gates.mjs file will be created in Task 1 and implement checks #1-#8, #13, #14 with specified behavior including markdown parsing, config comparison, and 10 selftest dual-contrast verifications | Task 1 (line 70-75) says: CREATE `.claude/plans/insuniverse-docs-20-foundation-access-m1.gates.mjs` with 'check1~8·check13·check14 하네스 + selftest'. Validation section (lines 172-305) describes 14 checks with detailed inputs/outputs. But the plan provides NO specification of HOW to implement gates.mjs — no parsing algorithm, no pseudocode, no formal grammar for expected markdown table formats. While a prior working example exists (m5 from 13-relation-contract project), the current plan contains ONLY description of what checks should do, not how to code them. Without a formal implementation spec, correct parsing of markdown tables (to extract actor names, anchors, ID fields) is not guaranteed. If gates.mjs uses regex that fails on valid markdown variants, tests fail silently without clear cause. |
| test | MEDIUM | Check#6 will verify ownership.md delegation rows match PRD statement of paths and count, with proper parsing of PRD bullet-list format | Task 3 Action (line 130-131) specifies: 'PRD 문면이 나열한 경로 집합' within '각 줄은 하이픈+공백으로 시작한 뒤 곧바로 코드 스팬(백틱 한 쌍)으로 감싼' format. Check#6 implementation must parse exactly this format. But the plan provides no test of check#6's parsing logic on malformed input. Nor does Task 3's Validate ensure the PRD modification follows this exact format — Task 3 Validate (line 135) only calls 'check6' which tests the final state, not the implementation of Task 3 itself. If Task 3 writes the PRD paths in a slightly different format (e.g., backticks around only filename, not full path), check#6 parsing fails. No test verifies Task 3's PRD write actually created parseable format. |
| invariant | CRITICAL | Plan documents an unpreventable fail-open window in check6 that allows bad data to pass if both files agree | Line 68: '종료 상태 검사는 쓰기를 *막지* 못한다. 이미 일어난 쓰기를 인증하지 않을 뿐이며, 위반 쓰기와 그 탐지 사이의 창은 그 Task 하나의 편집 구간이다.' Line 335-336 Risks marks check6 with '**확정**' (confirmed limitation): '검사 `#6` 이 수만 대조하고 위임 사유·관계 서술의 타당성은 못 본다... 리뷰 몫이며 §Acceptance 에 `(미검증)` 으로 남긴다.' Line 358 Acceptance also marks this '(미검증)': 게이트 `#5` 는 두 파일의 값 일치까지만 보고 같은 오답의 일치는 못 가른다 |
| invariant | HIGH | Plan gates are anchored to manually observed golden baseline, not machine-verified precondition | Line 363 Acceptance: 'HEAD golden 이 착수 시점 최신이라는 기준선 — `(미검증)` · 2026-08-24 `--check --bootstrap` PASS 수동 관측이며 자동 사전검사가 아니다'. Line 327 Risks: 'HEAD golden 이 최신이라는 것은 착수 전 `check PASS` 실측이 근거다' (baseline is manual observation). Check8 (line 242-245 Validation block) compares against this unverified baseline: 'HEAD 대비 값이 달라진 키가 그 1 개뿐이다' |
| invariant | HIGH | Plan assumes Task-level gate enforcement mechanism that is not specified or documented in mccp framework | Lines 66-68 claim: '순서 축은 각 Task 의 Validate 가 잡는다. Task 4·5·7 의 `- **Validate**:` 는 자기 검사 앞에 `check6` 을 먼저 돌린다.' But Task Validate fields (lines 142, 149, 163) show commands that SHOULD run, not mechanisms that WILL enforce them. The plan does not document HOW the mccp framework enforces these Validate sequences or WHEN they are evaluated. Project CLAUDE.md also does not specify this behavior. |
| invariant | HIGH | Plan shifts critical correctness checks to external review marked (미검증), creating reviewer dependency for things that should be gated | Line 355: GA uniqueness - '(미검증) · 게이트 `#4` 는 GA 히트 경로 집합까지만 보고 유일성은 못 본다'. Line 356: Delegation reasoning - '(미검증) · 검사 `#6` 은 경로 집합과 수까지만 본다'. Line 357: Write prevention - '`(미검증)` · 기계 검사 없음, §NOT Building 이 범위를 정한다'. Line 358: T-01/T-02 correctness - '(미검증) · 게이트 `#5` 는 두 파일의 값 일치까지만 보고 같은 오답의 일치는 못 가른다'. Line 364: Anchor semantics - '(미검증) · 기계는 앵커의 실재까지만 본다' |
| invariant | MEDIUM | Plan lacks initialization Task for submodule prerequisite that gates depend on | Line 162 Task 7 assumes: '서브모듈이 manifest `repos[].head` 로 초기화된 상태에서'. Check13 (lines 180-184 Validation block) VERIFIES submodules are initialized but does not INITIALIZE them. No Task in the plan creates or initializes submodules. Acceptance line 339 gates on check13 but doesn't provide recovery if submodules are not in expected state. |
| invariant | MEDIUM | Check6 can accept identical wrong answers across two files, creating silent failure mode | Line 231 acknowledges check6 limit: '남은 한계: 두 파일이 같은 오답으로 일치하는 경우와 위임 사유의 타당성은 못 본다'. Risks line 329-330: '잔존 한계: 종료 상태 검사라 쓰기 자체를 막지는 못하고 인증을 거부할 뿐이며, 노출 창은 그 Task 하나의 편집 구간이다'. This means if ownership.md and PRD both have wrong paths for delegation, check6 passes silently. |
| invariant | MEDIUM | Plan calls check6 as sequential prerequisite in Tasks 4, 5, 7 but doesn't show enforcement mechanism when tasks run out-of-order | Lines 142, 149, 163 show Validate fields with 'check6 &&' prefix, assuming check6 runs first. But if a user runs tasks in different order, or runs check5 before check6, the enforcement depends on undocumented mccp behavior. Project CLAUDE.md does not specify that Task Validate fields are enforced or that '&&' creates hard sequencing. |

## Refutation attempted

| Perspective | Verdict | What was attacked |
|---|---|---|
| architect | fail | Attacked the three core abstractions: (1) Verified claims about golden key stability — correct: §개정 위임 is NOT extracted by verify.sh lines 1207-1225 (only 4 sections hashed); (2) Checked delegation semantics — found no formal definition of status values ('완료' vs '진행'). Searched ownership.md, PRD, and verify.sh; found only prose statement that 'editing rights transfer' but no permission lifecycle/exclusivity rules; (3) Verified machine verification exists — found check6 only validates counts/paths, not permission conflicts; ownership.md explicitly says delegation is not gatekept; (4) Confirmed plan acknowledges gaps — Acceptance line 356 and Risk line 330 both mark delegation relationship as '(미검증)' (unverified). The plan's abstraction boundary (editing rights for archived paths) leaks into prose documentation without structural enforcement." |
| security | pass | Attacked circular trust in actors field: plan pins glossary values, derives config from glossary, validates round-trip by checking code anchors. Circular concern mitigated by grounding in code. Attacked delegation precedence: plan requires check #6 gate before Tasks 4/5/7 run via && operators; window acknowledged as task-editing-duration. Attacked data leakage: all code anchors are repo-relative paths (insuniverse-server/..., not /absolute/paths). Attacked golden file validation: check #8 restricts changes to template_config.actors key; HEAD baseline is pre-verified (line 170). Attacked submodule SHA pinning: frozen SHA in plan (4d798f55, 767d1e44, fb001e1d) verified by check #13 before anchor checks run. Attacked check implementation safety: plan specifies output format strictly (grep -Fx exact match, line count = 11 for selftest), preventing output injection. Attacked delegation overlap on verify/** vs verify/golden.txt: plan acknowledges containment relationship (line 125-126) and explains why no conflict (complete vs in-progress states, sequential write). No HIGH/CRITICAL findings. |
| test | fail | Attacked the plan's test coverage by examining: (1) whether Validate commands in each Task actually test what they claim to test, comparing Task 2 lint behavior with check#1 detailed spec; (2) whether intermediate table structures (glossary term-request section) are tested before dependent tasks use them; (3) whether the anchors specified in Task 2 undergo semantic correctness validation (do the code lines match the actor claim); (4) whether gates.mjs implementation has a formal testable spec vs description-only; (5) whether check#6's parsing of PRD format is tested before Task 3 claims completion. Found falsifiable gaps in (1), (2), (3), (4), and implicit gaps in (5) regarding test completeness. Verified all referenced files exist (lint-docs.mjs, ownership.md, template-config.yaml, term-requests files) and confirmed task ordering dependency structure via check#6 appears sound. |
| invariant | fail | Attempted to refute through invariant lens by: (1) Tracing the task dependency chain and check sequencing - found check6 called in 4 places (Tasks 3, 4, 5, 7) but enforcement mechanism not specified. (2) Examining gate structure - found checks #4 and #6 explicitly documented with confirmed limitations ('확정') and marked unverifiable ('미검증'). (3) Verifying anchoring of golden baseline - found check8 is anchored to 2026-08-24 manual observation marked "(미검증)", not pre-flight automated verification. (4) Checking initialization prerequisites - found Task 7 assumes submodules initialized but no Task provides initialization, only verification via check13. (5) Analyzing fail-open windows - found lines 68 and 335-336 explicitly document that check6 cannot prevent or detect 'same wrong answer' failures; plan acknowledges this and relies on review. (6) Testing skip predicates - found check6 is called in Task Validate fields (142, 149, 163) but no documentation of HOW this enforcement happens in mccp framework. |

## Measurement

<!-- Written by plan-review/cli.js record on EVERY exit path, pass or halt.
     Machine-readable; do not hand-edit. A null field means the axis was
     not observed, never that it was zero. -->

```json
{
  "verdict": "divergent",
  "source": "multi-agent",
  "layers": {
    "l1": "converged",
    "l2": "divergent",
    "l3": "not fired"
  },
  "quorum": {
    "responded": 4,
    "required": 3,
    "roles": 4,
    "of": 4,
    "passed": false
  },
  "wall_clock_ms": 512605,
  "halt_stage": null,
  "backlog_appended": 10,
  "backlog_skipped_nonblocking": 8,
  "granted": 4,
  "reviewed_plan_hash": "sha256:b7687ff9073df6a708912f166ca8ec9ab0f027f824be0e0ca6a627080539dae0",
  "plan_path": ".claude/plans/insuniverse-docs-20-foundation-access-m1.plan.md",
  "recorded_at": "2026-08-24T08:53:22.839Z"
}
```
