# 세션 자동 이어가기 Watchdog — 맥락노트 v2

## 결정 근거

### 왜 heartbeat인가?
- **PID 추적 실패**: 토르 실측 — schedule_id → system_prompt grep 76개 중 0개 매칭
- **flock 불가**: 토르 DA — Claude Bash 도구는 호출마다 새 셸, flock 잡은 셸 즉시 종료
- **heartbeat는 기존 인프라 활용**: post-tool-use.sh가 이미 task_id 읽기 구현, 1줄 추가로 완성
- **LLM 의존 없음**: hook이 OS 레벨에서 자동 실행, claude 세션이 살아있는 한 heartbeat 갱신

### 왜 systemd timer인가?
- **야누스 실측**: done-watcher.timer 등 15개 서비스가 이미 systemd user unit 패턴 사용
- **OnUnitActiveSec=120s**: "이전 실행 완료 후 2분" 보장, 동시 실행 방지 (flock 불필요)
- **crontab 부적합**: 상태 기반 감시자에 주기 실행 패턴은 맞지 않음

### 왜 usage/context 구분을 포기했는가?
- **불칸 분석**: 생존시간 기반 구분 정확도 30-40%
- **비용 비대칭**: 재위임 안 하는 쪽(작업 정체)이 재위임하는 쪽(세션 1회 낭비)보다 명백히 위험
- **circuit breaker로 대체**: 무조건 재위임 + 빠른 실패 시 30분 백오프

### 왜 10분 타임아웃인가?
- **오딘 권장**: 5분은 부족 (대용량 파일 읽기, WebFetch 대기 등에서 5분 초과 가능)
- 10분 + watchdog 주기 2분 = 실질 감지 12분, 오탐 방지와 적시 감지의 균형

## 기각된 대안

### cokacdir --cron 기반 followup (v1 설계)
- **기각 사유**: usage limit 시 followup 자체 불가. 판단 주체가 판단 대상에 종속.

### PID 추적 (schedule_id → system_prompt → PID)
- **기각 사유**: 토르 실측으로 구조적 불안정 확인. system_prompt 파일 생명주기 불예측.

### flock 기반 세션 생존 확인 (불칸 제안)
- **기각 사유**: 토르 DA — Bash 도구 stateless 문제. 구조적 불가.

### 자체 PID 파일 (오딘 D안)
- **기각 사유**: dispatch.py는 cokacdir에 스케줄 등록만 하고 리턴. 실제 claude PID를 알 수 없음.

### 생존시간 기반 usage/context 구분
- **기각 사유**: 정확도 30-40%. 오판 비용 비대칭 (재위임 안 하는 쪽이 더 위험).

### Dead Man's Switch TTL (불칸 v1)
- **부분 반영**: heartbeat 개념으로 흡수.

## 보안 조건 (로키 합격 조건)
1. anu-direct 작업은 watchdog 대상 제외
2. heartbeat 파일 퍼미션 600
3. systemd unit에 unset CLAUDECODE 명시
4. dispatch.py 호출 시 절대경로 사용
5. 변수 따옴표 처리 필수

## 프로세스 테스트 결과 (2026-04-12 실측)
- claude 프로세스 인자에 task_id 없음 (pgrep 불가)
- cokacdir workspace에 .task_id 파일 존재 (역추적 가능)
- system_prompt → PID 매핑 불안정 (76개 중 0개 매칭)
- post-tool-use.sh에서 CWD/.task_id 읽기 로직 이미 구현
