# task-2729+2 (P1) — NORMAL_CALLBACK_REGISTRATION_OR_HISTORY_MISMATCH reconciliation
## 회장 인가 (2026-06-05) — P1 먼저 처리 (P0-A finalize blocker)
audit-first. **PR #174(P0-A) 코드 변경 금지·보존.** P1 별도 task. 목표=fake 통과 아닌 **실제 4-source chain 정합**: ANU-owned collector registration → real schedule_id → owner_key(ANU) → schedule_history status=ok → inbound receipt.

## AUDIT 결과 (read-only, ANU 규명 — 근거)
4-source validator(`utils/normal_callback_registration_validator.py`)는 envelope `memory/events/anu_callback/<task_id>-normal-completion.json` 에서 **schedule_id + owner_key(==ANU_KEY c119085addb0f8b7) + schedule_history/<sid>.log status=ok + inbound** 를 AND 검증.
- 실패 재현(task-2729+1): "schedule_id missing/empty + owner_key missing in envelope".
- **근본**: 실제 cron 등록은 `dispatch.normal_fallback_callback_helper.launch_callback`(→cokacdir --cron→real schedule_id)에서 일어나고 `callback-prereg-launch.json`(status=ANU_OWNED_READY)에 기록되나, **validator가 읽는 envelope 에는 real schedule_id/owner_key 가 write-back 되지 않음**(registration marker ↔ validator input envelope mapping 불일치). finish-task GIT-GATE 중단/등록 분리 시 envelope 이 prereg 상태에 잔류 → FAIL.
- 결론: registration 결과(real sid/owner_key)를 validator envelope 로 **정합 전파(reconciliation)** 하면 4-source 정합. **fake 아님** — 실제 등록된 sid/key 를 propagate.

## P1 목표 (정합만 — 우회 금지)
1. `launch_callback`(또는 caller)이 실제 등록한 **real schedule_id** 와 **owner_key(ANU)** 를 validator envelope(`anu_callback/<task_id>-normal-completion.json`)에 **idempotent write-back**.
2. schedule_history `/home/jay/.cokacdir/schedule_history/<sid>.log` status=ok 와 envelope schedule_id 매칭(reconciliation) — validator 가 동일 sid 로 교차확인되게.
3. registration marker(prereg-launch.json) ↔ validator input envelope **schema/field alias 정합**(필요 시 validator input mapping 만 보정, 검증 약화 금지).
4. fake/self-collector 차단·§8 owner cross-check **유지·강화**(executor self-key → NON_AUTHORITATIVE 그대로).
5. 기존 callback/fallback behavior 무손상.

## expected_files (lock, ≤4 — 최소화. audit 후 dev 가 최소 locus 확정)
1. `scripts/harness/v36/callback_preregistration.py` — launch 성공 후 decision 의 real schedule_id/owner_key 를 envelope 에 write-back(현재 prereg-launch marker 만 기록). **주 locus 후보.**
2. `dispatch/normal_fallback_callback_helper.py` — launch_callback 이 real schedule_id 를 반환/노출하도록(+ §8 reconciliation 연계). 최소 변경.
3. `tests/regression/test_normal_callback_registration_reconciliation_2729p1.py` (신규) — 회귀: (a) 등록 후 envelope 에 real sid/owner_key write-back (b) validator 4-source PASS (c) sid↔schedule_history status=ok 매칭 (d) self-key → NON_AUTHORITATIVE 유지 (e) 기존 callback/fallback 회귀 무손상.
4. (필요 시) `utils/normal_callback_registration_validator.py` — input mapping/schema alias 정합만(검증 기준 약화 0).
- ★ 4 초과·validator 검증 약화·PR#174 파일 수정·forbidden 필요 시 CHAIR_REQUIRED.

## P1 완료 조건 (회장 7)
1. envelope 에 schedule_id/owner_key 정합 write-back. 2. schedule_history status=ok ↔ envelope schedule_id 매칭. 3. inbound receipt 검증. 4. fake/self collector 차단 유지. 5. 기존 callback/fallback 무손상. 6. ANU key raw 노출 0(상수 참조만, raw 출력 0). 7. ACTIVE=false 유지.
+ 신규+기존 regression PASS, py_compile PASS, L1 smoke(실 등록→envelope→validator PASS 1회 실증, 단 fake sid 금지).

## 금지 (회장 verbatim)
fake schedule_id 생성 · fake schedule_history 생성 · owner_key 임의 주입(validator 우회) · 수동 .done · **PR #174 코드 변경** · ACTIVE=true · admin/force/rebase/merge · expected_files 밖 수정. validator 검증 기준 약화 금지(정합만).

## doctrine
same-PR Gemini 후 push 금지(위반 시 Option A) · bot /gemini 트리거 무효 · long-polling 금지 · finalize 14단계+8항목 명시 · PR open 시 CI_WATCH_HANDOFF · normal callback = ANU key c119085addb0f8b7.
**★ 본 task 자체가 callback reconciliation 을 고치므로, 본 task 의 finalize 가 곧 fix 의 dogfood 검증.**

## PR 생성 전 재확인 → ANU
CI 11/11 · fresh Gemini HIGH/CRITICAL 0 · diff expected_files(≤4) 내 · forbidden 0 · ANU key raw 0 · ACTIVE=false. 통과 시 PR → owner_gemini → review-settle → MERGE_APPROVAL_CANDIDATE. merge 회장 승인 전 금지.

## 산출물
1. PR(fresh origin/main d925b873 base, ≤4 files). 2. `memory/reports/task-2729+2.md`(capability delta: callback registration IMPLEMENTED/VERIFIED/WIRED/ACTIVE 분리 + 4-source 정합 증거). 3. `memory/events/task-2729+2.done`.
4. P1 PASS → ANU 가 P0-A(PR#174) finish-task finalize 재시도 → P0-A 완료 시 P0-B 자동 진행.

## allowed_resources (본 task의 capability)

```yaml
allowed_resources:
  paths:
    - "scripts/harness/v36/callback_preregistration.py"
    - "dispatch/normal_fallback_callback_helper.py"
    - "tests/regression/test_normal_callback_registration_reconciliation_2729p1.py"
    - "utils/normal_callback_registration_validator.py"
    - "memory/reports/task-2729+2.md"
    - "memory/events/task-2729+2.*"
  forbidden_paths:
    - "bot_settings.json"
    - ".env.keys"
    - ".github/**"
    - "scripts/finish-task.sh"
    - "utils/replacement_pr_runner.py"
    - "scripts/ci_watch_handoff_runner.py"
    - "utils/pr_watcher_terminal_state_classifier.py"
    - "memory/events/*.cron-*"
  commands:
    - "pytest"
    - "python3 -m py_compile"
  merge_policy: "none"
  ttl_hours: 48
```