# ANU_CALLBACK_COLLECTOR_CONTROL_PLANE spec (task-2644) — 260524

회장 결정 (2026-05-24 00:50 KST · PR #146 task-2643 처리 중 dev6 callback 미인지 사건 후): **ANU collector 세션이 callback을 단순 log 저장 후 종료하지 않고, 자율 판단과 다음 action 까지 수행하게 만든다. Harness 단독으로 전체 자동화 불가능 · Harness + cokacdir + file-state control plane 결합 으로 가능.**

기반: `system_ci_watch_handoff_policy_spec_260523.md` (정책) + `system_ci_watch_handoff_runner_spec_260523.md` (runner) + `system_ci_watch_handoff_runtime_enforcement_gate_spec_260523.md` (Track A PreToolUse Hook) + PR #146 회장↔ANU 대화 (callback session-bound 한계 + 거짓말 사고 박제) + `ANU_v3_master_development_direction_final_260517_v2_4_harness_recovery.md`.

---

## 1. 본 task 범위

### 1.1 핵심 원칙 (회장 verbatim)
- **Harness 단독으로 전체 자동화 불가능** (ANU 외부 daemon 의존)
- **Harness + cokacdir + file-state control plane 결합** 으로 자동화 결선 가능
- **live `~/.claude/settings.json` 수정 0**, **live cokacdir 수정 0**, **live `claude --resume` 적용 0**
- **본 ANU 대화 세션 hook 감지 = 이중 안전망**, **주 경로 아님** (주 경로 = ANU collector 자율 진행)
- **PR #146 와 혼합 0** (별도 worktree / 별도 PR)

### 1.2 핵심 구조 (회장 verbatim flow)

```
dev bot normal callback
    ↓
cokacdir가 ANU collector 세션 spawn
    ↓
SessionStart hook이 ANU_CALLBACK_COLLECTOR 모드 강제
    ↓
collector가 task / spec / .anu_state / frozen anchor 로 context recovery
    ↓
callback adjudication (terminal_state / policy / Critical7 판정)
    ↓
next_action decision (11 enum 중 선택)
    ↓
자동 가능하면 다음 작업 dispatch
회장 결정 필요하면 Telegram report
    ↓
.callback ledger 기록
    ↓
Stop hook이 의무 완료 검증 후 종료 허용
```

---

## 2. 우선순위 8 (회장 verbatim 1:1)

1. **SessionStart hook** — collector mode 감지 + 의무 prompt/context 주입
2. **callback adjudicator** — terminal_state / policy / Critical7 판정
3. **next_action runner** — 자동 진행 or chair report 결정
4. **.callback ledger** — 처리 결과 durable 기록
5. **Stop hook** — 처리 의무 미완료/거짓 표현/next_action 누락 시 종료 차단
6. **batch callback aggregation** — 병렬 작업 all-settled 판단
7. **user_prompt_submit_hook .callback 감지** — 이중 안전망
8. **active session resume은 shadow 검증만, live 적용 금지**

---

## 3. SessionStart hook 요구 (회장 verbatim)

- **ENV `COKACDIR_MODE=ANU_CALLBACK_COLLECTOR`** 또는 callback envelope 존재 시 collector mode 감지
- **task_id / pr_number / callback_id / schedule_id 추출**
- **자동 로드**:
  - task md (`memory/tasks/<task_id>.md`)
  - spec md (frozen anchor 영역)
  - `memory/system/.anu_state.json` (ANU 회장 대화 영속화 state)
- **주입**:
  - frozen anchor 본문
  - forbidden action list
  - allowed auto action list
  - **collector 의무 7 단계**:
    1. envelope parse
    2. context recovery
    3. terminal_state classify
    4. next_action decide
    5. auto action or chair telegram
    6. .callback ledger write
    7. source attribution + exit

---

## 4. Stop hook 요구 (회장 verbatim · 종료 차단 8 조건)

- collector mode 에서 **callback_envelope_parsed** 없으면 종료 fail
- **context_recovered** 없으면 종료 fail
- **terminal_state_classified** 없으면 종료 fail
- **next_action_decided** 없으면 종료 fail
- **auto_action_dispatched / chair_report_emitted / noop_terminal_recorded / batch_wait_recorded** 중 하나 없으면 종료 fail
- **callback_ledger_written** 없으면 종료 fail
- **"callback received / 도착 / 수신" 표현 + source attribution 없으면** 종료 fail
- **schedule_history 사후 조회를 inbound 수신처럼 표현하면** 종료 fail

---

## 5. next_action enum (회장 verbatim 11)

1. `REQUEST_CHAIR_MERGE_APPROVAL`
2. `REPORT_CRITICAL7`
3. `REPORT_PERMISSION_OR_CREDENTIAL_EXPANSION`
4. `DISPATCH_AUTO_REMEDIATION`
5. `RERUN_ALLOWED_GATE`
6. `RUN_OWNER_GEMINI_TRIGGER_ROUTER`
7. `CREATE_FOLLOWUP_TASK_SPEC`
8. `WAIT_FOR_BATCH_SIBLINGS`
9. `BATCH_ADJUDICATE`
10. `NOOP_TERMINAL`
11. `HOLD_FOR_CHAIR`

---

## 6. 자동 진행 허용 (회장 verbatim 8)

- expected_files 내부 non-critical remediation
- phase3 timing race rerun
- allowed OWNER_GEMINI_TRIGGER_ROUTER nudge
- batch sibling callback wait
- all-settled batch adjudication
- follow-up task spec/preflight
- regression rerun
- callback ack/ledger update

## 7. 자동 진행 금지 (회장 verbatim 11)

- merge 실행
- live settings.json 적용
- live cokacdir 수정
- BOT App token 사용
- chair_authorization 발급
- PR #141 pilot
- production PR lifecycle activation
- expected_files 밖 수정
- credential/permission expansion
- admin override
- destructive git / foreign dirty cleanup

---

## 8. 필수 산출물 (회장 verbatim 15)

1. **SessionStart hook draft** → `hooks/session_start_anu_callback_collector.py`
2. **Stop hook draft** → `hooks/stop_anu_callback_collector_verifier.py`
3. **callback adjudicator module** → `utils/callback_adjudicator.py`
4. **next_action runner module** → `utils/callback_next_action_runner.py`
5. **callback ledger schema** → `schemas/callback_ledger_v1.json`
6. **next_action decision schema** → `schemas/callback_next_action_decision_v1.json`
7. **.anu_state minimal schema** → `schemas/anu_state_v1.json`
8. **batch callback aggregation schema** → `schemas/callback_batch_aggregation_v1.json`
9. **telegram chair report packet template** → `memory/specs/telegram_chair_report_packet_template_260524.json`
10. **source attribution guard** → `utils/source_attribution_guard.py` (Stop hook 사용)
11. **user_prompt_submit_hook .callback 안전망 확장안** → `hooks/user_prompt_submit_hook_callback_inbox.py` (staged · 이중 안전망)
12. **fixtures (7+)**:
    - MERGE_READY callback → REQUEST_CHAIR_MERGE_APPROVAL
    - Critical7 callback → REPORT_CRITICAL7
    - auto-remediation callback → DISPATCH_AUTO_REMEDIATION
    - sibling callbacks incomplete → WAIT_FOR_BATCH_SIBLINGS
    - final sibling callback → BATCH_ADJUDICATE
    - callback log only without next_action → fail
    - "callback received" misuse → fail
13. **regression tests** (각 fixture × adjudicator + next_action + Stop hook + source guard)
14. **rollback plan** → `memory/specs/task_2644_rollback_plan_260524.md`
15. **staged settings template** → `memory/specs/staged_settings_template_anu_callback_collector_260524.json`

---

## 9. 완료 등급 (회장 verbatim)

- **RUNTIME_GUARDED**: staged hook + dry-run + regression + ledger/adjudicator 구현
- **HARNESS_ENFORCED**: live settings 적용 + deny/allow/collector-mode live smoke + rollback 확인 후에만

본 task = **RUNTIME_GUARDED 까지만**. HARNESS_ENFORCED = 별도 회장 verbatim signature task.

---

## 10. 진행 방식 (회장 verbatim)

- task-2644 는 PR #146 과 섞지 않음 (별도 worktree / 별도 PR)
- 병렬 가능한 hook/schema/module/fixture/regression/telegram/report 작업 병렬화
- ANU-Codex loop 로 non-critical finding 자동수렴
- 회장 보고 트리거: Critical7 / live infra 변경 / credential/permission expansion 만

---

## 11. 금지 (회장 verbatim 6)

- live settings.json 수정 금지
- live cokacdir 수정 금지
- live `claude --resume` 적용 금지
- ANU 직접 CI/Gemini polling 금지
- PR #146 과 task-2644 혼합 금지
- BOT App token / chair_authorization / real auto-merge / PR #141 pilot 금지

---

## 12. acceptance (필수 조건)

- forbidden 28종 (기존 25 + 신규 3: hooks/* live · cokacdir live · claude --resume) 무수정 verified
- net-new credential 0 (PR scope)
- 신규 regression 전체 PASS
- 기존 baseline 유지 + 3 pre-existing 무관
- 본 ANU 직접 polling 0 (정책 dogfood)

---

## 13. frozen anchor

- ANCHOR-1: "본 task = ANU collector 자율 처리 + 다음 action 자동 진행 control plane · 박제/spec 수준 넘어 Harness+cokacdir+file-state 결합"
- ANCHOR-2: "Harness 단독 불가능 명시 (claude-code 본질 한계) · 협업 구조 필수"
- ANCHOR-3: "8 우선순위 산출물 + 15 필수 산출물 1:1 박제"
- ANCHOR-4: "SessionStart hook = collector mode 강제 자율 진행 / Stop hook = 의무 미완 거짓표현 종료 차단"
- ANCHOR-5: "next_action 11 enum + 자동 허용 8 + 자동 금지 11 명시"
- ANCHOR-6: "RUNTIME_GUARDED 까지만 본 task · HARNESS_ENFORCED = 별도 회장 verbatim signature task"
- ANCHOR-7: "본 ANU 대화 세션 hook = 이중 안전망 · 주 경로 아님"
- ANCHOR-8: "PR #146 task-2643 와 격리 · 별도 worktree / 별도 PR / 병렬 진행"
- ANCHOR-9: "거짓말 패턴 (수신 vs 사후 조회 흐림) Stop hook 으로 사전 차단"
- ANCHOR-10: "본 ANU 직접 polling 0 · 회장 verbatim dogfood 유지"

---

## 14. 회장 보강 5 (2026-05-24 01:10 KST · verbatim · dispatch 전 반영 필수)

### 14.1 source attribution enum 보강 (5 → 7)
기존 5 enum (RECEIVED_INBOUND_THIS_SESSION / LOG_LOOKUP_AFTER_CHAIR_QUESTION / LOG_LOOKUP_PROACTIVE / MEMORY_RECALL / INFERENCE_ONLY) 에 아래 2 enum 을 추가한다.

- **CALLBACK_COLLECTOR_PROCESSED**: collector 세션이 spawn 되어 inbound callback envelope 를 직접 받아 처리한 경우 (★ task-2644 의 주 경로)
- **CALLBACK_LEDGER_RECONCILED**: 이전 collector 세션 처리 결과를 ledger 에서 재조회/재확인한 경우 (post-hoc reconciliation)

**이유 (회장 verbatim)**: task-2644 의 핵심은 본 대화 세션 inbound 가 아니라 collector 세션이 callback 을 처리하고 ledger 에 기록한 것. 이를 표현할 source enum 이 없으면 received/lookup 표현이 다시 흐려진다.

### 14.2 next_action branch 명확화 (3 분기 mutually exclusive)

기존 spec §3 의 "자동 가능하면 다음 작업 dispatch / 회장 결정 필요하면 Telegram report" 를 아래 3 branch 로 정정한다.

- **auto-executable branch**: dispatch / rerun / nudge / batch_adjudicate 실행
  - 대상 enum: DISPATCH_AUTO_REMEDIATION / RERUN_ALLOWED_GATE / RUN_OWNER_GEMINI_TRIGGER_ROUTER / CREATE_FOLLOWUP_TASK_SPEC / WAIT_FOR_BATCH_SIBLINGS / BATCH_ADJUDICATE
- **chair-required branch**: Telegram chair report 의무 경로
  - 대상 enum: REQUEST_CHAIR_MERGE_APPROVAL / REPORT_CRITICAL7 / REPORT_PERMISSION_OR_CREDENTIAL_EXPANSION / HOLD_FOR_CHAIR
- **terminal noop branch**: noop_terminal_recorded
  - 대상 enum: NOOP_TERMINAL

**핵심 원칙**: Telegram 은 chair-required branch 에서만 의무 경로. auto-executable / terminal noop 에서 Telegram 발사 금지 (chair spam 방지).

### 14.3 merge policy lock (★ task-2644 범위 hard constraint)

- **MERGE_READY callback 의 기본 next_action 은 `REQUEST_CHAIR_MERGE_APPROVAL`** (hardcoded · override 불가)
- **collector 가 merge 실행 절대 금지**
- merge execution 허용 조건 (★ 본 task-2644 범위 아님):
  - pre-existing `merge_policy.auto_merge_allowed=true` (config 명시)
  - **AND** live auto-merge flag active
- **현재 task-2644 범위에서는 merge execution = 0 으로 고정** (hardcoded · 별도 회장 verbatim signature task 에서만 변경 가능)

### 14.4 .anu_state freshness 보강

`.anu_state` 단순 read 로는 부족. state freshness 강제 메커니즘:

- **회장-facing ANU 세션 의무**: 회장 verbatim 결정 수신 시 `.anu_state` append / update
- **task dispatch 시 의무**: `.anu_state` `snapshot_id` 또는 `state_version` 기록 (dispatch envelope 에 명시)
- **callback collector 의무**: `state_version` 검증 (envelope 의 snapshot_id vs 현재 .anu_state)
- **state mismatch / missing 시 fail-closed**:
  - `SAFE_DEGRADED_MODE` (제한된 next_action 만 허용 · NOOP_TERMINAL / HOLD_FOR_CHAIR 한정)
  - **OR** `HOLD_FOR_CHAIR` (next_action decision 자체를 chair 에게 위임)

### 14.5 next_action_result evidence (Stop hook 강화)

Stop hook 은 `next_action_decided` 만으로 부족. 실 실행 증거 검증:

**필수 필드 4종**:
1. `next_action_decided` (11 enum 중 어떤 것)
2. `next_action_attempted` (실 실행 시도 했는가)
3. `next_action_result` (아래 enum 중 하나)
4. `next_action_evidence_path` (증거 파일 path · cron-list/cron-history/telegram outbox/ledger entry)

**허용 result enum 6종**:
- `DISPATCH_REGISTERED`: cron 등록 성공 (schedule_id non-null)
- `TELEGRAM_SENT`: chair report 발사 성공
- `LEDGER_ONLY`: noop_terminal · ledger 기록만
- `HOLD_PACKET_CREATED`: HOLD_FOR_CHAIR 패킷 생성
- `BATCH_WAIT_RECORDED`: WAIT_FOR_BATCH_SIBLINGS 등록
- `FAILED`: 실 실행 실패 (재시도 또는 chair 보고)

**Stop hook 추가 종료 차단 조건 (8 → 9 조건)**:
- collector mode 에서 `next_action_result` 없으면 종료 fail
- `next_action_result=FAILED` 인데 recovery action 없으면 종료 fail

### 14.6 보강 5 반영 후 §4 Stop hook 종료 차단 조건 (8 → 10 조건)

1. callback_envelope_parsed 없으면 fail
2. context_recovered 없으면 fail
3. terminal_state_classified 없으면 fail
4. next_action_decided 없으면 fail
5. auto_action_dispatched / chair_report_emitted / noop_terminal_recorded / batch_wait_recorded 중 하나 없으면 fail
6. callback_ledger_written 없으면 fail
7. "callback received / 도착 / 수신" 표현 + source attribution 없으면 fail
8. schedule_history 사후 조회를 inbound 수신처럼 표현하면 fail
9. **(신규)** next_action_result 없으면 fail
10. **(신규)** state_version mismatch / .anu_state stale 인데 SAFE_DEGRADED_MODE / HOLD_FOR_CHAIR 둘 다 아니면 fail

### 14.7 추가 frozen anchor (10 → 13)

- ANCHOR-11: "source attribution enum 7 (★ CALLBACK_COLLECTOR_PROCESSED 가 주 경로 · received_inbound 흐림 차단)"
- ANCHOR-12: "next_action 3 분기 mutually exclusive · Telegram = chair-required 한정 의무 경로"
- ANCHOR-13: "merge execution 0 hardcoded · MERGE_READY → REQUEST_CHAIR_MERGE_APPROVAL only · pre-existing auto_merge_allowed + live flag 둘 다 active 일 때만 별도 task 에서 변경 가능"
- ANCHOR-14: ".anu_state freshness state_version 검증 · stale 시 SAFE_DEGRADED_MODE / HOLD_FOR_CHAIR fail-closed"
- ANCHOR-15: "Stop hook = decided + attempted + result + evidence_path 4 필드 + 6 result enum 검증 (decided 만 보지 않음)"

---

## 15. fixture 추가 (회장 verbatim 2026-05-24 · task-2643 1C0F6F52 사건 박제)

### fixture-8: fallback_safety_net_log_recovery_without_control_plane_adjudication

**상황 (실 사건 박제)**: task-2643 PR #146 처리 중 fallback safety-net (cron ID 1C0F6F52) 발사 → schedule_history chain (A5538865 / 4931B2AB / 4A8D4668 / F2ED77A3) status=ok 확인 → envelope 회수 → 그러나 callback control-plane protocol 미적용 (next_action_decision 0 / .callback adjudication 0 / source attribution 0).

**expected**:
- schedule_history chain ok ✓
- envelope recovered ✓
- next_action_decision ledger 부재 ✗
- .callback adjudication record 부재 ✗
- source attribution classification 부재 ✗
- **result = NOT_CONTROL_PLANE_COMPLIANT**

**검증 목적**: callback/fallback 세션이 envelope 회수 + status=ok chain 확인만 한 경우 NOT_CONTROL_PLANE_COMPLIANT 분류 강제. control-plane 적용 = 7 단계 protocol 완료 (envelope parse → context recovery → terminal_state classify → next_action decide → auto/chair/noop → ledger write → source attribution + exit) 모두 충족.

**source 분류 명시**: `LOG_LOOKUP_OR_SCHEDULE_HISTORY_VERIFICATION` (★ 회장 verbatim 추가 source) — `RECEIVED_INBOUND_THIS_SESSION` 아님.

### source attribution enum 7 → 8 (회장 verbatim 추가)

기존 7 enum + 추가 1:
- **LOG_LOOKUP_OR_SCHEDULE_HISTORY_VERIFICATION**: schedule_history / cron-history 기반 status=ok chain 사후 확인 (회장-facing ANU 세션에서 inbound 미수신 시 사용 · "ANU 수신 검증 완료" 표현 금지)
