# [DRAFT — HOLD] task-2726 finish-task worktree/path isolation correction

> ★ 설계 초안. 코드 수정·dispatch 금지(회장 승인 전). `scripts/finish-task.sh` = 자동 dispatch 금지 영역. 단일소스 진단: `memory/events/diagnosis_finish_task_external_dirty_260603.json`.

## 목표 (회장 A-task-2726)
finish-task 의 scope/git-gate/dirty 판정이 **shared main 이 아니라 task worktree/project_path 기준**으로 동작하도록. shared main 의 1238 누적 dirty 가 모든 task 의 .done/callback 을 막는 구조 해소.

## 근본 원인 (ANU read-only 확정)
`scripts/finish-task.sh`:
- line 7 `PROJECT_PATH="${3:-""}"`, line 123-163 task-timers.json worktree_path 자동보정.
- ★ **line 447-448**: `SCOPE_PROJ_DIR="${PROJECT_PATH:-$WORKSPACE}"` — PROJECT_PATH 미해결 시 **$WORKSPACE(shared main)로 silent fallback**. → main 작업트리 `git status` 가 1238 누적 dirty 를 보고 → `dirty_registry.classify_blocker` 가 expected_files 밖 → EXTERNAL_DIRTY → exit 1 → .done 미생성.
- line 647 `PROJ_DIR="${PROJECT_PATH:-$WORKSPACE}"`, line 652 `WORK_DIR` 동일 fallback.
- line 457 scope-base `${MAIN_BRANCH}..HEAD`(로컬 main, backlog B).
- ★ scheduler worktree(`/home/jay/.cokacdir/workspace/<sid>/wt-*`) PROJECT_PATH 미인식 가능(backlog start_task_guard scheduler-worktree gap).

## 핵심 설계 (코드 0 — 초안만)
1. **$WORKSPACE silent fallback 제거** → PROJECT_PATH 미해결 시 **fail-closed**: `WORKTREE_UNRESOLVED` terminal state(terminal_state_callback enum 연계) 로 명확 차단. shared main 기준 dirty 판정 절대 금지.
2. **PROJECT_PATH 해석 확장**: task-timers.json worktree_path + **scheduler workspace worktree 경로**(`/home/jay/.cokacdir/workspace/<sid>/wt-<task>-<team>`) 인식. (start_task_guard scheduler-worktree gap 통합)
3. **dirty classify = 해당 worktree 자기 변경만**: `git status` cwd = 검증된 worktree. main 누적 dirty 무관.
4. **scope-base = `merge-base(origin/main, HEAD)` 또는 task lock_sha** (backlog B 통합 — 로컬 main `..HEAD` 폐기). HEAD~1 fallback 폐기.
5. recurrence doctrine #2(WORKSPACE_ROOT_HARDCODE): workspace/path passthrough, $WORKSPACE 하드코딩 fallback 금지.

## expected_files 후보
1. `scripts/finish-task.sh` ← PROJECT_PATH 해석 확장 + SCOPE_PROJ_DIR/PROJ_DIR/WORK_DIR $WORKSPACE fallback 제거(fail-closed) + scope-base merge-base. ★ 자동 dispatch 금지 — 회장 승인 필수.
2. (선택) `scripts/start_task_guard*.sh` 또는 worktree 인식 헬퍼 ← scheduler worktree 인식.
3. `tests/regression/test_finish_task_worktree_isolation_2726.py` (신규) ← 회귀.

## regression plan
- fixture A: shared main 에 무관 dirty N개 + task worktree 자기 변경 2파일 → scope/dirty = 2파일만, EXTERNAL_DIRTY 0 (main dirty 무관).
- fixture B: PROJECT_PATH 미해결 → $WORKSPACE fallback 0, WORKTREE_UNRESOLVED fail-closed.
- fixture C: scheduler worktree(/home/jay/.cokacdir/workspace/<sid>/wt-*) → PROJECT_PATH 정확 인식.
- fixture D: out-of-scope 파일(worktree 내 expected_files 밖) → 여전히 SCOPE 차단(탐지력 보존).
- fixture E: 로컬 main 이 origin/main 뒤처진 상태 → merge-base 기준 무관 커밋 0 (backlog B).
- 기존 정상 task finish flow 무손상.

## risk / rollback
- **위험 MEDIUM-HIGH**: finish-task = 모든 task 종료 공유 경로. fallback 제거가 시스템 task(PROJECT_PATH 의도적 미지정)에 영향 가능 → 시스템 task 분기 명확화 필수(line 447 Codex 지적 맥락 보존).
- **rollback**: PROJECT_PATH 해석/SCOPE_PROJ_DIR 변경은 함수/분기 단위 → revert 용이. feature flag(`FINISH_TASK_WORKTREE_STRICT` default-off → pilot 후 on) 권장.
- emitter/gate 변경은 정상 path(.done 생성) 무변경 회귀 필수.

## 위험도/권한/승인
- finish-task.sh 수정 = 자동 dispatch 금지 영역 → **회장 승인 필수**. 설계검토(Codex/Loki) 선행 권장.
- task-2724 terminal_state_callback 의 WORKTREE_UNRESOLVED/EXTERNAL_DIRTY enum 과 연계(통지 경로 이미 merged).

