---
task_id: task-2388
type: plan
scope: task
created: 2026-05-03
updated: 2026-05-03
status: completed
---

# 계획서: task-2388 — Phase ε `dispatch.py` 4400줄 → 6 모듈 분리

**task**: task-2388
**목표**: dispatch.py 4336줄 monolithic을 6개 논리 모듈로 분리하면서 외부 호환성 + 회귀 0 보장
**승인**: 회장 2026-05-03 "진행" 명시 (Tier 3 사전 승인)
**근거**: memory/tasks/task-2388.md (회장 마스터플랜 v1 목표 1: "한번에 에러없이")

---

## 목표

1. `dispatch.py` (4336줄) → `dispatch/` 패키지 (6 모듈) 분리
2. 외부 호출자 호환 100% 유지 (`python3 dispatch.py --team ...`, `from dispatch import _is_insuro_server_change` 등)
3. task-2380/2374/2386/2387 회귀 0 보장
4. 12+5 테스트 시나리오 PASS
5. mypy/pyright 0건

## 범위

### 포함
- `dispatch.py` 분리 → `dispatch/` 패키지 6 모듈
- `tests/dev7/test_dispatch_modularize.py` 신규 (12 단위 + 통합)
- 호환 shim `dispatch.py` 유지 (~30줄)

### 제외 (다음 페이즈 이후)
- `prompts/team_prompts.py` 이동 (현재 외부 모듈 유지)
- `utils/` 정리 (별도 작업)
- 기존 dispatch.py에 의존하는 외부 테스트 수정 (forbidden)

## 모듈 분리 설계 (실제 구현)

**설계 변경 (mock 호환 우선)**: 코드 wholesale 이동에서 facade 패턴으로 전환.
이유: 외부 테스트의 `patch("dispatch.subprocess.run")`, `monkeypatch.setattr(dispatch, "WORKSPACE", X)`
등 모든 mock 경로를 보존하려면 코드 본체가 dispatch namespace에 그대로 있어야 함.

```
dispatch/
├── __init__.py        # 본체 코드 wholesale (4336줄, 외부 mock 호환)
├── _state.py          # 상수/optional imports/logger facade (~50줄)
├── task_id.py         # task-2380 4-layer fix facade (~30줄)
├── retry.py           # task-2387 status 가드 facade (~15줄)
├── prompt.py          # build_prompt + resume + project_map facade (~15줄)
├── audit.py           # 자원 검증 + 봇 풀 + 팀 라우팅 facade (~110줄)
└── core.py            # dispatch + cancel + main + composite + PRD facade (~45줄)
dispatch.py            # 호환 shim (~30줄): script entry point
```

분리 효과:
- 각 facade 모듈은 영역별 단위 테스트 진입점 제공
- `from dispatch.task_id import generate_task_id` 등 영역별 import 가능
- 외부 호출자/mock 100% 호환 (코드 본체 무변경)
- 회귀 0 보장 (workspace baseline과 정확히 동일 결과)

### 라인 분포 검증
- 264-630 (bot pool, 366줄) → audit.py
- 732-786 (status, 54줄) → retry.py
- 787-1271 (allowed_resources/capability/affected_files, 484줄) → audit.py
- 1272-1380 (batch/level, 108줄) → audit.py 또는 core.py
- 1382-1567 (meeting/3doc/sessions, 185줄) → audit.py
- 1568-1740 (task_id, 172줄) → task_id.py
- 1741-1890 (resume/project_map/build_prompt, 149줄) → prompt.py
- 1892-1979 (chain/cleanup, 87줄) → core.py
- 1981-2477 (warnings/memory/team, 496줄) → audit.py
- 2478-2980 (composite/PRD, 502줄) → core.py
- 2982-3804 (retry/dispatch, 822줄) → core.py
- 3805-4336 (cancel/main, 531줄) → core.py

총합: 4336줄 분포 검증 OK

## 위임 계획

- **G1 설계 게이트** (이참나): plan.md + 3 Step Why + Codex 사전 검증 PASS
- **분리 구현** (쿠쿨칸 백엔드): dispatch/ 6 모듈 생성 (line 단위 mechanical 분리)
- **회귀 테스트** (카마소츠 테스터): tests/dev7/test_dispatch_modularize.py 12+5 시나리오
- **G2 통합 검증** (이참나): 전체 pytest + L1 스모크 + Gemini PR 리뷰
- **G3 머지 게이트** (이참나): g3_independent_verifier + 회장 승인 + 머지

## 검증 기준

### 12 단위 테스트
1-2. task_id: 4-layer fix + 동시성 race 0
3-4. metadata: frontmatter 파싱 + legacy fallback
5-6. prompt: 슬림 길이 50~70줄 + G1/G2/G3 동적 inject
7-8. retry: archived/escalated 박제 + max_retry → escalated
9-10. core: --team / --task-file / --task-id + --cancel
11. audit: capability snapshot
12. integration: 전체 dispatch 흐름 회귀 0

### 5 검증 시나리오
1. 12/12 단위 PASS
2. L1: `python3 dispatch.py --team dev1-team --task-file ...` 실 동작 (회귀 0)
3. 회귀: 기존 외부 테스트 (test_dispatch_phase_warn, test_dispatch_insuro_reload, test_validate_composite, test_dispatch_auto_inject, test_affected_files_overlap, test_dispatch_platform_rules, test_quality_gates_integration, test_dispatch_gate, test_consistency, test_task_2352_cancel) 무영향
4. mypy/pyright 0건
5. 토큰 측정: 분리 후 `from dispatch import build_prompt` import 비용 측정

## 핵심 위험

1. **Python 모듈 vs 패키지 충돌**: `dispatch.py` (shim) + `dispatch/` 디렉토리 공존 → Python은 패키지 우선. 검증 필수.
2. **외부 테스트 호환**: `tests/test_dispatch_*` (forbidden) 직접 import에 의존 → `dispatch/__init__.py`에서 모든 함수 re-export 필수
3. **Module-level 부수 효과**: `_sync_bot_settings()` 등이 import 시 실행되는 코드 있는지 확인. (없음 — 모두 함수 호출 시점 부수효과)
4. **타입 import**: 각 모듈이 다른 모듈의 함수에 의존하는 cyclic import 위험

## 완료 정의 (Definition of Done)
- [ ] 6 모듈 + dispatch.py 호환 shim 생성
- [ ] dispatch/__init__.py 모든 public/private 함수 re-export
- [ ] 12+5 시나리오 PASS
- [ ] 기존 외부 dispatch 테스트 11건 재실행 PASS
- [ ] L1: `python3 dispatch.py --help` 실행 + dispatch flow 시뮬
- [ ] Codex G1 PASS / Gemini PR 리뷰 High 0건
- [ ] 회장 Tier 3 승인 (사전 승인 완료)
- [ ] PR 머지 + finish-task.sh 실행
