# CALLBACK_AUTHORITY_AND_SESSION_CONTINUITY_NEXT_HARDENING_PACKET_READY (★ priority 3 read-only packet)

- 작성 시각: 2026-05-26T20:10 KST
- 작성자: ANU 본 chair-facing session (`53e89540-5bed-4692-a726-ed857820758a`)
- 모드: **read-only design packet** (★ 회장 verbatim · 코드 수정 0)
- 회장 verbatim 강제 적용: "doctrine 설명만 쓰지 말고 실제 py/sh/yaml wiring 위치 기준 / 누가 어떤 argv/env/session/key 전달 / 6 사고 layer mapping"
- chair_authorization_id: (★ 회장 야간 통합 지시 priority 3 → 본 packet 자동 진행 승인)

## 0. 현재 코드 wiring 상태 baseline (★ 2026-05-26 20:00 origin/main 319170b9 기준)

### A. scripts/finish-task.sh (1149 lines)

★ **callback / cron / cokacdir / collector / envelope / ANU_KEY / chair_facing 결선 0건** (★ grep evidence).

존재 line 2건:
- L466: Gemini 리뷰 fallback 제거 주석 (★ callback 무관)
- L1141: `# 보고서 + .followup.txt 기반 회장결정/머지/미해결/다음단계 cron 발송` (★ comment 만 · 실 호출 0)

→ **finish-task.sh 는 normal callback 을 발사하지 않는다.** task md doctrine 만 의존 → 봇이 자율적으로 호출해야 하는데 실제 호출 0건이 task-2693 사고 직접 원인.

### B. dispatch/__init__.py (192KB · 4 cokacdir --cron call sites)

- L2879-2900: `cokacdir --cron` 호출 = **봇 spawn cron 등록** (★ work dispatch · ANU callback 아님)
- L3215-3246: `cokacdir --cron` fallback = **봇 spawn 재시도** (★ work dispatch · ANU callback 아님)
- L3848-3869: `cokacdir --cron` 호출 = 봇 spawn (★ work dispatch)
- L4034-4056: cron_response 처리

→ **dispatch/__init__.py 의 `cokacdir --cron` 4 site 모두 봇 work dispatch · ANU normal callback 등록 site 0**.

### C. dispatch/prompt.py (504B)

facade only. 본체 dispatch/__init__.py.

### D. utils/ 의 callback files (★ main 에 존재)

- `callback_adjudicator_v2.py` (★ collector spawn 후 분류 logic)
- `callback_collector_helper_integration.py`
- `callback_next_action_runner_v2.py` (★ adjudicator 후 다음 액션)
- `completion_callback_operational_cancel_seam.py`
- `normal_completion_callback_collector_entrypoint.py` (★ ANU collector spawn entry)
- `operational_collector_wiring.py`

→ **collector 측 (downstream) wiring 은 존재**. **registrar 측 (upstream) wiring 은 부재** — 즉, 봇이 cokacdir --cron 으로 ANU spawn 발사하는 site 0건.

### E. PR #152 추가 시 변화 (★ bd3f7ee head)

- `dispatch/normal_fallback_callback_helper.py` (★ helper 신규 251 lines)
- `utils/callback_authority_4source_validator.py` (★ Verdict + validate 189 lines)
- `schemas/anu_normal_callback_envelope_v1.json` (★ envelope schema 92 lines)
- `scripts/finish-task.sh` +20/-5 (★ task-2686+1 base 만 · callback wiring 코드 grep evidence 필요 / 본 packet read-only 검증)

→ helper 와 validator 추가됨 / **finish-task.sh 가 helper 를 호출하는 결선이 들어갔는지 task-2694 가 확인+enforce 해야 함**.

### F. task-2694 가 채워야 하는 4 wiring gap (★ 회장 verbatim 9 필수구현 + dogfood 10 조건의 코드 위치)

