# task-2660 — CALLBACK_NORMAL_FIRE_DELAY_REMEDIATION_PHASE_2

- Level: Lv.4 (Phase 2 remediation · normal callback fire delay 10분 → 30초 이내 · fallback/dead-man 동작 변경 0 · PR 생성 허용 · auto-merge 0)
- 담당: dev1 헤르메스 (회장 verbatim executor 지정 · dev6 페룬 audit 대상 제외 · dev5 마르둑 대안)
- base: origin/main 최신 (현재 HEAD `d4098b04 task-2642`)
- 단일소스 spec: 본 task md + audit packet `memory/events/callback-fire-at-delay-audit-packet-260525.json`
- chair_authorization_id: **`CHAIR-AUTH-CALLBACK-DELAY-P2-20260525-JJONGS-NORMAL-FAST-001`** (★ 회장 verbatim 1회성 발행 · 임의 생성 0)

## 배경

task-2659 normal callback fire delay 약 14분 idle gap 발생. 근본 원인 = `scripts/finish-task.sh:1369` `--at "10m"` 하드코딩 + `dispatch/normal_fallback_callback_helper.py:617` argparse default `"10m"`. 봇 개별 결함 아닌 시스템 정책 결함. ANU memory anchor (`feedback_progress_trigger_on_normal_callback_not_deadman_260518`) 직접 위반 — "고정시각/dead-man 게이트를 진행 트리거로 쓰면 ~수십분~수시간 idle 갭".

## 회장 verbatim 결정

- scope = **Phase 2 only**
- Phase 3 (fallback launcher 분리) / Phase 4 (threshold enforce) 본 task 금지 · 별도 회장 승인 강제
- executor = **dev1 헤르메스**
- 목표 = normal callback fire delay 10분 구조 → 30초 이내 구조 변경
- fallback/dead-man callback 본 task 변경 0

## smoking gun 위치 (audit packet 박제)

```
scripts/finish-task.sh:1369
  현재: --prompt "$T2626_ENVELOPE" --at "10m" \
  목표: --prompt "$T2626_ENVELOPE" --at "10s" \  (★ 또는 명시 제거)

dispatch/normal_fallback_callback_helper.py:617
  현재: lp.add_argument("--at", default="10m")
  목표: normal callback context 에서 default "10s" 또는 30초 이내
```

## 허용 6 (회장 verbatim 1:1)

1. `scripts/finish-task.sh:1369` 의 normal callback `--at "10m"` 제거 또는 `"10s"` 로 변경
2. `dispatch/normal_fallback_callback_helper.py` 의 normal callback default 를 `"10s"` 또는 30초 이내로 변경
3. normal callback 과 fallback callback 이 같은 helper 를 쓰더라도 **role/kind/source_attribution 을 구분하는 최소 보강** (★ Phase 3 구조 변경 금지 · 필드 라벨링만)
4. regression 추가 (★ 본 task md regression 6)
5. audit report / result marker / done marker 작성
6. PR 생성까지 허용

## 금지 10 (회장 verbatim 1:1)

1. fallback/dead-man delay 변경
2. fallback launcher 구조 변경
3. threshold enforce Phase 4 구현
4. dispatch.py 변경
5. live settings.json 변경
6. Axis 1/2/3 runtime 변경
7. PR #147 merge
8. auto-merge
9. policy 승격
10. HARNESS_ENFORCED 전체 선언

## 필수 regression 6 (회장 verbatim 1:1)

1. normal callback default fire delay ≤ 30s
2. `scripts/finish-task.sh` normal callback 호출 시 ≤ 30s 사용 확인
3. fallback/dead-man callback delay ≥ 600s 또는 **기존 동작 유지** (★ Phase 3 변경 0)
4. delay > 60s normal callback 에 reason 없으면 FAIL (★ 최소 lint · Phase 4 enforce 코드화 아님 · 단순 raise 또는 lint warning 수준 허용)
5. task-2659 timing fixture: `.done` 14:10대 → normal callback 14:25 같은 지연 **재발 금지** 검증
6. existing callback envelope byte limit (UTF-8 ≤ 3900) 유지

