# task-1369.1 완료 보고서: dispatch.py opus 모델 강제 적용 + 배너 재실행

## SCQA

**S**: dispatch.py의 `model_router`가 작업별 권장 모델을 분석하지만, 결과를 로그에만 기록하고 실제 봇 선택에 반영하지 않는다. 동적 봇 선택(design/marketing 팀) 시 dev8(Ra) 봇이 선택되면 sonnet으로 실행되어, image-qc-gate 워크플로우에서 로키의 DQ 평가가 sonnet으로 수행된다.

**C**: 제이회장님 직접 지적. opus로 실행되어야 할 DQ 평가가 sonnet으로 진행되어 품질 저하 + 토큰 낭비 + 보고서에 "opus" 거짓 기록 발생. bot_settings.json 확인 결과 9개 봇 중 dev8(Ra)만 `claude-sonnet-4-6`, 나머지 8개는 `claude-opus-4-6`.

**Q**: image-qc-gate 워크플로우 및 명시적 모델 지정 시 해당 모델의 봇만 선택하도록 dispatch.py를 수정할 수 있는가?

**A**: `bot_settings.json` 기반 모델 필터링 기능을 `_find_available_bot()`에 추가하여 해결. image-qc-gate 워크플로우 시 자동으로 `--model claude-opus-4-6`을 강제 적용. 기존 테스트 149/149 통과, Batch B/C 재위임 완료.

## 수정 내용

### dispatch.py 변경 (5개 수정 포인트)

1. **`_read_bot_models()` 신규 함수**: `~/.cokacdir/bot_settings.json`에서 {key_hash: model_name} 맵 반환
2. **`_find_available_bot(required_model)`**: 모델 필터링 파라미터 추가. BOT_TO_DEFAULT_TEAM → TEAM_BOT → BOT_KEYS 역추적으로 봇별 모델 확인
3. **`dispatch()` 함수**: `model` 파라미터 추가, 명시적 model 지정 시 봇 필터링 적용, timer metadata에 model 기록
4. **`_dispatch_composite()` 함수**: 동일 패턴으로 `model` 파라미터 추가
5. **CLI `__main__`**: `--model` 인자 추가, image-qc-gate 시 자동 opus 강제

### 설계 핵심 판단

- **model_router 추천 vs 명시적 지정 분리**: model_router의 추천은 로깅만 (기존 동작 유지), 봇 필터링은 `--model` 명시 또는 image-qc-gate 자동 적용 시에만 활성화. 이유: model_router가 모든 동적 팀 dispatch에서 봇 필터링을 하면 테스트 환경에서 bot_settings.json이 없어 전체 실패.
- **graceful fallback**: bot_settings.json 읽기 실패 시 빈 dict → 필터링 없이 기존 동작
- **하위 호환**: 모든 새 파라미터 기본값 None → 기존 코드 수정 불필요

## 배너 재실행 결과

- **Batch B** (task-1360 재실행): task-1370.1 → bot-c (claude-opus-4-6) ✅, design팀 아마테라스에게 위임
- **Batch C** (task-1361 재실행): task-1372.1 → bot-d (claude-opus-4-6) ✅, design팀 아마테라스에게 위임
- 기존 task-1360.1, task-1361.1 결과물 보존 (비교용)

## 발견 이슈 및 해결

### 자체 해결 (3건)

1. **model_router 추천이 봇 필터링을 과도하게 적용** — 명시적 `model` 파라미터와 model_router 추천을 분리하여 봇 필터링은 명시적 지정 시에만 적용
   - 상세: dispatch.py:1153에서 `required_model=model` (명시적 파라미터)만 전달, `_recommended_model` (model_router 결과)은 로깅용
2. **테스트 환경에서 bot_settings.json 부재로 모델 맵 구축 실패** — `_read_bot_models()` 실패 시 빈 dict 반환으로 graceful fallback
3. **Batch C 위임 시 design팀 충돌** — task-1370.1 이미 running이라 `--force` 플래그로 강제 위임 (별도 봇 bot-d 배정)

### 범위 외 미해결 (1건)

1. **test_dispatch_safeguards.py::test_2a_duplicate_description_blocks_dispatch 기존 실패** — 범위 외 사유: 중복 description 차단 로직의 기존 버그. 우리 변경과 무관 (model 관련 코드 미포함)

## 테스트 결과

- tests/test_dispatch.py: **149/149 통과** (0.79s)
- tests/test_dispatch_workflow.py: 전체 통과
- tests/test_dispatch_resume.py: 전체 통과
- teams/dev1/tests/test_dispatch_auto_timer.py: 전체 통과
- teams/dev1/tests/test_dispatch_counter_sync.py: 전체 통과
- 기존 실패 1건: test_dispatch_safeguards (본 작업 범위 외)

## 산출물

- `/home/jay/workspace/dispatch.py` (수정)

## 모델 사용 기록

- 팀원: 불칸(백엔드) / 작업 내용: dispatch.py 5개 수정 포인트 구현 / 사용 모델: sonnet / 정당성: -
- 팀장: 헤르메스 / 작업 내용: 설계, 검토, QC, 재위임 / 사용 모델: opus / 정당성: 팀장 역할
