# task-2553+9a — CALLBACK_FALLBACK_CANCEL_ON_SUCCESS (회장 결정, ANU-Codex loop 자동 수렴)

> **Lv**: Lv.2~3 callback 정책 보강 (실 PR open 0 / GitHub write 0 — fallback cron 제거만). **Executor**: 적합 dev 1회 한정 (ANU 배치안·Codex lint·refine·re-lint 선행 후 dispatch). **TTL**: 2h.
> **상태**: 회장 지시문 1 전체 인식·GO 확인("다 인식 했네. 이 작업 먼저 진행하자"). ANU-Codex loop 자동 수렴, HOLD 조건 시만 회장 보고. md/memory 박제만으로 완료 불가 — 실행코드+테스트+fixture+marker/result 필수.
> **근거**: callback (a) STANDARDIZED 의 fallback = 고정 절대시각 dead-man switch + 사후 dedup → normal collector 성공해도 fallback 뒤늦게 발화(비효율, 안전하나 redundant). 회장 직접 지적 + ANU 제안 cancel-on-success 를 정식 task 승격.

---

## 1. 문제 (회장 verbatim)

normal completion callback collector 가 성공적으로 회수·검증·회장 보고를 완료했는데도, dispatch 시점에 등록된 fallback callback cron 이 절대시각으로 남아 있다가 뒤늦게 발화한다. 현재 DUPLICATE_CALLBACK_IGNORED 는 안전하지만 비효율적이다.

## 2. 목표 (회장 verbatim)

normal collector 성공 시 사전 등록된 fallback callback cron 을 **자동 제거**하는 코드/파일 자동화를 구현한다. md/memory 박제만으로 완료하지 않는다. 반드시 실행 가능한 코드, 테스트, fixture, marker/result 를 포함한다.

## 3. 구현 목표 (회장 verbatim 7)

1. normal collector 가 성공적으로 result/report/collector-result marker 생성을 완료하면 fallback_cron_id 를 찾는다.
2. dispatch-fired marker 또는 callback contract 에서 fallback_cron_id 를 읽는다.
3. fallback_cron_id 가 존재하고 아직 pending 이면 cron remove 를 실행한다.
4. remove 성공 시 `fallback_cancelled=true` marker 를 남긴다.
5. remove 실패 또는 이미 발화/삭제된 경우에도 normal collector 성공 자체는 실패로 바꾸지 않는다.
6. fallback 이 이미 발화했다면 기존 DUPLICATE_CALLBACK_IGNORED 경로를 유지한다.
7. normal collector 가 실패하거나 중간 crash 하면 fallback 은 제거되지 않고 예정대로 발화해야 한다.

## 4. ANU 배치안 / expected_files (실제 파일명 ANU 확정 — 코드/테스트/fixture/marker 필수, 문서만 금지)

1. `utils/completion_callback_fallback_cancel.py` — fallback cron cancel 순수 로직 모듈. callback orchestrator(`utils/anu_delegation_completion_callback.py`) **무수정 — 본 모듈은 분리·독립**, scripts CLI 가 호출(§9-R.4). 함수: fallback_cron_id 추출(**dispatch-fired marker `callback_policy_a.fallback_callback_cron_id` 단일 권위 — §9-R.1, marker 부재/불일치 시 SKIPPED_UNTRUSTED; callback contract 는 marker 와 동일값 교차확인용 보조일 뿐 단독 권위 아님**) / §9-R.1 5조건 결합 검증 / §9-R.2 durable-evidence success gate / dependency-injected remover(§9-R.5) / 결과 분류(CANCELLED / ALREADY_GONE / ALREADY_FIRED / SKIPPED_NORMAL_FAILED / SKIPPED_UNTRUSTED / REMOVE_FAILED_WARNING).
2. `scripts/run_completion_callback_fallback_cancel.py` — CLI (dispatch-fired marker 경로 입력 → §9-R.2 durable evidence 검증으로 success 판정; `normal_collector_success` bool 은 **보조 신호일 뿐 §9-R.2 durable-evidence gate 에 종속**, 단독 권위 아님 → cancel-result JSON).
3. `tests/regression/test_completion_callback_fallback_cancel_2553plus9a.py` — §6 필수 테스트 10 + 추가 adversarial.
4. `memory/fixtures/callback_fallback_cancel_success.json` — normal success + fallback pending → CANCELLED
5. `memory/fixtures/callback_fallback_cancel_already_fired.json` — fallback 이미 발화 → DUPLICATE 경로 유지
6. `memory/fixtures/callback_normal_failed_fallback_remains.json` — normal 실패 → remove 금지
7. `memory/events/task-2553+9a.callback-cancel-result.json` — cancel-result 샘플(dry-run/mock).
8. `memory/reports/task-2553+9a.md`
9. `memory/events/task-2553+9a.result.json` — 완료 packet.

