---
task_id: task-2467
type: plan
scope: task
created: 2026-05-06
updated: 2026-05-06
status: completed
---

# 계획서: task-2467 — taskctl PR Lifecycle State Machine + 경로 강제 라우팅

**task**: task-2467
**목표**: 모든 PR lifecycle을 `taskctl` state machine으로만 진행하도록 시스템 거버넌스를 강제 전환
**승인**: 회장 2026-05-06 "state machine이 아니라 모든 실행 경로가 taskctl을 통과하도록 만드는 것이 Phase A의 본질이다."
**근거**: `memory/tasks/task-2467.md` (회장 통합 명령 §3), `memory/system_bot_orchestration_blueprint_260506.md` §10/§11/§16

---

## 목표

1. taskctl을 단일 관문으로 만들어, 다음 3가지 경로가 taskctl 외에서는 일어날 수 없게 한다:
   - PR 생성 (`taskctl pr-open`)
   - 승인 (`taskctl approve --by <human>`, self-approve 차단)
   - 머지 (`taskctl merge [--admin]`, `gh pr merge`는 taskctl 내부 1곳에서만)
2. 14정상 + 5예외 = 19개 상태를 enum으로 강제하고, 6개 금지 전이를 단위테스트로 차단
3. evidence 9종을 `.tasks/evidence/<task-id>/{name}.json`에 자동 박제
4. worktree_manager.py / finish-task.sh / anu_confirm_bot의 직접 PR/머지 코드 0건
5. 본 task 자체가 새 taskctl 흐름으로 머지 (drink your own champagne)

## 범위

### 포함
- `scripts/taskctl.py` 확장: 상태 enum 11→19, 신규 명령 9개, evidence 9종 자동 기록, admin override + audit
- `scripts/worktree_manager.py` 축소: `cmd_finish` 의 action="pr"에서 직접 `gh pr create`/`gh pr merge` 제거 → taskctl 라우팅
- `scripts/finish-task.sh` 정리: BLOCKED → `.done.blocked`, ESCALATED → `.done.escalated`
- `scripts/anu_confirm_bot/main.py`: taskctl approve → taskctl merge 라우팅 (현재는 merge만 호출)
- bot token 인증 경로: `.env.keys` / `BOT_GITHUB_TOKEN` env var (PAT 발급은 회장 책임, 코드는 graceful)
- 명세 2개: `taskctl-state-machine-spec.md`, `pr-lifecycle-spec.md`
- 테스트: `tests/state_machine/`, `tests/taskctl/` (전이/lifecycle/evidence/admin override/self-approve/grep audit) 20+케이스

### 제외 (다음 페이즈/별도 task)
- task-2468: Phase C — Gate 통합 (CI workflow의 hidden-path-audit)
- task-2469: Phase D — Penetration tests
- bot 계정 GitHub PAT 발급 (회장 운영 영역)
- GEMINI_API_KEY 도입 (절대 금지 — Gemini App만 사용)
- PR #29 / #30 / #31 변경 (회장 박제 보존)
- task-2465 / task-2466 결과물 변경

## 위임 계획

- **명세 + 3 Step Why + Codex 사전검증**: 페룬 (직접) — 회장 인용 정확성 + 거버넌스 판단
- **taskctl.py 확장 (코어)**: 스바로그 (sonnet) — 상태 enum + 신규 명령 + evidence 9종 + admin override
- **worktree_manager.py / finish-task.sh / anu_confirm_bot 축소**: 스바로그 (sonnet) — 우회 경로 제거
- **테스트 작성 (단위/회귀/grep audit)**: 벨레스 (sonnet) — 20+ 케이스, 6개 금지 전이 강제
- **L1 스모크 + drink-your-own-champagne**: 페룬 (통합) — taskctl pr-open/verify/approve/merge/done 자체 적용
- **모코시/라다**: N/A (UI 작업 없음, 시스템 거버넌스 task)

## 검증 기준

- 우회 경로 grep: `grep -rn "gh pr merge" --exclude-dir={.git,tests,fixtures,.worktrees,node_modules}` → `scripts/taskctl.py` 외 0건
- 우회 경로 grep: `grep -rn "gh pr create" --exclude-dir={.git,tests,fixtures,.worktrees,node_modules}` → `scripts/taskctl.py` 외 0건
- 우회 경로 grep: `grep -rn "git push origin main"` → 0건 (audit-trail.jsonl 제외)
- 단위 테스트: `pytest tests/taskctl/ tests/state_machine/` → 20건+ PASS
- 타입체크: `pyright scripts/taskctl.py` → 0 errors
- state 자체 적용: `python3 scripts/taskctl.py status task-2467` → state == MERGED → DONE
- 6개 금지 전이 차단: 테스트로 명시적 검증
- self-approve 차단: PR author == approver → ESCALATED 전이
- admin override 사용 시: `memory/orchestration-audit/admin-override.jsonl`에 audit log 기록
