# task-2628+1 보고서 — TEST_HARNESS_PORTABILITY_GAP_REMEDIATION

- **task_id**: task-2628+1
- **work_level**: Lv.2 (단일 test 파일 micro-remediation + clean isolated worktree 검증)
- **team**: dev6-team (페룬 팀장 / 벨레스 테스터)
- **base_commit**: d8ea371f (task-2628 산출물 · anu_v3 12 dependency + test 포함)
- **fix_commit**: 89f1eda4 (worktree branch `task/task-2628+1-dev6`, push/PR/merge 0)
- **작성일**: 2026-05-22 (KST)
- **dispatched_by**: ANU (회장 판정 2026-05-21 — task-2628 closeout NOT READY → micro-remediation)

---

## S (Situation) — 상황

task-2628 의 anu_v3 dependency closure 산출물(d8ea371f, 13 files)은 메인 workspace·/tmp 중립에서 회귀 8/8 PASS 였으나, **clean isolated worktree** 에서 실행 시 `test_02_import_without_conftest_syspath_injection` 1건이 실패(7/8)했다. 회장은 "동일 검증=8/8" 엄격 해석으로 d8ea371f 를 `CLOSEOUT_READY` 로 인정하지 않고 상태를 `ANU_V3_DEPENDENCY_READY_PARTIAL / TEST_HARNESS_PORTABILITY_GAP` 로 두고, **test_02a import isolation regression 을 수정하는 micro-remediation** 을 별도 지시했다.

## C (Complication) — 문제

`tests/regression/test_anu_v3_dependency_isolation_2628.py` 의 `_isolated_import` (구 L119-149) 의 sys.path 필터가 결함:

```python
kept = [p for p in saved_path if os.path.realpath(p or ".") != os.path.realpath(SRC)]
sys.path[:] = [tmp] + kept
```

하드코딩 `SRC=/home/jay/workspace` 와 일치하는 경로만 제거한다. 그런데 `cd <worktree> && python -m pytest` 로 실행하면 `python -m` 이 **cwd(=worktree root, anu_v3 포함)** 를 `sys.path[0]` 에 prepend 하고, 이 경로는 `SRC` 와 다르므로 `kept` 에 잔존한다. 결과적으로 **빈 closure tmp 에서도 `import anu_v3.runtime_reconcile_checkpoint` 가 worktree 경로로 해소**되어 `_isolated_import` 가 `None`(성공) 을 반환 → test_02a 의 `assert err is not None` 가 실패한다. 즉 테스트가 anu_v3 와 같은 트리에 위치+그 트리에서 실행될 때만 발생하는 **환경 의존(non-portable)** 결함이며, production anu_v3 12 모듈 동작 결함이 아니다.

**재현 확인 (수정 전, fresh worktree d8ea371f):**
```
cd /home/jay/.cokacdir/workspace/iso-2628p1-dev6 && python3 -m pytest <test> 
→ 1 failed, 7 passed
→ FAILED test_02 :: AssertionError: 빈 closure tmp 에서 ModuleNotFoundError 가 발생하지 않음
   assert None is not None    (← 빈 closure import 가 worktree 경로로 false-pass)
```

## Q (Question) — 핵심 질문

하드코딩 SRC 제거에만 의존하지 않고, **pytest rootdir/worktree root/cwd/conftest 어느 경로가 sys.path 에 들어와도 false-pass 가 발생하지 않도록** 테스트를 어떻게 이식성 있게 고칠 것인가? (empty closure → 반드시 ModuleNotFoundError, full closure(12) → import 통과)

## A (Answer) — 해결

회장 필수 구현 방향 6항목 중 **#2 (subprocess + 명시적 PYTHONPATH)** 채택 — 가장 hermetic 한 경로. `_isolated_import` 를 별도 파이썬 자식 프로세스로 격리 실행하도록 전면 교체:

```python
neutral_cwd = tempfile.mkdtemp(prefix="iso_cwd_")   # 빈 중립 cwd
env = dict(os.environ); env["PYTHONPATH"] = tmp       # 부모 PYTHONPATH override → tmp 만 허용
code = "import importlib, sys\ntry:\n    importlib.import_module(<modname>)\n" \
       "except Exception as e:\n    sys.stdout.write(type(e).__name__+': '+str(e)[:120])\n" \
       "    raise SystemExit(3)\n"
proc = subprocess.run([sys.executable, "-c", code], cwd=neutral_cwd, env=env,
                      capture_output=True, text=True, timeout=60)
return None if proc.returncode == 0 else (proc.stdout.strip() or <stderr 마지막 줄>)[:120]
```

