# task-87.1 완료 보고서: dispatch.py 재발 방지 로직 구현

**담당**: 헤르메스 (Hermes) - 개발1팀장
**팀원**: 불칸(백엔드), 아르고스(테스터)
**완료일시**: 2026-03-02

---

## 1. 작업 요약

task-75.1 봇D 수신 실패 재발 방지를 위한 4건의 안전장치를 dispatch.py와 task-timer.py에 구현.

---

## 2. 구현 항목

### 항목 1: dispatch 전 팀 가용성 확인
- dispatch() 함수에서 task_id 생성 전 task-timers.json 검사
- 해당 팀에 status=running 작업이 있으면 에러 반환
- --force 옵션으로 강제 위임 가능 (경고 출력 후 진행)
- 출력: `{"status":"error","message":"<team>에 running 작업(<task_id>)이 있습니다. --force로 강제 위임 가능"}`

### 항목 2: 이중 위임 방지 중복 검사
- running/reserved 작업의 description 첫 60자와 비교
- 프롬프트 본문에 기존 task_id가 포함되어 있는지 확인
- generate_task_id() 후 team_id/description을 reserved 엔트리에 보강 등록 (다음 dispatch 때 중복 감지 가능)
- --force로 무시 가능

### 항목 3: reserved 상태 타임아웃 감지
- TaskTimer.check_reserved(timeout_seconds=300) 메서드 추가
- CLI: `python3 task-timer.py check-reserved [--timeout 300]`
- 출력: `{"status":"warning","stale_tasks":[{"task_id":"...","reserved_at":"...","age_seconds":...}]}`
- 실제 데이터 검증: task-43.1, task-45.1, task-75.1 총 3건 stale 감지 확인

### 항목 4: cron_id / expected_execution 포함
- dispatch 성공 결과에 `cron_id`, `expected_execution` 필드 추가
- cokacdir 응답의 "id" 필드에서 cron_id 추출
- --verify 옵션 시 `verify_note` 필드 추가: "cokacdir --cron-list에서 해당 cron_id 소비 여부 확인 가능"

---

## 3. 생성/수정 파일 목록

- **/home/jay/workspace/dispatch.py** — 수정 (항목 1, 2, 4)
  - dispatch() 시그니처: force, verify 파라미터 추가
  - 팀 가용성 확인 로직 (175~196행)
  - 이중 위임 방지 로직 (198~224행)
  - reserved 엔트리 보강 (229~242행)
  - cron_id/expected_execution 결과 포함 (270, 281~308행)
  - argparse에 --force, --verify 옵션 추가

- **/home/jay/workspace/memory/task-timer.py** — 수정 (항목 3)
  - TaskTimer.check_reserved() 메서드 추가 (172~198행)
  - CLI check-reserved 서브커맨드 추가 (535~550행)
  - Usage 도움말 업데이트 (427행)

- **/home/jay/workspace/teams/dev1/test_dispatch_safeguards.py** — 신규 (테스트)

---

## 4. 테스트 결과

**21/21 PASSED** (0.14s)

- TestTeamAvailability: 4건 (running 차단, force 우회, completed 통과, 파일 없음 통과)
- TestDoubleDispatchPrevention: 4건 (description 중복, reserved 중복, task_id 포함, force 강제)
- TestCheckReserved: 4건 (stale 감지, 신선 ok, reserved_at 없음, CLI 실행)
- TestDispatchResultFields: 5건 (cron_id, expected_execution, verify_note 포함 여부)
- TestTaskTimerImport: 4건 (TaskTimer 통합 테스트)

---

## 5. 하위 호환성

- dispatch() 함수의 기존 파라미터와 반환 구조 100% 유지
- 새 파라미터(force, verify)는 기본값 False로 기존 호출에 영향 없음
- 반환 dict에 cron_id, expected_execution 추가 (기존 필드 유지)
- task-timer.py 기존 start/end/log/status/list 기능 무변경

---

## 6. 버그

발견된 버그 없음.

---

## 7. 비고

- 실제 운영 데이터로 check-reserved 검증 시, stale reserved 3건 감지 확인 (task-43.1, task-45.1, task-75.1)
- 이중 위임 방지는 description 첫 60자 비교 + task_id 참조 검사의 2중 체크로 구현
- generate_task_id()가 team_id/description을 모르므로, dispatch()에서 reserved 엔트리에 보강 등록하여 다음 dispatch 호출 시 중복 감지 가능하도록 설계
