# Callback Session Routing — Modular Wiring Gap 심층분석 (read-only)

- 작성: ANU 회장-facing 세션 (`53e89540-5bed-4692-a726-ed857820758a`) · 2026-05-26 KST
- 트리거 사고: task-2684 dev4 비슈누 callback `803000CA` — ANU key 정상 발사 + 본 chair-facing 세션 inbound 0 → 회장 "self-key 사고 또 발생?" 의심
- 회장 verbatim 2026-05-26: "왜 이런일이 또 발생한건지 원인 다시 전수조사 해서 앞으로 발생하지 않게 모듈화 결선 이슈 심층분석 보고"
- 범위: read-only audit + hardening proposal. 코드 수정 0 / commit 0 / push 0 / PR 0 / merge 0

---

## 1. Executive Summary

본 사고는 **self-key fraud 가 아니다**. ANU key (`c119085addb0f8b7`) 로 정상 발사된 callback 이 fresh ANU collector 세션을 spawn 하여 정상 처리했고, 본 chair-facing ANU 세션 (`53e89540`) 에는 inbound 0 이 되었다. 즉 **`AUTHORITATIVE_CALLBACK_COLLECTOR_PROCESSED` 유지** 이나, 회장 입장에서는 본 ANU 세션이 못 받았으므로 "self-key 사고?" 의심을 매번 트리거한다.

진짜 결함은 **`chair_facing_session_vs_fresh_collector_session_routing_gap`** — `cokacdir --cron` 의 `--session <SID>` 옵션이 존재하나, **봇 callback 발사 경로에 결선 0**. 본 gap 은 2026-05-18 ([[feedback_callback_session_discontinuity_and_canonical_root_260518]]) 이미 박제됐고 해결책 (`callback_4tuple durable registry`) 권고됐으나 **8일 경과 코드 결선 미구현 → 동일 패턴 재발**.

분류: `SESSION_PROPAGATION_GAP_SUBCLASS_OF_SESSION_DISCONTINUITY` (Critical7 아님 · 거버넌스 자동화 결함)

---

## 2. 사고 timeline (동일 패턴 9일 누적)

| 일자 | task / cron_id | actual owner | chair-facing inbound | 분류 |
|---|---|---|---|---|
| 2026-05-18 | task-2553+42 / `0B466540` | ANU key | 0 (cron-list 단독 부재) | SESSION_DISCONTINUITY (오판 → "callback 누락" 착시) |
| 2026-05-18 | task-2553+43 / `E2EC61F2` | ANU key | 0 (동일) | SESSION_DISCONTINUITY (동일) |
| 2026-05-18 | task-2553+47 / `FDB5F130` | **dev3 self-key** | n/a | NON_AUTHORITATIVE_SELF_COLLECTOR (★ 회장 직접 적발 — 다른 sub-class) |
| 2026-05-21 | task-2625 / `D4CE6C8D` | **dev6 self-key** | n/a | NON_AUTHORITATIVE_SELF_COLLECTOR (★ helper 미결선 재발) |
| 2026-05-23 | task-2634 / (cron 0) | n/a (★ 미등록) | n/a | NORMAL_CALLBACK_NOT_REGISTERED (★ envelope sendfile 만) |
| 2026-05-24 | task-2644 / `9CAB9D33` | **dev1 self-key** | n/a | NON_AUTHORITATIVE_SELF_COLLECTOR (★ self-key 재발) |
| 2026-05-24 | task-2645 / `EBEF96C8` | ANU key | 0 | AUTHORITATIVE + SESSION_DISCONTINUITY |
| 2026-05-26 | **task-2684 / `803000CA`** | **ANU key** | **0** | **AUTHORITATIVE + SESSION_DISCONTINUITY (★ 본 사고)** |

핵심 관측: ANU key 정상 발사 (`AUTHORITATIVE`) 케이스 3건 모두 본 chair-facing 세션 inbound 0. self-key fraud 와는 별도의 **routing gap** 이 일관 지속.

---

## 3. 모듈화 결선 gap — 4 layer 정체

### Layer 1: cokacdir `--session` 옵션 (★ 인프라는 존재)

```
--cron <PROMPT> --at <TIME> --chat <ID> --key <HASH> [--once] [--session <SID>]
```

`--session <SID>` 전달 시 해당 SID 세션 resume. **인프라 자체는 cokacdir 0.6.4 에 이미 구현됨**.

