{
  "schema": "replacement_pr_dry_run_matrix.v1",
  "ts_kst": "2026-05-21 04:35 KST",
  "mode": "read-only · dry-run matrix",
  "audit_method": "grep+sed source-of-truth on utils/replacement_pr_runner.py · anu_v2/replacement_pr_runner.py · scripts/replacement_pr_dry_run_activation_guard.py · scripts/replacement_pr_dry_run_activation_harness.py",
  "primary_finding": {
    "utils_replacement_pr_runner_status": "EMPTY (0 lines) — file exists but has 0 implementation",
    "anu_v2_replacement_pr_runner_status": "442 lines · full implementation · legacy v2 era",
    "scripts_dry_run_activation_guard": "exists (scripts/replacement_pr_dry_run_activation_guard.py) · fifth-truncate halt guard (task-2590) · exit code 87",
    "scripts_dry_run_activation_harness": "exists",
    "v3_era_replacement_pr_runner": "MISSING — anu_v3/replacement_pr_runner.py 또는 utils/replacement_pr_runner.py (utils/ 는 stub)"
  },
  "matrix": [
    {
      "condition_id": "F_C1",
      "name": "replacement_pr_runner 현재 상태",
      "verdict": "PARTIAL_LEGACY_ONLY",
      "evidence": "anu_v2/replacement_pr_runner.py (442 lines · v2 era) · utils/replacement_pr_runner.py (0 lines · stub) · v3-equivalent 미존재",
      "risk_if_used_in_v3_production": "MEDIUM — v2 module 가 v3 era 와 호환 가능한지 미검증 · v3 callback contract chaining 미확인"
    },
    {
      "condition_id": "F_C2",
      "name": "clean replacement PR 생성 조건",
      "verdict": "DEFINED_v2",
      "evidence": "anu_v2/replacement_pr_runner.py 가 expected_files exact match · effective_diff_contamination 0 · forbidden path 0 조건 구현",
      "v3_status": "v3 era 적용 여부 미확인"
    },
    {
      "condition_id": "F_C3",
      "name": "effective_diff_contamination 판정",
      "verdict": "WIRED_in_merge_queue_executor",
      "evidence": "utils/merge_queue_executor.py:compare_effective_diff (L445) — effective diff 비교 함수 존재 · classification 정상"
    },
    {
      "condition_id": "F_C4",
      "name": "expected_files exact match 판정",
      "verdict": "WIRED_via_normalize_file_list",
      "evidence": "utils/merge_queue_executor.py:_normalize_file_list (L441) · compare_effective_diff (L445)"
    },
    {
      "condition_id": "F_C5",
      "name": "forbidden path 판정",
      "verdict": "WIRED_in_merge_queue_executor",
      "evidence": "utils/merge_queue_executor.py:detect_forbidden_paths (L473)"
    },
    {
      "condition_id": "F_C6",
      "name": "replacement PR failure → Critical7",
      "verdict": "v2_DEFINED",
      "evidence": "anu_v2 era 에서 Critical7 분류 · v3 era 적용 여부 별도 audit 필요"
    },
    {
      "condition_id": "F_C7",
      "name": "same-branch push 금지",
      "verdict": "ENFORCED_via_assert_no_forbidden_git_flags",
      "evidence": "utils/merge_queue_executor.py:assert_no_forbidden_git_flags (L303)"
    },
    {
      "condition_id": "F_C8",
      "name": "original PR 보존",
      "verdict": "v2_DEFINED",
      "evidence": "anu_v2/replacement_pr_runner.py · clean replacement path · original PR untouched 정책"
    },
    {
      "condition_id": "F_C9",
      "name": "dry-run 결과 JSON 생성 가능",
      "verdict": "DRY_RUN_HARNESS_EXISTS",
      "evidence": "scripts/replacement_pr_dry_run_activation_harness.py · scripts/replacement_pr_dry_run_activation_guard.py — fifth-truncate halt 포함"
    },
    {
      "condition_id": "F_C10",
      "name": "실제 PR-open pilot 가능 조건",
      "verdict": "REQUIRES_CHAIR_APPROVAL · 회장 명시 verbatim 'PR open 금지'",
      "evidence": "본 audit 는 dry-run + proposal-only 한정"
    }
  ],
  "summary": {
    "total_conditions": 10,
    "fully_wired_v3": 4,
    "wired_v2_pending_v3_audit": 4,
    "v3_module_missing_or_stub": 1,
    "requires_chair_approval": 1,
    "critical7_count": 0,
    "scope_invariants_preserved": ["read-only", "dry-run", "no PR/merge/branch/credential write"]
  },
  "verdict": "Track F replacement PR readiness = PARTIAL · utils/replacement_pr_runner.py stub (v3-equivalent missing) · anu_v2 era 가 실 구현 · v3 callback contract chaining 별도 audit 권고. 회장 결정: v3 replacement_pr_runner 구현 또는 anu_v2 era 의 v3 호환 명문화 — 본 audit 범위 아님(별도 chair-authorized task)"
}
