# 고스트 태스크 추가 수정 — 3팀(Sonnet) 분석 기반

## 배경
2팀(Opus) 분석으로 6건 수정 완료 (task-485.1).
3팀(Sonnet) 분석에서 추가 발견한 2건이 미반영 상태.
3팀 보고서: /home/jay/workspace/memory/reports/task-482.1.md

## 수정 항목 (2건)

### 수정 A [HIGH]: test_dispatch.py 테스트 격리 — subprocess.run 모킹 추가

**이것이 고스트 태스크의 실제 트리거!**
test_dispatch.py의 4개 테스트가 subprocess.run을 모킹하지 않아 REAL task-timer.py가 실행됨.
→ 프로덕션 task-timers.json에 task-1.1, task-4.1이 running으로 직접 기록됨.

파일: `/home/jay/workspace/tests/test_dispatch.py`

수정할 테스트 4개:
1. `test_dispatch_nonexistent_project` (line ~551) — subprocess mock 없음 → task-1.1 생성
2. `test_dispatch_no_bot_key` (line ~558) — subprocess mock 없음 → task-1.1 생성
3. `test_dispatch_bot_key_none_exits` (line ~565) — subprocess mock 없음 → task-1.1 생성
4. `test_marketing_all_bots_busy_returns_error` (line ~1143) — subprocess mock 없음 → task-4.1 생성

수정 방법 (각 테스트에 subprocess mock 추가):
```python
# 예시
with (
    patch.object(dispatch_mod, "subprocess") as mock_sub,
    patch.object(dispatch_mod, "BOT_KEYS", {"dev1": "key1", "anu": "anu-key"}),
):
    mock_sub.run.return_value = MagicMock(returncode=0, stdout="{}", stderr="")
    result = dispatch_mod.dispatch(...)
```

또는 대안: `_load_dispatch_with_workspace()` fixture에서 TASK_TIMER 변수도 패치:
```python
_dispatch.TASK_TIMER = str(tmp_path / "memory" / "task-timer.py")
```
→ 실제 task-timer.py 대신 존재하지 않는 경로를 가리키게 하여 subprocess 실행 무력화

### 수정 B [MEDIUM]: task-timer.py start_task() — stale 상태 보호 추가

파일: `/home/jay/workspace/memory/task-timer.py`
위치: `start_task()` 함수, completed 가드 바로 아래

현재: completed만 거부, stale은 통과 → running으로 재전환됨
수정: stale도 거부

```python
# completed 가드 아래에 추가:
if existing and existing.get("status") == "stale":
    logger.warning(f"stale task 재시작 시도 거부: {task_id}")
    return {"status": "error", "reason": f"task_id '{task_id}' is in stale state. Use a new ID."}
```

## 테스트
- 수정 A: 해당 4개 테스트가 프로덕션 task-timers.json을 오염하지 않는지 확인
  - 테스트 실행 전후 task-timers.json diff → 변경 없어야 함
- 수정 B: stale 상태 task에 start 호출 시 거부되는지 단위 테스트 추가
- 기존 전체 테스트 PASS
- pyright 에러 0건

## 문서화
- `/home/jay/workspace/memory/reports/{task_id}.md`에 수정 내용 기록
- 2팀 + 3팀 분석을 통합한 최종 정리 포함

## 주의
- dashboard/ 파일 건드리지 마세요
- task-485.1에서 수정한 코드를 되돌리지 마세요 (추가만)
