# [DRAFT — HOLD] B. finish-task PROJECT_PATH misbinding + scope base selection defect

> ★ 이 문서는 **초안**입니다. dispatch 금지. `scripts/finish-task.sh` 는 **자동 dispatch 금지 목록** — 반드시 회장 승인 후에만 task-NNNN 할당 + 위임. 코드 변경 0 (현재 단계).

## 분류
- priority: Core hardening HIGH
- severity: operational (non-Critical7, 오탐 유발 → 머지 차단 false-positive)
- backlog 단일소스: `memory/events/backlog_finish_task_scope_guard_cumulative_diff_260601.json`

## 근본 원인 (read-only 확인, 2026-06-02)
`scripts/finish-task.sh` 약 line 453-457:
```
MAIN_BRANCH=$(git rev-parse --verify main … && echo main || echo master)
git -C "$SCOPE_PROJ_DIR" diff --name-only "${MAIN_BRANCH}..HEAD" > "$SCOPE_DIFF_FILE" …
  || git -C "$SCOPE_PROJ_DIR" diff --name-only HEAD~1 …
```
**defect 1 — scope base = 로컬 `main`**: 로컬 `main` 이 origin/main 보다 뒤처지거나(LOCAL_OPERATIONAL_PATCH 상태), worktree 가 다른 base 에서 분기하면 `main..HEAD` 가 **무관 누적 커밋**을 포함 → scope-guard false-positive (실증: task-2722 실제 origin/main..HEAD 2파일인데 42파일 오탐).
**defect 2 — PROJECT_PATH misbinding**: line 123-163 자동 보정이 task-timers.json worktree_path 의존. stale/누락 시 `$WORKSPACE`(메인 repo)로 fallback → 잘못된 repo 기준 diff. worktree finalize 시 메인 repo CWD 오바인딩 가능.
**defect 3 — fallback `HEAD~1`**: base 미해석 시 `HEAD~1` 단일커밋만 비교 → multi-commit task 누락.

## 목표
- scope base 를 **로컬 main 이 아니라** 다음 우선순위로 해석:
  1. task 의 기록된 base/lock_sha (task-timers.json/lock marker)
  2. `git merge-base origin/main HEAD` (origin/main 기준 공통조상)
  3. 최후 fallback 만 `main..HEAD`
- PROJECT_PATH 미지정/stale 시 worktree 경로 강제 바인딩 + 메인 repo 오바인딩 차단.

## expected_files 후보 (회장 확정 필요)
1. `scripts/finish-task.sh` ← scope base 선택 + PROJECT_PATH 바인딩 (★ FORBIDDEN AUTO-DISPATCH — 회장 승인 필수)
2. (선택) `scripts/task-scope-guard.sh` ← base SHA argv 수용 시
3. 회귀: finish-task scope-guard 동작 테스트 (경로 확정 필요 — 현재 scope-guard 단위 테스트 유무 조사 선행)

## forbidden (이 task 범위 밖)
- dispatch runtime / pickup driver / systemd / activation flag 수정 금지
- scope-guard 우회(SKIP 남발)로 해결 금지 — base 계산 자체를 고쳐야 함
- 머지 게이트 무력화 금지 (탐지력 보존 필수)

## verification_plan
1. 로컬 main 이 origin/main 보다 뒤처진 상태 재현 → 실제 task diff 만 scope 계산(무관 커밋 0) 회귀
2. multi-commit task → 전 커밋 diff 포함 확인 (HEAD~1 누락 회귀)
3. PROJECT_PATH 미지정 → worktree 정확 바인딩, 메인 repo 오바인딩 0
4. 정상 in-scope task → PASS 유지, out-of-scope → 여전히 FAIL (탐지력 보존)
5. shellcheck/bash -n 무손상

## bounded loop
- severity = operational HIGH(오탐). code fix remediation_round max 2/PR.
- finish-task.sh 는 머지 경로 핵심 → 회귀 광범위. 새 HIGH/CRITICAL 시 즉시 CHAIR_REQUIRED.

## base-resolution 알고리즘 (정교화 — 설계만, finish-task.sh 미수정)
scope base SHA 해석 우선순위(pseudo):
```
resolve_scope_base(task_id, project_dir):
  1. BASE = task-timers.json[task_id].base_sha (or lock_sha marker)   # 가장 정확
  2. if empty: BASE = git -C project_dir merge-base origin/main HEAD  # origin 기준 공통조상
  3. if empty/err: BASE = git -C project_dir merge-base main HEAD     # 로컬 fallback (merge-base 로 누적 회피)
  4. if still empty: SKIP scope-guard with WARN (단정 FAIL 금지)
  diff = git -C project_dir diff --name-only BASE..HEAD
```
핵심: 절대 `main..HEAD`(직접) 사용 금지 — 항상 merge-base 또는 기록 base. `HEAD~1` fallback 폐기(multi-commit 누락).
PROJECT_PATH: worktree_path 확정 시 그 경로 강제. stale/누락 시 `$WORKSPACE` fallback 전에 task-timers worktree_path 재조회 + 존재검증. 메인 repo 오바인딩 시 WARN 로그.

## test-plan (정교화)
- fixture A: 로컬 main 이 origin/main 보다 3 커밋 뒤 + worktree 2파일만 수정 → scope diff = 2파일 (무관 커밋 0)
- fixture B: multi-commit task(3 커밋) → 3 커밋 전체 diff 포함 (HEAD~1 누락 회귀)
- fixture C: PROJECT_PATH 미지정 + task-timers worktree_path 존재 → worktree 바인딩 정확
- fixture D: out-of-scope 파일 추가 → 여전히 FAIL (탐지력 보존)
- fixture E: base 해석 전부 실패 → SKIP+WARN (false FAIL 0)

## 상태
DRAFT_HOLD — auto_continue_allowed=false. chair_required_reason: finish-task.sh 자동 dispatch 금지 + 실제 코드 수정 PR 회장 승인 필수. (알고리즘/test-plan 정교화 완료 — dispatch-ready upon 회장 승인)
