# task-1971 완료 보고서: dispatch.py 봇 lazy start 문제 수정 + 시스템3문서 업데이트

## SCQA

**S**: dispatch.py는 cokacdir --cron으로 봇에 작업을 위임하며, 현재 10초 딜레이 후 전송하는 방식으로 운영 중이다.

**C**: 서버/cokacdir 재부팅 후 봇의 Claude 세션이 lazy start(첫 수동 메시지 수신 시에만 시작)되어 cron 메시지가 소실됨. 수동으로 봇에 메시지를 보내야만 이후 정상 동작.

**Q**: dispatch 전 봇 세션 상태를 확인하고 자동 wake-up하여 메시지 소실을 방지할 수 있는가?

**A**: `_check_bot_process()`로 pgrep 기반 봇 프로세스 확인 + `_wake_up_bot()`으로 빈 ping 메시지 전송 + 딜레이 자동 확대(10초→30초) 로직을 구현. dispatch()와 _dispatch_composite() 양쪽에 적용. pytest 179건 전체 통과, 시스템3문서 3개 파일 업데이트 완료.

---

## 수정 파일 목록

| 파일 | 변경 내용 | grep 검증 | 상태 |
|------|-----------|-----------|------|
| dispatch.py:1219 | `_check_bot_process()` 함수 추가 (pgrep -f 기반) | grep "def _check_bot_process" OK | verified |
| dispatch.py:1244 | `_wake_up_bot()` 함수 추가 (ping + polling 대기) | grep "def _wake_up_bot" OK | verified |
| dispatch.py:2181 | _dispatch_composite()에 wake-up 로직 삽입 | grep "lazy-start.*composite" OK | verified |
| dispatch.py:2957 | dispatch()에 wake-up 로직 삽입 | grep "lazy-start.*dispatch" OK | verified |
| tests/test_dispatch.py:121 | dispatch_mod fixture에 _check_bot_process mock 추가 | grep "_check_bot_process.*lambda" OK | verified |
| memory/plans/cross-verification-workflow/plan.md | 5.6절 봇 Lazy Start 대응 추가 | grep "5.6 봇 Lazy Start" OK | verified |
| memory/plans/cross-verification-workflow/context-notes.md | 2026-04-20 발견/원인/해결 기록 추가 | grep "2026-04-20.*Lazy Start" OK | verified |
| memory/plans/cross-verification-workflow/checklist.md | 봇 Lazy Start 대응 항목 추가 | grep "봇 Lazy Start 대응" OK | verified |

---

## 테스트 결과

- **pytest**: 179 passed in 18.21s (tests/test_dispatch.py)
- **L1 스모크테스트**:
  - `_check_bot_process('nonexistent')` → False ✅
  - `_check_bot_process('')` → False ✅
  - `get_dispatch_time(10/30)` → 정상 시간 반환 ✅

## L1 스모크테스트 결과
- 서버 재시작: 해당없음 (CLI 도구)
- API 응답 확인: 해당없음 (CLI 도구)
- 스크린샷: 해당없음

---

## 발견 이슈 및 해결

1. **_check_bot_process `ps aux` 오탐**: 초기 구현에서 `ps aux` + `key_hash in stdout` 방식을 사용했으나, 호출 프로세스 자체가 `ps aux` 출력에 포함되어 항상 True를 반환하는 오탐 발생. → `pgrep -f "cokacdir.*{key_hash}"` 방식으로 수정하여 해결.
2. **테스트 시간 초과**: wake-up 로직의 `time.sleep(5)` × 5 = 25초 대기가 기존 테스트마다 발생하여 전체 테스트 시간이 급증. → dispatch_mod fixture에서 `_check_bot_process = lambda key: True`로 패치하여 wake-up을 생략하도록 해결.
3. **test_dispatch_cokacdir_cmd_has_timeout_60 실패**: wake-up ping 호출(timeout=30)이 메인 dispatch 호출(timeout=60)과 혼동됨. → 루가 테스트에서 "." 메시지를 필터링하는 조건 추가로 해결.

---

## 모델 사용 기록

| 팀원 | 역할 | 모델 | 정당성 |
|------|------|------|--------|
| 루(Lugh) | 백엔드: dispatch.py 코드 구현 | sonnet | 일반 코딩/로직 구현 |
| 브리짓(Brigid) | 문서: 시스템3문서 업데이트 | sonnet | 문서 작업 |
| 다그다(Dagda) | 팀장: 설계/검증/통합 | opus | 판단/검토 |

---

## 셀프 QC 체크리스트

- [x] 1. 영향 파일: dispatch.py, tests/test_dispatch.py, 3문서 3개
- [x] 2. 엣지 케이스: 빈 key, 존재하지 않는 프로세스, wake-up 타임아웃
- [x] 3. 작업 지시 일치: 4개 수정 범위 모두 완료 (wake-up, 프로세스 확인, 경고 로그, 3문서)
- [x] 4. 에러 처리: subprocess 예외 시 False 반환, wake-up 실패 시 딜레이 확대
- [x] 5. 테스트: 179건 전체 PASS
- [x] 6. 이슈 모두 해결: 3건 발견, 3건 해결
- [x] 7. 코드 아키텍처: 기존 dispatch 패턴 유지, 새 함수 2개 추가
- [x] 8. 인터페이스 변경 없음
- [x] 13. L1 스모크테스트 완료

## 2차 검증 (2026-04-20, dev3 다그다)

### 추가 테스트 실행 결과
- `test_dispatch.py`: **179 passed** (17.39s)
- 8개 추가 테스트 파일 (`test_dispatch_gate.py`, `test_dispatch_routing.py`, `test_dispatch_phase_warn.py`, `test_dispatch_resume.py`, `test_dispatch_task_docs.py`, `test_dispatch_workflow.py`, `test_dispatch_memory_check.py`, `test_dispatch_platform_rules.py`): **117 passed** (1.68s)
- **총 296 테스트 전체 PASS**

### 3차 전체 검증 (2026-04-20)
- `pytest tests/` 전체 실행: **2366 passed** in 102.54s
- 기존 로직 변경 없음 확인, 모든 기존 테스트 정상 통과

### 시스템3문서 업데이트 (2026-04-20)
- **plan.md**: Section 5.6 + Section 10 "dispatch.py 봇 lazy start 대응 (task-1971)" 신규 추가
- **context-notes.md**: "2026-04-20 dispatch.py 봇 Lazy Start 문제 발견 및 해결 (task-1971)" 기록 완료
- **checklist.md**: "봇 Lazy Start 대응 — ✅ 완료 (task-1971, 2026-04-20)" 항목 8개 전부 [x] 체크 완료

