# task-2774+12 — PR #253 same-PR micro-fix: gate_result None-shape safety hardening (★회장 LOOP_BOUNDARY 1회 override)

상태명: `TASK2774P12_PR253_GATE_RESULT_NONE_GUARD_CHAIR_OVERRIDE_APPROVED_ACTIVE_FALSE`
담당: dev2 (PR #253 / branch `task/task-2774+8-dev2` 소유 봇)
회장 승인: same-PR micro-fix **1회** (2026-06-25). ★ **자동 micro-fix 연장 아님 — 회장 명시
LOOP_BOUNDARY 1회 override(null-shape safety hardening).** 이후 fresh MED 재발 시 자동수정 절대 금지.

## 배경
fresh head `6ba0b88b64bf7b3cd874e9a8c44ffad9721ffb5d` 에 Gemini 신규 MEDIUM 1건:
`gate_result.eligibility` 또는 `gate_result.reasons` 가 `None` 이면 `dict(None)` / `list(None)` 호출로
`TypeError` 발생 가능. D-2 fire safety wrapper(block result 빌더)가 **null/missing state 에서 크래시**.
원칙: 안전/terminal-state 코드는 None/empty/missing state 에서 죽지 말고 **명시 fail-closed 또는
안전 정규화**되어야 한다.

지점: `dispatch/anu_result_pickup_runner.py` 의 gate_result 기반 block-result 빌더(예 `_oneshot_wrapper_block`
및 동일 패턴으로 `eligibility=dict(gate_result.eligibility)` / `reasons=list(gate_result.reasons)+[...]` 를
구성하는 fire-safety wrapper 경로 — Gemini 가 지적한 site). 라인 예시 1437-1438 등.

## 승인 범위 (엄수)
- PR #253 **same-PR** micro-fix 1회 (새 PR 금지). branch `task/task-2774+8-dev2` 위 커밋.
- 수정 허용: **`dispatch/anu_result_pickup_runner.py`** + **`tests/regression/test_d2_fire_wiring_2774p8.py`** 만.
- 필요 시 design md correction note **1줄** 허용. expected_files 밖 필요 시 **STOP_REPORT**.
- ★ scope creep 금지: Gemini 가 지적한 **fire-safety wrapper block 빌더의 None 안전성**만 닫는다.
  무관한 함수/리팩터 확장 금지(이전 라운드에서 scope 확장이 새 MED 를 유발한 점 유의).

## 구현 요구
1. `gate_result.eligibility` 가 None 이어도 `TypeError` 안 나게.
2. `gate_result.reasons` 가 None 이어도 `TypeError` 안 나게.
3. 선호 구현: `eligibility = dict(gate_result.eligibility or {})` / `reasons = list(gate_result.reasons or [])`.
4. `gate_result` 자체가 None 일 가능성이 있는 진입점이면 **명시 fail-closed status** 로 처리(silent 통과 금지).
5. **정상 gate_result 경로 의미 변경 금지.** None 을 성공/​fire 허용으로 해석 금지. 오류 삼켜 성공 처리 금지.
6. Gemini 가 지적한 site 와 **동일 null-crash 위험을 공유하는 인접 wrapper-block 빌더**에도 일관 적용 가능
   (단 expected_files 내·forbidden 함수 미접촉 한정). 무관 site 확장 금지.
7. raw key 노출 0 / real fire 0 / ACTIVE=false 유지.

## 수정 금지 (회귀 무손상)
- owner-proof / governor / G2 / G3 / D-1 path / `build_callback_launch_fn` 수정 금지.
- `attempt_owner_fire` 기존 동작 수정 금지. target 조건 완화 금지.
- registered fail-closed 로직 완화 금지. subprocess bytes 처리(+10) 완화 금지.
  flag_reader `INVALID_FLAG_READER` guard(+11) 완화 금지.

## 테스트 보강 (test_d2_fire_wiring_2774p8.py, 순수 추가)
- `gate_result.eligibility=None` → `TypeError` 없이 fail-closed/안전 block result.
- `gate_result.reasons=None` → `TypeError` 없이 fail-closed/안전 block result.
- `eligibility=None, reasons=None` 동시 케이스.
- 정상 eligibility/reasons 기존 경로 유지(의미 무변경).
- None 정규화가 **fire_fn 호출로 이어지지 않음**.
- None 정규화가 **subprocess 호출로 이어지지 않음**(mock `assert_not_called`).
- raw key 노출 0.
- 기존 D-2 wiring **45 tests 유지**. 핵심 회귀 유지. `py_compile` PASS.

## 검증 (봇 보고 포함)
- PR head 새 sha. diff expected_files 안. raw key 0 / real fire 0 / callback 0 / ACTIVE=false 유지.
- D-2 테스트 PASS 수(≥48 기대). 정상 경로 의미 무변경 입증.

## ★ 루프 경계 재확정 (회장 verbatim)
- **이번은 회장 명시 override(1회 예외).** PR #253 에서 fresh MED 자동 micro-fix 는 **더 이상 반복 금지.**
- 이후 fresh **HIGH/Critical** → STOP_REPORT.
- 이후 fresh **MED 가 또 나오면 자동수정 금지** → 상태명
  `TASK2774P12_PR253_GEMINI_MED_LOOP_BOUNDARY_CHAIR_DECISION_REQUIRED_ACTIVE_FALSE` 로 **회장 판단 요청.**
  회장 판단 없이 dev 위임·코드 수정·commit·push 금지.

## 절대 금지
merge / auto-merge / real fire / ACTIVE gate ON / callback 자동발사(아래 ANU callback 예외) /
systemd start/enable / thread 수동 resolve / Gemini comment dismiss / evidence-defer 임의종결 /
production activation 표현 / ENFORCED=true 단정.

## 완료 처리 + ANU callback (필수)
- 완료 시 `memory/events/<task_id>.done` + `memory/reports/<task_id>.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#253·new head sha·result_path·report_path·one-line).
- **merge 절대 금지.** PASS 나와도 ANU 가 독립검증 → fresh-head Gemini 재리뷰 → CI 확인 →
  MERGE_CANDIDATE 로만 보고. 회장 명시 승인 전까지 PR #253 open 유지.

## 진행
dev2 는 micro-fix 구현·테스트·로컬검증 후 branch push 로 PR #253 갱신, 보고서 + .done +
ANU callback 으로 마감. (ANU 가 이후 독립검증/Gemini 재리뷰/CI 확인 담당)

## allowed_resources (본 task의 capability)

```yaml
allowed_resources:
  paths:
    - "dispatch/anu_result_pickup_runner.py"
    - "tests/regression/test_d2_fire_wiring_2774p8.py"
    - "memory/plans/spawn_safety_governor/d2_fire_wiring_design_2774p8.md"
    - "memory/reports/task-2774+12.md"
    - "memory/events/task-2774+12.done"
  forbidden_paths:
    - ".github/**"
    - "memory/events/*.cron-*"
    - "scripts/finish-task.sh"
  commands:
    - "pytest"
    - "python3 -m py_compile"
    - "git"
    - "gh"
  merge_policy: "manual"
  ttl_hours: 24
```