## 성공 조건 6 (회장 verbatim 1:1)

1. normal callback delay ≤ 30s
2. fallback/dead-man 동작 변경 0
3. regression PASS (6/6)
4. forbidden_action_count = 0
5. PR 생성 완료
6. auto-merge 0

## 완료 상태 (회장 verbatim)

- 성공: **`CALLBACK_NORMAL_FIRE_DELAY_REMEDIATION_P2_PR_READY`**
- 실패: **`CALLBACK_NORMAL_FIRE_DELAY_REMEDIATION_HOLD_FOR_CHAIR`**

## 보고 필수 7 (회장 verbatim 1:1)

1. PR 번호
2. changed_files
3. normal delay before/after
4. fallback 영향 여부
5. regression 결과 (6/6 개별)
6. forbidden_action_count
7. auto-merge 0 확인

## expected_files (~6)

- `scripts/finish-task.sh` (★ line 1369 수정)
- `dispatch/normal_fallback_callback_helper.py` (★ line 617 또는 argparse 분기 수정 · fallback default 영향 0)
- `tests/callback_fire_delay_remediation/test_regression_6.py` (★ 신규 · 6 fixture)
- `memory/events/task-2660.done`
- `memory/events/task-2660.callback-normal-fire-delay-remediation-result-260525.json`
- `memory/reports/task-2660.md`

## allowed_resources

```yaml
allowed_resources:
  paths:
    - "scripts/finish-task.sh"
    - "dispatch/normal_fallback_callback_helper.py"
    - "tests/callback_fire_delay_remediation/**"
    - "memory/system/.callback_ledger.jsonl"
    - "memory/.callback_inbox/**"
    - "memory/tasks/task-2660.md"
    - "memory/reports/task-2660.md"
    - "memory/events/task-2660.done"
    - "memory/events/task-2660.callback-normal-fire-delay-remediation-result-260525.json"
    - "memory/events/callback-fire-at-delay-audit-packet-260525.json"
    - "INDEX.md"
  read_only_reference:
    - "utils/anu_callback_registrar.py (★ default delay_seconds=10 이미 정상 · 변경 0)"
    - "utils/anu_callback_fallback.py (★ fallback module · 변경 0 anchor)"
    - "utils/completion_callback_fallback_cancel.py (★ cancel-on-success · 변경 0)"
    - "prompts/DIRECT-WORKFLOW.md (★ 538-547 callback section · 변경 0)"
  forbidden_paths:
    - "/home/jay/.claude/settings.json"
    - "/home/jay/.claude/settings.local.json"
    - "/home/jay/.claude/hooks/**"
    - "/usr/local/bin/cokacdir"
    - ".github/**"
    - "schemas/**"
    - "hooks/**"
    - "dispatch.py"
    - "dispatch/__init__.py"
    - "utils/replacement_pr_runner.py"
    - "utils/anu_callback_registrar.py"
    - "utils/anu_callback_fallback.py"
    - "utils/completion_callback_fallback_cancel.py"
    - "utils/**axis_1**"
    - "utils/**axis_2**"
    - "utils/axis_3_canary_scale_aware_guard/**"
    - "utils/anu_spawn_visibility_guard/**"
    - "memory/tasks/task-2641*"
    - "memory/tasks/task-2642*"
    - "memory/tasks/task-2643*"
    - "memory/tasks/task-2644*"
    - "memory/tasks/task-2645*"
    - "memory/tasks/task-2646*"
    - "memory/tasks/task-2647*"
    - "memory/tasks/task-2648*"
    - "memory/tasks/task-2649*"
    - "memory/tasks/task-2650*"
    - "memory/tasks/task-2651*"
    - "memory/tasks/task-2652*"
    - "memory/tasks/task-2653*"
    - "memory/tasks/task-2654*"
    - "memory/tasks/task-2655*"
    - "memory/tasks/task-2656*"
    - "memory/tasks/task-2657*"
    - "memory/tasks/task-2658*"
    - "memory/tasks/task-2659*"
    - "**/.env*"
    - "**/credentials*"
  commands:
    - "python3 -m py_compile"
    - "python3 -m json.tool"
    - "python3 -m pytest"
    - "python3 -c"
    - "ls"
    - "cat"
    - "stat"
    - "git status"
    - "git diff"
    - "git log"
    - "git checkout"
    - "git branch"
    - "git add"
    - "git commit"
    - "git push"
    - "git worktree"
    - "gh pr create"
    - "gh pr view"
    - "sha256sum"
    - "wc"
    - "printf"
    - "grep"
    - "find"
    - "tail"
    - "cokacdir --cron"
    - "cokacdir --cron-history"
    - "cokacdir --cron-list"
    - "cokacdir --currenttime"
    - "touch"
    - "mkdir"
  merge_policy: "phase_2_normal_callback_fire_delay_pr_only_no_auto_merge"
  ttl_hours: 72
```

