# task-2729+12 — CANONICAL_EXECUTION_PATH_ALIGNMENT_B 구현/검증 보고서

> 팀: dev1-team(헤르메스) | 레벨: Lv.3 | 작성: 2026-06-07
> 판정: **CODE_DATA_PATH_ALIGNMENT_VERIFIED_ACTIVE_FALSE** + **MERGE_APPROVAL_CANDIDATE_CODE_DATA_ALIGNMENT_ACTIVE_FALSE**
> 종료 상태: **ESCALATED_OWNER_DECISION** (G4 fix_loop_cap=2, scope_violation=false) — 구현·검증 완료, merge/activation 은 task 명령상 회장 승인 전 금지 → 회장 결정 대기. `.done.escalated` 발행.

## SCQA 요약

**S**: P0-b pickup 의 systemd 실행경로는 `cd /home/jay/workspace → PYTHONPATH=/home/jay/workspace python3 -m dispatch.anu_pickup_driver` 이며, canonical working tree 는 task-2716(75fdf540) parked 상태다.

**C**: canonical 에는 `anu_result_pickup_runner.py`·`anu_pickup_entrypoint.sh` 가 ABSENT(+driver 등 4개 DIFFER)여서 지금 enable 하면 driver→runner ModuleNotFoundError 로 크래시하며 #186/#187 코드를 미참조한다.

**Q**: task-2716/live artifacts 무손상으로 CODE 경로만 #186/#187 포함 코드로 정렬할 수 있는가?

**A**: B안(CODE=clean main worktree / DATA=canonical) 채택. `CANONICAL_ROOT` 절대 하드코딩이 DATA=canonical 을 보장하므로 entrypoint 의 cd/PYTHONPATH(+systemd 3줄)만 CODE_ROOT 로 분리하면 된다. clean worktree `${HOME}/p0b-pickup-main`(origin/main 70f36d82) 생성 + entrypoint/service 수정 + 회귀 9건 + isolated 시뮬레이션(128 NOOP_LEGACY_SKIP, 이동 0)으로 검증 완료. driver/runner 무변경, ACTIVE=false 유지, systemd enable 0, real spawn 0.

## 생성/수정 파일 (EXPECTED FILES 정확히 5)
1. `scripts/anu_pickup_entrypoint.sh` — CODE_ROOT 분리(cd/PYTHONPATH), DATA(FLAG_FILE/LOCK_DIR) canonical 유지, CODE_ROOT fail-closed (불칸)
2. `deploy/systemd/anu-pickup.service` — WorkingDirectory/Environment/ExecStart → `%h/p0b-pickup-main` (불칸)
3. `tests/regression/test_canonical_execution_path_alignment_b_2729p12.py` — CODE/DATA 분리 6건 + legacy NOOP 3건 = 9 PASS (아르고스)
4. `memory/reports/task-2729+12.md` — 본 보고서
5. `memory/plans/p0b-pickup/execution_path_alignment_b_validation_260607.md` — isolated evidence/설계
- ★ driver/runner/path **무변경**.

### 파일별 검증 (PR worktree `/home/jay/workspace/.worktrees/task-2729+12-dev1`, origin/main base — canonical=task-2716 parked 무손상)
- scripts/anu_pickup_entrypoint.sh — `grep CODE_ROOT` 8건 (cd/PYTHONPATH 분리 + fail-closed), FLAG/LOCK 은 WORKSPACE 유지
- deploy/systemd/anu-pickup.service — `grep p0b-pickup-main` 3건 (WorkingDirectory/Environment/ExecStart)
- tests/regression/test_canonical_execution_path_alignment_b_2729p12.py — `grep NOOP_LEGACY_SKIP` 다건, pytest 9 passed
- memory/reports/task-2729+12.md, memory/plans/p0b-pickup/execution_path_alignment_b_validation_260607.md — 본 보고서/evidence
> ★ 산출물은 worktree PR 브랜치 커밋(canonical 미커밋·task-2716 무손상)이므로 canonical git diff 기준 file-touch-ratio 는 구조상 N/A. 실재·grep·pytest 검증은 worktree 기준 통과(상기), PR diff = 정확히 5파일(아래 PR 섹션).

테스트 결과: 9 passed (회귀, worktree PYTHONPATH 실행).

