# task-2729+10 (r2) — START_TASK_GUARD worktree-root hardening + Gemini HIGH remediation (Option A replacement)

## 레벨
Lv.3 (infra guard hardening + nullglob HIGH 보안 remediation. production activation 아님)

## 배경 (단일 소스)
- PR #185(head 8bed1fee) = SUPERSEDED. G1(start_task_guard worktree-root #7) + G2(finish-task EXTERNAL_DIRTY 면제) 핵심 로직은 self-validated(본 task 봇 자기 worktree exempt → commit/finalize 성공). 단 Gemini fresh **HIGH** 적발 → merge blocker.
- same-PR push 금지 → **Option A replacement**(fresh origin/main base 새 branch)로 수정.
- 기존 #185 산출 5파일을 base 로 하되 아래 HIGH/MEDIUM 수정 반영.

## ★ Gemini HIGH/MEDIUM (수정 목표)
1. **HIGH (`finish-task.sh:881`)**: `nullglob` 상태에서 `ls -d "$WORKSPACE/.worktrees/${TASK_ID}-"*` 가 빈 인자로 확장 → `ls -d` 가 `.` 을 성공(return 0) → worktree 없는데 `_WT_ISOLATED=1` 오판 → canonical dirty 잘못 면제.
   - **fix**: `ls -d` + nullglob 의존 **제거**. `for _wt in "$WORKSPACE/.worktrees/${TASK_ID}-"*; do [ -e "$_wt" ] && _WT_ISOLATED=1 && break; done` (기본 `_WT_ISOLATED=0`). matching worktree 없으면 **반드시 0**.
2. **G2 면제 조건 강화**: worktree 실제 존재 + task_id/branch/base 조건 일치할 때만 EXTERNAL_DIRTY 면제. `OWN_DIRTY`/`UNKNOWN`/forbidden path/expected_files 초과 → 계속 **fail-closed**.
3. **MEDIUM (`test:356`)**: 회귀 테스트의 bash 스니펫을 실제 G2 로직(루프 방식)과 동기화.

## allowed_resources
```yaml
allowed_resources:
  paths:
    - "scripts/start_task_guard.py"
    - "scripts/finish-task.sh"
    - "tests/regression/test_start_task_guard_worktree_root_2729p10.py"
    - "memory/reports/task-2729+10.md"
    - "memory/plans/p0b-pickup/canonical_branch_assumption_design_260606.md"
    - "memory/events/task-2729+10.*"
    - "memory/tasks/task-2729+10-start-task-guard-r2.md"
  read_only_reference:
    - "scripts/git-hooks/pre-commit (lock 검증 — 참조)"
    - "memory/events/task-2729+10.pr185-hold-fresh-high.json (HIGH evidence)"
  forbidden_paths:
    - "/home/jay/workspace (canonical working tree — 브랜치전환/reset/clean/stash/checkout -f 금지)"
    - "memory/events/task-* (다른 task live 마커)"
    - "memory/tasks/** (task-2729+10 제외)"
    - "dispatch.py"
    - "dispatch/**"
    - "utils/**"
    - ".github/**"
    - "hooks/**"
    - "/home/jay/.claude/**"
    - "/usr/local/bin/cokacdir"
```

## EXPECTED FILES (정확히 5 — 초과 시 즉시 HOLD_FOR_CHAIR)
1. `scripts/start_task_guard.py` — G1 worktree-root #7 (유지)
2. `scripts/finish-task.sh` — G2 + **nullglob-safe 루프 fix(HIGH)**
3. `tests/regression/test_start_task_guard_worktree_root_2729p10.py` — 루프 동기화(MEDIUM) + worktree-없음 케이스 추가
4. `memory/reports/task-2729+10.md`
5. `memory/plans/p0b-pickup/canonical_branch_assumption_design_260606.md`

## ★ base 요구 (필수)
- 반드시 **fresh origin/main(8c5af051 또는 이후)** base. stale 시 즉시 HOLD.

## 필수 검증 (회장 verbatim 11)
1. worktree 없음 + canonical dirty → **면제 금지**(_WT_ISOLATED=0). 2. worktree 있음 + unrelated canonical dirty → 면제 허용. 3. worktree OWN_DIRTY → fail. 4. stale/behind/diverged worktree → fail. 5. forbidden/expected_files 초과 → fail. 6. canonical task-2716 branch + live memory artifacts 무손상. 7. regression PASS. 8. raw key 0. 9. ACTIVE=false. 10. systemctl enable 0. 11. real spawn 0.

## ★ 중단 조건 (회장 verbatim)
fresh HIGH/CRITICAL 재발 / expected_files 초과 / canonical reset·clean·stash·switch 필요 / task-2716 수정 필요 / production ACTIVE·systemctl·real spawn 필요 → 즉시 HOLD_FOR_CHAIR.

## 금지
1. PR #185 same-branch push  2. rebase/force  3. canonical reset/clean/stash/switch  4. task-2716 branch 수정  5. live memory artifacts 이동·삭제  6. production ACTIVE/systemctl enable/real spawn  7. ACTIVE=true 선언  8. merge
- 모든 검증 isolated temp git repo. canonical 무손상.

## 완료 판정
- PR 생성 후 CI/Gemini fresh gate PASS → **MERGE_APPROVAL_CANDIDATE_INFRA_HARDENING_ACTIVE_FALSE**.
- merge·production activation 별도 회장 승인 전 금지.
- ★ commit/finalize 가 EXTERNAL_DIRTY_BLOCKER 로 막히면(본 task 가 고치는 그 blocker) 수동 .done 금지, ANU recovery(lock 복구+commit+PR) 허용.

## doctrine
직접 코딩 금지(ANU)/봇 위임 / canonical 무손상 / isolated temp git repo 검증 / same-PR post-Gemini push 금지 / fail-closed 우선 / callback ANU key 독립·self-collector 금지.