> 설계: cron remove 는 **실 cokacdir --cron-remove 호출**이되, **본 task 구현·테스트에서는 mock/dry-run**(실 fallback cron 제거는 callback (a) 정책 적용 후 운영 collector 가 수행). 본 task 산출 = 메커니즘 코드+테스트+fixture. ownership 검증 실패·id mismatch·타 cron 위험 시 remove 절대 미실행.

## 5. 권한 경계 (회장 verbatim — fallback cron 제거만 허용)

dev 재가동 금지 / dispatch 금지 / branch·commit·push·PR open 금지 / GitHub write 금지 / merge 금지 / credential·OWNER PAT 조작 금지 / real write 금지 / dev status 변경 금지 / 자동 closeout 금지. 허용 = **fallback cron 제거만**.

## 6. 필수 테스트 (회장 verbatim 10)

1. normal collector success + fallback pending → cron remove 호출, `fallback_cancelled=true`
2. normal collector success + fallback already deleted → no failure, idempotent
3. normal collector success + fallback already fired → no failure, duplicate path 유지
4. normal collector failure → fallback remove 호출 금지
5. fallback_cron_id missing → HOLD 또는 `cancel_skipped_reason` 기록
6. wrong chat_id fallback → remove 금지
7. fallback id mismatch → remove 금지
8. cron remove 실패 → warning marker, collector success 유지
9. duplicate callback path 기존 regression 무회귀
10. callback policy(a) collector-only 권한 유지

## 7. HOLD_FOR_CHAIR 조건 (회장 verbatim)

fallback_cron_id 를 신뢰할 수 없는 경우 / chat_id·key ownership 확인 불가 / cron remove 가 다른 작업 cron 을 건드릴 가능성 / callback collector 본체 수정이 forbidden target 에 해당하는 경우 / 권한 확대 필요 / Critical 7

## 8. forbidden_write_targets (수정 0)

`utils/anu_delegation_completion_callback.py`(callback orchestrator 본체) / `tests/regression/test_anu_delegation_completion_callback_2595.py` / `tests/regression/test_completion_callback_dup_ignored_realworld_2553plus1.py` / 9B3BEB11 fixture / dispatch.py / scripts/finish-task.sh / task-timer.py / post-tool-use.sh / anu_v3/pre_authorized_* / anu_v3/goal_* / task-2553+1~+8 md. (orchestrator 무수정 — 본 task 는 분리 모듈 신설로 collector flow 가 호출. dedup 경로 무회귀.)

## 9. 완료 후 보고 (회장 verbatim 6)

구현 파일 목록 / regression 결과 / normal success → fallback cancel 증거 / normal failure → fallback remains 증거 / duplicate callback 기존 경로 무회귀 증거 / callback(a) 정책에 적용 가능한지 여부

## 10. ANU-Codex loop (자동 수렴)

batch plan(본 §4 확정) → Codex lint → ANU refine → Codex re-lint → dispatch(적합 dev 1회 한정, TTL 2h, callback (a) normal+fallback) → 구현 → regression → 자동 micro-fix → post-result audit → ANU·Codex adjudication → 완료 packet. 회장 중간 라우팅 0, HOLD 조건 적중 시만 회장 보고.

## 9-R. Codex lint 반영 정밀 보강 (NEEDS_REFINEMENT → 자동 수렴, agent a59253262b7c75c9a)

### 9-R.1 (HIGH AXIS-2/8 해소) safe-remove 결합 검증 알고리즘 (오발 제거 0)