## frozen anchors

- ANCHOR-1: "Phase 2 only · Phase 3 fallback launcher 분리 / Phase 4 threshold enforce 본 task 금지 · 별도 회장 승인 강제"
- ANCHOR-2: "normal callback delay ≤ 30s · fallback/dead-man delay 기존 동작 유지 (변경 0)"
- ANCHOR-3: "수정 파일 = scripts/finish-task.sh + dispatch/normal_fallback_callback_helper.py 만 · 그 외 utils/anu_callback_*.py 변경 0"
- ANCHOR-4: "auto-merge 0 · PR #147 merge 0 · 본 task PR merge 회장 verbatim 별도 강제"
- ANCHOR-5: "observer chain 영향 0 · Axis 1/2/3 runtime 변경 0 · dispatch.py 변경 0 · live settings.json 변경 0"
- ANCHOR-6: "role/kind/source_attribution 구분 = 필드 라벨링 최소 보강만 · Phase 3 구조 변경 금지"
- ANCHOR-7: "BOT App token 부재 시 (ghs_ 없음 / OWNER PAT만) push/PR 불가 → CALLBACK_NORMAL_FIRE_DELAY_REMEDIATION_HOLD_FOR_CHAIR 분류 + 회장 결정 대기 (★ 봇 자율 PAT 사용 금지)"

## finalize 프로토콜

1. base = origin/main 최신 fetch · HEAD `d4098b04 task-2642`
2. 별도 worktree task-2660-dev1
3. dev1 헤르메스 봇 작업
4. `scripts/finish-task.sh:1369` 수정 (`--at "10m"` → `--at "10s"` · 또는 제거)
5. `dispatch/normal_fallback_callback_helper.py:617` 수정 (normal default `"10s"` 또는 30초 이내 · fallback default 변경 0 유지)
6. role/kind/source_attribution 최소 보강 (★ envelope 필드 추가 · 구조 변경 0)
7. tests/callback_fire_delay_remediation/test_regression_6.py 작성 (6 fixture)
8. 6 regression all PASS
9. forbidden_action_count = 0 확인 · fallback 동작 영향 0 확인
10. commit (Phase 2 PR 범위) + push
11. gh pr create (★ auto-merge label 절대 금지)
12. result marker + report + .done 발행
13. ANU normal callback cron (helper · ★ ANU key `c119085addb0f8b7` 강제 · self-key 등록 금지 · UTF-8 ≤3900 bytes hard limit · envelope only · ★ 본 task 결과로 normal callback delay 변경되었으므로 본 task 의 callback 은 기존 정책 적용 OK)

## 회장 보고 형식 (verbatim)

성공: **`CALLBACK_NORMAL_FIRE_DELAY_REMEDIATION_P2_PR_READY`**
실패: **`CALLBACK_NORMAL_FIRE_DELAY_REMEDIATION_HOLD_FOR_CHAIR`**

끝
