# task-2729+1 — AUDIT-FIRST report (read-only, 구현 금지)
3개 운영 재현 결함의 capability 재분석 / delta / remediation 설계. 근거: merged main `d925b873` 코드 + automation_capability_matrix.json + PR#173 운영기록.
> 원칙: "코드 존재 ≠ 실제 동작". IMPLEMENTED/VERIFIED/WIRED/ACTIVE 엄격 분리.

═══════════════════════════════════════
## 산출물 1) AUDIT REPORT (결함별 6필드)
═══════════════════════════════════════

### 결함1. CI_WATCHER_SESSION_LIFETIME_GAP
- 최초 발생: PR #143/#144 (CLAUDE.md 박제) → 백로그 `ci_watcher_session_lifetime_gap_backlog_260523.json` → **PR #173 재현(2026-06-04~05)**: watcher 73E07442/dead-man A33C763E session-bound 사멸, ~25h 무수렴.
- 실제 증상: PR open 후 head 감시 watcher가 부모 세션 종료와 함께 사멸 → cron-list 0 + schedule_history 0 + PR BLOCKED 방치.
- 재현 조건: session-bound cron 으로 watcher 등록 → 부모 세션 종료 → poll 미실행.
- 코드 위치: `scripts/ci_watch_handoff_runner.py` (WatcherState 6상태/run_once/fire_terminal_callback/quiet-window/main argparse). **line 15·429·433-434: "live gh polling 루프는 골격만, 미실행"**.
- capability 상태: progress_watcher = IMPLEMENTED✓ · VERIFIED✓(regression) · WIRED=`partial_record_only` · ACTIVE=false.
- ACTIVE 결선 요건: (a) **live poll loop 실구현**(현재 skeleton) (b) **OS-level 비-session 진입**(systemd-path/OS-cron 가 runner main 직접 실행, cokacdir cron=relay only) (c) lifetime fixture.

### 결함2. NORMAL_CALLBACK_REGISTRATION_OR_HISTORY_MISMATCH
- 최초 발생: task-2625/2634/2643 self-key·미등록 변종 → **PR #173 재현**: `task-2729.callback-launch.json` verdict=PASS·ANU_OWNED_READY 인데 schedule_history fire 0.
- 실제 증상: registrar 가 REGISTERED/ANU_OWNED_READY 보고했으나 실제 cron 이 schedule_history 에 없음(등록 주장↔실재 불일치). DISPATCH_FALSE_OK 변종(cokacdir cron ok ≠ spawn).
- 재현 조건: finalize 콜백 등록 호출 후 schedule_history 교차확인 없이 성공 단정.
- 코드 위치: `dispatch/__init__.py:197-221`(finalize_with_callback_registration·build_anu_owned_callback_request·enforce_callback_owner 결선) + `dispatch/finalize_hooks.py`(287L, build→register→update, register_normal_callback, 5축 status).
- capability 상태: IMPLEMENTED✓ · VERIFIED✓(regression: test_anu_callback_registrar / normal_callback_registration_enforcement / 4tuple_registry) · **WIRED✓**(task-2635 결선 — 3중 중 가장 결선됨) · ACTIVE=n/a(enforcement).
- ACTIVE 결선 요건: **registration_result_status=REGISTERED ↔ schedule_history 실재 reconciliation** 1마일 + `REGISTERED_BUT_NO_HISTORY` 분류 + fixture. (코드/wiring 골격은 이미 존재)

### 결함3. live_prune_not_wired
- 최초 발생: callback fallback lifecycle(task-2728) → matrix active_blocked_reason: **ABEE96D2 dogfood fallback callback 후 미prune 실증**. PR #173 에 capability 동봉.
- 실제 증상: collector success 트랜잭션에서 registry pending fallback 을 real cancel/tombstone 하는 live 관측 0(dry-run/fake 만 PASS).
- 재현 조건: 운영 collector 가 success 후 실제 fallback cron 을 cancel/tombstone 하는지 live 관측 → 미발생.
- 코드 위치: `utils/completion_callback_fallback_cancel.py`(RemoverResult/DefaultRemover real path/evaluate_durable_evidence/collect_and_prune). **line 105-116: DefaultRemover dry_run=True 기본 — 실 subprocess 0, 운영 collector 만 실제**.
- capability 상태: callback_fallback_prune = IMPLEMENTED✓ · VERIFIED✓(fake/DI regression) · WIRED=`live_prune_success_gated_candidate` · ACTIVE=false.
- ACTIVE 결선 요건: **live collector real-prune 1회 운영 관측(dry_run=False)+tombstone 증거** → 회장 승인 후 ACTIVE. (코드/wiring 아님 = 운영증거)

═══════════════════════════════════════
## 산출물 2) CAPABILITY DELTA REPORT
═══════════════════════════════════════
(IMPLEMENTED → VERIFIED → WIRED → ACTIVE, 현재 위치와 ACTIVE까지 delta)

