# task-2729+7 — P0-B pickup activation hardening (MAX_FILES + legacy cutoff + ledger failure)

## 레벨
Lv.3 (시스템 hardening 구현 + isolated 검증 — production ACTIVE 전환 아님)

## 한 줄 목표
pickup activation readiness blocker(C1)와 precondition(C2)를 해소: ① scan_once **MAX_FILES 상한** ② **legacy cutoff**(activation epoch 이전 result.json 자동 wake 제외, canonical move 0) ③ **ledger/marker 실패 명시 처리**. **canonical mass mutation 0 / production ACTIVE=false 고정 / systemctl enable 0**. 해소 후 isolated temp root 재-audit로 ACTIVATION_READY 재판정 가능 상태 산출.

## 현재 blocker / precondition / false-positive (단일 소스: pickup_activation_readiness_audit_260606.json)
1. **`C1_SCAN_ONCE_MAX_FILES_ABSENT_WITH_126_LEGACY_RESULT_BACKLOG`** (BLOCKER): scan_once MAX_FILES 부재 + canonical events 126 legacy result.json(terminal marker 0) → 첫 activation 시 owner_proof_fail 로 126개 일괄 quarantine MOVE = canonical mass mutation. 실증: isolated sim verdict 분포 QUARANTINE 126/126.
2. **`C2_LEDGER_MARKER_FAILURE_HANDLING_PRECONDITION`** (PRECONDITION): ledger/done marker write 실패가 fail-safe pass(silent) → activation 후 ledger write 실패 시 dedupe 누락 → duplicate wake 위험. 명시적 실패 처리/관측 필요.
3. **`C3_RAW_KEY_EXPOSURE_FALSE_POSITIVE_RESOLVED`** (FALSE-POSITIVE, 해소): preflight 286건 전부 venv 서드파티 hex, pickup 스택 raw key 0. blocker 아님. 추가 조치 불요(기록만).

## 설계 (구현 가능 범위 — isolated sim 실증)
### D1. scan_once MAX_FILES 상한
- `scan_once` candidates = `sorted(glob)` 에 단일 cycle 처리 상한(`MAX_FILES`, 후보 50) 적용. 초과분은 다음 cycle. 무제한 일괄 처리 차단(runaway 방지 보강).
### D2. legacy cutoff (canonical move 0 의 핵심)
- activation 시각 기준 `activation_epoch` 마커(예: `memory/state/p0b_activation_epoch`, **driver 생성·읽기 전용**) 도입.
- `process_one`: result.json mtime < activation_epoch → **`NOOP_LEGACY_SKIP`** (move 0 · wake 0 · quarantine 0 · canonical 무수정). activation 이후 생성 result.json 만 정상 decision path.
- ★ 실증: isolated sim 에서 126 legacy 전부 NOOP_LEGACY_SKIP → canonical mutation 0 (quarantine move 0). **126 backlog 실제 처분(이동/삭제) 불필요**.
### D3. ledger/marker 실패 명시 처리
- 현 `except OSError: pass` → 명시적: 실패 시 `DriverRecord.error`/verdict 에 `LEDGER_WRITE_FAILED`/`MARKER_WRITE_FAILED` 기록 + 관측. dedupe 보장 위해 ledger write 실패 시 wake fail-closed 옵션 검토(중복 wake 방지 우선).
### D4. (정책 제안, 실행은 회장 별도 승인) 126 legacy backlog 처분
- 옵션 A(권장): legacy cutoff 로 skip만 — 실제 처분 불요, canonical write 0.
- 옵션 B: 일괄 `.pickup.acked` 명시 종결(canonical write 필요 → 회장 승인).
- 옵션 C: archive move(canonical write 필요 → 회장 승인).
- ※ 본 task 는 **A(skip) 기준 구현**. B/C 는 설계 제안만(실행 0).

## allowed_resources
```yaml
allowed_resources:
  paths:
    - "dispatch/anu_pickup_driver.py"
    - "dispatch/anu_result_pickup_runner.py"
    - "tests/regression/test_anu_pickup_activation_hardening_2729p7.py"
    - "memory/reports/task-2729+7.md"
    - "memory/plans/p0b-pickup/legacy_cutoff_backlog_policy_260606.md"
    - "memory/events/task-2729+7.*"
    - "memory/tasks/task-2729+7-pickup-activation-hardening.md"
  read_only_reference:
    - "tests/regression/test_anu_pickup_driver_2721.py (★ 기존 회귀 무영향 확인 — 수정 0)"
    - "tests/regression/test_anu_result_pickup_runner_2720.py (★ 기존 회귀 무영향 확인 — 수정 0)"
    - "scripts/harness/v36/anu_pickup_p0b_audit_decision_check.py (★ sim 재검증 참조 — 수정 0)"
    - "scripts/anu_pickup_entrypoint.sh (★ activation epoch 마커 생성 위치 검토 — read only, 수정은 별도)"
    - "deploy/systemd/anu-pickup.path"
    - "deploy/systemd/anu-pickup.service"
    - "memory/events/pickup_activation_readiness_audit_260606.json"
    - "★ dev4 task-2729+5 audit 산출(merged main 514562bb): memory/reports/task-2729+5-p0b-audit-first.md (입력 자료로만)"
  forbidden_paths:
    - "memory/events/task-*.result.json"
    - "memory/events/owner-trigger-audit.jsonl"
    - "memory/events/callback_4tuple_index.jsonl"
    - "memory/state/p0b_driver_enabled"
    - "memory/p0b_state/**"
    - "deploy/systemd/**"
    - "scripts/anu_pickup_entrypoint.sh"
    - "scripts/ci_watch_handoff_runner.py"
    - "utils/**"
    - "scripts/finish-task.sh"
    - "dispatch.py"
    - ".github/**"
    - "hooks/**"
    - "/home/jay/.claude/**"
    - "/home/jay/.config/systemd/**"
    - "/usr/local/bin/cokacdir"
```