## 필수 검증 (회장 verbatim 14) — 전체 PASS
| # | 항목 | 결과 |
|---|---|---|
1. CODE worktree = origin/main 70f36d82 → **PASS** (HEAD==origin/main, detached)
2. #184 real wake / #186 guard·G2 / #187 dogfood 포함 → **PASS** (3 commit 확인)
3. CODE path `python3 -m dispatch.anu_pickup_driver` import (runner 포함) → **PASS** (driver OK + runner OK)
4. DATA root = canonical /home/jay/workspace → **PASS** (CANONICAL_ROOT:83 하드코딩, CODE_ROOT import 시에도 .env.keys=canonical 로드, FLAG/LOCK=WORKSPACE)
5. legacy 140 = 128 target(`task-*.result.json`) + 12 NOOP_NOT_TARGET → **PASS**
6. legacy_cutoff=True → pre-activation result 이동·삭제·quarantine 0 → **PASS** (isolated: 128 NOOP_LEGACY_SKIP, before==after, quarantine 미생성)
7. raw key(ANU c1190…) 출력 0 → **PASS** (`c11908` leak False)
8. ACTIVE=false 유지 → **PASS** (flag ABSENT=disabled)
9. systemd enable 0 → **PASS** (anu-pickup unit 미설치/미enable)
10. real spawn 0 → **PASS** (launcher_fn=None default, dry_run, subprocess sabotage 0)
11. path unit canonical events watch 유지(무변경) → **PASS** (`%h/workspace/memory/events/task-*.result.json` 그대로)
12. entrypoint/service CODE_ROOT/DATA_ROOT 분리 → **PASS**
13. canonical reset/clean/stash/checkout 0 → **PASS** (HEAD 75fdf540 불변, events 140 불변)
14. task-2716 수정 0 → **PASS** (task-2716 branch/tracked 파일 미변경)

(activation_epoch 생성 0 추가 확인: epoch 마커 ABSENT)

## L1 스모크테스트 결과 (필수)
- **서버 재시작**: 해당없음 (production systemd enable 금지 task — unit 기동 0)
- **API 응답 확인**: 해당없음 (HTTP 서비스 아님)
- **실동작 확인 (subprocess/스크립트)**:
  - `bash -n scripts/anu_pickup_entrypoint.sh` → 문법 OK (exit 0)
  - CODE path import: `PYTHONPATH=${HOME}/p0b-pickup-main python3 -c "import dispatch.anu_pickup_driver; import dispatch.anu_result_pickup_runner"` → `driver import OK / runner import OK`
  - isolated scan_once 실동작: CODE=clean worktree + temp DATA(128 복제) → `NOOP_LEGACY_SKIP: 128`, MOVE/DELETE 0, quarantine 미생성, canonical 140→140 무손상 (실제 driver 코드 실행으로 확인 — pytest PASS 와 별개 실동작)
  - 회귀 pytest 9/9 PASS
- **스크린샷**: 해당없음 (백엔드/CLI 작업)

## CODE_ROOT 운영안 (생성/동기)
- **생성**: `git worktree add --detach ${HOME}/p0b-pickup-main origin/main` (영속 sibling, /tmp·휘발성 금지).
- **동기**: PR merge 후 `git -C ${HOME}/p0b-pickup-main fetch origin && git -C ${HOME}/p0b-pickup-main checkout --detach origin/main`. (정기 동기를 cron/타이머로 두는 것은 activation 단계에서 별도 결정.)
- **fail-closed**: CODE_ROOT 부재/비-git 시 entrypoint 가 no-op(exit 0)+stderr 1줄 → 안전 차단.
- **override**: `PICKUP_CODE_ROOT` 환경변수로 경로 재지정 가능.

## 발견 이슈 및 해결
### 자체 해결 (1건)
1. **회귀 테스트 미사용 import 경고** — `pytest`, `VERDICT_NOOP_LEGACY_SKIP` 미사용 import 제거 (pyright lint 정리, 9 PASS 유지).

### 범위 외 미해결 (0건)
- pyright `Import "dispatch.anu_pickup_driver" could not be resolved` 는 pyright 의 PYTHONPATH 미설정 한정(런타임/pytest 정상). 소스 무변경 원칙상 테스트 코드만으로 회피 불가 — 실행 정상이므로 범위 외.