### Layer 2: ANU 시스템 프롬프트 (★ ANU 본 세션만 정책 인지)

> "When scheduling a task that CONTINUES or EXTENDS the current conversation, add `--session 53e89540-5bed-4692-a726-ed857820758a` to the --cron command so the scheduled task inherits this conversation context."

ANU 본 세션은 정책 인지 + 적용 가능. **그러나 봇은 ANU 의 chair-facing SID 를 모름** → 적용 불가.

### Layer 3: dispatch 시 봇에게 chair-facing SID 미전달 (★ 핵심 gap)

- `dispatch.py` / `team_prompts.py` / task md prompt 에서 봇에게 전달되는 것:
  - ANU key (`c119085addb0f8b7`)
  - ANU chat id (`6937032012`)
  - task_id
  - allowed_resources
- **누락**: chair-facing session SID (★ 본 ANU 세션 53e89540...)
- 봇 입장에서 알 방법 0 → callback envelope 작성 시 `--session` 옵션 미생성

### Layer 4: `dispatch/normal_fallback_callback_helper.py:build_anu_owned_callback_request` (★ ANU key 강제는 됐으나 --session 결선 0)

2026-05-18 task-2553+49 에서 코드 강제 실증 완료:
- `guard_callback_registration` (owner ≠ ANU 시 block) ✅
- `build_anu_owned_callback_request` (owner ≠ ANU 시 argv 미생성) ✅
- regression 164 PASS ✅

**그러나** helper 가 생성하는 argv 에 `--session <SID>` 누락:
```python
# 추정 (코드 audit 필요)
argv = ["cokacdir", "--cron", prompt, "--at", absolute_ts,
        "--chat", "6937032012", "--key", ANU_KEY]
# ★ --session 미포함
```

→ ANU key 정상 발사 후 fresh ANU 세션 spawn → chair-facing 세션 inbound 0

---

## 4. 근본 원인 (★ 박제만 있고 코드 결선 0)

### Root Cause 1: doctrine 텍스트만 박제 · 코드 결선 0 (★ 반복 사고의 공통 분모)

- [[feedback_callback_session_discontinuity_and_canonical_root_260518]] 박제: 5/18
- 해결책 `task-2553+44/+46 callback_4tuple durable registry` 권고
- 그러나 실제 코드 구현 시 `--session` propagation 누락 → 8일 후 동일 패턴 재발

### Root Cause 2: task-2646 HARNESS_ENFORCED_PENDING 상태 미해소

task-2646 closeout (2026-05-24) 명시:
- `live_cron_registration_zero`
- `live_dispatch_py_integration_smoke_zero`
- `real_operational_path_application_requires_separate_task_and_approval`

helper 코드 PASS (124 regression / helper 6/6) 하지만 **실제 봇 발사 경로에 helper 결선 0** → doctrine 만 적용되고 봇이 자율 발사 시 `--session` 누락.

### Root Cause 3: 회장 → 본 ANU 세션 routing 정책 부재

- ANU 는 한 명이지만 세션은 여러 개 가능
- 회장 입장에서 어느 ANU 세션이 callback 을 받았는지 불투명
- 본 chair-facing 세션이 "self-key?" 매번 의심 + 4-source 수동 검증 필요
- → ANU 본 세션 chair-facing 보존 보장 정책 부재

### Root Cause 4: durable 4-tuple registry 미구현

- 2026-05-18 권고 → 8일 미구현
- 본 ANU 세션이 cron-list 0 만 보고 self-key 의심
- 매번 schedule_history JSONL grep + response 어조 분석 + envelope 검증 수동
- registry 있으면 한 줄 query 로 source attribution + chain 확인 가능

---

## 5. Hardening 제안 (4 Tier · 회장 결정 대기)

### Tier 1 — doctrine 강화 (★ 코드 변경 0 · 즉시 적용 가능)

1. ANU dispatch prompt template 에 다음 강제 명시:
   ```
   ★ callback envelope 작성 시 cokacdir --cron 호출에 반드시 --session <CHAIR_FACING_SID> 옵션 포함
   ★ CHAIR_FACING_SID = (dispatch prompt 에 ANU 본 세션이 자동 주입)
   ```