## EXPECTED FILES (산출 — 정확히 5파일, 초과 시 중단·보고)
1. `dispatch/anu_pickup_driver.py` — D1 MAX_FILES + D2 legacy cutoff(NOOP_LEGACY_SKIP) 구현
2. `dispatch/anu_result_pickup_runner.py` — D3 ledger/marker 실패 명시 처리
3. `tests/regression/test_anu_pickup_activation_hardening_2729p7.py` — 신규 회귀(MAX_FILES/legacy cutoff/ledger failure) + 126-legacy sim 케이스
4. `memory/reports/task-2729+7.md` — 구현+재-audit 결과
5. `memory/plans/p0b-pickup/legacy_cutoff_backlog_policy_260606.md` — cutoff/backlog 정책
- (기존 회귀 test_anu_pickup_driver_2721.py / test_anu_result_pickup_runner_2720.py = 무영향 확인만, 수정 0)
- ★ **5파일 초과 필요 시 즉시 중단하고 HOLD_FOR_CHAIR 보고**

## ★ 회장 verbatim 필수 구현 조건 (2026-06-06) — paraphrase 금지
1. MAX_FILES 기본값은 **안전한 상한**으로.
2. MAX_FILES 초과 시 **전수 처리 금지** → bounded 처리 또는 HOLD/DEFER 상태로 멈춤.
3. legacy cutoff 는 **activation_epoch 기준** 동작.
4. activation_epoch 없거나 불명확하면 **fail-open 금지** → NOOP/HOLD 계열로 안전하게 멈춤.
5. legacy skip 은 **canonical 파일 이동 없이 verdict 만** 남기는 방식.
6. ledger/marker 실패 시 **duplicate wake 미발생** fail-safe 처리.
7. raw ANU key 출력 0 유지.
8. ACTIVE=false 유지.

## ★ 회장 verbatim 검증 (10)
1. isolated temp root 에서 126 legacy result.json simulation. 2. activation_epoch 이전 → NOOP_LEGACY_SKIP. 3. activation_epoch 이후 신규만 bounded scan. 4. MAX_FILES 상한 동작. 5. duplicate pickup 0. 6. terminal marker 존재 시 no-op. 7. ledger/marker failure fail-safe. 8. raw key exposure 0. 9. canonical delta 0. 10. regression PASS.

## ★ 즉시 중단 조건 (HOLD_FOR_CHAIR)
- fresh HIGH/CRITICAL / expected_files 5 초과 / credential·permission expansion / ACTIVE=true 필요 / systemd enable 필요 / canonical write 필요 / 126 backlog 실제 처분 필요

## FORBIDDEN / 금지
1. systemctl enable --now  2. production ACTIVE 전환  3. **canonical memory/events 실제 이동·삭제·수정**(126 result.json 실제 quarantine 금지)  4. real ANU spawn  5. runtime pickup 코드 수정의 **dispatch 전 실행**(구현은 봇 worktree 내, canonical 무영향)  6. PR merge/push/comment 자동 실행  7. ACTIVE=true 선언  8. `memory/state/p0b_driver_enabled` 생성  9. systemd unit 설치/수정

## LOCK (재확인)
- canonical write **금지** (events/ledger/state/systemd) — legacy cutoff 는 skip이지 move 아님
- 모든 audit/dry-run/sim 은 **isolated temp root** 강제
- **production ACTIVE=false 고정**
- 산출은 worktree 내 코드 변경 + 회귀; canonical 무영향

## activation 전 재-audit 조건 (본 task 산출에 포함)
1. legacy cutoff 적용 후 126 legacy → **NOOP_LEGACY_SKIP** + canonical mutation **0** (isolated sim 재실증)
2. MAX_FILES 상한 동작(초과분 다음 cycle) 회귀 PASS
3. ledger/marker 실패 시 LEDGER_WRITE_FAILED 명시 기록 회귀 PASS
4. 기존 회귀(46) 무영향 + 신규 회귀 PASS
5. raw key 0 / canonical_untouched=true

## controlled pilot 재수행 필요 여부
- **필요** — legacy cutoff 추가로 decision path 분기 변경(NOOP_LEGACY_SKIP 신규). task-2729+6 controlled pilot 을 cutoff skip 케이스 포함해 **1회 재수행** 권장(별도 회장 승인). 본 task 는 설계+구현+isolated 재-audit 까지, pilot 재수행은 후속.

## 완료 판정 (회장 verbatim)
- 조건 충족 시 **`ACTIVATION_HARDENING_VERIFIED_ACTIVE_FALSE`** 또는 **`DISPATCH_READY_FOR_RE_AUDIT`** 보고.
- canonical write 필요 / 126 backlog 처분 필요 시 **`HOLD_FOR_CHAIR`** 보고.
- fresh HIGH/CRITICAL · expected_files 초과 · credential/permission expansion · ACTIVE=true 필요 · systemd enable 필요 시 즉시 중단.
- ★ 본 task PASS 여도 **pickup production ACTIVE 전환 아님**. PASS 결과 = controlled pilot 재수행 + activation approval 판단의 **입력 자료로만**. pickup chain = IMPLEMENTED / WIRED candidate / **ACTIVE=false** 유지.

## doctrine
직접 코딩 금지(ANU)/봇 위임 / same-PR post-Gemini push 금지 / chain hard limit / long polling 금지 / cron PROMPT ≤2800자·≤3900 bytes / callback ANU key 독립 발사 / executor self-collector 금지.
