{
  "schema": "replacement_pr_dry_run_fixture_matrix.v1",
  "track": "Track F — replacement PR v3 gap closure plan",
  "ts_kst": "2026-05-21 05:04 KST",
  "mode": "fixture design · dry-run matrix · 실 GitHub API 0 · subprocess 0",
  "purpose": "replacement PR runner (v3 shim → anu_v2) 의 dry-run 검증 시나리오 매트릭스. 회장 verbatim 14조건 + RPF1~RPF8 결선 검증",
  "matrix": [
    {
      "fixture_id": "FDR1",
      "name": "expected_files exact match · contamination 0",
      "input": {"expected_files": ["src/a.py", "src/b.py"], "actual_diff": ["src/a.py", "src/b.py"]},
      "expected_contamination": {"contaminated": false, "extra_files": [], "missing_files": []},
      "expected_decision": {"replacement_pr_required": false},
      "downstream_action": "기존 merge gate 정상 진행 (queue head 검사 등)",
      "wired_in_v2": true
    },
    {
      "fixture_id": "FDR2",
      "name": "extra_files only · scope 확장",
      "input": {"expected_files": ["src/a.py"], "actual_diff": ["src/a.py", "src/leaked.py"]},
      "expected_contamination": {"contaminated": true, "extra_files": ["src/leaked.py"], "missing_files": []},
      "expected_decision": {"replacement_pr_required": true, "clean_branch_name_pattern": "task-{id}-clean-replacement"},
      "downstream_action": "create_clean_replacement_pr 6 stage 실행",
      "wired_in_v2": true
    },
    {
      "fixture_id": "FDR3",
      "name": "missing_files only · 누락",
      "input": {"expected_files": ["src/a.py", "src/b.py"], "actual_diff": ["src/a.py"]},
      "expected_contamination": {"contaminated": true, "extra_files": [], "missing_files": ["src/b.py"]},
      "expected_decision": {"replacement_pr_required": true},
      "downstream_action": "clean PR 생성 시 expected_files 모두 stage",
      "wired_in_v2": true
    },
    {
      "fixture_id": "FDR4",
      "name": "BOT_GITHUB_TOKEN 부재",
      "input_env": {"BOT_GITHUB_TOKEN": ""},
      "expected_stage_failure": {"stage": "bot_token", "reason": "bot_token_unavailable"},
      "expected_classification": "CRITICAL_DIFF_REPLACEMENT_FAILED (Critical7 #N · precondition failure)",
      "is_critical7": true,
      "wired_in_v2": true
    },
    {
      "fixture_id": "FDR5",
      "name": "expected_files 빈 리스트",
      "input": {"expected_files": [], "actual_diff": ["src/x.py"]},
      "expected_stage_failure": {"stage": "precondition", "reason": "expected_files_empty"},
      "expected_classification": "CRITICAL_DIFF_REPLACEMENT_FAILED (Critical7 · precondition)",
      "is_critical7": true,
      "wired_in_v2": true
    },
    {
      "fixture_id": "FDR6",
      "name": "git checkout -b 실패 (branch 충돌)",
      "simulated_git_returncode_at": "checkout -b",
      "expected_stage_failure": {"stage": "branch", "reason": "git_checkout_b_failed"},
      "expected_classification": "CRITICAL_REPLACEMENT_FAILED (Critical7 · downstream)",
      "is_critical7": true,
      "wired_in_v2": true
    },
    {
      "fixture_id": "FDR7",
      "name": "refs/pull/{N}/head fetch 실패",
      "simulated_git_returncode_at": "fetch origin refs/pull/.../head",
      "expected_stage_failure": {"stage": "fetch", "reason": "git_fetch_pull_head_failed"},
      "expected_classification": "CRITICAL_DIFF_REPLACEMENT_FAILED (Critical7 · precondition fail · fetch downgraded to precondition per v2 classify_failure)",
      "is_critical7": true,
      "wired_in_v2": true,
      "note": "v2 L394 downstream_stages = {branch, checkout, commit, push, pr_create} · fetch 는 precondition 분류"
    },
    {
      "fixture_id": "FDR8",
      "name": "git push 실패 (network or auth)",
      "simulated_git_returncode_at": "push origin clean_branch_name",
      "expected_stage_failure": {"stage": "push", "reason": "git_push_failed"},
      "expected_classification": "CRITICAL_REPLACEMENT_FAILED (Critical7 · downstream)",
      "is_critical7": true,
      "wired_in_v2": true
    },
    {
      "fixture_id": "FDR9",
      "name": "gh pr create 실패",
      "simulated_gh_returncode_at": "pr create",
      "expected_stage_failure": {"stage": "pr_create", "reason": "gh_pr_create_failed"},
      "expected_classification": "CRITICAL_REPLACEMENT_FAILED (Critical7 · downstream)",
      "is_critical7": true,
      "wired_in_v2": true
    },
    {
      "fixture_id": "FDR10",
      "name": "gh pr create stdout PR 번호 파싱 실패",
      "input": {"gh_stdout_simulated": "no url at last line"},
      "expected_stage_failure": {"stage": "pr_create", "reason": "gh_pr_number_unparsable"},
      "expected_classification": "CRITICAL_REPLACEMENT_FAILED (Critical7 · downstream)",
      "is_critical7": true,
      "wired_in_v2": true
    },
    {
      "fixture_id": "FDR11",
      "name": "forbidden_path detected (.github/workflows/* in expected_files)",
      "input": {"expected_files": [".github/workflows/x.yml"], "actual_diff": [".github/workflows/x.yml"]},
      "expected_v3_external_judgment": "Critical7 · FORBIDDEN_PATH_TRIGGERED (merge_queue_executor.detect_forbidden_paths L473)",
      "is_critical7": true,
      "wired_in_v3_path": true,
      "note": "replacement_pr_runner 진입 前 차단 — v3 external judgment 가 sole 결정"
    },
    {
      "fixture_id": "FDR12",
      "name": "OWNER_PAT detected as token",
      "input_env": {"BOT_GITHUB_TOKEN": "ghp_OWNER_PAT_PREFIX"},
      "expected_v3_external_judgment": "FAIL_CLOSED · OWNER_PAT_FALLBACK_BLOCKED (select_merge_token_decision)",
      "is_critical7": true,
      "wired_in_v3_path": true,
      "note": "replacement_pr_runner 진입 前 차단 · prefix 5자 분류 · 실 token value 0 노출"
    },
    {
      "fixture_id": "FDR13",
      "name": "original PR OPEN 유지 (preserve_original_pr 검증)",
      "input": {"original_pr": 999},
      "expected_action": "gh / git 호출 0 · audit jsonl append only",
      "expected_preservation_record": {"original_pr": 999, "preserved_state": "OPEN", "audit_path": "{audit_root}/replacement_pr_999.jsonl"},
      "wired_in_v2": true
    },
    {
      "fixture_id": "FDR14",
      "name": "executor contract dict 생성",
      "input": {"contamination": "FDR2 (extra leaked.py)", "original_pr": 1234, "expected_files": ["src/a.py"], "clean_branch_name": "task-1234-clean"},
      "expected_dict": {"replacement_pr_required": true, "replacement_pr_runner_input": {"original_pr": 1234, "expected_files": ["src/a.py"], "clean_branch_name": "task-1234-clean", "contamination": "FDR2 dict"}},
      "wired_in_v2": true
    }
  ],
  "summary": {
    "total_fixtures": 14,
    "is_critical7_count": 9,
    "wired_in_v2_count": 12,
    "wired_in_v3_external_path": 2,
    "not_wired_count": 0,
    "execution_mode": "mock-based · 실 GitHub API 0 · subprocess 0 · 실 PR open 0"
  },
  "regression_implementation_proposal": {
    "test_file_candidate": "tests/regression/test_replacement_pr_dry_run_matrix.py (신규)",
    "dependencies": [
      "anu_v2/replacement_pr_runner.py (sole source)",
      "utils/replacement_pr_runner.py (v3 shim · 회장 승인 시)",
      "utils/merge_queue_executor.py (forbidden path / token decision external)"
    ],
    "fixtures_data_dir": "memory/fixtures/replacement_pr_dry_run_*.json"
  },
  "auto_progress": false,
  "chair_approval_required": true,
  "scope_invariants_preserved": [
    "fixture design only", "실 execution 0", "실 PR open 0", "merge 0",
    "GitHub write 0", "credential raw exposure 0",
    "token value 0 노출 (prefix 5자만)",
    "Track C 미접촉", "zombie cron 미접촉"
  ]
}
