# task-566.2 완료 보고서: Phase 2 위스퍼 비서 핵심 구현

**S**: 마스터 프로젝트 Phase 1(기반 구축) 완료 후, 파일 기반 위스퍼 비서 시스템(AI 토큰 0원)을 구현하여 아누의 매 프롬프트마다 팀 상태/완료 작업/프로젝트 진척/세션 가이던스를 자동 브리핑해야 한다.

**C**: 현재 아누는 .done 파일, bot-activity.json, task-timers.json, 보고서를 각각 수동으로 읽어 상황을 파악하고 있어 세션당 5~15K 토큰이 낭비되고, 세션 간 컨텍스트가 소실된다.

**Q**: 파일 기반 스크립트 2개 + hook 수정으로 아누 세션의 상태 인식을 자동화하고 세션 간 연속성을 확보할 수 있는가?

**A**: whisper-compile.py(14.9KB, 9개 함수) + whisper-save-guidance.py(7.5KB, 6개 함수) 구현 + hook 2개 수정 + 양방향 질문 채널 구축 완료. 테스트 80건 전부 통과, pyright 에러 0건, black/isort 준수. 아누 hook 통합 테스트에서 XML 브리핑 정상 주입 확인.

---

## 작업 상세

### 2-1. whisper-compile.py
**파일**: `/home/jay/workspace/scripts/whisper-compile.py` (14,986 bytes)

