# post_pr150_runtime_wiring_audit · Sub-spec 1/5 · PR watcher terminal classifier 결선
- task: task-2685
- chair_authorization_id: CHAIR-AUTH-POST-PR150-RUNTIME-WIRING-AUDIT-20260526-JJONGS-AUDIT-001
- audit_mode: read-only (코드 0 · runtime 변경 0)
- audit_date: 2026-05-26 04:20 UTC
- main_repo_head_actual: 2752182a (task-2661 Phase 2b · 2026-05-25)
- main_repo_head_claimed: 319170b95b1330c3e9554eca88973e68f60e93e9 (★ git cat-file fail · NON-EXISTENT)
- pr150_actual_commits: 8f7c56c6 / 522a1174 / 0aa96e1b (★ branch `task/task-2673-dev8` only · origin/main 미머지)

## 영역 1 결선 verdict

| Sub-check | Verdict | Evidence (file:line · 1-line quote) |
|---|---|---|
| A. utils/pr_watcher_terminal_state_classifier.py runner import | **FAIL** | `git ls-tree -r origin/main --name-only | grep pr_watcher_terminal_state_classifier` → 0건. worktree task-2673-dev8 외부에서 production import 0. test 파일 4건만 (test_classify_hold_for_chair.py L17 외) |
| B. fresh Gemini + unresolved>0 → 즉시 HOLD_FOR_CHAIR | **PASS (worktree only)** | `.worktrees/task-2673-dev8/utils/pr_watcher_terminal_state_classifier.py:168-173` — `if gemini_fresh and unresolved > 0 and mss == "BLOCKED": return HOLD_FOR_CHAIR` |
| C. LOOP_BOUNDARY priority deprioritization | **PASS (worktree only)** | 동 파일 L200-215 — `if elapsed_watcher_sec >= max_watch_seconds: if unresolved > 0 or mss == "BLOCKED": return HOLD_FOR_CHAIR` (HOLD_FOR_CHAIR 우선 분기) |
| D. terminal_state 시 ANU normal callback 등록 보장 | **PARTIAL (design only)** | 동 파일 `register_terminal_callback()` L298-377, envelope builder L220-278 · ★ production caller 0 (grep 0건) |

## 핵심 결함

| ID | Severity | Path · line | 설명 |
|---|---|---|---|
| D1.A1 | CRITICAL | task md L10 vs `git cat-file 319170b9` | task md가 주장한 PR #150 머지 SHA가 repo에 존재하지 않음. read-only audit 전제 자체 false. |
| D1.A2 | CRITICAL | `utils/pr_watcher_terminal_state_classifier.py` (origin/main) | 파일이 origin/main에 존재하지 않음 (`git ls-tree -r origin/main --name-only | grep pr_watcher` → 0건). `task/task-2673-dev8` worktree에만 399 lines. |
| D1.A3 | HIGH | grep `pr_watcher_terminal_state_classifier` import production paths | scripts/** dispatch/** utils/** import 0건. worktree tests/pr_watcher_terminal_state_classifier/**/test_*.py 4건만 import. |
| D1.D | HIGH | worktree `utils/pr_watcher_terminal_state_classifier.py:298-377` (register_terminal_callback) | 함수 정의는 잘되어 있으나 production caller 0. `dispatch/finalize_hooks.py`는 `utils.anu_callback_registrar` import (다른 helper) → 결선 미완. |

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

| 컴포넌트 | reachable? | 비고 |
|---|---|---|
| classifier 파일 자체 | NO | task/task-2673-dev8 worktree only |
| `classify()` | NO | 4 test files만 호출 |
| `register_terminal_callback()` | NO | 0 production caller |
| `build_callback_envelope()` (classifier 버전) | NO | dispatch는 `utils.anu_callback_registrar` 사용 |

## 종합 verdict

**FAIL (NOT_OPERATIONALIZED)** — 분류 로직 자체는 설계대로 작동하나 origin/main runtime 결선 0. PR #150 미머지 + 4 test only.

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

1. task-2673-dev8 worktree → main 머지 PR 신규 발행
2. watcher runner 1곳을 `classify()` 호출로 결선 (scripts/ci-watcher.sh 또는 anu_v2 runner)
3. terminal_state branch → `register_terminal_callback()` 호출 wiring
4. regression 4 test → main 보존
