# CANONICAL_EXECUTION_PATH_ALIGNMENT — 설계안 (audit-first, 실행 0)

> 상태: **CANONICAL_EXECUTION_PATH_ALIGNMENT_READY** (정렬안 설계만 / 구현·activation 별도 회장 승인 전까지 금지)
> 작성: ANU 2026-06-07 / 코드 기준: origin/main `70f36d82` (#186/#187 포함)
> 목적: production activation 전, **canonical execution path 가 #186/#187 포함 코드를 실제 참조**하도록 안전 정렬. canonical task-2716 dirty/live artifacts 무손상.
> ★ systemctl enable / ACTIVE=true / activation_epoch 생성 / real spawn / canonical reset·clean·stash -u·checkout -f / task-2716 수정 **미실행**.

## 1. 실행 경로 실측 (blocker 근거)
- systemd: `WorkingDirectory=%h/workspace`, `ExecStart=/bin/bash %h/workspace/scripts/anu_pickup_entrypoint.sh`.
- entrypoint: `cd ${HOME}/workspace` → `PYTHONPATH="${WORKSPACE}" python3 -m dispatch.anu_pickup_driver` → `main()` → `scan_once(CANONICAL_ROOT, legacy_cutoff=True)`.
- **canonical working tree(/home/jay/workspace) = task-2716(75fdf540) parked**. 실행 핵심 파일 blob 대조:
  - DIFFER: `dispatch/anu_pickup_driver.py`, `dispatch/anu_pickup_wake_launcher.py`, `scripts/start_task_guard.py`, `scripts/finish-task.sh`
  - **ABSENT**: `dispatch/anu_result_pickup_runner.py`, `scripts/anu_pickup_entrypoint.sh` (canonical 에 파일 자체 없음)
- ⇒ 지금 enable 시 `cd /home/jay/workspace; python3 -m dispatch.anu_pickup_driver` 는 **task-2716 버전 driver 를 import → `from dispatch.anu_result_pickup_runner import pickup_once` ModuleNotFoundError 크래시**(실증). 즉 canonical 실행경로는 #186/#187 미참조 + 기동 불능.

## 2. ★ 핵심 발견 — CODE/DATA 분리 가능 (정렬 안전성의 근거)
- `CANONICAL_ROOT = "/home/jay/workspace"` (절대경로 하드코딩, `dispatch/anu_owned_callback_enforcement.py:83`).
- `main()` → `scan_once(CANONICAL_ROOT, legacy_cutoff=True)`: **DATA root(events/flag/epoch/ledger/quarantine)는 코드 import 위치와 무관하게 항상 /home/jay/workspace(canonical)**.
- `scan_once(root=...)` 의 root 는 DATA, **CODE 는 PYTHONPATH/모듈 해석 경로**로 별개.
- ⇒ **PYTHONPATH(코드)만 origin/main 클린 worktree 로 바꾸면 DATA 는 자동으로 canonical 유지.** canonical working tree(task-2716) 무손상 정렬 가능.

## 3. 선택지 비교 (A / B / C)

### A. canonical checkout 을 main 으로 복귀
- 메커니즘: /home/jay/workspace working tree 를 task-2716 → origin/main(70f36d82) 로 전환. code=data=canonical 단일 경로.
- 필요한 write: `git checkout/switch main` (working tree clean 전제).
- **위험: HIGH.** task-2716 는 dirty + parked WIP. clean 전환하려면 task-2716 변경 commit/stash 필요 → standing 금지 #5(stash -u/checkout -f)·#6(task-2716 수정) 충돌. live work 유실/오염 위험. dirty 상태로 switch 시 충돌.
- rollback: `git switch task/task-2716...` + stash 복원. 단 중간 오염 시 비가역 위험.
- 판정: **권장 안 함** — task-2716 disposition 별도 회장 결정 없이는 금지영역.

### B. ★ production pickup/systemd 가 별도 clean main worktree 참조 (권장)
- 메커니즘: 클린 worktree(origin/main) 1개 생성 = CODE. entrypoint/systemd 의 PYTHONPATH·cwd 를 그 worktree 로 변경. DATA 는 `CANONICAL_ROOT` 하드코딩으로 자동 /home/jay/workspace 유지.
  - 예: worktree `/home/jay/p0b-pickup-main`(또는 `.worktrees/pickup-main`) ← `git worktree add <path> origin/main`.
  - entrypoint: `cd $CLEAN_MAIN` → `PYTHONPATH=$CLEAN_MAIN python3 -m dispatch.anu_pickup_driver`. systemd `WorkingDirectory=$CLEAN_MAIN`.
  - DATA(events/flag/epoch/ledger/quarantine/.done) = /home/jay/workspace (canonical, 하드코딩).
- 필요한 write: ① clean worktree 생성(origin/main) ② `scripts/anu_pickup_entrypoint.sh` PYTHONPATH/cwd 수정 ③ `deploy/systemd/anu-pickup.service` WorkingDirectory 수정. **canonical working tree 코드 0 수정, task-2716 0 수정, live artifacts 0 이동.**
- **위험: MEDIUM-LOW.** 검증 필요: worktree origin/main 동기 유지(fetch+checkout), entrypoint cwd 가 canonical dispatch 를 shadow 안 하도록(cwd=clean_main 필수), key 런타임 로드(.env.keys)는 canonical 경로 그대로.
- rollback: worktree 제거(`git worktree remove`) + entrypoint/systemd revert. **canonical 전 과정 무손상**.
- 판정: **권장** — task-2716 parked + live artifacts 완전 보존, 가역적, CODE(origin/main)/DATA(canonical) 깨끗한 분리. #2 발견으로 실현성 확정.

### C. canonical parked 유지 + 실행경로만 #186/#187 path 로 고정(frozen pin)
- 메커니즘: B 와 유사하되 클린 코드를 **70f36d82 고정 export/pin**(worktree 대신 `git archive`/detached pin)으로 immutability 확보. PYTHONPATH=pinned dir.
- 필요한 write: pinned code dir 생성(70f36d82) + entrypoint/systemd PYTHONPATH 수정. canonical 무손상.
- **위험: MEDIUM.** B 와 동일 위험 + drift(후속 origin/main fix 자동 미반영 → 수동 재pin 필요). immutability 이점.
- rollback: pin dir 제거 + entrypoint/systemd revert.
- 판정: 가역적·안전하나 유지보수성 B 우위. **immutability 강제 필요 시에만 C.**

**ANU 권고: B** (클린 main worktree=CODE / canonical=DATA). 구현 = 별도 dispatch dev task(entrypoint+systemd 수정+worktree 생성), 회장 승인 게이트.

## 4. activation_epoch 생성 전 result.json 140 → pre-activation legacy 고정 조건
- lineage(현재 측정): events/*.result.json **140**. 이 중 driver scan 대상 `task-*.result.json` = **128**, 비-task(`task-` 미시작) **12** = driver 가 애초에 `NOOP_NOT_TARGET`(scan 제외).
- 고정 조건: activation 승인 후 enable **직전** `memory/state/p0b_activation_epoch = time.time()` 1회 생성·**불변**. 생성 시점 기준 **현재 존재하는 140(scan 대상 128) 전부 mtime < epoch → 영구 pre-activation legacy**.
- invariant: epoch 불변(후퇴 금지) + `legacy_cutoff=True` 상시. ⇒ 128 영구 `NOOP_LEGACY_SKIP`, 12 영구 `NOOP_NOT_TARGET`. **기존 126 기준이 아니라 현재 140 기준으로 전체 재고정**(회장 #5 지시 반영).

## 5. legacy 140 이동·삭제·quarantine 0 — isolated temp root 재확인 결과 (#7 완료)
- 방법: origin/main(#186/#187) 코드를 임시 worktree 로 격리 + canonical 128 `task-*.result.json` 의 basename·**원본 mtime 보존 복제**를 temp DATA root 에 구성(원본 canonical 0 손상) + `flag=enabled` + `epoch=now` + **`scan_once(root, legacy_cutoff=True)`**(production `main()` 동일).
- 결과: `NOOP_LEGACY_SKIP: 50`(reason `pre_activation_epoch`) + `NOOP_MAX_FILES_DEFER: 1`(나머지 78 다음 cycle). **temp events 128 before=after(이동·삭제 0), quarantine 이동 0, processed/wake 0.** ⇒ cycle 누적 시 128 전부 legacy skip, 0 move.
- ★ 주의(중요): `legacy_cutoff=True` 미전달 시(인자 누락) legacy 체크 우회 → QUARANTINE 발생(ANU 1차 하니스 오류로 실증). production `main()` 은 `legacy_cutoff=True` 고정이나, **entrypoint 가 main() 경로(legacy_cutoff=True)를 타는지**가 activation 필수 precondition. epoch 부재 시 `_legacy_cutoff_check` → `epoch_absent` 보수적 skip(fail-closed, move 0)도 확인.
- canonical 무손상 재확인: HEAD task-2716(75fdf540), events 140 유지, 격리 worktree 정리 완료.

## 6. real wake dry_run=False controlled pilot (#8 — 별도 단계 분리)
- 본 정렬안은 **execution path 정렬까지**. real auto-wake(launch_wake dry_run=False)는 **별도 단계**.
- 순서: (정렬 B 구현·검증) → (dry_run=False controlled pilot 1회: mock 아닌 실제 spawn 1건 격리 관측) → (full activation). pilot 은 회장 별도 승인.

## 7. 구현 task 예정 범위 (dispatch 후보, 승인 게이트)
- 회장이 A/B/C 중 택1 → 해당 옵션 구현 task(dev 위임): entrypoint+systemd 수정(B/C), worktree/pin 생성, preflight(canonical base #186/#187 참조 확인) + isolated 재검증 + 회귀. **canonical/task-2716/live artifacts 무손상, ACTIVE=false 유지.**
- 본 문서 단계: 설계·근거·#7 재확인만. 구현·enable·epoch·spawn 0.

## 판정
**CANONICAL_EXECUTION_PATH_ALIGNMENT_READY** — 정렬안 A/B/C 비교·위험/write/rollback·140 legacy 재고정 조건·#7 isolated NOOP 재확인(이동 0) 완료, ANU 권고 B. 단 **(1) A/B/C 택1 (2) 구현 dispatch 승인 (3) dry_run=False pilot (4) activation 자체 = 회장 결정 대기**. packet/설계만 준비, **canonical path 정렬 구현·activation 실행 0**.
