# task-2643 — CI_WATCH_HANDOFF_RUNTIME_ENFORCEMENT_GATE (v2.4 Harness Recovery)

- Level: Lv.4 (Harness-first hook + watcher contract + auto-wrapper + regression CI guard 병렬)
- 담당: dev6 페룬 (4트랙 단일 dispatch · ANU-Codex loop 자동수렴 병렬)
- base: origin/main 최신 (PR #145 task-2642 merge 후 진입 권장 · 현재 0e172435 / PR #145 OPEN)
- 단일소스 spec: `memory/specs/system_ci_watch_handoff_runtime_enforcement_gate_spec_260523.md`
  - sha256: `f1abe811543e1f561bae8f15fc9e0fb8a90b4800dca06d3c8d9bcfdd80b2991b`
  - 정독 전 sha256sum 검증 필수
- 정책 spec: `memory/specs/system_ci_watch_handoff_policy_spec_260523.md`
- runner spec: `memory/specs/system_ci_watch_handoff_runner_spec_260523.md`
- 사고 박제: `memory/feedback_anu_direct_polling_violation_pr_145_260523.md` · `memory/events/anu_direct_ci_polling_violation_pr_145_260523.json`
- 개발방향: `ANU_v3_master_development_direction_final_260517_v2_4_harness_recovery.md` + `anu_batch_hold_adjudication_auto_remediation_v2_4_harness_recovery.md`
- 회장 결정 (2026-05-23 21:40 KST): v2.4 Harness Recovery 기준 4트랙 병렬 + ANU-Codex loop 자동수렴

## 목표 (회장 verbatim)
박제/spec 수준이 아니라 ANU 본체의 위험 tool call 을 실행 전 차단하는 Harness-first 구조를 만든다. 단 live `~/.claude/settings.json` 직접 수정은 최종 회장 승인 전까지 금지.

## 4 트랙 (병렬)

### Track A — PreToolUse Hook Enforcement
- `hooks/pre_tool_use_anu_guard.py` draft (staged · live 미적용)
- `memory/specs/staged_settings_template_pre_tool_use_anu_guard_260523.json`
- `memory/events/pre_tool_use_anu_guard_dry_run_report_260523.json` (deny/allow report)
- forbidden Bash pattern 5 그룹 deny + fail-closed + deny-to-retry allowed_alternative 포함

### Track B — Watcher Contract / Dead-letter
- `schemas/watcher_contract_v1.json` (9 필수 필드 + owner/collector_role 위장 차단)
- `schemas/watcher_dead_letter_v1.json` (4 dead-letter state)
- TTL 만료 후 ANU 직접 polling 복귀 금지

### Track C — PR Open Watcher Auto-Wrapper
- `utils/pr_open_watcher_wrapper.py` (dry-run only · live `gh pr create` 호출 0)
- `tests/fixtures/pr_open_watcher_wrapper/<6 시나리오>/{evidence,expected,PROVENANCE}` (18 file)
- bzaona6au 사건 fixture 재현

### Track D — Repo Regression / CI Guard
- `tests/regression/test_forbidden_bash_pattern_static_guard.py`
- `tests/regression/test_anu_direct_polling_violation_guard.py` (PR #145 박제 승격 7 acceptance)
- `tests/regression/test_watcher_contract_validation.py`
- `tests/regression/test_pr_open_watcher_wrapper_dry_run.py`
- `tests/regression/test_closeout_grade_auto_classifier.py`
- `utils/closeout_grade_auto_classifier.py` (4 enum: DOCUMENTED_ONLY / REGRESSION_GUARDED / RUNTIME_GUARDED / HARNESS_ENFORCED)

## 12 완료 산출물 (회장 verbatim 1:1)
1. task-2643 spec → 본 spec md
2. PreToolUse hook draft → `hooks/pre_tool_use_anu_guard.py`
3. staged settings template → `memory/specs/staged_settings_template_pre_tool_use_anu_guard_260523.json`
4. deny/allow dry-run report → `memory/events/pre_tool_use_anu_guard_dry_run_report_260523.json`
5. watcher contract schema → `schemas/watcher_contract_v1.json`
6. watcher dead-letter schema → `schemas/watcher_dead_letter_v1.json`
7. PR open watcher wrapper dry-run → `utils/pr_open_watcher_wrapper.py` + fixture
8. bzaona6au violation fixture → `tests/fixtures/forbidden_bash_pattern/bzaona6au_violation_replay/`
9. delegated watcher allow fixture → `tests/fixtures/watcher_contract/delegated_watcher_allow/`
10. closeout grade auto-classifier → `utils/closeout_grade_auto_classifier.py` + regression
11. rollback plan → `memory/specs/task_2643_rollback_plan_260523.md`
12. final activation packet → `memory/specs/task_2643_final_activation_packet_template_260523.json`

## ANU-Codex loop (회장 verbatim)
- non-critical finding (lint/test/schema/style/quality/medium/non-critical HIGH) → 자동수렴
- Codex final verdict 명시
- PASS_WITH_RECOMMENDATIONS → recommendations acceptance backlog 기록 후 계속 진행

## 공통 acceptance (회장 verbatim 10 + 1)
- live settings.json 수정 0
- PR #141 pilot 0
- BOT App token 사용 0
- chair_authorization 발급 0
- real auto-merge activation 0
- production PR lifecycle activation 0
- finish-task.sh / cokacdir / replacement_pr_runner 수정 0
- foreign dirty cleanup 0
- destructive git/rm/reset/force push 0
- PR #145와 task-2643 혼합 0 (별도 worktree / 별도 PR)
- forbidden 25종 무수정 (15 + owner_trigger 4 + owner_gemini_trigger_router 3 + ci_watch_handoff_runner 3)

## 회장 보고 트리거 (verbatim 6)
- Critical7 hit
- credential expansion
- permission expansion
- live settings 적용 시도
- GitHub destructive write
- forbidden target 수정

## 허용 (회장 verbatim)
- spec/schema/fixture/test/hook draft/staged settings template/dry-run runner/rollback plan 작성
- ANU-Codex loop 반복
- 병렬 subagent fan-out (4 트랙 동시)
- non-critical lint/test/schema finding 자동수렴
- PASS_WITH_RECOMMENDATIONS continue

## 필수 regression
- 신규 Track D 5 regression PASS
- 기존 baseline 유지 (PR #145 merge 후 main 기준 추정 1576+ · PR #145 미merge 시 1493)
- full new fail 0 (3 pre-existing test_stash_origin_audit_compat 무관)

## expected_files (task-2643 범위 · ~50 file 추정)
- spec/template 4 (본 spec md + staged settings template + rollback plan + activation packet)
- hook 1 (`hooks/pre_tool_use_anu_guard.py`)
- schemas 2 (`schemas/watcher_contract_v1.json` + `schemas/watcher_dead_letter_v1.json`)
- utils 2 (`utils/pr_open_watcher_wrapper.py` + `utils/closeout_grade_auto_classifier.py`)
- fixture 24 (Track C 6 시나리오 × 3 + Track D 6 시나리오 × 3 + INDEX)
- regression 5 (Track D)
- dry-run report 1 (events JSON)

## finalize 프로토콜 (★ BOT App token 부재 — 로컬 한정)
1. base = origin/main 최신 clean
2. 신규 helper + schema + fixture + regression PASS · 기존 baseline 유지 · full new fail 0
3. **로컬 commit 만** (push/PR/merge 금지)
4. ANU normal callback (★ 본 task = harness enforcement 자체 자기검증 강제):
   - validate_spawn_callback_contract self-check (task-2640 결선 active)
   - envelope 5축 + canonical_root=/home/jay/workspace 명시
   - REGISTERED + schedule_id non-null + DELIVERED + UNCONFIRMED
   - envelope UTF-8 ≤3900 bytes
   - result.json 에 callback prompt UTF-8 byte 수 기록
5. ANU collector key: c119085addb0f8b7
6. executor 시작/종료 ts + 로컬 commit SHA 명기

## frozen anchor
- ANCHOR-1: "본 task = Harness-first 구조 · ANU 본체 위험 tool call 실행 전 deny · 박제/spec 수준 넘어선 실 enforcement"
- ANCHOR-2: "4 트랙 병렬 (A PreToolUse Hook / B Watcher Contract+Dead-letter / C PR Open Watcher Auto-Wrapper / D Repo Regression+Auto-Classifier)"
- ANCHOR-3: "12 완료 산출물 1:1 박제"
- ANCHOR-4: "live settings.json 수정 0 (staged template + dry-run 까지만) · 회장 최종 승인 후 별도 task"
- ANCHOR-5: "fail-closed (hook timeout/parse error/config missing → DENY · allow fallback 금지)"
- ANCHOR-6: "watcher contract 9 필드 + dead-letter 4 state · owner/collector_role 위장 폴링 차단"
- ANCHOR-7: "closeout grade 4 enum 자동 산정 · 수동 선언 authoritative 아님"
- ANCHOR-8: "ANU-Codex loop + 병렬 subagent fan-out · PR #145 혼합 0 · PR #141 pilot 0 · real auto-merge 0"
- ANCHOR-9: "PR #145 / bzaona6au 사건 fixture 박제 (Track C + Track D cross-link)"
- ANCHOR-10: "v2.4 Harness Recovery 정합 · 회장 verbatim 2026-05-23 21:40 KST"

## callback envelope byte-limit 정책 (★ task-2612+3 박제 강제)
- callback prompt UTF-8 ≤3900 bytes hard limit · 3500+ warning
- envelope 만 포함 · 상세는 result.json/report.md 위임
- 측정: `printf '%s' "$P" | wc -c` (wc -c · NOT wc -m)
- result.json 에 callback prompt UTF-8 byte 수 기록 강제
