# Agent 미팅 v2: 세션 Watchdog 재검증 — Usage Limit + Heartbeat 설계

**날짜**: 2026-04-12
**소집 이유**: v1 설계(cokacdir --cron 기반)의 usage limit 무력화 문제 + PID 추적 불가 발견
**참여 페르소나**: 오딘, 토르, 불칸, 야누스, 로키, 헤임달
**미팅 모드**: hybrid
**토론 깊이**: thorough (Opus 모델)
**총 사이클 수**: 3

---

## 핵심 발견 (v1 대비)

### 1. PID 추적 체인 실패 (토르 실측)
- schedule_id → system_prompt grep: 76개 workspace 중 매칭 0개
- system_prompt 파일은 세션 종료 후 정리 또는 좀비화 — 구조적 불안정

### 2. usage limit 무력화
- cokacdir --cron = claude 세션 실행 → usage limit 시 followup 자체 불가
- 판단 주체(claude)가 판단 대상(usage limit)에 종속 → 근본적 결함

### 3. flock 구조적 불가 (토르 DA)
- Claude Bash 도구는 호출마다 새 셸 → flock 잡은 셸이 즉시 종료 → lock 자동 해제

### 4. post-tool-use hook이 이미 존재!
- PostToolUse hook이 Edit/Write/Task/Bash 매 도구 사용 후 자동 실행
- CWD/.task_id에서 task_id 읽는 로직 이미 구현
- ~/.claude/settings.json 전역 설정 → 모든 claude 세션에서 작동
- cokacdir workspace에 .task_id 파일 존재 (실측 확인)

---

## Cycle 1 — Opus Independent

### 오딘
- cron+bash 전환 YAGNI 위반 아님, 자체 PID 파일 제안
- 동시 재위임 상한(3건/cycle) + backoff 필요

### 토르 (핵심)
- PID 추적 체인 **실측으로 깨짐 확인** (76개 workspace 중 매칭 0개)
- system_prompt 파일 생명주기 불안정

### 불칸
- 생존시간 구분 정확도 30-40% → **구분 포기, 무조건 재위임 + HALF_OPEN circuit breaker**
- 재위임 안 하는 쪽이 더 위험 (비용 비대칭)

### 야누스
- systemd timer(done-watcher 패턴 일관성), OnUnitActiveSec=120s
- bash 스크립트 + EnvironmentFile 패턴

### 로키
- 보안 표면 넓어짐. 변수 따옴표, 절대경로, flock, 토큰 stdin 전달 필수

### 헤임달
- 좀비 PID, JSON 파손, 시간 역전, PID 재사용 엣지 케이스 추가

---

## Cycle 2 — Sequential + DA

### 불칸 심화
- flock 제안: `flock -n /tmp/dispatch-{task_id}.lock` → 커널 레벨 세션 생존 확인

### 토르 DA ★
- flock **구조적 불가**: Bash 도구 = 호출마다 새 셸, flock 잡은 셸 즉시 종료 → lock 해제
- 대안: **heartbeat 파일** — "매 단계마다 date > heartbeat 갱신", mtime 기반 판정

### 야누스 비관습적 대안
- Heartbeat Inversion: TTL lease 파일, /dev/shm 사용, done-watcher 확장
- 채택 판정: **부분 반영** (heartbeat 개념 채택, tmpfs는 미채택)

---

## Cycle 3 — 최종 합의

### 아누 제안: post-tool-use hook heartbeat
- post-tool-use.sh에 1줄 추가: `date +%s > heartbeats/{task_id}.heartbeat`
- LLM 의존 없는 자동 heartbeat (hook이 모든 도구 사용 후 실행)
- systemd timer가 heartbeat mtime 체크

### 오딘 최종
- 동의. 10분 타임아웃 권장 (5분은 부족). 2 Phase로 충분.

### 로키 최종
- 조건부 합격: anu-direct 제외, 퍼미션 600, unset CLAUDECODE

---

## 최종 합의 사항

1. **Heartbeat 프로토콜**: post-tool-use.sh에 1줄 추가 → 자동 heartbeat
2. **Watchdog**: systemd timer (OnUnitActiveSec=120s) + bash 스크립트
3. **판정 로직**: .done → pass, heartbeat < 10분 → alive, > 10분 → stalled → 재위임
4. **재위임**: dispatch.py 직접 호출, 무조건 재위임 + circuit breaker (빠른 실패 시 30분 백오프)
5. **Usage limit 독립**: bash 스크립트, LLM 불필요
6. **보안 3조건**: anu-direct 제외, heartbeat 퍼미션 600, unset CLAUDECODE

## v1 대비 변경점
- ❌ cokacdir --cron 기반 followup → ✅ systemd timer + bash
- ❌ PID 추적 (schedule_id → system_prompt → PID) → ✅ heartbeat mtime 기반
- ❌ 생존시간 기반 usage/context 구분 → ✅ 구분 안 함, 무조건 재위임 + circuit breaker
- ❌ flock → ✅ heartbeat (Bash 도구 stateless 문제 회피)
- ❌ 타임아웃 20분 고정 → ✅ heartbeat 10분

## Phase 분리
- Phase 1: post-tool-use.sh 수정 + heartbeats 디렉토리 + watchdog 스크립트 + systemd timer
- Phase 2: circuit breaker 세밀화 + 대시보드 연동 + 통합 테스트

## 미해결 항목
- heartbeat 디렉토리 초기 생성 방법 (mkdir -p)
- 대시보드에서 재위임 이력 표시 (Phase 2)
- circuit breaker 상태 파일 위치 결정