**왜 이식성이 보장되는가:**
- `python -c` 의 `sys.path[0]("")` = cwd = **빈 중립 디렉토리** → cwd/worktree-root 경로로 anu_v3 해소 불가.
- 자식의 `PYTHONPATH` 를 **closure tmp 로만** 명시 설정(부모 PYTHONPATH override) → anu_v3/dispatch 는 오직 closure tmp 로만 해소.
- 부모(pytest) in-process sys.path·conftest sys.path 주입·pytest rootdir 는 **자식 프로세스에 전파되지 않음** → false-pass 원천 차단.
- 따라서 import 성공 여부는 "closure tmp 안에 모듈이 있는가" 에만 의존(워크트리/실행 위치 무관).

**수정 범위 최소화:** `_isolated_import` 및 import 블록(`importlib`→`subprocess`)만 변경. `_isolated_import` 를 사용하는 test_01/02a/04 만 영향, test_03/05/06/07/08 의 검증 의미·강도 불변.

---

## 회장 완료 보고 7항목 (verbatim 대응)

1. **test_02a 실패 원인**: 하드코딩 `SRC` 만 sys.path 에서 제거하고, `python -m pytest` 가 prepend 한 cwd(worktree root·anu_v3 포함) 는 `kept` 에 잔존 → 빈 closure 에서도 anu_v3 가 worktree 경로로 해소되어 `err=None` → `assert err is not None` 실패 (환경 의존 non-portable).
2. **수정한 import isolation 방식**: 회장 #2 (subprocess + 명시 PYTHONPATH). `_isolated_import` 를 빈 중립 cwd + `PYTHONPATH=closure tmp` 자식 프로세스(`python -c`)로 실행. in-process sys.path/conftest/worktree root/rootdir 누수가 자식에 전파 불가.
3. **clean isolated worktree regression (§3-(1) 합격선)**: **8/8 PASS** (수정 전 7/8 → 수정 후 8/8). rootdir=`/home/jay/.cokacdir/workspace/iso-2628p1-dev6`.
4. **/tmp neutral regression**: **8/8 PASS** (rootdir=`/tmp/iso_neutral_2628p1`, workspace conftest 미적용).
5. **conftest false-pass 차단 증거**: (a) /tmp 중립(workspace conftest 미적용) 8/8 → conftest sys.path 주입 의존 0. (b) 직접 증명: 부모 sys.path 에 `/home/jay/workspace`(anu_v3 존재)가 있는 상태에서도 `_isolated_import(empty_closure)` = `"ModuleNotFoundError: No module named 'anu_v3'"`, `_isolated_import(full_closure_12)` = `None`. 자식 프로세스는 부모 conftest/sys.path 를 전파받지 않으므로 false-pass 불가.
6. **후속 micro commit diff**: `89f1eda4` (base `d8ea371f`), `tests/regression/test_anu_v3_dependency_isolation_2628.py` 1 file changed, **+41 / -28**.
7. **ANU_V3_DEPENDENCY_READY_ACCEPTED 가능 여부**: **가능 (test fix verified — §9 판정 기준 3-context 8/8 + empty→MNFE + full→pass + conftest 비의존 전부 충족)**. 단 self-key(executor 1e41a2324a3ccdd0) 환경이므로 본 collector 결과는 NON_AUTHORITATIVE → ANU 독립 재검증 + 회장 최종 ACCEPT 필요.

---

## ★ HARD GATE — 3-context regression (§3)

| 컨텍스트 | 실행 조건 | 결과 |
|---|---|---|
| (1) clean isolated worktree | `cd <worktree> && python -m pytest` (cwd=worktree root·anu_v3 포함 — 이전 실패 환경) | **8 passed** (수정 전 7/8 → 수정 후 8/8) |
| (2) /tmp 중립 | `cd /tmp/iso_neutral_2628p1 && python -m pytest` (workspace conftest 미적용, rootdir=/tmp) | **8 passed** |
| (3) 메인 workspace | `cd /home/jay/workspace && python -m pytest` (cwd=SRC, conftest 활성) | **8 passed** (임시복사-복원, 메인 영구 변경 0·sha256 동일 복원) |

→ §3-(1) 핵심 합격선 포함 3개 컨텍스트 전부 8/8. **test fix verified.**

---

## ★ L1 스모크테스트 결과 (필수 기록)

본 task 는 test 하니스(subprocess 격리) 수정으로, L1 = **실제 subprocess 프로세스 실행 + 결과 확인** (워크플로우 4.8 "subprocess/정제 작업" 경로).

- **서버 재시작**: 해당없음 (서버/API/프론트 미관여 — test 하니스 한 파일 수정)
- **API 응답 확인**: 해당없음
- **스크린샷**: 해당없음
- **실동작 확인 (L1 통과)**:
  - 3개 컨텍스트 `python -m pytest` 실제 실행 — 각 8/8 (각 테스트가 `subprocess.run([python, -c, ...])` 실 자식 프로세스 스폰).
  - 직접 `_isolated_import` 호출 증명: empty closure → `ModuleNotFoundError: No module named 'anu_v3'`, full closure(12) → `None`(성공).
  - py_compile 통과, pytest 9.0.2 / Python 3.12.3.

