---
task_id: task-2449
type: plan
scope: task
created: 2026-05-05
updated: 2026-05-05
status: implemented
---

# 계획서: task-2449 — taskctl MVP

**task**: task-2449
**목표**: main 진입 단일화 + 상태 enforcement layer 코드화
**승인**: 회장 (2026-05-05) "task.md 수정 금지. 봇은 본 payload만 실행."
**근거**: `memory/tasks/task-2449.md` (단일 payload)

---

## 목표

> "taskctl을 거치지 않고는 main을 절대 변경할 수 없다."

- `scripts/taskctl.py` 단일 진입점 — 11 상태 모델 + 강제 전이 + evidence 자동 수집
- 기존 거버넌스 (guard.sh, qc_report_guard.py, 8 required CI checks)는 보존하면서 **머지 라우팅만** taskctl 경유로 전환

## 범위

### 포함
- `scripts/taskctl.py` (CLI MVP — 11 서브커맨드)
- `scripts/taskctl.README.md` (사용법)
- `scripts/git-hooks/pre-push` (보강 — main direct push 차단 + taskctl status 검사)
- `scripts/anu_confirm_bot/main.py` (gh pr merge 직접 호출 → taskctl 라우팅)
- `scripts/auto_merge.py` (TASKCTL_INVOKED 가드)
- `.github/workflows/guard.yml` (별도 CI guard — ci.yml 보호)
- `tests/test_taskctl.py` (8 케이스 + bypass + 구조 검증, 13 테스트 모두 PASS)
- `memory/reports/task-2449.md` (SCQA 보고서)
- `.tasks/state/.gitkeep` (state 디렉토리 마커)

### 제외 (다음 페이즈)
- ruleset 등록 (회장이 직접)
- Lite Evaluator 연동 (task-2448 — taskctl 머지 후 dispatch)
- finish-task.sh 변경 (현 코드베이스에 직접 머지 호출 없음 — N/A)
- auto_merge_controller.py (코드베이스 부재 — N/A)

## 위임 계획

- 본 task는 dev2 오딘이 통합 실행 (auto_merge_controller 직접 작성 경험)
- ★ 봇 자체 머지 절대 금지 — manual_after_full_enforcement 정책
- 회장 게이트키퍼 7 케이스 (A~G) 모두 PASS 시에만 .done.acked

## 검증 기준

- 합격 조건 A: `python3 scripts/taskctl.py --help` → 11 서브커맨드 출력 + py_compile PASS
- 합격 조건 B/C/D: `pytest tests/test_taskctl.py` → 13 테스트 모두 PASS (정상 3 + 차단 5 + bypass 1 + 구조 4)
- 합격 조건 E: 기존 8 required checks 회귀 0건 — `.github/workflows/ci.yml` 미수정
- 합격 조건 F: `git grep "gh pr merge"` → taskctl.py / 문서 외 0건
- 합격 조건 G: 본 task PR ruleset 통과 후 회장 manual merge

## 참조

- task-2440: ruleset enforcement
- task-2444: auto_merge_controller (기존 작성 — 본 코드베이스에는 부재)
- task-2445: ci.yml guard fix
- task-2448: Lite Evaluator (본 task 머지 후 dispatch)
