# task-2774+13 보고서 — normal callback delivery real launcher wiring (micro-PR, ACTIVE=false)

담당: dev2-team (오딘/팀장) · 작업 ID: task-2774+13 · 레벨: Lv.2 · merge_policy: manual
PR: https://github.com/Jeon-Jonghyuk/dev_workspace/pull/254 · branch: `task/task-2774+13-dev2`

## S (Situation)
ANU dry 가드에서 governor ALLOW + owner-proof PASS + `WAKE_BUILT` 까지 도달했으나, normal callback
delivery 경로 `pickup_once → callback_launch_fn(build_callback_launch_fn → launch_callback_for_closeout)
→ anu_runner_pickup_and_fire` 가 **surface-only** 였다. ANU-owned callback argv(`cokacdir --cron …
--key <ANU_KEY> --once`)를 생성만 하고 **실 cokacdir 1-shot 발사 코드가 결선돼 있지 않았다**.

## C (Complication)
ad-hoc harness 발사기 주입은 "우회 발사"라 경로가 실제 wired 됐다는 증명이 못 된다. 정식 결선이
필요하되, 회장 승인 범위는 **결선만**(default OFF·ACTIVE=false·PR 내부 real fire 0). 잘못 결선하면
governor BLOCK / owner-proof FAIL / self-key 자가발사 / raw ANU key 노출 / 중복 발사 위험이 있다.

## Q (Question)
surface argv → 실 launcher 사이를, **회귀 0 · default OFF · real fire 0 · raw key 0 · single-flight**
를 모두 만족하며 최소 범위로 어떻게 닫는가? 기존 D-2 발사기를 재사용할 수 있는가?

## A (Answer)
`launch_callback_for_closeout`(anu_callback_launch_audit.py) step 5 에 **gated real-fire 분기**를 추가했다.
ANU-owned callback request `rr`(rr.argv) 빌드 직후:
- **(5-a) default OFF**: `real_launch_fn is None`(기본) → 현행 `LAUNCH_ENFORCED`(surface-only, real fire 0).
- **(5-b) gate 미충족**: real_launch_fn 주입됐으나 `not (activation_intent and canary_only)` → `REAL_FIRE_BLOCKED`(fire 0).
- **(5-c) 전 게이트 충족**: ACTIVE flag ON(step 0) + activation_intent + canary_only + real_launch_fn →
  주입된 **D-2 발사기 `build_oneshot_cokacdir_fire_fn`(재사용)** 로 rr.argv 를 **정확히 1회** 발사 →
  성공 `REAL_FIRED` / 실패·예외 `REAL_FIRE_FAILED`.

callback argv 가 `--cron`+`--once` 를 모두 포함하므로 D-2 발사기와 호환 → **신규 발사기 0**.
governor ALLOW · owner-proof PASS 는 상류 `pickup_once`(step 2.45 governor, step 2.5 owner gate)가
이미 강제하므로, BLOCK/FAIL 시 callback_launch_fn 자체가 **미호출 → real launcher 0**.

## 보고 항목 (task 필수)
- **수정 파일**: `dispatch/anu_callback_launch_audit.py`(+144), `tests/regression/test_normal_callback_real_launcher_2774p13.py`(신규 13종). 설계 문서 `memory/plans/spawn_safety_governor/normal_callback_real_launcher_wiring_design_2774p13.md`. **expected_files(2) 밖 코드 수정 0** (anu_result_pickup_runner.py / anu_owned_callback_enforcement.py / anu_pickup_driver.py 무수정).
- **연결점(surface→real)**: `launch_callback_for_closeout` step 5-c — `outcome = real_launch_fn(raw_argv)` 정확히 1회. raw_argv = rr.argv(=anu_runner_pickup_and_fire 가 surface 하던 그 argv).
- **D-2 발사기 재사용**: 예. `dispatch.anu_result_pickup_runner.build_oneshot_cokacdir_fire_fn` 반환 fire_fn 을 호출자가 `real_launch_fn=` 로 주입. 신규 발사기 미작성. default 실발사 fire_fn 0(명시 주입만).
- **default OFF 보존 증거**: production `anu_pickup_driver.main → build_callback_launch_fn(CANONICAL_ROOT)` 는 real_launch_fn 무주입 → (5-a) surface-only. driver 무수정.
- **real fire 0 증거**: 신규/회귀 테스트 + L1 스모크에서 mock launcher 만 사용·subprocess.run/Popen assert_not_called. 실 cokacdir 호출 0.
- **governor BLOCK 시 fire 0**: 회귀 `test_pickup_governor_block_no_callback` — spawn_governor_fn BLOCK → `PICKUP_SPAWN_BLOCKED`, spy calls 0.
- **owner-proof FAIL 시 fire 0**: 회귀 `test_pickup_owner_gate_fail_no_callback` — owner_gate not-ready → `PICKUP_OWNER_GATE_BLOCKED`, spy calls 0.
- **G2/G3 STOP 시 fire 0**: activation preflight(2774+5) 상류 STOP → driver 미진입 → callback_launch_fn 미생성. 본 PR 변경 무관(상류 보존).
- **raw key 노출 0 증거**: `_redact_callback_argv` 가 `--key <value>` → `<ANU_SEALED_KEY>`. result.argv/audit jsonl 에 raw key 0(L1-5 검증: audit 에 FAKE key 미포함). 발사 예외/실패는 고정 라벨만.
- **CI/Gemini 상태**: PR #254 OPEN. Gemini 리뷰/CI 는 ANU 독립검증 단계에서 확인(merge_policy=manual·회장 머지 판단).