| gap | wiring 위치 | 채워야 할 행위 |
|---|---|---|
| 1 | `scripts/finish-task.sh` (1149 lines 어딘가에 callback 단계 신규 삽입) | (a) `cokacdir --cron --key c119085addb0f8b7 --session 53e89540-...` 호출 (b) schedule_id 회수 (c) schedule_history `<sid>.log` status=ok grep (d) registration 실패 시 exit non-zero · .done 생성 차단 |
| 2 | `dispatch/normal_fallback_callback_helper.py` | (a) build envelope (b) actual cron 발사 enforce (c) `schedule_type=to_be_registered_by_finish_task_sh` 어구 작성 금지 (d) ANU key 강제 |
| 3 | `utils/normal_callback_registration_validator.py` 신규 | (a) 4 source validation 진입점 (b) schedule_id + schedule_history + owner_key + inbound 모두 PASS 시에만 PASS (c) `_load_schedule_history` 실 파일 read |
| 4 | `utils/callback_registration_marker.py` 신규 | (a) NORMAL_CALLBACK_NOT_REGISTERED marker auto-emit (b) `memory/events/<task_id>.normal-callback-not-registered.json` 작성 (c) `.done.escalated` 대체 정책 |

---

## 1. SECTION 1 — Deterministic Callback Authority Verifier (7 sources)

### 1.1 7 source 코드 레벨 정의

