# task-648.1 완료 보고서

**작업**: 위스퍼 봇 트래킹 수정 — stuck processing 자동 복구
**팀**: dev3-team
**완료일**: 2026-03-17

---

## SCQA

**S**: bot-activity.json에서 봇 상태가 "processing"으로 영구 고정되는 버그가 존재했다. finish-task.sh 미호출 시 idle 복귀 경로가 없어, 한 번 processing으로 바뀐 봇이 영원히 해당 상태에 머무를 수 있었다.

**C**: stuck 상태가 해소되지 않으면 dispatch.py가 해당 팀을 사용 중으로 판단해 새 작업을 배정하지 못하고, 전체 워크플로우가 멈추는 심각한 장애로 이어진다.

**Q**: 외부 개입 없이 stuck processing 상태를 자동 감지·복구할 수 있는가?

**A**: 30분 타임아웃 기반 워치독 스크립트(bot-status-watchdog.py) 신규 생성 + activity-watcher.py 메인 루프에 통합 + done-watcher.py 신규 생성으로 3중 방어망을 구축했다. pytest 62건 전체 통과, pyright 에러 0건, black/isort 준수. done-watcher.py의 `scan_done_files()` 버그 1건 자체 수정 완료.

---

## 구현 상세

### 생성/수정 파일 (4건)

| 파일 | 변경 | 내용 |
|------|------|------|
| `scripts/bot-status-watchdog.py` | 신규 | 워치독 단독 스크립트 (1회/--daemon 모드) |
| `scripts/activity-watcher.py` | 수정 | 메인 루프에 5분마다 워치독 체크 통합 |
| `scripts/done-watcher.py` | 신규 | .done 파일 감지 → bot idle 전환 |
| `scripts/notify-completion.py` | 수정 | set_bot_idle() try/except 방어 코드 강화 |

### 테스트 파일 (3건)

| 파일 | 테스트 수 |
|------|----------|
| `tests/test_bot_status_watchdog.py` | 16건 (신규) |
| `tests/test_done_watcher.py` | 14건 (신규) |
| `tests/test_activity_watcher.py` | 32건 (+6건 보강) |

---

## 발견 이슈 및 해결

### 자체 해결 (1건)

1. **done-watcher.py `scan_done_files()` 버그** — `any(Path.glob() for ext in [...])` 패턴에서 generator 객체가 항상 truthy로 평가되어 ALL .done 파일이 항상 제외되는 버그. `.exists()` 패턴으로 수정.
   - 수정: `scripts/done-watcher.py:129` — `any(EVENTS_DIR.glob(f"{done_file.name}.*") for ext in [...])` → `any((EVENTS_DIR / (done_file.name + ext)).exists() for ext in processed_exts)`

### GLM aborted 처리

GLM 세션이 `aborted: true`로 종료되어 done 파일이 미생성됨. 주요 코딩 작업(4개 파일)은 완료된 상태였으므로 라 팀장이 직접 검토 및 후속 작업(테스트 작성, 버그 수정) 수행.

### 셀프 QC 체크리스트

- [x] 1. 영향 파일: bot-status-watchdog.py, activity-watcher.py, done-watcher.py, notify-completion.py (scripts/ 범위 내)
- [x] 2. 엣지 케이스: since 파싱 실패(None 반환), 파일 없음(빈 dict), 이미 idle(스킵), 동시 쓰기(원자적 tmp→replace)
- [x] 3. 스펙 전수: 4개 작업 항목 모두 구현 (워치독 생성, activity-watcher 통합, notify-completion 방어코드, done-watcher 신규)
- [x] 4. 에러 처리: OSError 구체적 예외, set_bot_idle() try/except 강화
- [x] 5. 테스트: 62건 전체 통과, 새 기능 100% 커버
- [x] 6. 이슈 자체 해결: done-watcher 버그 1건 직접 수정

---

## 검증 결과

### pytest

```
62 passed (test_bot_status_watchdog: 16, test_done_watcher: 14, test_activity_watcher: 32)
전체 스위트: 838 passed, 0 failed
```

### pyright
```
0 errors, 0 warnings, 0 informations
```

### black/isort
```
All files: unchanged (compliant)
```

---

## QC 자동 검증 결과

```json
{
  "task_id": "task-648.1",
  "overall": "PASS",
  "summary": "7 PASS, 3 SKIP",
  "checks": {
    "api_health": "SKIP",
    "file_check": "PASS",
    "data_integrity": "PASS",
    "test_runner": "PASS (838 passed)",
    "tdd_check": "PASS",
    "schema_contract": "SKIP",
    "pyright_check": "PASS (0 errors)",
    "style_check": "PASS"
  }
}
```
