# task-2774+5 완료 보고 — activation 전 안전 PR (G2 fail-closed + G3 backlog 보호, guard-native)

상태명: `TASK2774_ACTIVATION_PRECURSOR_SAFETY_G2_G3_GUARD_NATIVE_ACTIVE_FALSE`
PR: **#252** (base main, OPEN, MERGEABLE) · base = origin/main `23f1b6db` (PR#251) · **ACTIVE=false 유지** · merge 미승인

## SCQA

**S**: P0-b systemd-path driver(`dispatch/anu_pickup_driver.py`)는 B real bounded activation 직전 단계이며, canonical p0b_inbox 에 실 backlog 12건이 존재한다.

**C**: activation 을 켜는 순간, (G2) activation-check/governor 주입 실패가 조용히 None 으로 넘어가 governor 미주입 상태로 live 진행될 위험, (G3) activation/canary 실행이 canonical 12건 backlog 를 무차별 consume 할 위험이 코드에 그대로 남아 있었다.

**Q**: flag/systemd/canary 를 켜지 않은 채(ACTIVE=false), 위 2개 위험을 코드로 fail-closed 하게 닫을 수 있는가?

**A**: activation-intended 전용 preflight 게이트를 신규 추가해 G2(예외/미활성/governor 미주입 → STOP)·G3(explicit canary scope 강제 + backlog 밖 1건이라도 감지 시 STOP)로 fail-closed 처리. driver `main` 에는 기본 OFF(`activation_intended=False`) opt-in 파라미터로 결선하여 기존 경로 100% 보존. 신규 11종 + 핵심 회귀 86종 PASS, 실 12건 backlog 미소비(개수·sha 불변) 실증 완료.

## 구현 diff (정확히 3파일)
- `dispatch/anu_activation_preflight.py` (신규, 161줄) — self-contained preflight helper(stdlib only, driver import 0). `activation_intended_preflight(root, *, paths, build_governor_fn, is_activated_fn=None, inbox_dir_rel=None) -> dict(ok,reason,stop)`.
- `dispatch/anu_pickup_driver.py` (수정) — `main(argv=None, *, activation_intended: bool=False)` 최상단에 preflight 게이트 결선. True 일 때만 scan 전 STOP 판정, False(기본)는 미호출.
- `tests/regression/test_activation_intended_safety_2774p5.py` (신규, 464줄) — 회귀 11종.

3파일 밖 수정 0 (forbidden_paths: dispatch.py / anu_result_pickup_runner.py / replacement_pr_runner.py / matrix / flag 무접촉).

## G2 fail-closed 처리 내역 (순서대로 첫 STOP 즉시 반환)
- is_activated_fn 예외 → `ACTIVATION_CHECK_ERROR` (조용한 None 금지)
- 미활성(False) → `NOT_ACTIVATED`
- build_governor_fn 예외 → `GOVERNOR_BUILD_ERROR`
- governor None → `GOVERNOR_NOT_INJECTED`
- governor non-callable → `GOVERNOR_NOT_CALLABLE`

## G3 backlog 보호 증거 (12건 불변)
- paths 미지정 → `CANARY_PATHS_REQUIRED`
- canonical backlog 중 canary paths 밖 1건이라도 → `CANONICAL_BACKLOG_DETECTED`
- backlog 는 읽기 glob 만 수행(삭제/수정/이동/소비 0)
- 실증: 실 canonical `/home/jay/workspace/memory/events/p0b_inbox` 12건에 대해 forced-activated preflight 실행 → CANONICAL_BACKLOG_DETECTED STOP, 실행 전후 파일 개수 12 불변 + listing sha256 `228df2c0...` 동일.

## 테스트 결과
- 신규 `test_activation_intended_safety_2774p5.py` 11/11 PASS
- 기존 `test_driver_governor_wiring_2774p3.py` 8/8 PASS (결선 보존)
- 핵심 회귀: `test_anu_result_pickup_runner_2720.py` 12, `test_spawn_safety_governor_2774.py` 12, `test_anu_pickup_driver_2721.py` 34, `test_p0b_event_strategy_wiring_2760.py` 20 — 전부 PASS
- py_compile: `dispatch/anu_pickup_driver.py` + `dispatch/anu_activation_preflight.py` PASS

## L1 스모크테스트 결과
- 서버 재시작: 해당없음 (라이브러리/게이트 모듈 — 서버 프로세스 없음)
- API 응답 확인: 해당없음 (HTTP API 아님). 대신 실 실행 검증:
  - G2 5개 reason 실 STOP 실증(ACTIVATION_CHECK_ERROR / NOT_ACTIVATED / GOVERNOR_BUILD_ERROR / GOVERNOR_NOT_INJECTED) — non-pytest 실행 OK
  - G3 실 12건 backlog → CANONICAL_BACKLOG_DETECTED STOP + backlog 미소비(개수 12 불변, listing sha 동일)
  - driver `main(activation_intended=True)` 실 OFF flag 실행 → `NOT_ACTIVATED` STOP, scan_once/scan_live/report 호출 0회, rc=0 (scan/fire 0, 기존 OFF 동작 보존)
- 스크린샷: 해당없음 (프론트엔드 작업 아님)

## 머지 판단
- **머지 필요**: Yes (단, 독립검증/CI/Gemini/final gate 통과 후 — 본 PR 은 생성까지만)
- **브랜치**: task/task-2774+5-dev2
- **워크트리 경로**: /home/jay/workspace/.worktrees/task-2774+5-dev2
- **머지 의견**: 3파일 격리·기존 OFF 경로 무변경·회귀 0·base 23f1b6db fresh. activation-intended 는 기본 OFF 로 production 무영향. task 지시(merge 금지)에 따라 자동 머지 미시도 — 회장 final gate 대기.

## 비고
- base=23f1b6db (강제 pull 0, stale local main 미사용) · ACTIVE=false 유지 · flag/systemd/canary/real callback 미발사
- B 재결정 가능 여부: **가능**. activation-intended 모드는 코드로 정의만 되었고 기본 OFF 라 B 활성화 여부는 회장 별도 승인으로 독립 결정 가능.
- 모델 사용 기록: 팀장(오딘, Opus) 설계/구현(preflight helper + driver 결선)/검토. 헤임달(테스터, Sonnet) 테스트 11종 작성/검증. haiku 미사용.
- unresolved 0 · final gate 전 merge 금지.
