---
task_id: task-2451
type: context
scope: task
created: 2026-05-05
updated: 2026-05-05
status: completed
---

# 맥락 노트: task-2451 — taskctl 라우팅 검증

**task**: task-2451

---

## 결정 근거

### 핵심 결정 1: 위임 단위 (토르 통합 vs 분할)

**결정**: Fix 1+3+4는 토르(백엔드)에게 통합 위임. Fix 2만 헤임달(테스터)에게 분리.

**근거**:
- Fix 1(정상)/Fix 3(차단)/Fix 4(bypass)는 동일한 taskctl CLI를 다른 입력으로 호출하는 검증 시퀀스. 분리하면 dummy task-id 상태 공유가 어렵고, 9 케이스 매트릭스 통합이 흐트러짐.
- Fix 2는 GitHub remote 의존(gh pr create / CI workflow). 통신 실패 시 재시도 로직 분리 필요 → 별도 위임이 안전.

**대안 기각**: 5 fix를 각각 5명에게 위임 → sub-agent 5개 동시 실행으로 dummy state 충돌 발생 가능.

### 핵심 결정 2: worktree 사용 여부

**결정**: worktree 미사용. 신규 브랜치 `task/task-2451-dev2`를 main에서 직접 생성.

**근거**:
- 본 task는 시스템 작업(project_id 없음). worktree_manager.py는 projects/{project_id} 기준.
- 변경 파일이 보고서/3문서/dummy 1줄로 매우 제한적. 충돌 위험 낮음.
- forbidden_paths 다수 → worktree 격리 효익보다 단순성이 더 중요.

### 핵심 결정 3: dummy PR과 본 task 보고서 PR 분리

**결정**: dummy PR(`task/task-test-2451-dummy`)은 검증용으로 close. 본 task 보고서(`task/task-2451-dev2`)는 별도 PR로 생성하여 회장 manual merge 대기.

**근거**:
- merge_policy=no_merge — 봇 자체 머지 0건. 본 task의 핵심 메타 검증 항목.
- dummy PR은 ruleset+workflow 통합 검증용이지 산출물이 아님 → close + delete-branch.

## 3 Step Why 자문 (Lv.3+)

**1st Why: 왜 이 검증이 필요한가?**
A: task-2447 절반 처리 사고와 같은 "이론상 PASS / 실제 미동작" 패턴 재발 방지. taskctl이 main에 머지된 직후 enforcement가 실제 적용되는지 검증해야 안심하고 운영 가능.

**2nd Why: 왜 dummy task-id + dummy PR 방식인가?**
B: 실제 task로 검증하면 production 데이터 오염 위험. dummy로 분리하면 (1) state JSON 격리 (2) PR 검증 후 close 가능 (3) 코드 0 변경 원칙 유지 가능.

**3rd Why: 왜 9 케이스인가? 더 많이 / 더 적게 안 되나?**
C: 9 케이스는 enforcement 4 layer(CLI gate / pre-push hook / workflow guard / bypass evidence)를 모두 커버하는 최소 집합. 더 적으면(예: 5) bypass 또는 pre-push가 빠짐. 더 많으면(예: 15) 검증 시간 증가 vs 추가 신뢰도 한계 효용 낮음.

**A-B-C 일관성**: ✅ 일관됨. 검증 필요성(A) → dummy 분리(B) → 4 layer 커버(C) 논리 흐름.

## Codex 사전 검증 결과 (2026-05-05 12:50)

**결과**: FAIL (critical 2, high 2, medium 1)

**핵심 발견**:
1. [critical] dummy task-id `task-test-routing-001`은 pre-push hook + guard.yml 정규식 `task-[0-9]+`와 매치되지 않음 → taskctl-state-guard 미활성화 가능성
2. [critical] guard.yml은 CANCELLED만 차단, state 파일 없으면 graceful skip → 절대 기준 미달
3. [high] taskctl.py merge 함수에서 CANCELLED 분기가 HUMAN_APPROVED 검사보다 뒤에 있어 CANCELLED 메시지 출력 불가
4. [high] REQUIRED_CHECKS에 `taskctl-state-guard` 없음 → 8+1이 아닌 8만 enforce
5. [medium] tests/test_taskctl.py 회귀 테스트가 정상 흐름이 아닌 차단을 assert

**결정**: task.md 절대 원칙(회장: "task.md 수정 금지. 중간 정정 = 100% 무효")에 따라 task.md 그대로 실행. Codex 사전 분석은 본 검증이 발견하려던 "이론상 PASS / 실제 동작 PASS 별개" 불일치 자체를 미리 노출한 것 → 실증의 가치를 오히려 강화. 9 케이스 매트릭스에 실제 실행 결과를 정직하게 기록하고 회장 manual judgment에 맡긴다.

**근거 파일**: `/home/jay/workspace/memory/events/task-2451.codex-gate`

## 참조 자료

- task.md: `/home/jay/workspace/memory/tasks/task-2451.md`
- taskctl.py: `/home/jay/workspace/scripts/taskctl.py`
- 선행 task-2449 (taskctl MVP): mergeCommit `cef642c7`
- 선행 task-2440 (Ruleset enforcement): 8 required checks
- 선행 task-2450 (Phase A1 multi-repo): 7 리포 ruleset
- 회장 거버넌스: `/home/jay/workspace/system_governance_4layer.md`

## 주의사항

- ⚠️ **forbidden_paths 절대 수정 금지**: scripts/, .github/workflows/, dispatch.py, dashboard/, teams/shared/, CLAUDE.md
- ⚠️ **dummy PR 머지 금지**: merge_policy=no_merge. 검증 후 즉시 close + delete-branch
- ⚠️ **본 task PR 봇 자체 머지 금지**: 회장 manual merge만 허용
- ⚠️ **task.md 수정 금지**: 회장 명시 — 중간 정정 = 100% 무효
- ⚠️ **dummy state 파일 정리 필수**: `.tasks/state/task-test-*.json` 모두 삭제 후 .done
- ⚠️ **scripts/ git diff 0건 검증**: 검증만, 코드 0 — 어떤 이유로도 scripts/ 수정 시 task FAIL