cron remove 는 **아래 5조건 전부 충족 시에만** 실행. 하나라도 불충족 → `SKIPPED_UNTRUSTED`(remove 미실행) 또는 HOLD:
1. dispatch-fired marker(`memory/events/<task_id>.dispatch-fired.json`)가 단일 권위 — `callback_policy_a.fallback_callback_cron_id` 값 == 제거 대상 id (정확 문자열 일치)
2. 동일 marker 의 `task_id` == 현재 처리 task_id (task-level binding)
3. ownership: chat_id == 6937032012 AND anu-key(c119085addb0f8b7) — 다른 chat/key 소유 cron 절대 미접근
4. 제거 대상 cron 의 역할 == fallback(해당 task 의 fallback callback) — dispatch cron / normal collector cron / 무관 schedule 이면 즉시 SKIPPED_UNTRUSTED
5. id 가 stale·재사용·typo 의심(marker 값과 불일치, 또는 marker 부재) → SKIPPED_UNTRUSTED/HOLD, 절대 추정 remove 0
→ 동일 owner 의 **다른 live task cron** 도 task_id binding(조건 2)·역할(조건 4) 불일치로 차단.

### 9-R.2 (HIGH AXIS-3/8 해소) success gate = durable evidence 기반 (boolean 단독 금지)

cancel eligibility 는 caller-supplied `normal_collector_success` bool **단독으로 판정 금지**. **durable 증거 검증 필수**: §3.1/§9 가 명시한 collector 성공 산출물 — `memory/events/<task_id>.result.json`(존재 AND status 가 성공/비-HOLD/비-failure) + report + collector-result marker — 가 실재·정합할 때만 cancel 진행. 산출물 부재·HOLD·failure·partial → `SKIPPED_NORMAL_FAILED`(fallback 보존, 예정대로 발화). boolean 은 보조 신호일 뿐 권위 아님.

### 9-R.3 (HIGH AXIS-5 해소) adversarial regression 보강

§6 필수 10 + 추가:
11. concurrent: normal-success-cancel vs fallback-fire race → 단일 결과(이중 처리·재escalate 0)
12. same-owner 이나 다른 live task 의 cron id → task_id binding(9-R.1-②) 불일치 → remove 0
13. enforced mock transport: regression 중 실 subprocess `--cron-remove` 호출 시 테스트 FAIL(주입된 fake remover 외 호출 0 정적·동적 증명)
14. fallback_cron_id 추출 2-source(dispatch-fired marker AND callback contract) 양쪽 경로 검증
15. crash window: marker 생성 ~ cancel 호출 사이 중단 → fallback 보존(미제거)
16. durable evidence 부재인데 boolean=true 주입 → SKIPPED_NORMAL_FAILED(9-R.2 입증)

### 9-R.4 (MED AXIS-1 해소) 호출 seam 명시 (orchestrator 무수정 보장)

본 메커니즘 호출점 = **`scripts/run_completion_callback_fallback_cancel.py`(분리 CLI) 단독**. 운영 normal-collector flow 가 자기 success marker 생성 **후** 이 CLI 를 호출(또는 collector dispatch prompt 의 마지막 step 에 CLI 호출 1줄 추가 — 이는 dispatch prompt text 이지 orchestrator 코드 아님). `utils/anu_delegation_completion_callback.py` **byte-identical 무수정** — import/호출 결합 0, 본 task 의 §7 HOLD("collector 본체 수정 필요") 구조적 미발생.

### 9-R.5 (LOW AXIS-6 해소) mock transport 강제 메커니즘

`utils/completion_callback_fallback_cancel.py` 의 cron-remove 실행은 **dependency-injected `remover: Callable` 파라미터**(기본값 = 실 cokacdir --cron-remove wrapper). regression 은 fake remover 주입 + "실 subprocess 호출 0" assert(monkeypatch/spy). 실 remove 는 callback (a) 정책 적용 후 운영 collector 만.

→ 9-R.1~9-R.5 로 Codex HIGH 3 + MED/LOW 3 전건 해소. CRITICAL 0 유지. 회장 라우팅 0. Codex re-lint GO_READY 시 dispatch.

## 11. task-2553 계열 (혼선 방지)

+1=F1 / +2·+3=초안 / +4=gate / +5=deriver+binding / +6=activation runner / +7=goal controller v0(DEFENSIVE_HOLD_PASS) / +8=isolated-worktree evidence(controller·evidence COMPLETE, 첫 적용 DEFENSIVE_HOLD — branch collision, 회장 결정 대기) / **+9a(본건)=callback (a) fallback cancel-on-success 메커니즘 (실 PR open 무관·별개 트랙)**.