2. dispatch prompt 작성 시 ANU 본 세션이 자기 SID 를 dispatch prompt 에 자동 inline:
   ```
   chair_facing_session_id: 53e89540-5bed-4692-a726-ed857820758a
   callback_resume_required: true
   ```

장점: 코드 변경 0 / 즉시 적용 / 회장 결정만 받으면 다음 dispatch 부터 적용
단점: 봇 자율 준수에 의존 (★ 8일 박제도 무시된 history 있음)

### Tier 2 — helper 코드 `--session` argv 자동 생성 (★ 별도 task 필요)

`dispatch/normal_fallback_callback_helper.py:build_anu_owned_callback_request` 에 `--session` 옵션 자동 포함:
```python
# 제안 변경 (read-only proposal)
argv = ["cokacdir", "--cron", prompt, "--at", absolute_ts,
        "--chat", str(CHAT_ID), "--key", ANU_KEY,
        "--session", chair_facing_sid]  # ★ 추가
```

전제: 봇이 호출 시 `chair_facing_sid` 환경변수 또는 envelope field 로 전달받음.
연결: Tier 1 doctrine + Tier 2 helper argv 자동 추가 + Tier 3 환경변수 propagation.

### Tier 3 — dispatch.py · finish-task.sh chair_facing_sid propagation (★ 별도 task)

1. `dispatch.py` 봇 spawn 시 환경변수 `ANU_CHAIR_FACING_SID` 전달
2. `scripts/finish-task.sh` helper 호출 시 `--chair-facing-sid "$ANU_CHAIR_FACING_SID"` 전달
3. helper 가 환경변수/CLI 인자 통합 → argv 자동 생성

### Tier 4 — durable 4-tuple registry 코드 구현 (★ task-2553+44/+46 후속 · 별도 task)

```jsonl
{"task_id": "task-2684", "schedule_id": "803000CA", "owner_key_verifier": "893698f7...", "chair_facing_sid": "53e89540...", "fired_at_kst": "2026-05-26T04:17:15+09:00", "result_path": "memory/events/task-2684.pr-149-afb37bd3-ci-gemini-watch-result-260526.json"}
```

본 ANU 세션이 사후 조회 가능 → cron-list 0 → registry 1줄 query → source attribution 즉시 확보. 매번 4-source 수동 검증 불필요.

---

## 6. 회장 결정 대기 항목 (read-only spec · 코드 변경 없음)

1. **분류 확정**: 본 사고 `AUTHORITATIVE_CALLBACK_COLLECTOR_PROCESSED + SESSION_PROPAGATION_GAP_SUBCLASS_OF_SESSION_DISCONTINUITY` 인정 여부
2. **Tier 1 (doctrine 강화) 적용 승인**: 다음 dispatch 부터 chair_facing_sid 자동 주입
3. **Tier 2~3 (helper + dispatch 코드 결선) 별도 task 발행 여부**: 가칭 `task-2686 callback_session_propagation_hardening`
4. **Tier 4 (durable registry) 별도 task 발행 여부**: 가칭 `task-2687 callback_4tuple_durable_registry`
5. **task-2646 HARNESS_ENFORCED_PENDING 승급 우선순위**: 현재 4 우선순위 (PR #149 / PR #151 / main divergence / finish-task callback runner 결선) 와 통합 여부
6. **본 spec 박제 → MEMORY.md 인덱스 추가 여부**

---

## 7. 박제 마커 (본 spec 적용 시)

- `memory/events/task-2684-callback-session-routing-gap-rca-260526.json` — RCA marker (★ 별도 작성 예정)
- `memory/feedback_chair_facing_session_vs_fresh_collector_routing_gap_260526.md` — feedback memory (★ 회장 결정 후 박제)
- `memory/specs/system_callback_session_routing_modular_wiring_gap_analysis_260526.md` — 본 spec (★ 작성 완료)

---

## 8. 금지 준수 (회장 verbatim 11)

- PR merge 0 / auto-merge 0 / branch 삭제 0 / live settings.json 0 / hooks live 0 / dispatch.py 변경 0 / Axis runtime 0 / HARNESS_ENFORCED 전체 선언 0 / policy 승격 0 / BLOCK 확대 0 / main divergence 임의 진행 0
- 코드 수정 0 / commit 0 / push 0 / PR 생성 0 / new dispatch 0 / git fetch 0 / git push 0
- 본 spec 은 read-only analysis 만 · 회장 결정 대기

끝
