---
task_id: "task-2694+1"
type: enforcement
scope: callback-registration
status: completed
team: dev7
level: 3
priority: P1
depends_on: ["task-2694"]
created_at: 2026-05-27T03:50:00+09:00
deadline: null
dri: itzamna
chair_authorization_id: CHAIR-AUTH-NORMAL-CALLBACK-REGISTRATION-ENFORCEMENT-20260527-JJONGS-REDISPATCH-001
---

# Plan: NORMAL_CALLBACK_REGISTRATION_ENFORCEMENT (redispatch)

## 목표 (회장 verbatim)
envelope 작성만으로 완료 처리되는 것을 코드로 차단한다.

## 범위
- `scripts/finish-task.sh`: callback registration enforce 단계 삽입 (Step 2.9.5 위치)
- `dispatch/normal_fallback_callback_helper.py`: actual cron 발사 enforce (신규)
- `utils/normal_callback_registration_validator.py`: 4-source validator (신규)
- `utils/callback_registration_marker.py`: NORMAL_CALLBACK_NOT_REGISTERED marker (신규)
- `schemas/anu_normal_callback_envelope_v1.json`: schedule_type enum 보강 (신규)
- `tests/regression/normal_callback_registration_enforcement/**`: 신규 regression
- `tests/regression/finish_task_callback_fail_closed/**`: 신규 regression

## 4-source validation 명세 (회장 verbatim ANCHOR-3)
모두 PASS 시에만 callback PASS:
1. **schedule_id**: cokacdir --cron 호출 후 회수된 실제 sid (envelope에 명기)
2. **schedule_history**: `/home/jay/.cokacdir/schedule_history/<sid>.log` 실 파일에 `status=ok` 라인 grep PASS
3. **owner_key**: `cokacdir --cron-history <sid> --key c119085addb0f8b7` (ANU key) 응답 hit. self-key channel hit 시 NON_AUTHORITATIVE fail
4. **inbound/receipt**: ANU inbound 또는 authoritative collector receipt 둘 중 하나 verifiable

## Codex suggestion 반영 (sid 재사용/stale 방어)
- validator는 `task_id + schedule_id + owner_key + chair_facing_session_id + envelope sha256` 함께 결합 검증
- 단순 grep 의존 줄이고 Python validator 한 곳에 4-source 판정 + marker 발행 집중
- Shell은 orchestration만 (validator 호출 + exit code 반영)

## 차단 어구 (회장 verbatim ANCHOR-2)
envelope 또는 .done payload에 아래 어구 발견 시 즉시 fail-closed:
- `schedule_type=to_be_registered_by_finish_task_sh`
- `schedule_type=deferred`
- `schedule_type=pending`

## 회귀 케이스 (Codex suggestion 4 — 6 fail + 1 pass)
1. envelope-only PASS 금지
2. deferred/to_be_registered schedule_type 차단
3. schedule_history missing
4. owner_key mismatch (self-key channel hit)
5. inbound/receipt missing
6. stale sid reused (다른 task의 sid 재사용)
7. dogfood: task-2694 normal callback 본 enforcement 통과 (정상 case)

## 금지 (회장 verbatim 금지 10)
- dispatch.py 전역 변경 0
- live settings.json/hooks 변경 0
- PR #152 / PR #154 / PR #151 / PR #149 / task-2691+b 혼합 0
- auto-merge 0

## 완료 기준
- PR 생성 (auto-merge 0) + Gemini 리뷰 대응
- regression PASS
- 본인 dogfood: task-2694+1 자체의 normal callback이 본 enforcement 통과 (actual cron + schedule_history + ANU key + chair-facing inbound)
- 필수 보고 10 필드 모두 명시
