# task-2760+1 — HIGH 1 + MEDIUM 4 ledger bounded fix (event strategy 핵심 불변식)

## ★ 회장 결정 (2026-06-17)
PR #241 HIGH 1(_move_processed 실패 시 stuck file/idempotency leak) = event strategy 핵심 불변식 위반(canary "1회 처리·retrigger 0" 위협). MEDIUM 4(같은 ledger robustness 축)와 함께 **bounded fix 1회** 승인. PR #241 직접 push 금지 → **fresh replacement PR**. 상태 `P0B_EVENT_STRATEGY_HIGH1_LEDGER_BOUNDED_FIX_APPROVED_ACTIVE_FALSE`. ACTIVE=false.

## base / branch / PR
- base = clean origin/main `f641cd58`. fresh branch `task/task-2760+1`. isolated worktree. 참조 = `origin/task/task-2760`(67a06d8f) 2파일.
- **PR #241 추가 push 금지**. branch push only(ANU가 fresh PR 생성·#241 superseded close 통제).

## 수정 = HIGH 1 + MEDIUM 4만, expected_files 2파일 내부
- `dispatch/anu_pickup_driver.py` · `tests/regression/test_p0b_event_strategy_2760.py`
- **신규 파일 금지** · expected_files 밖 수정 필요 시 STOP_REPORT.

## HIGH 1 — move/ledger 일관성 (핵심 불변식)
- 처리 완료 ledger 기록은 **processed/archive move 성공과 일관**되게.
- `_move_processed` **실패 시**: 완료 ledger로 dedupe되어 inbox에 **stuck 되는 상태 금지**. move 실패는 (a)retry 가능/pending 상태로 남기거나 (b)완료 ledger 기록 안 하거나 (c)명확한 **failure record로 분리**.
- 동일 `(task_id, sha256)`에 대해 **완료 상태 vs pending/failure 상태가 혼동되지 않게**.

## MEDIUM 4 (같은 ledger robustness 축, 함께)
- 손상 ledger entry 파싱 방어(JSONDecodeError/skip)
- `task_id`/`sha` None → 불완전 튜플 `(None,None)` 방어
- root 경로 glob 특수문자(`[`,`]`) → `glob.escape` 등으로 방어
- ledger 무한증가/매 cycle 전체 읽기 → compaction 또는 read-limit 정책

## busy-skip
누락 아니라 **pending/delayed**로 유지.

## 필수 테스트 (각각 + 기존 9 유지)
1. `_move_processed` 실패 시 **완료 ledger 안 남음**
2. move 실패 후 파일이 **stuck-complete dedupe-skip 안 됨**
3. 재시도 가능한 **pending/failure 상태**
4. 손상 ledger entry 파싱 방어
5. task_id/sha None incomplete tuple 방어
6. root glob 특수문자
7. ledger growth/read **bounded 또는 compaction/limit**
8. 기존 신규 9 tests 유지
9. canary 실행 0 · ACTIVE=false

## 금지 (위반 시 STOP_REPORT)
PR #241 직접 push · merge/auto merge/admin override · canary 실행 · systemd enable/install · 실제 callback/wake launch · external probe/key custody/daemon 구현 · matching/allowlist 재도입 · _coerce · type-safety hygiene 일반 확장 · Gemini watcher/replacement runner 확장 · ACTIVE=true · expected_files 밖 · 신규 파일 · PR 생성/merge.

## 중단 조건 (STOP_REPORT)
expected_files 밖 · 새 파일 필요 · HIGH 남거나 새 HIGH/Critical7 · 새 MEDIUM이 **같은 ledger robustness 축에서 반복**(추가 수렴 금지) · driver 공개 시그니처 변경 필요 · matching 재도입 · systemd/callback/wake/production/merge 축 터치.

## ★ 산출물 / callback (polling 금지 — dev callback 필수)
`task/task-2760+1` branch commit + push(PR 0). **종료 전 ANU normal callback 필수** — ANU key `c119085addb0f8b7`(self-key 금지·UTF-8 wc -c ≤3900 bytes·envelope만: task_id/branch/head/result_path/sha256/collector_role=ANU/HIGH1·MEDIUM4 대응·테스트수 1줄). ANU는 foreground polling 안 함 — dev callback으로 결과 수신.

## allowed_resources
```yaml
allowed_resources:
  paths:
    - "dispatch/anu_pickup_driver.py"
    - "tests/regression/test_p0b_event_strategy_2760.py"
  forbidden_paths: ["**/*.service","**/*.path",".github/**","memory/state/automation_capability_matrix.json","dispatch/v2_13_gate.py"]
  commands: ["pytest","python3 -m py_compile","git"]
  merge_policy: "none"
  ttl_hours: 12
```
