# task: bot-activity.json since 타임스탬프 버그 수정 (v2)

## 문제 현상
bot-activity.json의 since 필드가 전혀 갱신되지 않음.
현재 시간: 2026-03-17 10:05 인데 since 값이 전부 2026-03-16 (어제).
- dev1: since 2026-03-16T18:08:00Z → 실제 task-635.1 완료 오늘 09:38
- dev2: since 2026-03-16T20:12:00Z → 실제 task-633.1 완료 오늘 09:25
- dev3: since 2026-03-16T23:01:00Z → 실제 task-634.1 완료 오늘 09:50

## 근본 원인 (아누가 분석 완료)

### activity-watcher.py의 구조적 결함
`activity-watcher.py`가 `processing → idle` 상태 전환을 감지해서 `update_bot_since()`를 호출하는 구조.
**그러나 아무도 bot-activity.json의 status를 "processing"으로 변경하지 않음:**
- dispatch.py: status 필드를 쓰지 않음
- notify-completion.py: status 필드를 쓰지 않음
- finish-task.sh: status 필드를 쓰지 않음
- cokacdir: bot-activity.json에 관여하지 않음

결과: status는 항상 "idle" → `processing → idle` 전환이 절대 발생 안 함 → `update_bot_since()` 절대 호출 안 됨 → since 영원히 갱신 안 됨.

## 수정 방안

### 방안 A: 양쪽에서 status 직접 기록 (권장)
1. **dispatch.py**: 위임 성공 시 bot-activity.json의 해당 봇 status를 "processing"으로 변경
2. **notify-completion.py**: 작업 완료 시 bot-activity.json의 해당 봇 status를 "idle"로 변경 + since를 현재 UTC로 갱신

이렇게 하면:
- dispatch → processing 기록
- 완료 → idle + since 갱신
- activity-watcher의 전환 감지도 자연스럽게 동작

### 구현 상세

#### 1. 공통 헬퍼 함수 작성 (새 파일 또는 기존 utils에 추가)
```python
# utils/bot_activity.py (또는 적절한 위치)
import json
from pathlib import Path
from datetime import datetime, timezone

BOT_ACTIVITY_FILE = Path("/home/jay/workspace/memory/events/bot-activity.json")

TEAM_TO_BOT = {
    "dev1-team": "dev1",
    "dev2-team": "dev2",
    "dev3-team": "dev3",
}

def set_bot_status(team_id: str, status: str) -> None:
    """bot-activity.json의 봇 status와 since를 갱신"""
    bot_name = TEAM_TO_BOT.get(team_id)
    if not bot_name:
        return

    try:
        data = json.loads(BOT_ACTIVITY_FILE.read_text()) if BOT_ACTIVITY_FILE.exists() else {"bots": {}}
        if bot_name not in data.get("bots", {}):
            data.setdefault("bots", {})[bot_name] = {}

        data["bots"][bot_name]["status"] = status
        data["bots"][bot_name]["since"] = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")

        BOT_ACTIVITY_FILE.write_text(json.dumps(data, indent=2, ensure_ascii=False))
    except Exception:
        pass  # 실패해도 작업 진행에 영향 없음
```

#### 2. dispatch.py에 호출 추가
위임 성공 직후 (`result.returncode == 0` 블록 안):
```python
set_bot_status(team_id, "processing")
```

#### 3. notify-completion.py에 호출 추가
task-timer end 호출 후:
```python
# team_id는 task-timers.json에서 조회하거나 .done 파일에서 추출
set_bot_status(team_id, "idle")
```

#### 4. 기존 activity-watcher.py의 update_bot_since()
- 유지 (백업 매커니즘으로). 혹시 다른 경로로 processing→idle 전환이 발생하면 그때도 since 갱신.
- 기존 로직 삭제하지 말 것.

## 조사 대상 파일
1. `/home/jay/workspace/dispatch.py` — 위임 성공 후 set_bot_status("processing") 추가
2. `/home/jay/workspace/scripts/notify-completion.py` — 완료 시 set_bot_status("idle") 추가
3. `/home/jay/workspace/scripts/activity-watcher.py` — 기존 로직 유지 (삭제 금지)
4. `/home/jay/workspace/memory/events/bot-activity.json` — 현재 상태 확인

## 추가 확인
- notify-completion.py에서 team_id를 어떻게 가져올지 확인 필요
  - task-timers.json에서 task_id로 team_id 조회 가능
  - 또는 .done 파일 내용에서 team_id 추출 가능

## 검증
1. 수정 후 dispatch.py 호출 시 bot-activity.json status가 "processing"으로 바뀌는지
2. notify-completion.py 호출 시 status가 "idle"로 + since가 현재시간으로 바뀌는지
3. 기존 테스트 회귀 없음: `pytest tests/test_dispatch.py tests/test_chain_manager.py scripts/tests/test_activity_watcher.py scripts/tests/test_notify_completion.py -v`
4. 신규 테스트: set_bot_status 함수 단위 테스트

## 산출물
- 수정된 코드: dispatch.py, notify-completion.py, (신규) utils/bot_activity.py
- 테스트: 기존 + 신규 (모두 통과)
- 보고서: `memory/reports/<task_id>.md`

## 작업 레벨: Lv.2 (다중 파일 수정 + 설계)
