# task-2029: done-watcher.py에 .failed 패턴 추가

## S - Situation
task-2028에서 finish-task.sh가 QC FAIL 시 `.failed` 이벤트 파일을 생성하도록 구현 완료. done-watcher.py는 `.done` 파일만 감시하는 상태였다.

## C - Complication
QC FAIL 시 `.failed` 파일이 생성되지만, 아누(개발실장)에게 알림이 전달되지 않아 FAIL 상태를 수동 확인해야 했다.

## Q - Question
done-watcher.py가 `.failed` 파일도 감지하여 아누에게 자동 FAIL 알림을 전송할 수 있는가?

## A - Answer
done-watcher.py에 `.failed` 파일 스캔/처리 로직과 Telegram 알림 전송 함수를 추가. 메시지 포맷 `[QC FAIL] task-XXXX — {fail_reason}`, 처리 후 `.failed.acked`로 rename하여 중복 알림 방지. 기존 `.done` 감지 기능은 정상 유지. pytest 16건 전체 PASS, 문법 검증 PASS.

## 수정 파일

| 파일 | 변경 내용 | grep 검증 | 상태 |
|------|-----------|-----------|------|
| scripts/done-watcher.py:49 | send_telegram_notification() 함수 추가 | grep "send_telegram_notification" 3건 OK | verified |
| scripts/done-watcher.py:257 | scan_failed_files() 함수 추가 | grep "scan_failed_files" 2건 OK | verified |
| scripts/done-watcher.py:273 | process_failed_files() 함수 추가 | grep "process_failed_files" 4건 OK | verified |
| scripts/done-watcher.py:306 | run_once()에 failed 처리 호출 추가 | grep "failed_processed" OK | verified |
| scripts/done-watcher.py:315 | run_daemon()에 failed 처리 호출 추가 | grep "failed_processed" OK | verified |
| scripts/done-watcher.py:334 | main() docstring 업데이트 | grep ".failed 파일 감시" OK | verified |
| tests/test_done_watcher.py | .failed 관련 테스트 7건 추가 | grep "TestScanFailedFiles" OK | verified |

## 완료 시그니처 검증
- [grep] `\.failed|failed.*pattern` @ `scripts/done-watcher.py` → 11건 매칭 OK
- [grep] `send_telegram_notification` @ `scripts/done-watcher.py` → 3건 매칭 OK

## 테스트 결과
- `tests/test_done_watcher.py`: 16건 PASS (기존 9건 + 신규 7건, 회귀 없음)
- `python3 -c "import ast; ast.parse(...)"`: 문법 검증 PASS
- 수동 통합 테스트:
  - scan_failed_files() 빈 상태 → 정상 반환
  - .failed 파일 생성 → scan_failed_files() 감지 OK
  - .failed.acked 마커 존재 → 제외 OK
  - scan_done_files() 기존 기능 정상 동작 확인

## 검증 시나리오
1. .failed 파일 수동 생성 → scan_failed_files() 감지 → OK
2. .failed.acked 마커 존재 → 중복 감지 방지 → OK
3. 기존 .done 감지 정상 동작 유지 → 테스트 9건 PASS
4. ANU_BOT_TOKEN 미설정 시 알림 스킵, .failed 파일 미rename → OK
5. JSON 파싱 실패 시 건너뜀 → OK
6. 알림 성공 시 .failed → .failed.acked rename → OK

## L1 스모크테스트
- 서버 재시작: 해당없음 (데몬 스크립트, 서버 아님)
- API 응답 확인: 해당없음
- 스크린샷: 해당없음
- ast.parse 문법 검증: PASS
- pytest 16건: PASS

## 발견 이슈 및 해결

### 자체 해결 (2건)
1. **미사용 sys import (done-watcher.py)** — Pyright 경고. `import sys` 제거 (파일 내 사용처 없음).
2. **미사용 import (test_done_watcher.py)** — 기존 테스트에 미사용 `os`, `tempfile`, `datetime`, `timedelta`, `timezone` import 존재. 정리 완료.

### 범위 외 미해결 (1건)
1. **test_qc_gate.py 실패 3건** — 범위 외 사유: task-2028에서 qc_verify.py의 `.done` 생성 로직 제거로 인한 기존 테스트 불일치. test_qc_gate.py는 `.done` 파일 생성을 assert하나 현재 finish-task.sh만이 `.done`을 생성하므로 테스트 업데이트 필요. 본 작업(done-watcher.py)과 무관.

## 모델 사용 기록
- 팀원: 토르(Thor) / 작업 내용: done-watcher.py .failed 패턴 + 알림 구현 / 사용 모델: sonnet / 정당성: -
- 팀원: 헤임달(Heimdal) / 작업 내용: test_done_watcher.py 테스트 7건 추가 / 사용 모델: sonnet / 정당성: -

## 머지 판단
- **머지 필요**: No (시스템 작업, 프로젝트 worktree 미사용)
- **브랜치**: N/A (main 직접 수정)

## 세션 통계
- 총 도구 호출: 0회