## DoD 충족
1. default OFF surface-only/회귀 0 — ✅ (5-a) + 회귀 231 PASS.
2. activation_intent+canary_only+owner-proof PASS+governor ALLOW 시에만 발사 — ✅ (5-c) + 상류.
3. governor BLOCK → 0 — ✅.   4. G2/G3 STOP → 0 — ✅(상류).   5. owner-proof/freshness FAIL → 0 — ✅.
6. `.ok`/`.argv` contract — ✅ `CallbackLaunchResult.ok` + `.argv`(redacted).
7. raw key 0 — ✅ redaction + 고정 라벨.   8. dedupe/single-flight 보존 — ✅ `_AUDIT_DEDUPE_VERDICTS=(LAUNCH_ENFORCED, LAUNCH_REAL_FIRED)`.
9. py_compile PASS · 회귀 PASS · expected_files 밖 0 — ✅.   10. Gemini HIGH/Critical 0 — PR 단계 ANU 확인 대기.

## 테스트 결과
- `python3 -m py_compile` (3 allowed files): **PASS**
- 신규 회귀 `test_normal_callback_real_launcher_2774p13.py`: **13 passed**
- 관련 회귀 스윕(2763/2774p8/2720/2717/2742/2741/2774/2774p3/2774p5 + 신규): **231 passed, 0 failed (회귀 0)**

## L1 스모크테스트 결과 (필수)
- 서버 재시작: 해당없음(라이브러리 결선 — 서버 무관)
- API 응답 확인: 해당없음. 대신 **실 런타임 standalone 실행**(`/tmp/l1_smoke_2774p13.py`)으로 6종 검증:
  - L1-1 default OFF → `LAUNCH_ENFORCED`, redacted argv(`<ANU_SEALED_KEY>`, raw key 0) — PASS
  - L1-2 real_launch_fn 주입+게이트 미충족 → `REAL_FIRE_BLOCKED`, launcher calls 0 — PASS
  - L1-3 전 게이트 충족 → `REAL_FIRED`, launcher **정확히 1회**, result.argv redacted, sid 반영 — PASS
  - L1-4 ACTIVE flag OFF → `LAUNCH_NOOP_DISABLED`, launcher calls 0(전 게이트라도 fire 0) — PASS
  - L1-5 audit.jsonl 에 raw key 미포함 — PASS
  - L1-6 D-2 발사기 `build_oneshot_cokacdir_fire_fn` 재사용 + `subprocess.run/Popen` **NOT called**(실 cokacdir 발사 0) — PASS
- 스크린샷: 해당없음(CLI 라이브러리). L1 stdout 로그가 증거.

## 모델 사용 기록
- 토르(백엔드): **sonnet** — 결선 코드 + 회귀 13종 적용/검증. (정확한 사전 설계 스펙 기계적 적용 + pytest 검증)
- 오딘(팀장): **opus** — 설계 확정·타입 오류(rr.argv Pyright) 직접 수정·설계 문서·PR·검증 통합.
- 미미르/프레이야/헤임달: 미소집(백엔드 단일 파일 결선 + 회귀로 충분, 디자인/프론트 작업 없음).
- haiku 미사용.

## 발견 이슈 및 해결
- (해결) Pyright `reportAttributeAccessIssue` — `rr.argv`(rr: object) 직접 접근. `getattr(rr, "argv", None) or []` 로 수정(상위 가드가 argv 非None 보장). 재검증 py_compile PASS·테스트 PASS.
- (정리) 테스트 stub 의 unused `import pytest` 제거. 잔여 ★(stub 시그니처 unused param)는 API-shaped 의도적 — non-blocking.

## 머지 판단
- **머지 필요**: Yes (manual — ANU 독립검증/Gemini/CI 후 회장 판단). 팀장 자동 머지 안 함.
- **브랜치**: `task/task-2774+13-dev2`   · **워크트리**: `/home/jay/workspace/.worktrees/task-2774+13-dev2`
- **머지 의견**: +144/-11(audit.py) 순증 위주 + 신규 테스트. 기존 surface-only 경로 무손상(real_launch_fn 기본 None). driver/runner/enforcement 무수정 → blast radius 최소. 회귀 231 PASS·real fire 0·raw key 0 검증 완료. 충돌 가능성 낮음(단일 함수 분기 추가).

## 비고
- PR 내부 real fire 0. 실 1-shot 은 머지 후 별도 승인된 B 실행에서만(real_launch_fn 명시 주입 + ACTIVE flag ON + activation_intent + canary_only 전부 참일 때).
- callback_schedule_created: false (executor 자가 callback cron 미등록 — OS-level pickup runner 소유). ANU normal collector callback 은 finish-task.sh 의 launcher 게이트(독립 ANU key)가 등록.
