# Plan Review Panel — ops-20-statements-m1-ship

**Plan**: `.claude/plans/ops-20-statements-m1-ship.plan.md` · **Plan version**: `sha256:92fd7e69623f776ccc9bb1a7cfda1f3ae64098665863b6c4fecfab155274d6ec`
**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: 6 blocking finding(s): architect/HIGH, architect/FAIL, test/FAIL, invariant/CRITICAL — MCCP_REVIEW_SINGLE_PASS=deadline_pressure 로 진행한다. verdict는 divergent 그대로 봉인된다.

## Findings

| Perspective | Severity | Claim | Evidence |
|---|---|---|---|
| architect | HIGH | ops-40-db-snapshot-m2.json demonstrates the pattern of 'security 축은 두 부정 필드의 동시 부재로만 돌았다 를 표현한다' (simultaneous absence of two negation fields to express 'ran') | .claude/plans/ops-20-statements-m1-ship.plan.md:129 claims ops-40-db-snapshot-m2.json shows this pattern. However, reading the actual file at .claude/receipts/mccp-implement-codex/ops-40-db-snapshot-m2.json shows line 32: security_skipped=false and line 34: security_force_override=true. The file demonstrates the OPPOSITE pattern — it uses the audit field (security_force_override) mechanism, not simultaneous negation field absence. The correct example for the claimed pattern is ops-10-cells-ship.json (correctly cited in Task 2 line 231), which has both fields false. |
| test | MEDIUM | Validation 4 checks that m1.sh reverify correctly outputs provenance_proven 0 | Plan line 73 lists '`m1.sh reverify` \| rc 0 · `reverify ok` · `provenance_proven 0`' as measurement. However, Validation 4 at lines 310-311 only runs 'bash ops/statements/_harness/m1.sh reverify' and 'm0.sh reverify' without capturing or verifying their stdout output. The m1.sh harness does output 'provenance_proven 0' (m1.sh line 253), but the test does not validate this output. |
| test | MEDIUM | Validation 10 verifies the receipt json contains all critical fields | Plan line 118 states the receipt should have provenance_proven=0. Plan lines 109-114 discuss that provenance_proven will be 0 as a documented tradeoff. However, Validation 10 (lines 353-380) only checks: meta.security_skipped, meta.security_force_override, and receipt_hash. It does not verify meta.provenance_proven exists or equals 0, despite this being a load-bearing claim documented at line 118. |
| invariant | CRITICAL | Plan requires PR body must contain '### Security Reviewer' section as proof security-reviewer ran, but this critical requirement is not formalized as any Validation or Gate. It is only listed in prose, marked as a manual human check, and can be silently skipped. | Plan lines 228-230 state: 'PR 본문에 `### Security Reviewer` 절이 없으면 그것도 실패다' (missing section is also failure) and '그 대조는 사람이 하고' (that comparison is done by humans). No Validation checks PR body. No Gate enforces this requirement. Validations 1-10 (lines 270-381) check harness, reproducibility, and receipt integrity, but none check PR body content. |
| invariant | HIGH | Post-validation block (Validations 7, 8, 10, which verify receipts were created and security fields are correct) is not machine-enforced by any Gate. These validations are manual shell script steps that could be skipped. If skipped, manually-forged receipts with correct hash would not be detected. | Plan lines 265-266: 'Acceptance 의 "Validation passes" 는 **둘 다** rc 0 을 뜻한다' requires both pre and post blocks pass. But Task 2 Gate (line 237-238) only validates `mccp:pr` command output (0 blocking), not the plan's 10-step validation harness. Validation 10 (lines 353-380) checks receipt_hash mismatch would fail, but only if run. If operator skips post-block, Validation 10 never executes. |
| invariant | MEDIUM | Plan's security of receipt integrity depends on receipt_hash validation, but the plan does not verify or document that the receiptHash function itself is secure against forgery. Plan assumes receiptHash is trustworthy without explaining its security properties or whether an attacker could compute a valid hash for a manually-modified receipt. | Plan line 374-378 recomputes receipt_hash and compares with stored value, expecting mismatch to detect tampering. But plan lines 370-372 do not verify receiptHash function is correct, only that 'receipt_hash' field contains a sha256: value. Plan does not explain: (a) whether receiptHash is deterministic, (b) whether accessing receiptHash requires authentication, (c) whether hash function covers all security-critical fields. |
| invariant | MEDIUM | New receipt will have `provenance_proven: 0` (different from M1's `provenance_proven: 1`), but no automatic documentation in receipt file itself explaining why this value is 0. Reader of receipt alone would see 0 and might misinterpret as 'provenance not proven' rather than 'provenance re-proved elsewhere'. | Plan line 118 acknowledges new receipt will have `provenance_proven: 0` because `reverify` is used instead of `validate`. Plan lines 109-113 and 402 document this is expected and cost is '명시' (noted) in Risks table, but receipt_hash will not include explanatory metadata. Closure document 1-m1-policy-axis.md (separate file) proves provenance_proven=1, but new receipt won't reference it. Acceptance requires readers to correlate two separate receipt files. |

## Refutation attempted

| Perspective | Verdict | What was attacked |
|---|---|---|
| architect | fail | Verified citation accuracy in Patterns to Mirror table against actual files. Checked ops-40-db-snapshot-m2.json and found it contradicts the claimed pattern (has security_force_override=true, not the simultaneous-false pattern). Confirmed Task 2 Mirror section correctly identifies ops-10-cells-ship.json for the dual-false pattern. Verified ops-20-statements.prd.md exists with claimed Delivery Milestones table structure. Verified Files to Change section is consistent with boundary claims (only .claude/** files, no ops/** or prds/** changes). Examined Validation blocks for structural consistency (two-block approach with numbered skips is intentional and documented). No boundary leaks found in task dependencies or file ownership. The misquote in Patterns to Mirror is a concrete error with verifiable evidence. |
| security | pass | Attacked: (1) Receipt-hash integrity for new files — plan claims store.js lines 127-135 prevent tampering, but that guard applies only to tracked receipt overwrites. These three new receipts (mccp-plan-codex, mccp-implement-codex, mccp-pr-codex for ops-20-statements-m1-ship) are new files, not overwrites. Plan explicitly acknowledges this gap (line 216): "증명하지 못한다" — cannot prove execution. Mitigation: single production path (gates write only) + human PR body verification. (2) Security field validation completeness — Validation 10 (lines 361-368) strictly checks `security_skipped !== false` and `security_force_override !== false`, not just falsy values. Prevents partial-state escalation. (3) Trust boundary on external gate logic — plan depends on plugin-cache implementations (receiptHash function, security_skipped auto-set on tool failure) not visible in this repo. Plan cites specific line numbers (write.js 901, store.js 127-135) and directly addresses prior refutation (R2 lines 439-448) with those cites, demonstrating awareness. (4) Tracked receipt preservation — Validation 9 (lines 323-331) correctly excludes the new -ship.json files from the directory-wide scan using grep filter. Task 3 Gate (line 250) checks three directories don't contain ops-20-statements-m1-ship.json paths outside the new ones. (5) Layer 2 production code isolation — Task 1 Gate (line 179) + Validation 6 (line 318-319) prevent changes to ops/** and .claude/prds/** via git status checks. (6) PR body verification is manual — Plan documents this requirement (lines 199, 227-230) as the only human judgment needed. Checked plan's Acceptance section (lines 499-504): requires explicit `gh pr create` and operator visual verification. All security concerns found in plan's own review record (R1-R3, lines 411-477) have documented mitigations in Task 2 and Validation blocks. No hidden defects identified. |
| test | fail | Attacked the plan's key claims through test falsifiability lens: 1. Validated that all Validation commands (1-10) reference files that exist: check-statements.mjs, m0.sh, m1.sh, git commands, node modules. ✓ 2. Verified Validation test structure:     - Validation 1-6: Pre-gate checks before receipts exist (make sense, rc 0 sufficient)    - Validation 7-8,10: Post-gate checks after receipts created (logically sound) 3. Checked output format of check-statements.mjs: confirmed it produces "key value" format matching the hardcoded baseline in Validation 3. ✓ 4. Verified reverify mode exists in m1.sh and outputs "provenance_proven 0" to stdout (line 253 of m1.sh confirms this). ✓ 5. Examined Validation 10 Node.js code (lines 353-380): checks only security_skipped, security_force_override, and receipt_hash. Does NOT check provenance_proven field. 6. Confirmed Validation 4 (lines 310-311) runs reverify but does NOT capture or verify its stdout output including "provenance_proven 0" claim. 7. Verified plan documents at line 73 and 118 that provenance_proven should be 0, but no automated check validates this in the Validation section. |
| invariant | fail | Attacked fail-open drift by checking all Tasks and Gates for blocks that degrade to warnings. Found gates are fail-closed. Attacked skip predicates by tracing whether later gates require earlier validations: Task 2 Gate requires mccp:pr validation (0 blocking), but plan's 10-step validation harness is not machine-enforced, leaving room to skip critical checks. Attacked anchoring by verifying receipt binds to correct artifact: M1 receipt pins to commit 0b072d5 with provenance_proven=1 via separate closure doc; ship receipt pins to HEAD with provenance_proven=0. Semantically correct but ambiguous without reading plan. Attacked HALT vs degrade on gate machinery failure: if security-reviewer tool unavailable, implement gate sets security_skipped=true, which causes Validation 10 to fail — this is fail-closed. But Validation 10 only runs if post-validation block runs, which is manual step. Searched for all Validations and Gates in plan: found Validations 1-10 are manual shell script blocks in Validation section, only Validations 7/9 and Task gates are overlapping. No automated enforcement of requirement that PR body contains '### Security Reviewer' section — plan states this is 'manual human check' at line 229. |

## 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": 543059,
  "halt_stage": null,
  "backlog_appended": 6,
  "backlog_skipped_nonblocking": 4,
  "granted": 4,
  "reviewed_plan_hash": "sha256:92fd7e69623f776ccc9bb1a7cfda1f3ae64098665863b6c4fecfab155274d6ec",
  "plan_path": ".claude/plans/ops-20-statements-m1-ship.plan.md",
  "recorded_at": "2026-08-26T06:45:13.849Z"
}
```
