# task-2569 — finish-task.sh / workspace isolation / task md 보존 시스템 fix

**팀**: 3팀 (다그다) — 시스템 fix 적임 + 직전 task-2568+3 시스템 영역 경험
**Lv**: 3
**우선순위**: critical
**날짜**: 2026-05-13
**작성 사유**: task-2568 Phase B 진행 중 발견된 시스템 손상 (task md 사라짐, 3-docs 사라짐, stash 누적 20+) — 회장 박제

---

## 1. 배경 (회장 박제 사건)

task-2568 Queue Merge Chain Executor 진행 중 (2026-05-13):
- Phase B PR #117 처리 도중 dev3 다그다 finish-task.sh 실행 (19:27)
- **3-docs 디렉토리 사라짐** (19:25 다그다 인지)
- **task-2568.md / task-2568+1.md / task-2568+2.md 사라짐** (19:33 다그다 인지)
- **task-timer.json / member-status.json / whisper/* 시스템 상태 reset** (whisper에 옛 task 번호 2390~2403 표시)
- 다그다가 stash 일부 복구 + 본 파일 재생성으로 부분 회복
- read-only 원인 추적으로 root cause 4 후보 + 추가 6 영역 박제

본 task는 위 시스템 손상의 **근본 원인을 제거**하고 **재발 방지 가드**를 도입한다.

---

## 2. ★★★ Root Cause 4 후보 (회장 명시 — 반드시 포함)

### RC-1. cleanup-stale-tasks.sh 매시간 cron과 task md 보존 정책 충돌
- 현재 crontab: `0 * * * * bash /home/jay/workspace/scripts/cleanup-stale-tasks.sh`
- 내부 호출: `task-timer.py cleanup --running-hours 24 --reserved-minutes 60`
- ★ task-timer cleanup의 부수효과가 task md / 3-docs 영향 가능성 audit
- 보호 정책: `memory/tasks/`, `memory/plans/tasks/` protection list 추가

### RC-2. cleanup-workspace.py / file_cleanup.py 의 unlink/rmtree 대상 path audit
- `scripts/cleanup-workspace.py` line 130: `shutil.rmtree(p) if p.is_dir() else p.unlink()` — 직접 삭제
- `scripts/file_cleanup.py` line 344: `p.unlink()` — 파일 삭제
- 대상 path가 정확히 무엇인지 audit + protection list 추가 + dry-run 모드 기본화

### RC-3. finish-task.sh stash lifecycle 결함
현재 증상:
- `git stash list` 결과 **20+ stash 누적**
- "pre-task-N stash" / "finish-task-quarantine" / "task-N-other-files-stash" 등 패턴
- stash pop 누락 또는 drop으로 다른 task의 untracked 파일 격리 후 복원 실패
- 회장 박제: stash 누적 / pop 누락 / unrelated dirty state 격리 후 복원 실패

수정 방향:
- stash 진입 전 audit log 박제 (어떤 파일이 stash에 들어가는지)
- stash pop 강제 또는 explicit drop 정책
- stash가 누적되지 않도록 lifecycle 관리

### RC-4. dispatch.py task md overwrite 패턴 + untracked task md 보존 실패
- 현재: dispatch.py가 `task-NNN.md` 본 파일을 attempt별 내용으로 overwrite (attempt-2/attempt-3 패턴)
- untracked 상태로 생성 → git tracking 미반영
- 어떤 cleanup 경로에서 untracked 파일 삭제 시 보존 실패

수정 방향:
- task md 생성/수정은 dispatch.py만 가능, 다른 프로세스 read-only
- task md를 `--intent-to-add` 또는 별도 directory로 격리하여 untracked cleanup 영향 회피
- attempt 별 task md는 별도 파일 (`task-NNN.attempt-K.md`)로 유지하고 overwrite 금지

---

## 3. ★★★ 추가 포함 (회장 명시)

### AD-1. PR sub-task worktree scope guard 기준
- 현재 finish-task.sh pre-push-guard B-1이 메인 workspace WORKSPACE dirty를 task scope 밖으로 검출
- PR sub-task worktree (`/home/jay/workspace/.worktrees/task-NNN+M-devX/`)와 메인 workspace 격리 미흡
- sub-task에서는 task scope guard가 worktree 내부 + lock_sha..HEAD 기준이어야 함

### AD-2. lock_sha..HEAD 기준 diff 지원
- main..HEAD 기준 diff는 PR sub-task에서 오판 발생 (main의 다른 변경까지 scope 포함)
- lock_sha..HEAD 기준 diff = sub-task 시작 시점 SHA에서부터의 변경만 scope

### AD-3. main..HEAD 오판 방지
- main..HEAD 기준 scope guard 사용 시 PR sub-task에서 의도치 않은 scope expansion 검출
- finish-task.sh / guard.sh가 PR sub-task 컨텍스트 감지 시 자동으로 lock_sha..HEAD로 전환

### AD-4. memory/tasks/ 파일 보존 정책
- task md는 시스템 critical 파일
- 어떤 cleanup 데몬도 임의로 삭제 불가
- protection list (`memory/tasks/`, `memory/plans/tasks/`, `memory/reports/`) 명시

### AD-5. task md / 3-docs / report / event marker lifecycle 보호
- 각 lifecycle 단계 (생성/수정/완료/acked/삭제)에 대한 audit log
- 특히 untracked 파일의 lifecycle 보호 (git stash / clean 영향 방지)

### AD-6. post-merge evidence consistency check
- PR merge 후 evidence marker (post-merge.done / reconcile-evidence.json) 일관성 검증
- merge marker가 stale 처리되지 않도록 watcher 정책 조정 (현재 자동 escalated 발생: 30분 미응답)

---

## 4. 허용

- `scripts/finish-task.sh` 최소 수정 (stash lifecycle / protection list)
- `scripts/cleanup-stale-tasks.sh` 수정 (protection list)
- `scripts/cleanup-workspace.py` / `scripts/file_cleanup.py` 수정 (path audit + protection)
- `scripts/guard.sh` 또는 `git-hooks/pre-push` 수정 (lock_sha..HEAD 지원)
- `dispatch.py` 일부 수정 (task md 보존 정책)
- 신규 protection list config 파일 추가
- regression test 최소 추가

## 5. 금지 (회장 명시)

- ❌ 이미 merged된 PR #117/#118/#119에 추가 commit 금지
- ❌ marker 수동 조작 금지
- ❌ force push / rebase / admin override / manual merge 금지
- ❌ GitHub-hosted fallback 금지
- ❌ 다른 task의 task md / events 직접 수정 금지
- ❌ scope expansion (root cause 4 + 추가 6 영역 외)

## 6. 완료 조건

1. RC-1: cleanup-stale-tasks.sh / task-timer.py cleanup의 task md 영향 audit 완료 + protection list 적용
2. RC-2: cleanup-workspace.py / file_cleanup.py 대상 path audit 보고서 + dry-run 모드 + protection list
3. RC-3: finish-task.sh stash lifecycle 수정 (audit log + pop 강제 또는 drop 정책)
4. RC-4: dispatch.py task md 보존 정책 수정 (overwrite 패턴 개선)
5. AD-1~3: lock_sha..HEAD 기준 scope guard 지원 (PR sub-task worktree 컨텍스트 자동 감지)
6. AD-4~5: memory/tasks/, memory/plans/tasks/ 등 protection 정책 명시 + lifecycle audit log
7. AD-6: post-merge evidence consistency check 정책 (stale .done.escalated 자동 발생 방지)
8. regression test 추가 (각 RC/AD 별 최소 1건)
9. 보고서 작성 (memory/reports/task-2569.md)

## 7. 보고

- Phase별 짧게 보고 (예: RC-1 완료, RC-2 완료, ...)
- 신규 finding 발생 시 자동 fix 금지, 회장 escalate
- Critical 7 발생 시 즉시 보고

## 8. 참조

- task-2568 (Queue Merge Chain Executor) — 전체 완료, 본 사건의 origin
- task-2568+3 (다그다 micro-patch) — finish-task.sh stash 동작 직접 인지 보고서
- `git stash list` 결과 (20+ 누적)
- `memory/events/task-2568.phase-b.new-valid-findings.escalation.json` (회장 escalate 사례)
- 본 사건 박제 시점: 2026-05-13 19:25~19:33

## 9. allowed_resources

```yaml
allowed_resources:
  paths:
    - "scripts/finish-task.sh"
    - "scripts/cleanup-stale-tasks.sh"
    - "scripts/cleanup-workspace.py"
    - "scripts/file_cleanup.py"
    - "scripts/guard.sh"
    - "scripts/git-hooks/pre-push"
    - "dispatch.py"
    - "memory/task-timer.py"
    - "tests/regression/test_task_md_preservation_*.py"
    - "tests/regression/test_finish_task_stash_lifecycle_*.py"
    - "tests/regression/test_scope_guard_lock_sha_*.py"
    - "tests/regression/test_cleanup_workspace_protection_*.py"
    - "memory/plans/tasks/task-2569/**"
    - "memory/reports/task-2569.md"
    - "memory/events/task-2569.*"
    - "memory/specs/protection-list.md"
  forbidden_paths:
    - "anu_v2/**"
    - ".github/workflows/**"
    - "memory/tasks/task-2568*"
    - "memory/tasks/task-2563*"
    - "memory/tasks/task-2564*"
    - "memory/tasks/task-2565*"
    - "memory/events/task-2568*"
    - "memory/events/task-2563*"
    - "memory/events/task-2564*"
    - "memory/events/task-2565*"
    - "memory/events/task-2566*"
    - "memory/reports/task-2568*"
    - "memory/reports/task-2563*"
    - "memory/reports/task-2564*"
    - "memory/reports/task-2565*"
    - "memory/specs/anu-system-spec*"
    - "memory/capabilities/**"
    - ".env*"
    - "**/*.pem"
    - "secrets/**"
    - "dist/**"
    - "node_modules/**"
    - ".worktrees/**"
  commands:
    - "pytest"
    - "python3 -m py_compile"
    - "gh pr view"
    - "gh api"
    - "git"
    - "shellcheck"
  merge_policy: "tiered"
  ttl_hours: 36
```