| source | 코드 위치 (★ PR #152 + task-2694 head 가정) | argv / env / file / runtime 매개 | self-key 검출 logic |
|---|---|---|---|
| **envelope key** | `memory/events/anu_callback/<task_id>-normal-completion.json` `owner_key` field | static file read | `owner_key != ANU c119085addb0f8b7` → ENVELOPE_OWNER_NOT_ANU |
| **runtime owner key** | `dispatch/normal_fallback_callback_helper.py` 의 `build_anu_owned_callback_request()` 내부 변수 `owner_key` | env `ANU_KEY` 또는 argv `--key` | hard-coded `ANU c119085addb0f8b7` 외 비교 시 reject |
| **actual cron owner** | `cokacdir --cron-history <SID> --key <K>` 응답의 channel owner | external CLI invocation | response 가 `not found` → ACTUAL_CRON_OWNER_NOT_ANU 또는 NOT_REGISTERED |
| **collector runtime key** | `utils/normal_completion_callback_collector_entrypoint.py` 의 spawn argv 의 `--key` 또는 spawn env `OWNER_KEY` | spawn argv | spawn key ≠ ANU 시 SELF_COLLECTOR |
| **schedule_history owner** | `/home/jay/.cokacdir/schedule_history/<sid>.log` JSON 의 `owner_key` field 또는 `chat_id`/`key_hash` proxy | filesystem read | line 부재 → NOT_REGISTERED · `owner_key ≠ ANU` → SELF_COLLECTOR |
| **authoritative receipt** | `memory/events/anu_callback/task-<id>-normal-completion.received.json` (★ collector spawn 후 작성) | filesystem write at collector spawn | 파일 부재 → ENVELOPE_ONLY |
| **self-key detection** | bot_settings.json `bot_key` vs envelope `owner_key` 비교 | runtime comparison | bot self_key 가 envelope.owner_key 또는 actual_cron_owner 와 일치 시 SELF_KEY_REGISTRATION |

### 1.2 verifier 호출 흐름 (★ 7 source 모두 검증 후 verdict)

```text
# 호출 site: utils/normal_callback_registration_validator.py (task-2694 신규)
verdict = validate_all_7(
    envelope_path="memory/events/anu_callback/<tid>-normal-completion.json",
    expected_anu_key="c119085addb0f8b7",
    schedule_id_after_cron_register=<from cokacdir --cron return>,
    schedule_history_root="/home/jay/.cokacdir/schedule_history",
    bot_self_key=<from env or bot_settings>,
    chair_facing_sid="53e89540-5bed-4692-a726-ed857820758a",
)
if not verdict.passed:
    emit_marker(NORMAL_CALLBACK_NOT_REGISTERED, verdict)
    sys.exit(non_zero)
```

★ **PR #152 의 `callback_authority_4source_validator.validate()` 는 위 7 중 4만 검증** (envelope owner + actual cron + schedule_history + 3 SID). task-2694 는 나머지 3 (runtime owner / collector runtime key / authoritative receipt) 보강 + finish-task.sh 결선.

---

## 2. SECTION 2 — Chair-facing Session Continuity (5 wiring)

### 2.1 SID propagation chain (★ dispatch → bot → helper → callback)

```text
[dispatch.py]
  → spawn cokacdir --cron --session 53e89540-... --key <BOT_KEY>
    ※ dispatch/__init__.py L2883-2898 (★ 현재 cron 호출 site)

[bot session spawn (cokacdir)]
  → CHAIR_FACING_SESSION_ID env or argv 주입
    ※ 현재 wiring 검증: cokacdir CLI 의 --session arg 전달 chain 확인 필요

[finish-task.sh]
  → 봇 작업 완료 시 callback 단계 진입
    ※ 현재 L1141 comment만 · 실 호출 0 (★ task-2694 가 신규 wiring)

[helper: dispatch/normal_fallback_callback_helper.py]
  → build_anu_owned_callback_request(
      owner_key=ANU,
      chair_facing_sid="53e89540-...",
      collector_sid="53e89540-...",
      delivery_sid="53e89540-...",
    )
  → cokacdir --cron --session 53e89540-... --key c119085addb0f8b7 --at <T>
    ※ PR #152 의 helper 251줄에 build 함수 존재 / cron 호출 결선 확인 필요

[cokacdir cron fire]
  → ANU collector spawn (★ 새 process · session id 인계 여부 = chair-facing continuity 핵심)
    ※ cokacdir --session argv 가 spawn 된 collector 의 chair-facing 세션 인지 결정

[utils/normal_completion_callback_collector_entrypoint.py]
  → collector startup
  → 본 chair-facing session 53e89540 와 동일 session_id 로 inbound deliver
    ※ 현재 wiring: collector entrypoint 가 chair_facing_sid 인지 / 본 ANU session 인지 검증 필요
```

### 2.2 5 wiring location (★ 회장 verbatim section 2 enum)

| wiring | 현재 main 상태 | PR #152 추가분 | task-2694 enforce | 누가 argv/env 전달 |
|---|---|---|---|---|
| `cokacdir --session` propagation | dispatch 가 `--session` 미전달 시 봇 spawn 새 session | helper(`dispatch/normal_fallback_callback_helper.py`) 가 `--session 53e89540-...` 전달 코드 추가 | finish-task.sh 가 helper 호출 시 `CHAIR_FACING_SESSION_ID` env 전달 | dispatch → bot env / bot → helper argv |
| dispatch → bot → helper → callback 전체 SID chain | chain L1~L4 자르지 않고 propagate 보장 wiring 부재 | helper 가 envelope 3 SID 모두 chair_facing_sid 동일값 작성 | finish-task.sh 가 helper 결과 envelope schema 검증 후 actual cron 발사 | bot session env `CHAIR_FACING_SESSION_ID` → helper argv |
| fresh collector spawn vs current chair-facing session routing | collector 가 새 session spawn 시 chair-facing inbound 0 (★ task-2684 사고) | collector entrypoint 가 routing 결정 시 chair_facing_sid 매핑 | task-2687.reserved durable registry 활용 또는 sid registry 조회 | cokacdir CLI → collector process env |
| inbound continuity guarantee | collector spawn → ANU chat 도착 보장 부재 (★ task-2684) | envelope schema 에 chair_facing_session_id 필수 (★ PR #152 schema 92줄) | finish-task.sh 가 collector receipt 도착 polling 또는 ANU heartbeat 확인 후 PASS | collector 가 `memory/events/anu_callback/<tid>-normal-completion.received.json` 작성 |
| collector routing policy | 6일간 8 사고 (★ AUTHORITATIVE 3 모두 chair-facing inbound 0) | helper 가 envelope ANU key 강제 작성 | finish-task.sh 가 receipt 도착 verification 또는 N분 timeout fallback | dispatch 가 fallback safety-net cron 추가 등록 ([[feedback_dispatch_must_register_fallback_safetynet_260520]]) |

---

## 3. SECTION 3 — Callback Lifecycle States Enum (8 states)

| enum | 정의 | 검출 logic 위치 | 발생 사고 |
|---|---|---|---|
| **AUTHORITATIVE** | 7 source 모두 PASS · chair-facing inbound 도착 | `validator.validate_all_7().passed == True` AND receipt 파일 존재 | task-2645 EBEF96C8 |
| **SELF_COLLECTOR** | actual cron channel owner ≠ ANU (★ 봇 self-key 등록) | `_is_anu(actual_cron_owner_key) == False` | task-2625 D4CE6C8D · task-2644 9CAB9D33 |
| **NOT_REGISTERED** | actual cron 등록 0 · cokacdir 호출 0 또는 응답 not found | `cokacdir --cron-history` not found AND schedule_history `<sid>.log` 부재 | task-2634 · task-2693 (★ NORMAL_CALLBACK_NOT_REGISTERED) |
| **SESSION_DISCONTINUITY** | AUTHORITATIVE 통과 but chair_facing_session 단절 (★ collector 새 session spawn) | receipt 파일 작성 위치 vs chair_facing_sid 불일치 | task-2684 |
| **STALE_COLLECTOR** | collector spawn 후 N분 timeout 도래 시까지 inbound 0 | collector watchdog timeout | (★ task-2684 변형) |
| **ENVELOPE_ONLY** | envelope 작성 / cron 발사 0 / receipt 0 | envelope 파일 존재 AND actual cron not found AND receipt 파일 부재 | task-2693 (★ envelope `to_be_registered_by_finish_task_sh` 자기 자백) |
| **OWNER_MISMATCH** | envelope.owner_key ≠ actual_cron_owner_key (★ envelope text 정확 / cron 등록 self-key) | `env_owner != actual_owner` cross-check | task-2691+a 725DEFDF (★ envelope ANU 텍스트 / actual dev6 self) |
| **CALLBACK_BYPASS** | callback 단계 스킵 (★ finish-task.sh 가 callback 호출 0 또는 ESCALATED bypass) | finish-task.sh callback enforce site 호출 부재 | task-2693 state_file_missing → callback 단계 스킵 |

---

## 4. SECTION 4 — Hard Fail Gates (8 gates)

| gate | code-level 위치 (★ task-2694 신규) | fail-closed 행위 | 6 사고 mapping |
|---|---|---|---|
| **actual cron absent** | `validator.validate_all_7()`: cokacdir --cron-history not found | exit non-zero · marker NOT_REGISTERED · .done 차단 | task-2634 · task-2693 |
| **state_file_missing** | finish-task.sh: `[ -f /home/jay/workspace/.tasks/state/$TID.json ]` not exist | exit non-zero (★ .done 생성 금지 · 현재는 ESCALATED 발급 후 봇이 .done 생성 시도) | task-2693 (★ ESCALATED 후 봇 .done 생성) |
| **envelope-only** | validator: envelope 존재 AND actual cron not found | NORMAL_CALLBACK_NOT_REGISTERED marker · HOLD_FOR_CHAIR | task-2693 (★ `to_be_registered_by_finish_task_sh` 어구) |
| **callback registrar skip** | finish-task.sh: helper 호출 site grep 0 시 fail | finish-task.sh exit non-zero | task-2693 (★ helper 호출 site 부재) |
| **owner mismatch** | validator: envelope.owner_key != actual_cron_owner_key | OWNER_MISMATCH classification | task-2691+a |
| **collector mismatch** | collector entrypoint: spawn key ≠ ANU | SELF_COLLECTOR classification | task-2625 · task-2644 |
| **stale callback** | collector watchdog timeout 도래 | STALE_COLLECTOR marker | task-2684 변형 |
| **missing authoritative receipt** | validator: receipt 파일 부재 + 5분 grace period | ENVELOPE_ONLY 또는 SESSION_DISCONTINUITY | task-2684 |

---

## 5. SECTION 5 — Wiring Locations (7 locations)

### 5.1 wiring location 별 책임 + argv/env/key 전달

| location | 파일 경로 (★ task-2694 후) | 책임 | 전달해야 할 argv/env/session/key |
|---|---|---|---|
| **finish-task.sh** | `scripts/finish-task.sh` L1141 인근 신규 callback 단계 삽입 | (a) state file 존재 검증 (b) helper 호출 (c) actual cron 등록 evidence 검증 (d) registration 실패 시 exit non-zero | env: `TASK_ID` · `CHAIR_FACING_SESSION_ID` · `ANU_KEY=c119085addb0f8b7` |
| **helper** | `dispatch/normal_fallback_callback_helper.py` (PR #152 추가 251줄 · task-2694 가 actual cron 발사 enforce 추가) | (a) build envelope (b) cokacdir --cron 실제 호출 (c) schedule_id 회수 (d) envelope 에 schedule_id 명기 (e) deferred 어구 작성 금지 | argv: `--task-id` · `--session 53e89540-...` · `--key c119085addb0f8b7` · `--at <T>` |
| **callback registrar** | `utils/anu_callback_registrar.py` (★ main 부재 · task-2694 가 신규? 또는 PR #152 가 추가하는지 검증 필요) | (a) helper 결과 envelope schema validate (b) registrar 호출 일관성 보장 | argv: envelope path · helper output path |
| **dispatch propagation** | `dispatch/__init__.py` L2879-2900 (★ 봇 spawn cron 호출 site) | (a) 봇 spawn 시 `--session 53e89540-...` argv 전달 (b) bot env `ANU_KEY=c119085addb0f8b7` 노출 (c) bot env `CHAIR_FACING_SESSION_ID` 전달 | dispatch 가 봇 spawn cron 발사 시 argv |
| **cokacdir --session** | external CLI `/usr/local/bin/cokacdir` | (a) --session argv 받으면 cron 등록 시 metadata 저장 (b) cron fire 시 spawn 된 collector 에 session env 인계 (c) schedule_history `<sid>.log` 에 session 명기 | cokacdir 내부 (외부 CLI · ANU 본 packet 변경 금지) |
| **schedule_history** | `/home/jay/.cokacdir/schedule_history/<sid>.log` | (a) cron fire 시 JSON line append (b) status field · owner_key field · session_id field 명기 | cokacdir 내부 write |
| **ANU collector entrypoint** | `utils/normal_completion_callback_collector_entrypoint.py` (★ main 존재) | (a) collector spawn 시 chair_facing_sid env 확인 (b) chair-facing inbound 라우팅 (c) receipt 파일 작성 `memory/events/anu_callback/<tid>-normal-completion.received.json` | spawn env: `CHAIR_FACING_SESSION_ID` · `OWNER_KEY` |

---

## 6. 6 사고 layer mapping (★ 회장 verbatim 강제 적용)

| 사고 | 일자 | 봇 | schedule_id | 분류 | 실패 layer | 코드 wiring 갭 |
|---|---|---|---|---|---|---|
| **task-2625** | 2026-05-21 | dev6 페룬 | D4CE6C8D | NORMAL_CALLBACK_SELF_KEY_REGISTRATION / SELF_COLLECTOR | layer 1 (registrar) + layer 2 (helper) | helper 가 ANU key 강제 import 0 → 봇이 자기 key 로 cron 등록 |
| **task-2634** | 2026-05-23 | dev6 페룬 | (미발사) | NORMAL_CALLBACK_NOT_REGISTERED 변종 1 | layer 1 (finish-task.sh) | 봇이 envelope 작성만 / cokacdir --cron 호출 0 / sendfile 만 |
| **task-2644** | 2026-05-24 | dev1 헤르메스 | 9CAB9D33 | NON_AUTHORITATIVE_SELF_COLLECTOR | layer 2 (helper) + layer 4 (dispatch propagation) | helper 호출 site self-key fallback / dispatch ANU_KEY env 미전달 |
| **task-2645** | 2026-05-24 | dev2 오딘 | EBEF96C8 | AUTHORITATIVE_CALLBACK_COLLECTOR_PROCESSED | (★ 성공 케이스 · 봇이 ANU key 명시 사용) | wiring 부재인데 봇 자율로 ANU key 발사 → 우연한 PASS / 표준 wiring 없음 |
| **task-2684** | 2026-05-26 | dev1 헤르메스 | (★ 9CAB9D33 분석 후속) | AUTHORITATIVE_BUT_SESSION_DISCONTINUITY | layer 5 (cokacdir --session) + layer 7 (collector entrypoint) | cokacdir cron 발사 시 --session 미전달 → collector 새 session spawn / chair-facing inbound 0 |
| **task-2693** | 2026-05-26 | dev2 오딘 | (★ envelope 작성만) | NORMAL_CALLBACK_NOT_REGISTERED 변종 2 (★ envelope-only + state_file_missing) | layer 1 (finish-task.sh) + layer 4 (dispatch propagation) | finish-task.sh callback wiring 0 / state_file_missing escalate 후 .done 생성 / 봇 envelope `to_be_registered_by_finish_task_sh` 어구 deferred 우회 |

### 6.1 분류별 layer 책임

- **layer 1 (finish-task.sh)** 실패 → 3건 (task-2634 · task-2693 · 부분 task-2684)
- **layer 2 (helper)** 실패 → 2건 (task-2625 · task-2644)
- **layer 4 (dispatch propagation)** 실패 → 3건 (task-2644 · task-2693 · 부분 task-2684)
- **layer 5 (cokacdir --session)** 실패 → 1건 (task-2684)
- **layer 7 (collector entrypoint)** 실패 → 1건 (task-2684)

→ **finish-task.sh callback wiring (layer 1)** 이 가장 큰 갭. **task-2694 = layer 1 + layer 2 (helper actual cron 발사 enforce) 중심**.

### 6.2 task-2694 dogfood 시 검증할 8 사고 미발생 evidence

task-2694 본인 dogfood 가 PASS 하려면 위 6 사고 패턴 모두 미발생 evidence 필요:

1. ✓ `validate_all_7().passed == True`
2. ✓ envelope.owner_key = ANU
3. ✓ actual_cron_owner_key = ANU (★ self-key 아님)
4. ✓ `cokacdir --cron-history <SID> --key c119085addb0f8b7` hit (★ NOT_REGISTERED 아님)
5. ✓ schedule_history `<sid>.log` status=ok
6. ✓ `memory/events/anu_callback/task-2694-normal-completion.received.json` 작성 (★ collector spawn evidence)
7. ✓ chair_facing_sid = `53e89540-5bed-4692-a726-ed857820758a` (★ SESSION_DISCONTINUITY 아님)
8. ✓ envelope `schedule_type` ≠ `to_be_registered_by_finish_task_sh` / deferred / pending (★ ENVELOPE_ONLY 아님)

---

## 7. 회장 verbatim 후속 결정 대기 항목 3

1. **PR #152 unresolved thread 1건** 처리 정책 (★ task-2694 PASS 후 PR #152 재평가 시 별도 mini-task or 회장 verbatim 인정)
2. **layer 5 (cokacdir --session)** = 외부 CLI · ANU 변경 금지 영역 / 우회 wiring 결정 (★ env propagation 또는 file-based registry)
3. **task-2687.reserved durable registry** 활성화 결정 (★ 본 packet 의 chair_facing_sid routing 강화)

---

## 8. ANU 본 세션 자동 진행 규칙 (★ 회장 야간 보고 규칙)

- 본 packet 작성 = 자동 진행 (★ marker 누적만)
- task-2694 callback inbound 도착 시: 8 evidence 1:1 verdict + 10 dogfood 조건 + 12 즉시 보고 trigger 교차 검증
- 12 trigger 미발견 + 10/10 PASS → DOGFOOD_PASSED marker + 회장 보고 (★ priority 1 산출물)
- 12 trigger 1+ 발견 → 즉시 회장 보고

끝
