# Zero-Error Dispatch Phase 1: 확정 버그 + QC 게이트

**task_id**: task-413.1
**레벨**: Lv.2
**미팅 기록**: `memory/meetings/2026-03-09-zero-error-dispatch.md`
**계획서**: `memory/plans/zero-error-dispatch/plan.md`

---

## 작업 5개 (모두 시스템 작업, 워크스페이스: /home/jay/workspace/)

### 1-1. chain.py `--task` → `--task-file` 변경

**파일**: `/home/jay/workspace/chain.py` 193-199행 `_dispatch_phase()` 함수

**현재 코드 (버그)**:
```python
cmd = (
    f"source {ENV_KEYS} && "
    f"python3 {DISPATCH_PY} "
    f"--team {task['team']} "
    f"--task '{task['description']}' "  # ← 이 줄이 문제!
    f"--level {task['level']} "
    f"--chain {chain_id}"
)
```

**수정 방향**:
1. `task['description']`을 임시 파일에 쓴다: `memory/tasks/chain-{chain_id}-phase{n}-{team}.md`
2. `--task '{description}'` → `--task-file <파일경로>`로 교체
3. 기존 `--task` 방식은 완전 제거

**테스트**: 기존 chain 관련 테스트 PASS + 특수문자(`'`, `"`, `$`, 백틱) 포함 description 테스트 추가

---

### 1-2. subprocess.run() timeout 추가

**대상 파일 3개**:
- `/home/jay/workspace/dispatch.py` 350행: `subprocess.run(cmd, capture_output=True, text=True)`
- `/home/jay/workspace/chain.py` 202행 부근: `subprocess.run(...)` 호출
- `/home/jay/workspace/scripts/notify-completion.py` 46행 부근: `subprocess.run(...)` 호출

**수정 내용**:
```python
try:
    result = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
except subprocess.TimeoutExpired:
    logger.error(f"cokacdir 호출 타임아웃 (60초 초과)")
    # 적절한 에러 처리
```

**테스트**: 타임아웃 시 적절한 에러 메시지 반환 확인 (mock 사용)

---

### 1-3. DIRECT-WORKFLOW.md QC 타이밍 수정

**파일**: `/home/jay/workspace/prompts/DIRECT-WORKFLOW.md`

**현재 문제**: QC(qc_verify.py)가 .done 파일과 보고서 생성 전에 실행되어 file_check가 FAIL됨 (오탐).

**수정된 Step 순서**:
```
Step 4: 결과를 통합하고 전체 테스트 (pytest + pyright)
Step 4.5: Worktree 정리 (있는 경우)
Step 5: 보고서 작성 (memory/reports/{task_id}.md에 저장)
Step 6: QC 자동 검증 (python3 teams/{team}/qc/qc_verify.py --gate --task-id {task_id})
  - PASS/WARN → .done 파일 자동 생성
  - FAIL → 수정 후 재검증 (최대 3회). 3회 실패 시 보고서에 "QC FAIL" 기록 후 .done 생성(에스컬레이션)
Step 7: task-timer end
Step 8: 아누에게 완료 통보
```

**핵심**: .done 생성을 qc_verify.py가 제어 (Step 6에서 --gate 플래그로)

---

### 1-4. qc_verify.py --gate 플래그

**대상 파일 2개**:
- `/home/jay/workspace/teams/dev1/qc/qc_verify.py`
- `/home/jay/workspace/teams/dev2/qc/qc_verify.py`

**수정 내용**:
1. `--gate` CLI 플래그 추가
2. `--gate` 활성화 시:
   - 전체 결과가 PASS 또는 WARN이면 → `.done` 파일 자동 생성 (`memory/events/{task_id}.done`)
   - FAIL이면 → `.done` 파일 미생성, 에러 메시지 출력
3. `.done` 파일 생성 시 QC 결과 요약을 파일에 포함:
   ```
   task_id: task-413.1
   team: dev1-team
   qc_result: PASS
   timestamp: 2026-03-09T17:50:00
   ```

**테스트**:
- --gate + PASS → .done 생성 확인
- --gate + FAIL → .done 미생성 확인
- --gate 없이 실행 → 기존 동작 유지 (하위호환)

---

### 1-5. orphan-watchdog.py

**파일**: `/home/jay/workspace/scripts/orphan-watchdog.py` (신규)

**기능**:
1. `memory/task-timers.json`에서 `status: "started"` (= running)이고 `start_time`이 60분 이상 경과한 태스크 감지
2. 감지된 태스크 목록을 아누에게 cokacdir로 알림
3. 아누 알림 텍스트 예시: `"[좀비 태스크 감지] task-XXX.Y가 60분 이상 running 상태입니다. 확인 필요."`

**실행 방식**: 크론 등록
```bash
cokacdir --cron "좀비 태스크 감지 실행: python3 /home/jay/workspace/scripts/orphan-watchdog.py" --at "*/30 * * * *" --chat 6937032012 --key <ANU_KEY>
```
- 실제 크론 등록은 보고서에 명령어만 기록 (아누가 등록)

**테스트**: task-timers.json에 가짜 좀비 항목 넣고 감지 확인

---

## 공통 규칙

1. **모든 기존 테스트 PASS 유지** (pytest 전체 실행)
2. **pyright 에러 0건**
3. **QC 파이프라인 통과** (qc_verify.py 실행)
4. 변경한 파일만 git add + commit
5. 보고서: `memory/reports/task-413.1.md`
6. 완료 시: `.done` 파일 생성 + 아누 통보