# task-370.1: 자동 체이닝 시스템 구현 (리스크 헷지 포함)

## 배경
한정 위임 시 "자동으로 이어서 진행"이라고 해도, 실제로는 제이회장님이 말을 걸어야 아누가 .done을 감지하는 문제.
팀장 완료 통보 cron이 아누 세션을 열 때, 체인 파일을 확인하여 자동으로 다음 작업을 dispatch하는 시스템 구현.

## 수정 대상 파일
1. **신규**: `/home/jay/workspace/chain_manager.py` — 체인 등록/조회/업데이트 유틸
2. **수정**: `/home/jay/workspace/prompts/DIRECT-WORKFLOW.md` — 11번 단계 완료 통보에 체인 확인 지시 추가
3. **신규**: `/home/jay/workspace/memory/chains/` 디렉토리

## 구현 요구사항

### 1. chain_manager.py — 체인 관리 유틸
```python
# CLI 인터페이스
python3 chain_manager.py create --chain-id <id> --tasks '<JSON>'
python3 chain_manager.py next --task-id <완료된task>  # 다음 pending 작업 반환
python3 chain_manager.py update --task-id <id> --status <running|done|failed|stalled>
python3 chain_manager.py check-stalled --max-hours 2  # 정체 작업 확인
python3 chain_manager.py list  # 활성 체인 목록
```

#### 체인 파일 스키마 (`memory/chains/chain-<id>.json`)
```json
{
  "chain_id": "chain-20260307-001",
  "created_by": "anu",
  "created_at": "2026-03-07T01:00:00",
  "status": "active",
  "scope": "영상 자동화 Phase 2~4 + pm-skills 분석",
  "max_tasks": 10,
  "tasks": [
    {
      "order": 1,
      "task_file": "memory/tasks/dispatch-xxx.md",
      "team": "dev1-team",
      "status": "pending|running|done|failed|stalled",
      "task_id": null,
      "gate": "auto|none",
      "started_at": null,
      "completed_at": null
    }
  ]
}
```

#### next 명령어 로직
1. 완료된 task_id로 해당 체인 파일 검색
2. 해당 task의 status를 "done"으로 업데이트
3. gate가 "auto"이면: 이전 작업의 QC 결과 확인 (보고서에서 FAIL 키워드 검색)
   - FAIL 발견 → 체인 일시정지 + `{"action": "stalled", "reason": "QC FAIL"}` 반환
   - PASS → 다음 pending 작업 반환
4. gate가 "none"이면: 무조건 다음 pending 작업 반환
5. 다음 pending 없으면: `{"action": "chain_complete"}` 반환
6. 동일 task_file 중복 감지 → 차단

#### 원자적 상태 업데이트 (race condition 방지)
- 체인 파일 수정 시 lock 파일 사용: `memory/chains/chain-<id>.lock`
- `open(lock_path, 'x')` 시도 → 성공하면 작업 → 완료 후 lock 삭제
- `FileExistsError` → 5초 대기 후 3회 재시도 → 실패 시 에러

#### 최대 작업 수 캡
- 체인의 tasks 길이가 max_tasks(기본 10) 초과 시 create 거부

### 2. DIRECT-WORKFLOW.md 수정 — 11번 단계
현재 아누 통보 프롬프트:
```
"{task_id} 완료 처리. ... 보고서 읽고 보고하라."
```

변경:
```
"{task_id} 완료 처리. ... 보고서 읽고 보고하라.
그리고 python3 /home/jay/workspace/chain_manager.py next --task-id {task_id} 실행.
결과가 action=dispatch이면 표시된 task_file과 team으로 dispatch.py 위임하라.
결과가 action=stalled이면 제이회장님께 '체인 정체: {이유}' 보고하라.
결과가 action=chain_complete이면 '체인 전체 완료' 보고하라."
```

### 3. watchdog cron (타임아웃 감시)
- chain_manager.py create 시 watchdog cron 자동 등록
  - `--at 2h` 후 실행
  - 프롬프트: "python3 chain_manager.py check-stalled --max-hours 2 실행. stalled 작업 있으면 제이회장님께 보고."
- 체인 완료 시 watchdog cron 자동 제거

### 4. 실패 시 안전장치
- dispatch 실패: 체인 status를 "stalled" + 제이회장님 통보 cron 발송
- 30분 후 재시도 cron 1회 등록 (최대 1회, 무한 재시도 방지)
- 재시도도 실패 시: "stalled" 확정 + 수동 개입 필요 통보

### 5. 체인 파일 백업
- 상태 업데이트 시 `.bak` 복사 후 덮어쓰기
- 읽기 실패 시 `.bak`에서 복구 시도

## 검증
- chain_manager.py create/next/update CLI 정상 동작
- next 실행 시 다음 pending 작업 올바르게 반환
- 동일 task_file 중복 감지 차단
- lock 파일 동시 접근 시 순차 처리
- max_tasks 초과 시 create 거부
- QC FAIL 감지 시 stalled 상태 전환
- DIRECT-WORKFLOW.md 변경이 기존 워크플로우 깨뜨리지 않는지 (체인 없는 작업은 "no chain" 출력하고 패스)

## 제약
- 체인 파일은 `/home/jay/workspace/memory/chains/`에만 저장
- chain_manager.py는 `/home/jay/workspace/` 하위에 생성
- dispatch.py, task-timer.py와 동일 레벨