# Limited Runtime Pilot — Kill Switch Dry-run Plan (산출물 4/4)

상태명: `LIMITED_RUNTIME_PILOT_DESIGN_PACKET_APPROVED_ACTIVE_FALSE`
작성: 2026-06-27 (KST) · 작성자: 아누 · 근거: main `189f1f0d`

> 목적: **실제 pilot 전에** kill switch가 정말 fire를 막는지, **canonical 부작용 없이·real fire 0으로** 검증한다.
> "안전장치를 달았다 ≠ 안전장치가 당겨진다" — 이 dry-run으로 *당겨짐*을 1회 관측한다.

---

## 1. 검증 목표 (무엇을 입증하나)
- (G1) `memory/state/p0b_kill` 존재 시 driver가 **`NOOP_KILL_SWITCH`로 전면 NOOP** 되는가 (driver:644).
- (G2) kill NOOP 경로에서 **flag write 0** — `p0b_driver_enabled` 미생성/미변경 (kill 우선, 회귀 test:166-181).
- (G3) kill NOOP 경로에서 **real fire 0 / spawn 0 / governor·launcher 미호출**.
- (G4) kill 마커 제거 후 driver가 **정상 경로로 복귀**(kill 없으면 일반 평가).

## 2. dry-run 방식 — 격리 우선 (canonical write 0)
**방식 A (1차·필수): 격리 회귀 테스트**
- 이미 존재하는 회귀가 kill fail-closed를 검증함:
  `tests/regression/test_limited_activation_bounds_2775.py:166` —
  *"tmp_path 에 p0b_kill 터치 → NOOP_KILL_SWITCH, p0b_driver_enabled 미생성"* (G1+G2).
- 실행: `PYTHONPATH=. python3 -m pytest tests/regression/test_limited_activation_bounds_2775.py -q`
- **canonical 부작용 0**: 테스트는 `tmp_path` 격리 root 사용 → canonical `memory/state/` 미접촉.
- **real fire 0**: real_launch_fn 미주입 + tmp root → 실제 `cokacdir` 호출 없음.
- 이 방식이 G1·G2·G3(미호출)을 **canonical 무접촉**으로 입증 → **1차 dry-run은 이걸로 충분**.

**방식 B (2차·선택, 회장 승인 시): canonical kill 경로 1회 격리 호출**
- driver를 **임시 격리 root**(`CANONICAL_ROOT` override 또는 main에 tmp root 인자)로 1회 호출하되,
  kill 마커를 그 tmp root에만 생성. canonical `/home/jay/workspace/memory/state/`는 **절대 안 건드림**.
- 절대 금지: canonical `p0b_kill` 생성 후 canonical driver 가동(= 실제 운영 경로 — dry-run 아님).
- 방식 B는 방식 A로 불충분하다고 판단될 때만. **기본은 방식 A.**

## 3. canonical write 미발생 보장 방법
- dry-run은 **tmp_path/격리 root에서만** 수행. canonical 경로 상수(`CANONICAL_ROOT`=`/home/jay/workspace`)
  하위 `memory/state/`·`memory/events/`·`memory/p0b_state/`에 **write 0**.
- dry-run 전/후 canonical 마커 상태 스냅샷 비교:
  ```
  ls -la memory/state/p0b_kill memory/state/p0b_driver_enabled \
         memory/state/p0b_activation_epoch memory/state/p0b_callback_launch_enabled 2>&1
  # dry-run 전후 동일해야 함 (driver_enabled=disabled 9bytes 불변, 나머지 부재 불변)
  ```
- canonical 마커가 dry-run 후 1바이트라도 바뀌면 → **즉시 STOP**(§7).

## 4. real fire 0 보장 방법
- real_launch_fn **미주입**(default None) → `launch_callback_for_closeout`가 surface-only `LAUNCH_ENFORCED`만,
  실제 `cokacdir --cron` 호출 경로 진입 안 함 (audit:400-403).
- dry-run 중·후 **ANU cron 0** 재확인: `cokacdir --cron-list ... | schedules == 0`.
- `p0b_processed_ledger.jsonl`에 신규 `LIVE_PROCESSED` 행 0 (dry-run이 실 pickup 안 만듦).
- governor `spawn_decisions.jsonl`에 dry-run발 ALLOW 0 (격리 root라 canonical 로그 미접촉).

## 5. kill ON 상태에서 driver fail-closed 확인 (관측 포인트)
- 격리 실행 결과 verdict == `NOOP_KILL_SWITCH` (driver_runs.jsonl 또는 반환값).
- flag write 0: 격리 root의 `p0b_driver_enabled` **미생성**(kill은 disabled write조차 안 함 — 전면 NOOP).
- governor/launcher 호출 0 (kill 게이트가 build 이전에 단락).
- rc/return 값이 kill 경로 규약과 일치(전면 NOOP).

## 6. kill OFF 복귀 확인
- 격리 root에서 `p0b_kill` 제거 후 driver 재호출 → kill 게이트 통과, 일반 평가 경로 진입(G4).
- canonical에서는 애초에 kill 마커를 안 만들었으므로 복귀할 것도 없음(불변 확인만).
- 만약 방식 B로 canonical에 kill을 썼다면(비권장) 반드시 제거 + 부재 재확인.

## 7. dry-run이 실제 activation으로 오인되지 않도록 하는 guard
- dry-run은 **격리 root pytest** 또는 **명시적 tmp root 인자**로만. canonical flag/marker **write 0**.
- dry-run 세션에 `activation_intended=True` / `limited_runtime=True` **실 canonical 전달 금지**
  (격리 테스트 인자만). 동시 True는 코드상 `return 1` STOP이므로 어차피 차단.
- dry-run 산출물(로그·결과)은 `memory/reports/`에 "DRY_RUN" 라벨로 저장 → activation 증거와 혼동 방지.
- dry-run 전후 **운영 상태명 불변**: `..._READY_FOR_LIMITED_PILOT_DECISION_ACTIVE_FALSE` 유지.
- real fire 0 · cron 0 · systemd inactive·disabled 재확인으로 마감.

## 8. dry-run 실패 시 STOP 상태명
- kill인데 `NOOP_KILL_SWITCH` 아님 / kill 경로에서 flag write 발생 / real fire·spawn·cron 발생 / canonical
  마커 변경 / governor·launcher 호출:
  → **`LIMITED_PILOT_KILLSWITCH_DRYRUN_FAILED_CHAIR_REQUIRED`**.
- 이 경우 limited pilot **착수 금지**(안전장치가 안 당겨지는데 운전하면 안 됨). 회장 보고 + 코드 재점검 안건 분리.

---

## 9. dry-run 실행 절차 요약 (회장 승인 시)
1. canonical 마커 스냅샷(§3) 기록.
2. 방식 A: `pytest tests/regression/test_limited_activation_bounds_2775.py -q` → kill·N·T·epoch fail-closed
   케이스 PASS 확인(특히 :166 kill).
3. canonical 마커 스냅샷 재기록 → **전후 동일** 확인(write 0).
4. ANU cron 0 · `p0b_processed_ledger` 신규행 0 · driver_enabled=disabled 불변 확인.
5. 결과를 `memory/reports/limited_pilot_killswitch_dryrun_<id>.md`에 DRY_RUN 라벨로 저장.
6. PASS → pilot 착수 가능(여전히 별도 승인). FAIL → §8 STOP.

> ★ dry-run 자체도 **pilot 실행이 아니다**. 격리 검증일 뿐, canonical activation·real fire 0 유지.