- **CI_WATCHER**: IMPLEMENTED✓ VERIFIED✓ WIRED=partial(record-only) ACTIVE✗
  - Δ to ACTIVE = **코드(poll loop 실구현) + 결선(OS-level 비-session invocation)** → 2개 갭. 가장 큼.
- **NORMAL_CALLBACK**: IMPLEMENTED✓ VERIFIED✓ WIRED✓ ACTIVE=n/a(enforcement)
  - Δ = **운영 verification(registration↔history reconciliation) 1마일**. 코드/wiring 존재. 갭 최소.
- **live_prune**: IMPLEMENTED✓ VERIFIED✓(fake) WIRED=candidate ACTIVE✗
  - Δ = **순수 운영증거(live real-prune 관측)**. 코드/wiring 아님.

### ★ "코드 vs 결선" 핵심 판정 (회장 질문 직답)
| 결함 | 진짜 부족한 것 |
- CI_WATCHER → **코드(poll loop) + lifecycle 결선** 둘 다 (실질 부족 최대)
- NORMAL_CALLBACK → **결선 마지막 1마일(history reconciliation) + 운영 verification** (코드 충분)
- live_prune → **운영증거 only** (코드·결선 충분, 실행 관측만 부재)

분류 축:
- CI_WATCHER = watcher lifecycle 문제 + wiring 부족 + (poll loop) 코드 구현 부족
- NORMAL_CALLBACK = callback registration 문제(운영 verification/reconciliation) — DISPATCH_FALSE_OK 변종
- live_prune = 운영증거 부족 (코드 구현·wiring 아님)

═══════════════════════════════════════
## 산출물 3) REMEDIATION PHASE PROPOSAL (설계만, 미구현)
═══════════════════════════════════════
> 전제: dev dispatch/코드수정/PR/merge/ACTIVE=true 전부 회장 별도 승인 후. 본 단계는 설계.

### CI_WATCHER (P0) — 예상 2 Phase
- Phase1: live poll loop 실구현(gh pr view/api→PRSnapshot→6상태 전이) + LOOP unit fixture. ACTIVE=false 유지.
- Phase2: OS-level 비-session invocation(systemd-path 또는 OS-cron 가 runner 직접 실행, cokacdir cron=relay) + lifetime-gap 재현 fixture(부모세션 종료에도 watcher 생존). task-2717 Phase2(OS-level 강제실행)와 연계.
- 자동 remediation: 부분 가능하나 코어 lifecycle = 신중.

### NORMAL_CALLBACK (P1) — 예상 1 Phase
- Phase1: finalize_hooks 에 post-register **schedule_history reconciliation**(REGISTERED 후 실재 확인)+`REGISTERED_BUT_NO_HISTORY` 분류 + fixture. 비코어·저위험.
- 자동 remediation: 가능.

### live_prune (P2) — 예상 1 Phase(+운영 pilot)
- Phase1: low-risk live collector 1회 real-prune pilot(dry_run=False) 관측 + tombstone 증거 수집 → ACTIVE 전환은 회장 승인. 코드변경 최소.
- 자동 remediation: 불가(운영증거는 실행으로만 확보).

### 권장 순서: P0(CI_WATCHER) → P1(NORMAL_CALLBACK) → P2(live_prune). P0 가 실제 idle-gap 사고원이라 최우선.

═══════════════════════════════════════
## 최종 요약표
═══════════════════════════════════════
1) CI_WATCHER_SESSION_LIFETIME_GAP
- 현재상태: IMPLEMENTED+VERIFIED, **WIRED=partial(record-only)**, ACTIVE=false
- 운영증거: NEGATIVE(PR#173 실패 실증)
- 재현 fixture: 부분(terminal callback fixture 존재 / **lifetime-death 재현 fixture 부재**)
- 자동 remediation: 부분 가능(코어 lifecycle 신중)
- 예상 Phase: 2
- 우선순위: **P0**

2) NORMAL_CALLBACK_REGISTRATION_OR_HISTORY_MISMATCH
- 현재상태: IMPLEMENTED+VERIFIED+**WIRED**, ACTIVE=n/a(enforcement)
- 운영증거: NEGATIVE(launch PASS↔history 0)
- 재현 fixture: 부분(registration enforcement fixture 존재 / **history reconciliation fixture 부재**)
- 자동 remediation: 가능
- 예상 Phase: 1
- 우선순위: **P1**

3) live_prune_not_wired
- 현재상태: IMPLEMENTED+VERIFIED(fake), **WIRED=candidate**, ACTIVE=false
- 운영증거: ABSENT(ABEE96D2 미prune)
- 재현 fixture: 존재(real_tombstone DI fixture — 단 fake/DI, live 아님)
- 자동 remediation: 불가(운영 pilot 필요)
- 예상 Phase: 1(+pilot)
- 우선순위: **P2**

## 결론
3개 모두 IMPLEMENTED. 진짜 부족: CI_WATCHER=코드+결선(P0) / NORMAL_CALLBACK=결선 1마일+verification(P1) / live_prune=운영증거(P2). **task-2729+1 구현 착수 여부는 회장 판단 대기.** 구현/dispatch/PR/merge/ACTIVE 전환 0.
