# task-2775+2 — PR #255 same-branch 보정: active+epoch 부재 fail-closed를 limited/fire-capable 모드 한정 결선 (B안, ACTIVE=false)

상태명: `TASK2775_PLUS2_ACTIVE_EPOCH_MISSING_LIMITED_MODE_MICROFIX_APPROVED_FOR_DEV2_ACTIVE_FALSE`
담당: dev2-team (PR #255 / branch `task/task-2775-dev2` 소유)
회장 승인: 2026-06-26 — **PR #255 같은 브랜치 보정용 +2 micro-fix 1회, B안 채택**.
★ 이 승인은 **activation / merge / real fire / systemd enable·start / flag 생성 / canary / recurring /
backlog consumption 승인이 아님.** ACTIVE=false · systemd disabled · flags OFF 유지.

## 배경 (ANU 독립검증 잔여 갭)
ANU 독립검증(`memory/reports/task2775p1_anu_verification_active_epoch_missing_gap_260626.md`):
`ACTIVE_EPOCH_MISSING_PRODUCTION_GAP_ACTIVE_FALSE`. +1에서 epoch-scope N 카운트는 잘 고쳤으나,
**production main() 호출부가 `limited_activation_bound_gate(CANONICAL_ROOT)`로 `is_activated_fn`을
주입하지 않아**, `p0b_driver_enabled=enabled`인데 `p0b_activation_epoch`가 없거나 손상되면
**fail-closed 없이 조용히 pass-through → scan_once 진행**. 즉 limited 가동 시 기준선(N/T) 없이
무기준으로 흐를 수 있음. (현재 ACTIVE=false라 즉시 위험은 0이나, limited GO 전 반드시 닫아야 할 갭.)

## ★ 설계 선택: B안 (회장 확정 — A안 보류)
- **A안(test-2760 수정 + expected_files 3개 확장)은 보류.**
- **B안**: epoch 부재 fail-closed를 **legacy scan_once 라우팅 전체에 걸지 말고, limited activation /
  fire-capable 모드에서만** 적용. legacy 라우팅·test-2760 무손상하면서 실제 가동 안전만 닫는다.

## 핵심 목표
실제 limited activation 가동 조건에서 `p0b_driver_enabled=enabled`인데 `p0b_activation_epoch`가
**없거나 손상**되면, **production main() 실제 경로에서 governor·launcher build 이전에 fire 0으로 단락**하고
`p0b_driver_enabled`를 **atomic disabled** 처리(`NOOP_ACTIVE_EPOCH_MISSING_AUTO_DISABLED`).

## 구현 원칙
1. **production main()에서 조용한 pass-through 금지** — limited/fire-capable 모드 + epoch 부재/손상이면 단락.
2. **limited/fire-capable 모드에서만** epoch 부재/손상 → `NOOP_ACTIVE_EPOCH_MISSING_AUTO_DISABLED`.
3. **legacy scan_once / test-2760 라우팅은 무손상.**
4. 기존 epoch-scope N 카운트 · `processed_at` timezone-aware 파싱 · 부재/파싱실패 보수적 제외 정책 **유지**.
5. T=120 / N=3 / kill 순서와 fire 0 단락 **무회귀**.

## 구현 방식 (★중요 — 임의 확장 금지)
- `limited_activation_bound_gate()`에 **무조건 일반 `is_activated`를 걸어 test-2760을 깨는 방식은 금지.**
- 대신 **기존 코드의 `activation_intended` 또는 fire-capable limited 조건**을 이용해, **실제 limited
  activation으로 볼 수 있는 경우에만** epoch 부재 fail-closed가 발동되도록 결선.
- ★ **조건이 애매하면 STOP 보고.** 임의로 **더 넓은 activation 정의를 만들지 말 것.** (예: 새 flag 발명,
  is_activated 단독을 limited로 간주하는 등 정의 확장 금지. 기존 신호만 사용. 불명확하면 멈추고 보고.)

## 범위 (엄수)
- **PR #255 같은 브랜치(`task/task-2775-dev2`) 위 commit 추가**. **새 PR 생성 금지**(불가 시 STOP).
- expected_files **2개만**:
  - `dispatch/anu_pickup_driver.py`
  - `tests/regression/test_limited_activation_bounds_2775.py`
- **수정 금지**: **test-2760** / governor / runner / launcher / owner-proof / freshness / systemd /
  `.github/**` / `scripts/finish-task.sh`.
- **금지**: merge / activation / real fire / `systemctl enable·start` / activation flag 생성 / canary 주입 /
  recurring 등록 / backlog consumption.

## 필수 테스트 (test_limited_activation_bounds_2775.py)
- **production main() 실제 경로**: limited/fire-capable 모드 + epoch **부재** → auto disabled + fire 0 +
  **governor/launcher 미호출**.
- **production main() 실제 경로**: limited/fire-capable 모드 + epoch **손상** → auto disabled + fire 0.
- **legacy scan_once / test-2760 라우팅 무손상**(enabled + epoch 미설정인 legacy 경로가 fail-closed로
  바뀌지 않음).
- epoch 정상 존재 시 기존 N/T/kill 경로 **무회귀**.
- epoch 이전/이후 N 카운트 테스트 **유지**.
- `processed_at` timezone / 부재 / 파싱실패 테스트 **유지**.
- T=120 `main()` L1 스모크 **유지**.
- `py_compile` PASS · 기존 14(+0/+1 누적) 테스트 + driver 회귀 PASS · expected_files 밖 수정 **0**.

## 중단 조건 (하나라도 → STOP_REPORT, 우회 0)
- **limited/fire-capable 조건이 기존 신호로 명확히 정의되지 않음** → 임의 확장 말고 STOP.
- expected_files 밖 수정 필요 / test-2760 수정 불가피 / 새 PR 불가피.
- governor/runner/launcher/systemd/finish-task 수정 필요.
- activation 또는 real fire가 필요해지는 경우.
- legacy scan_once / test-2760 / 기존 N·T·kill 경로를 깨는 경우.

## 결과 보고 (필수)
- PR #255 **유지 여부** · base/head SHA · **expected_files 2개 내 diff 증거**.
- **active+epoch 부재 production main L1 결과**.
- **active+epoch 손상 production main L1 결과**.
- **test-2760 무손상 결과**.
- **2775 bounds 전체 PASS**.
- ACTIVE=false / systemd disabled / flags OFF / real fire 0 / canary 0 증거.
- **MERGE_CANDIDATE 가능 여부**.

## 완료 처리 + ANU callback (필수)
- 완료 시 `memory/events/task-2775+2.done` + `memory/reports/task-2775+2.md`.
- 봇 idle 전 **ANU callback 필수**(성공/실패/blocked 무관). collector=ANU, owner_key=`c119085addb0f8b7`,
  self-key 금지. callback prompt UTF-8 **≤3900 bytes** (`printf '%s' "$P" | wc -c`), envelope 만
  (task_id·PR#255·new head sha·result_path·report_path·one-line). **merge 절대 금지.**
- PASS 나와도 **머지 금지** — ANU 독립검증 → fresh-head Gemini → CI 확인 → MERGE_CANDIDATE로만 보고.
  회장 명시 승인 전까지 PR #255 open 유지.

## 진행
dev2는 B안 limited-mode 한정 fail-closed 결선 구현·테스트(real fire 0)·로컬검증 후 branch push로
**PR #255 갱신**, 보고서 + .done + ANU callback으로 마감. ANU가 이후 독립검증/Gemini/CI 확인 → 회장 머지 판단.

## allowed_resources (본 task의 capability)

```yaml
allowed_resources:
  paths:
    - "dispatch/anu_pickup_driver.py"
    - "tests/regression/test_limited_activation_bounds_2775.py"
    - "memory/reports/task-2775+2.md"
    - "memory/events/task-2775+2.done"
  forbidden_paths:
    - ".github/**"
    - "memory/events/*.cron-*"
    - "scripts/finish-task.sh"
    - "tests/regression/test_*2760*.py"
    - "utils/spawn_safety_governor.py"
    - "dispatch/anu_result_pickup_runner.py"
    - "dispatch/anu_callback_launch_audit.py"
    - "dispatch/anu_owned_callback_enforcement.py"
    - "memory/state/p0b_driver_enabled"
    - "memory/state/p0b_callback_launch_enabled"
  commands:
    - "pytest"
    - "python3 -m py_compile"
    - "git"
    - "gh"
  merge_policy: "manual"
  ttl_hours: 24
```