# post_pr150_runtime_wiring_audit · Sub-spec 4/5 · stale watcher result 무시 로직
- task: task-2685
- chair_authorization_id: CHAIR-AUTH-POST-PR150-RUNTIME-WIRING-AUDIT-20260526-JJONGS-AUDIT-001
- audit_mode: read-only
- audit_date: 2026-05-26 04:20 UTC
- main_repo_head: 2752182a

## 영역 4 결선 verdict

| Sub-check | Verdict | Evidence |
|---|---|---|
| A. target head vs latest/merged head 비교 | **FAIL** | `git grep -n "target_head\|target_sha\|stale_head\|head_drift\|latest_head" origin/main -- '*.py'` → 0건 (node_modules/.codegraph-venv 제외) |
| B. PR merged 시 stale 분류 | **FAIL** | watcher context에서 `is_merged` / `pr.merged` / `pr_merged` 0건. 단 `anu_v2/gemini_stale_prevention_runner.py:737-789` `classify_replacement_contract_framing()` 가 `original_pr_merged_at` 사용 — ★ replacement PR contract scope (watcher terminal state 아님) |
| C. stale 결과 최신 상태 오염 0 | **PARTIAL** | fresh evidence HOLD guard `.worktrees/task-2673-dev8/utils/pr_watcher_terminal_state_classifier.py:166-173`에 존재 — but stale result injection 차단 0. (fresh evidence 보호 ≠ stale result discard) |
| D. STALE_WATCHER_RESULT_IGNORED marker 작성 여부 | **FAIL** | `git grep -n "STALE_WATCHER_RESULT_IGNORED" origin/main` → 0건. `.worktrees/task-2673-dev8/` 0건. `.worktrees/task-2680-dev2/` 0건. 본 marker는 task-2685 task md L45 requirement 만 존재. |
| E. anu_v2 stale_prevention 인프라 coverage | **PARTIAL** | `anu_v2/gemini_stale_prevention_runner.py` 존재 (5 fixtures · 24 regression · `ORIGINAL_PR_UNMERGED_STATES` frozenset L85-100) — but layer mismatch: replacement PR contract scope vs watcher terminal state scope |

## 결함 list

| ID | Severity | Path · line | 설명 |
|---|---|---|---|
| D4.A | HIGH | 미구현 | watcher의 recorded target HEAD vs current latest/merged HEAD 비교 코드 0. PR head drift 시 watcher 결과 stale 분류 불가. |
| D4.B | HIGH | 미구현 | PR merged 시 watcher 결과 자동 stale 분류 0. anu_v2 `original_pr_merged_at` 사용은 replacement contract 분기로 layer 별. |
| D4.C | HIGH | 미구현 | stale watcher 결과가 fresh state 오염하는 경로 차단 0. fresh evidence HOLD (D1.B)는 orthogonal safety. |
| D4.D | MEDIUM | task md L45 requirement only | STALE_WATCHER_RESULT_IGNORED marker 코드/문서 0. |
| D4.E | MEDIUM | `anu_v2/gemini_stale_prevention_runner.py` (origin/main) | 인프라 존재하나 watcher terminal state 결선에는 wired 0. |

## 결선 reachability 매트릭스 (origin/main)

| 컴포넌트 | reachable? |
|---|---|
| target_head vs latest_head 비교 | NO |
| PR merged → stale auto-classify (watcher scope) | NO |
| stale result discard guard | NO |
| STALE_WATCHER_RESULT_IGNORED marker emit | NO |
| anu_v2 stale_prevention runner | YES (replacement scope) · watcher scope NO |
| `utils/silent_corruption_guard.py` (task-2471 · mergedAt/mergeCommit/ancestry) | YES (merged PR safety) · stale watcher scope NO |

## 종합 verdict

**FAIL** — stale watcher result 무시 로직 origin/main 미구현. 인접 인프라(anu_v2 stale_prevention runner · silent_corruption_guard)는 다른 layer scope. STALE_WATCHER_RESULT_IGNORED marker는 task md requirement만 존재.

## 권고 (★ 별도 task + chair signature)

1. watcher runner에 target_head record 추가 (poll 시점 PR head SHA 박제)
2. terminal state 결정 직전 current_head 조회 → `target_head != latest_head` 시 STALE_WATCHER_RESULT_IGNORED marker emit + state pollution 차단
3. PR merged 시 watcher 결과 자동 discard branch 추가
4. regression: merged PR mid-watch · stale result injection · fresh state preservation 3 시나리오
