# task-1451.1 완료 보고서 — 봇 현황 단일 모듈 통합

**S**: dispatch.py, whisper-compile.py에서 봇 상태 관련 로직(충돌방지, whisper 표시, 논리적 팀 라우팅)이 각각 독립적으로 구현되어 있으며, 단일 소스 원칙(SSOT) 위반 상태였다.

**C**: 동일 로직이 3곳에 분산되어 변경 시 일관성 유지가 어렵고, 봇 점유 판단 기준이 파일마다 미묘하게 다를 위험이 있었다. 논리적 팀 도메인 매핑도 constants.json에 이미 존재하나 각 모듈이 독립적으로 파싱하고 있었다.

**Q**: 하나의 모듈만 확인하면 봇 충돌방지, whisper 표시, 논리적 팀 라우팅이 전부 해결되는 단일 소스 구조를 달성할 수 있는가?

**A**: `utils/bot_status.py`에 `BotStatusManager` 클래스를 생성하여 7개 API로 통합 완료. dispatch.py와 whisper-compile.py를 BotStatusManager 위임 + fallback 구조로 리팩토링. 기존 테스트 112개 + 신규 테스트 27개 = 총 139개 전부 통과. 실 운영 환경에서 봇 3개 busy, 5개 idle, design팀 bot-b 점유 상태를 정확히 탐지 확인.

---

## 산출물

- `/home/jay/workspace/utils/bot_status.py` (신규 — BotStatusManager 모듈)
- `/home/jay/workspace/utils/tests/test_bot_status.py` (신규 — 27개 테스트)
- `/home/jay/workspace/dispatch.py` (수정 — BotStatusManager 위임)
- `/home/jay/workspace/scripts/whisper-compile.py` (수정 — BotStatusManager 위임)

## BotStatusManager API

- `get_busy_bots(exclude_task_id)` — running 상태 봇 점유 정보
- `get_idle_bots()` — 유휴 봇 목록
- `is_bot_available(bot_id)` — 봇 가용 여부
- `get_team_status(team_id)` — 팀 상태 문자열 (작업중/봇점유/유휴)
- `get_bot_occupation()` — 논리적 팀의 물리 봇 점유 탐지
- `suggest_team(task_desc)` — 키워드 기반 팀 추천
- `validate_routing(team_id, task_desc, override_routing)` — 라우팅 검증

## 설계 결정

1. **Backward Compatibility**: dispatch.py, whisper-compile.py의 기존 함수 시그니처를 유지하고 내부에서 BotStatusManager로 위임. import 실패 시 기존 로직 fallback.
2. **Dependency Injection**: `BotStatusManager(workspace_root=..., task_timers=...)` 생성자로 테스트 격리 지원. whisper-compile.py는 이미 로드된 task_timers를 주입.
3. **3단계 Config Fallback**: org_loader → ConfigManager → constants.json 직접 읽기
4. **constants.json의 `logical_teams` 키**: 이미 존재하는 키를 그대로 활용 (신규 키 추가 불필요)

## 테스트 결과

- `utils/tests/test_bot_status.py`: 27 passed (0.11s)
- `tests/test_dispatch_routing.py`: 18 passed (0.13s)
- `scripts/tests/test_whisper_compile.py`: 94 passed (0.36s)
- **총 139 passed, 0 failed**

## 발견 이슈 및 해결

### 자체 해결 (3건)
1. **BotStatusManager에 workspace_root 파라미터 누락** — 테스트 격리를 위해 `__init__(workspace_root=None)` 추가
   - `utils/bot_status.py:135` 생성자에 `workspace_root` 파라미터 추가
2. **whisper-compile.py에서 BotStatusManager가 실 파일을 읽어 테스트 격리 깨짐** — `task_timers` 주입 파라미터 추가
   - `utils/bot_status.py:139` `task_timers` keyword-only 파라미터 추가
3. **validate_routing 메시지 포맷 불일치** — dispatch.py에서 CLI 스타일(`--override-routing`)로 변환 레이어 추가
   - `dispatch.py:1084-1088` 메시지 변환 코드

## 모델 사용 기록

- 카르티케야 / BotStatusManager 모듈 생성 / sonnet
- 카르티케야 / dispatch.py 리팩토링 / sonnet
- 카르티케야 / whisper-compile.py 리팩토링 / sonnet
- 하누만 / BotStatusManager 테스트 작성 / sonnet