구현 함수 9개:
- `load_bot_activity()`: bot-activity.json에서 팀 상태 추출 (dev1→1팀 매핑)
- `load_task_timers()`: running 작업 + 24시간 이내 completed 작업 필터링
- `scan_done_files()`: *.done 스캔 (*.done.clear 제외)
- `extract_report_scqa()`: 보고서 SCQA 첫 4줄 정규식 추출
- `load_guidance()`: session-guidance.json 이전 세션 가이던스 로드
- `load_project_context()`: CWD 기반 프로젝트 context.md 로드
- `load_questions()`: questions/*.json 미응답 질문 로드
- `detect_idle_teams()`: 3시간 이상 유휴 팀 감지
- `compile_briefing()`: 전체 XML 브리핑 조합 + stdout 출력

CLI: `python3 whisper-compile.py [CWD]`
모든 함수 `base_dir` 파라미터 지원 (테스트 격리용)

### 2-2. whisper-save-guidance.py
**파일**: `/home/jay/workspace/scripts/whisper-save-guidance.py` (7,471 bytes)

구현 함수 6개:
- `load_bot_activity()`: 유휴 팀 목록 추출
- `load_task_timers()`: active(running) 작업 목록
- `scan_done_files()`: 미처리 완료 작업
- `generate_guidance()`: 가이던스 텍스트 자동 생성
- `save_guidance()`: session-guidance.json 저장
- `run()`: 전체 파이프라인 실행

CLI: `python3 whisper-save-guidance.py` (인자 없음)

### 2-3. Hook 수정
**user-prompt-submit.sh** (수정):
- 아누 케이스 최상단에 `whisper-compile.py "$CWD"` 호출 추가
- 기존 .done 체크, 이벤트 큐, pending-actions 로직 보존
- 실패 시 `2>/dev/null || true`로 graceful 처리

**stop-qc-reminder.sh** (수정):
- 아누 케이스에 `whisper-save-guidance.py &` 백그라운드 호출 추가
- 기존 봇 idle 기록 로직 보존

### 2-4. 양방향 대화 채널 (Letta #4)
- `memory/events/questions/` 디렉토리 생성 완료
- 팀장 질문 JSON 형식: `{"from":"hermes","question":"...", "task_id":"task-565"}`
- whisper-compile.py가 questions/*.json 감지 → 브리핑 [질문] 섹션에 포함
- 응답 후 `.answered`로 rename하면 다음 브리핑에서 제외

### 2-5. 테스트
**테스트 파일 2개, 총 80건 PASS**:

`scripts/tests/test_whisper_compile.py` (50건):
- TestEmptyState: 8건 (모든 파일 없을 때 graceful 처리)
- TestBotActivity: 5건 (JSON 로드 + 손상 처리)
- TestTaskTimers: 4건 (running/completed 필터링)
- TestDoneFiles: 4건 (.done 스캔 + .done.clear 제외)
- TestReportSCQA: 5건 (SCQA 추출 정확성)
- TestGuidance: 4건 (session-guidance.json 로드)
- TestQuestions: 5건 (질문 파일 + .answered 제외)
- TestIdleTeams: 6건 (3시간 유휴 탐지)
- TestProjectContext: 4건 (cwd 기반 프로젝트 context)
- TestFullBriefing: 5건 (전체 XML 통합 테스트)

`scripts/tests/test_whisper_save_guidance.py` (30건):
- TestLoadBotActivity: 4건
- TestLoadTaskTimers: 4건
- TestScanDoneFiles: 4건
- TestGenerateGuidance: 8건
- TestSaveGuidance: 4건
- TestIntegration: 6건

---

## 생성/수정 파일 목록

- **신규** `scripts/whisper-compile.py` — 위스퍼 브리핑 컴파일러 (14,986 bytes)
- **신규** `scripts/whisper-save-guidance.py` — 세션 가이던스 저장 (7,471 bytes)
- **신규** `scripts/tests/test_whisper_compile.py` — 단위/통합 테스트 50건
- **신규** `scripts/tests/test_whisper_save_guidance.py` — 단위/통합 테스트 30건
- **신규** `memory/whisper/session-guidance.json` — 런타임 생성 (가이던스 저장소)
- **신규** `memory/events/questions/` — 양방향 대화 채널 디렉토리
- **수정** `~/.claude/hooks/user-prompt-submit.sh` — 아누 케이스에 whisper-compile.py 호출 추가
- **수정** `~/.claude/hooks/stop-qc-reminder.sh` — 아누 케이스에 whisper-save-guidance.py 호출 추가

---

## 검증 결과

- pytest: 80/80 PASS (0.15s)
- pyright: 0 errors, 0 warnings
- black + isort: OK
- Hook 통합 테스트: 아누 CWD에서 XML 브리핑 정상 주입 확인
- 실제 데이터 테스트: bot-activity.json + task-timers.json 기반 브리핑 생성 확인

⚠️ 기존 테스트 실패 3건 (본 작업 범위 외):
- `test_notify_completion.py::TestBuildPrompt::test_prompt_length_under_120_chars` — 프롬프트 길이 289자 > 120자 제한
- `test_notify_completion.py::TestMainWithMock::test_main_calls_cokacdir` — COKACDIR_KEY_ANU 환경변수 미설정
- `test_notify_completion.py::TestMainWithMock::test_main_custom_chat_id` — 동일 환경변수 문제

---

## 발견된 이슈 (Zero Issue Red Flag 방지)

1. **유휴 경고 시간 정확도**: bot-activity.json의 `since` 필드가 UTC이고 task-timers.json의 `start_time`은 로컬 시간대인 경우 시간 계산이 불일치할 수 있음. 현재 UTC 기준으로 통일하여 처리 중이나, 로컬 환경에서 시간대 설정이 다르면 유휴 시간 오차 발생 가능.

2. **whisper-compile.py 아누 상태 표시**: 아누가 hook을 실행하는 시점에는 bot-activity.json이 이미 processing으로 갱신되어 있으므로 아누 자신은 항상 "processing"으로 표시됨. 아누 자신의 상태는 브리핑에서 제외하는 것이 더 자연스러울 수 있음.

3. **보고서 SCQA 추출 한계**: SCQA 형식이 아닌 보고서(예: `**S**:` 패턴 없음)는 빈 요약으로 처리됨. 전체 보고서 중 SCQA 미준수 비율 미확인.

4. **Hook 실행 시간**: whisper-compile.py가 많은 파일을 읽는 경우 실행 시간이 300~500ms까지 증가할 수 있으나, 10초 타임아웃 이내이므로 영향 미미.

---

## QC 자동 검증

```json
{
  "task_id": "task-566.2",
  "overall": "PASS (조건부)",
  "checks": {
    "api_health": "SKIP (서버 작업 아님)",
    "file_check": "PASS (보고서 + .done 생성 완료)",
    "data_integrity": "PASS (task-566.2 running→done)",
    "test_runner": "WARN (기존 실패 3건 — test_notify_completion.py, 본 작업 범위 외)",
    "tdd_check": "PASS (테스트 파일 2개 + 구현 파일 2개, TDD 순서 준수)",
    "pyright_check": "PASS (0 errors, 0 warnings)",
    "style_check": "PASS (black OK, isort OK)",
    "scope_check": "SKIP"
  }
}
```

---

## 다음 Phase

- **다음 Phase 지시서**: `memory/tasks/task-566.3.md`
- **내용**: Phase 3 gstack 코드 구현 (A1/A2/A4/A7/A13/A15/A17, 7개 항목)
- **한정승인**: 아누 승인 대기 없이 즉시 진행

---

*작성: 헤르메스 (개발1팀장) | task-566.2 | 2026-03-15*