## Gemini PR 리뷰 대응 (PR #188)
Gemini 리뷰 HIGH 2 + MEDIUM 1:
- **[수용] HIGH — entrypoint:55 git dubious ownership**: `git -C ... rev-parse` 의존이 타 사용자/권한 실행 시 정상 CODE_ROOT 에서도 no-op 오작동 위험. → git 의존 제거, driver 파일(`${CODE_ROOT}/dispatch/anu_pickup_driver.py`) 존재 체크로 교체 (불칸, 638d0a68). 회귀에 `git -C` 부재 단언 추가 (아르고스, 10587a4e).
- **[기각] HIGH — service:8 CODE_ROOT 부재 닭-달걀**: 회장 verbatim 스펙이 ExecStart→CODE_ROOT 를 "entrypoint canonical 부재 → CODE_ROOT 참조 필수" 로 명시 지시. %h/workspace 복귀는 task-2716 트리 동기화(금지영역) 필요. CODE_ROOT 부재 시 systemd CHDIR/EXEC 실패는 fail-SAFE(서비스 미기동→pickup 0→DATA 무손상). CODE_ROOT 생성은 activation precondition. 스크립트 fail-closed 는 부분 동기 상태 2차 방어선으로 유효. → PR 코멘트에 기각 사유 게시.
- **[참고] MEDIUM — 문자열 매칭**: 정적 config 분리 검증은 task 작업방식 의도. subprocess 통합 테스트는 향후 개선 후보. PASS 무영향.

미수정 HIGH 0건(수용 1 + 사유부 기각 1).

## 모델 사용 기록
- 불칸(백엔드, entrypoint/service): **sonnet** — 정밀 코드 수정.
- 아르고스(테스터, 회귀): **sonnet** — 테스트 설계/구현.
- 팀장(헤르메스, Opus): worktree 생성·검증·isolated 시뮬레이션·보고서. haiku 미사용.

## 머지 판단
- **머지 필요**: Yes (단, **회장 승인 게이트** — 본 PASS 후에도 merge·activation 은 별도 승인 전까지 금지)
- **브랜치**: `task/task-2729+12-dev1`
- **워크트리 경로**: `/home/jay/workspace/.worktrees/task-2729+12-dev1` (origin/main 70f36d82 base)
- **머지 의견**: 회귀 9/9 PASS, isolated NOOP 이동 0, canonical/task-2716 무손상, ACTIVE=false·systemd enable 0·real spawn 0. CODE/DATA 분리 최소 변경(2 code files + 3 systemd line). Gemini fresh HIGH/CRITICAL 0 + CI GREEN 확인 시 `MERGE_APPROVAL_CANDIDATE`. merge 자동 실행 0.

## 완료 마무리 / 종료 상태
finish-task.sh 진행: QC PASS(Gate WARN, file_touch_ratio SKIP=worktree topology) → SCOPE-GUARD PASS(4 files, worktree main..HEAD) → GIT-GATE/MERGE-BASE/CI-PREFLIGHT PASS → GOAL-GATE PASS(CODE_ROOT cwd 에서 `python3 -m dispatch.anu_pickup_driver` exit 0, NOOP_DISABLED, canonical result.json 140 무손상) → **G4-GATE ESCALATED_OWNER_DECISION**.
- G4: `gate_trigger=fix_loop_cap`, `fix_loop_count=2>=max=2`, **scope_violation=false** → OWNER_DECISION_REQUIRED. 품질 결함 아님(Gemini 초기리뷰+HIGH수정 1회 = fix-loop 2). 카운터 reset 금지(#9) 준수 → reset 0.
- `.done.escalated` 마커 발행(escalation_marker.py, source=finish-task.sh) → 회장/아누 라우팅. 수동 `.done` 생성 0.
- 이 종료 상태는 task 의 "merge·activation 별도 회장 승인" 요구와 일치. **회장 merge 승인 시** worktree PR #188 머지 → CODE_ROOT 동기 → (별도) activation 게이트.

### G3 독립검증: PASS (file_existence 5, grep 5, SCQA PASS).
### 회장 결정 요청 사항
1. PR #188 merge 승인 여부 (fresh HIGH 0: 1수용+1사유부기각, scope_violation false).
2. (merge 후 별도) systemctl enable / ACTIVE=true / activation_epoch / real wake pilot 승인 — 본 task 범위 외.

## 비고
- 본 작업은 execution path 정렬 **구현·검증까지**. systemctl enable / ACTIVE=true / activation_epoch / dry_run=False real wake pilot 은 별도 회장 승인 전까지 금지.
- CI gate 잡(gemini-review-gate/phase3-merge-gate 등) pending 다수는 runner 큐/머지시점 트리거 특성(FAIL 0건). 최종 CI GREEN 확인은 merge 단계에서 수행 권장.
