---
task_id: task-2517
type: context
scope: task
created: 2026-05-09
updated: 2026-05-09
status: completed
---

# 맥락노트: task-2517 — canonical_workspace_resolver

**task**: task-2517

---

## 결정 근거

### 회장 결정 (2026-05-09)

> "5 모듈 구현 자체는 완료되었다. 이제 병목은 기능 부족이 아니라 runtime determinism / repository governance / lifecycle consistency다. 본 task는 P0 최우선 serial. 현재 전체 시스템의 highest-priority runtime hardening task."
>
> "앞으로는 '문서 보강'보다 'runtime determinism 확보 코드' 우선순위를 높인다."

### 본 task가 구조적으로 제거해야 할 4 ambiguity (task-2516+1에서 노출)

1. wrong cwd — 어느 worktree/main에서 명령 실행 중인지 불명확
2. stale main — origin/main 최신 HEAD vs 로컬 main 불일치, fetch 누락
3. dirty workspace false detection — 다른 task의 unstaged 파일이 본 task scope 검증에 영향
4. finish-task context mismatch — finish-task 호출 시점의 worktree와 검증 시점 불일치

## 3 Step Why 자문

**1st Why: 왜 이 설계(CanonicalWorkspace dataclass + resolve entrypoint + 5 assert/evaluate 함수)가 필요한가?**
→ A: 6 hook(scope-guard / finish-task / guard / smoke / qc / merge_execution)이 각자 독립적으로 cwd/worktree/main_head를 평가하면 task-2516+1에서 노출된 4 ambiguity가 매번 재발생한다. 단일 deterministic 인스턴스를 한 번 resolve하고 6 hook이 공유해야 일관성이 보장된다.

**2nd Why: 왜 A(단일 dataclass + resolve entrypoint 공유)가 최선의 접근인가?**
→ B: (1) 회장 명시 "새 abstraction 과다 생성 금지" — dataclass 1개 + resolver 함수만 허용. (2) frozen=True dataclass는 race condition 방지(immutable snapshot). (3) 6 hook 통합 인터페이스 = caller가 한 번만 resolve, 인스턴스를 hook에 전달 → run-to-run 결정성 확보. (4) 5 모듈 본체 미변경 제약 하에서 6 hook 통합을 위한 인터페이스만 제공하는 게 정확히 본 task의 책임이다. wiring은 task-2518/2519의 책임.

**3rd Why: 왜 B(frozen dataclass + resolve entrypoint)가 다른 대안보다 나은가?**
→ C: 대안들과 비교:
- **(대안1) Context Manager 패턴**: setup/teardown 라이프사이클을 강제하는데, 6 hook이 동시 진입/이탈하지 않고 caller가 인스턴스를 생성·전달하는 구조이므로 부적합.
- **(대안2) Singleton/global state**: 테스트 격리 어려움. 회귀 14건 중 fixture-based 테스트가 다수라 immutable snapshot이 필수.
- **(대안3) 6 helper module**: 회장 명시 "새 abstraction 과다 생성 금지" 위반. expected_files 2건 제약 위반.
- **선택안 (frozen dataclass + resolve)**: (a) immutable → race-free, (b) JSON serialization → CLI 출력 + hook 간 전달 표준화, (c) 단일 entry → 4 ambiguity 단일 지점 차단, (d) testable → 14 fixture로 회귀 검증 가능.

**A-B-C 일관성 검증**: A(공유 인스턴스 필요) → B(frozen dataclass + resolve로 충족, 회장 제약 준수) → C(대안 모두 회장 제약 또는 테스트 가능성 위반) — 일관 PASS.

## 참조 자료

- task spec: `memory/tasks/task-2517.md`
- 정책 본체: `memory/feedback/feedback_critical_escalation_only_260508.md`
- 5 모듈 worktree/cwd 패턴 참조 (READ ONLY):
  - `utils/replacement_pr_runner.py:135` (`git fetch origin main --quiet`)
  - `utils/replacement_pr_runner.py:144` (`git checkout -b branch origin/main`)
  - `utils/replacement_pr_runner.py:255` (`git diff --name-only origin/main...HEAD`)
- guard hook 패턴: `scripts/start_task_guard.py:127-216` (cwd / worktree / branch 검증 5축)
- finish-task 패턴: `scripts/finish-task.sh:65-108` (PROJECT_PATH 자동 인식 / worktree_path 우선)

## 주의사항

- **expected_files 정확 매칭**: `utils/canonical_workspace_resolver.py` + `tests/regression/test_canonical_workspace_resolver_2517.py` 외 어떤 파일도 수정/생성 금지
- **forbidden actions** (task spec §금지 19종): 새 abstraction 과다 생성 / enum redesign / contract schema 변경 / policy md 보강 / dispatch.py 수정 / 5 모듈 본체 수정 / task-2516+1 영역 침범 / task-2518/2519 wiring 직접 시도 / force push / rebase / admin override / manual .done / required CI bypass / PR #52/#49/#50/#51 수정 / 자동 cherry-pick 구현 / live pilot 직접 시도 / Critical 7종 외 회장 보고 / amendment 무시
- **fetch 동작**: `--no-fetch` CLI 옵션은 테스트용. 프로덕션 호출 시 fetch 필수 (stale main 차단)
- **WORKSPACE_ROOT vs git rev-parse 충돌**: git rev-parse 우선 (task spec §2 명시)
- **테스트 격리**: 14 회귀 테스트는 tmp_path / monkeypatch 활용. 실제 origin/main fetch 의존 금지 (no-fetch + fixture로 stub)