→ **L1 통과** (pytest PASS 가 아니라 실 subprocess 스폰 + import 해소 결과를 직접 관측).

---

## 발견 이슈 및 해결

- **이슈 1 (해결)**: 구 `_isolated_import` 의 `importlib` 가 본 변경으로 미사용 → ruff F401 위험. → import 블록에서 `import importlib` 제거하고 `import subprocess` 추가(자식 코드 문자열 내부에서만 importlib 사용). py_compile 통과.
- **이슈 2 (환경 한계, 비차단)**: ruff 미설치 → `ruff check` 미수행. py_compile + pytest 8/8 로 대체 검증.
- **이슈 3 (정적분석 노이즈, 비차단)**: Pyright `reportMissingImports` (anu_v3.*/dispatch.* on test_05-08) — worktree 경로가 Pyright 분석 경로에 없어 발생하는 **기존(pre-existing) 노이즈**이며, 런타임 import(`_ensure_src_dispatch` 경유)는 정상. 본 수정과 무관(test_05-08 미변경).

---

## FOREIGN_DIRTY_BLOCKER 분류 (finish 경로)

메인 workspace 는 본 task 와 무관한 foreign dirty 5건(memory/specs ×3 + utils/replacement_pr_runner.py + tests/regression/test_replacement_pr_runner_2510.py) + 다수 시스템 자동 파일이 uncommitted 상태다. `finish-task.sh` GIT-GATE(`PROJ_DIR=$WORKSPACE` 의 uncommitted 검사)는 이들(특히 memory/specs·replacement_pr_runner 는 제외 목록 비포함)로 인해 BLOCKED 된다.

- 이는 task md §4 가 예견한 **FOREIGN_DIRTY_BLOCKER (공유 workspace GIT-GATE 오발화)** — task-2628+1 산출물 결함 아님.
- doctrine(`project_no_bot_app_token_local_only_completion_260521` · `feedback_finish_task_shared_branch_gate_misfire_260521`)에 따라 **로컬 micro-commit + reflection-ready 보고로 종료** (반복 루프 금지, foreign dirty 정리 금지, 수동 .done 생성 금지).
- 산출물: worktree micro-commit `89f1eda4` + `memory/events/task-2628+1.result.json` + 본 보고서. push/PR/merge 0.

---

## 머지 판단

- **머지 필요**: No (회장 push/PR/merge 승인 대기 · §6 push/PR/merge 금지)
- **브랜치**: `task/task-2628+1-dev6`
- **워크트리 경로**: `/home/jay/.cokacdir/workspace/iso-2628p1-dev6`
- **머지 의견**: 3-context 8/8 검증 완료 + test_01~08 검증 의미 보존 + blob 동결(anu_v3/dispatch 미수정) 준수 + foreign dirty 미접촉. 코드 품질·충돌 위험 낮음(단일 test 파일). 단 self-key 환경 → collector 결과 NON_AUTHORITATIVE → ANU 독립 재검증 후 회장 최종 ACCEPT/머지.

---

## 모델 사용 기록

- **벨레스 (테스터)** — `sonnet`: 지정된 2개 Edit(import 블록 + `_isolated_import` 전면 교체) 정밀 적용 + grep/py_compile/worktree pytest 자체검증. (test 파일 정밀 수정은 정확성 요구 → haiku 미사용.)
- **페룬 (팀장, Opus)** — 결함 진단·subprocess 설계·worktree 생성·3-context HARD GATE 검증·git micro-commit·result.json/보고서 작성. (직접 코딩 아닌 설계/검증/통합/판단.)
- **haiku 미사용** (정밀 test 수정 + 검증 작업 성격).

---

## 산출물

- `tests/regression/test_anu_v3_dependency_isolation_2628.py` — 이식성 수정 (worktree 커밋 `89f1eda4`)
- `memory/events/task-2628+1.result.json` — callback contract 9 fields + 7항목 + 3-context regression
- `memory/reports/task-2628+1.md` — 본 보고서
- 로컬 micro-commit (push/PR/merge 0 · 회장 승인 대기)

## 준수 invariants

소스(anu_v3/dispatch) 수정 0 · push/PR/merge 0 · hook 미우회 · foreign dirty 5건 미접촉 · memory/specs 미정리 · replacement_pr_runner 미수정 · d8ea371f closeout 승격 안 함 · production enforcement 완료 판정 안 함 · callback reflection 미진행(envelope-only prepared, NOT fired · self-key fail-closed).
