---
task_id: task-2550
type: checklist
scope: task
created: 2026-05-11
updated: 2026-05-11
status: completed
---

# 체크리스트: task-2550 — .worktrees auto-cleanup policy

**task**: task-2550

---

## Phase 0 — G1 사전 검증

- [x] task 파일 분석
- [x] worktree 생성 (task-2550-dev5)
- [x] 3문서 작성 (plan.md, context-notes.md, 본 파일)
- [x] G1 Codex 사전 검증 (1차 — 구현 전 critical 자연 발생, 진행)

## Phase 1 — 구현 (엔키, 백엔드)

- [ ] A. `anu_v2/worktree_cleanup.py` 작성 (6대 안전조건 helper)
  - check_safety_condition_1_done_acked(task_id, workspace_root) → bool
  - check_safety_condition_2_pr_merged(pr_number) → bool (gh API 의존성 주입)
  - check_safety_condition_3_merge_done(task_id, workspace_root) → bool
  - check_safety_condition_4_branch_in_main(branch, workspace_root) → bool
  - check_safety_condition_5_not_in_use(worktree_path, workspace_root) → bool
  - check_safety_condition_6_apply_explicit(apply_flag) → bool
  - is_dirty_worktree(worktree_path) → bool
  - is_main_worktree(worktree_path, workspace_root) → bool (★ 절대 보호)
  - enumerate_worktrees(workspace_root) → list[WorktreeCandidate]
  - cleanup_worktree(path, apply: bool) → CleanupResult
  - cleanup_all_dry_run(workspace_root, apply=False) → list[CleanupResult]

- [ ] B. `anu_v2/post_merge_smoke_runner.py` 수정
  - 새 메서드 `run_post_merge_worktree_cleanup_dry_run(task_id, workspace_root, apply=False)` 추가
  - 기존 `run_post_merge_smoke()` 시그니처 절대 변경 X (task-2539 박제)
  - 호출 통합: post_merge_smoke PASS + marker 생성 후 cleanup dry-run 1회 호출
  - 결과 dict에 `worktree_cleanup_result` 키 추가 (optional)

## Phase 2 — 회귀 테스트 (닌기르수, 테스터)

- [ ] A. `anu_v2/tests/test_worktree_cleanup_2550.py` 작성
  - 6대 안전조건 each PASS / FAIL 회귀
  - dirty worktree skip + log 어설션
  - dry-run 기본 mode → 실제 삭제 0건 어설션
  - --apply mode → 실제 삭제 1건 이상 (mock subprocess)
  - main worktree 절대 삭제 X 어설션 (workspace_root 명시 차단)
  - 머지 안 된 PR worktree skip 어설션
  - token / API key 노출 0 (raw token 검사)

- [ ] B. `anu_v2/tests/test_post_merge_smoke_worktree_integration_2550.py` 작성
  - post_merge_smoke PASS → cleanup dry-run 1회 트리거 어설션
  - post_merge_smoke FAIL → cleanup 미실행 어설션
  - cleanup 결과가 main 결과 dict에 포함 어설션

- [ ] C. 기존 회귀 (test_post_merge_smoke_runner_2539.py) PASS 확인 (시그니처 호환)

## Phase 3 — UX 검토 (나부, UX/UI)

- [ ] A. dry-run / --apply CLI 메시지 검토 (운영자 관점)
- [ ] B. 로그 박제 format 검토 (memory/events/worktree-cleanup-skipped-<ts>.json)

## Phase 4 — G2 (마아트 + 로키)

- [ ] A. 마아트 QC 독립 검증 (코드 품질, 시그니처 호환)
- [ ] B. 로키 보안 레드팀 (Critical 7 + token raw 노출 + main worktree 보호 적대적 검증)
- [ ] C. .qc-result PASS

## Phase 5 — G3 independent_verifier + self-test

- [ ] A. python3 -m pytest anu_v2/tests/test_worktree_cleanup_2550.py -v → PASS
- [ ] B. python3 -m pytest anu_v2/tests/test_post_merge_smoke_worktree_integration_2550.py -v → PASS
- [ ] C. python3 -m pytest anu_v2/tests/test_post_merge_smoke_runner_2539.py -v → PASS (기존 회귀)
- [ ] D. python3 -m pyright anu_v2/ → 0 errors
- [ ] E. self-test dry-run: 머지된 task의 worktree 삭제 후보 list 출력 (실제 삭제 X)
- [ ] F. python3 scripts/g3_independent_verifier.py --task-id task-2550 → PASS
- [ ] G. G1 Codex re-check → PASS

## Phase 6 — PR 생성 + 머지

- [ ] A. micro-commit: 각 파일 변경 즉시 커밋
- [ ] B. PR 생성 (Gemini fresh + unresolved 0)
- [ ] C. CI all SUCCESS + mergeStateStatus CLEAN
- [ ] D. BOT squash merge
- [ ] E. post_merge_smoke + reconcile + done.acked + merge-done + lineage

## 보고

- [ ] 최종 보고서 작성 (memory/reports/task-2550.md, SCQA)
- [ ] 3문서 status: completed로 업데이트
- [ ] 모델 사용 기록 (팀원별)
- [ ] L1 스모크테스트 결과 기록

## 완료 기준 (task 본질 11항목)

- [ ] 1. PR 생성
- [ ] 2. effective diff == corrected expected_files
- [ ] 3. forbidden path 0
- [ ] 4. regression PASS
- [ ] 5. pyright 0
- [ ] 6. CI all SUCCESS
- [ ] 7. Gemini fresh + unresolved 0
- [ ] 8. mergeStateStatus CLEAN
- [ ] 9. mergedBy = app/jeon-jonghyuk-taskctl-bot
- [ ] 10. post-merge smoke PASS
- [ ] 11. reconcile evidence 존재
- [ ] 12. self-test dry-run 정상 어설션 (실제 삭제 X)
- [ ] 13. 신규 Critical 7 = 0