## ★★ 회장 진행 승인 (2026-06-03, 1순위 — 확정본)
dev team dispatch → PR → OWNER /gemini review → CI/Gemini watcher → MERGE_READY_CANDIDATE 까지 자율 수렴. **merge 회장 승인 전 금지.**

## expected_files (확정 — 회장 고정)
1. `scripts/finish-task.sh`
2. `tests/regression/test_finish_task_worktree_isolation_2726.py` (신규)
3. `memory/tasks/task-2726.md` (this)
4. `memory/reports/task-2726.md`

## 구현 가드 (회장 6)
1. feature flag/strict mode default-off 둘 수 있으면 둘 것(`FINISH_TASK_WORKTREE_STRICT` default-off 권장).
2. 기존 정상 finish flow 깨지 말 것.
3. shared main dirty 있어도 task worktree diff 가 clean/expected 면 scope/git gate 오판 0 — 테스트로 증명.
4. PROJECT_PATH/worktree 미해결 시 **shared main fallback 대신 명시적 HOLD/FAIL marker**(`WORKTREE_UNRESOLVED`/`PROJECT_PATH_REQUIRED`).
5. **`.done` 위조 금지.**
6. `TERMINAL_CALLBACK_ENABLED` activation 과 섞지 말 것(별개).

## 필수 regression (회장 6)
1. PROJECT_PATH 없음 + scheduler worktree 존재 → **worktree 기준 판정**.
2. PROJECT_PATH 없음 + worktree 미해결 → **shared main fallback 금지, WORKTREE_UNRESOLVED**.
3. shared main dirty 1000개 + task worktree diff expected_files 내부 → **EXTERNAL_DIRTY 오판 0**.
4. task worktree forbidden diff → **정상 차단**(탐지력 보존).
5. main branch 가 다른 dev branch 에 있어도 task worktree 판정 영향 0.
6. 기존 finish-task 정상 경로 회귀 PASS.

## loop 기준 (회장)
- LOW/MEDIUM = expected_files 내부 최대 2회 bounded fix.
- HIGH/CRITICAL = 자동 fix 금지 → CHAIR_REQUIRED.
- expected_files 밖 수정 필요 → CHAIR_REQUIRED.
- finish-task 정상 flow 깨는 finding → CHAIR_REQUIRED.

## 금지 (회장 verbatim)
- shared main stash/reset/clean/delete 금지 · dev4 branch 개입 금지 · task-2727 artifact cleanup 실행 금지 · task-2725 구현 혼입 금지 · task-2724 activation/flag on/pilot 금지 · systemctl/actual wake/callback operation 금지 · merge 금지 · Work 착수 금지.

## doctrine
- same-PR post-Gemini push 금지(bounded fix = 새 commit→new head→non-force push). bot `/gemini review` 무효(인간 OWNER 1회). long polling 금지(watcher 위임).

## finalize (PR 생성 → MERGE_READY_CANDIDATE — merge 금지)
1. fix → 6 regression PASS → `git add` → commit → `worktree finish --action pr` 로 PR 생성(fresh origin/main base).
2. `memory/reports/task-2726.md` 보고서(L1 + 정상 flow 무손상 확인).
3. `memory/events/task-2726.done` 생성.
4. ANU normal callback cron 강제 등록 — collector_role=ANU, ANU_KEY=c119085addb0f8b7(sealed, literal 노출 금지). self-key 금지. cron 0+sendfile only=NOT_REGISTERED fail-closed.
5. ★ merge 금지 — ANU/watcher → 새 head OWNER /gemini review → CI/Gemini watcher → CI GREEN + fresh unresolved 0 + diff expected_files + forbidden 0 + flag default-off 시 MERGE_READY_CANDIDATE 보고.

## allowed_resources
```yaml
allowed_resources:
  paths:
    - "scripts/finish-task.sh"
    - "tests/regression/test_finish_task_worktree_isolation_2726.py"
    - "memory/reports/task-2726.md"
    - "memory/events/task-2726.done"
  forbidden_paths:
    - "teams/shared/verifiers/critical_gap.py"
    - "scripts/harness/v36/terminal_state_callback.py"
    - "deploy/systemd/**"
    - ".github/**"
  commands:
    - "pytest"
    - "python3 -m pytest"
    - "python3 -m py_compile"
    - "bash -n"
  merge_policy: "none"
  ttl_hours: 48
```

## goal_assertions (auto)
- `python3 -m pytest tests/regression/test_finish_task_worktree_isolation_2726.py -q`
- `bash -n scripts/finish-task.sh`
- `python3 -c "import sys; s=open('scripts/finish-task.sh').read(); sys.exit(0 if 'WORKTREE_UNRESOLVED' in s or 'PROJECT_PATH_REQUIRED' in s else 1)"`

## 상태
CHAIR_APPROVED_1순위 (확정본) — ★ "3번에 나눠서 얘기" 예고 → 2·3번 메시지 종합 후 dispatch. merge 회장 승인 전 금지. PR #169 HOLD / task-2727·2725 병행 대기(구현 금지).