# Agent 미팅: .done 파일 감지 갭 개선

**날짜**: 2026-03-14
**소집 이유**: 대화 중 팀 작업 완료를 감지하지 못하는 구조적 결함 (2회 연속 사고 발생)
**참여 페르소나**: 헤르메스(1팀장), 야누스(DevOps), 로키(레드팀/DA), 아르고스(테스터)
**미팅 모드**: hybrid
**토론 깊이**: thorough
**총 사이클 수**: 2

---

## 근본 원인

1. `dispatch.py` L512-513: `_register_followup` 데드 코드 (정의만 있고 호출 0건)
2. CLAUDE.md: "매 대화 시작 시" .done 체크 → 대화 중 감지 불가
3. `notify-completion.py`가 존재하지만 팀장이 호출을 누락할 수 있는 구조
4. 실제 사고: task-544.1, task-545.1 완료를 제이회장님이 먼저 지적

---

## Cycle 1

### 아누 분석
- dispatch.py L243: `_register_followup` 함수 정의만 있고 호출 없음 (grep 결과 0건)
- dispatch.py L512-513: 주석 "크론 폴링 제거 — .done 파일 기반 이벤트 감지로 전환"
- 대체 메커니즘이 "대화 시작 시에만" 동작하여 대화 중 사각지대 발생

### 페르소나 의견

**헤르메스**: 3-Layer Defense 제안
- L1 Push: notify-completion.py를 qc_verify.py --gate에 통합
- L2 Passive Pull: CLAUDE.md "매 응답 시" .done 체크
- L3 Safety Net: 시스템 crontab 1분 폴링 done-watcher-cron.sh
- 태스크 분해: Task A(qc통합), B(CLAUDE.md), C(cron), D(데드코드), E(문서)

**야누스**: systemd Timer > cron
- systemd Timer(30초) + Type=oneshot → 동시 실행 원천 차단
- EnvironmentFile로 .env.keys 공식 로드 (cron의 source 방식보다 안전)
- 보안 CRITICAL: notify-completion.py 하드코딩 봇 키 fallback 발견
- heartbeat 파일 + health-check 통합 권장

**로키**: 실제 버그 발견 + 3-Layer 한계
- `.done.false` 파일 2건 (task-120.1, task-132.1) — 영구 감지 누락 중
- `.done.clear2/3` 파일 6건 — 멱등성 실패 증거
- notify-completion.py L16: 하드코딩 키 보안 결함
- 3-Layer 전체 실패: 팀 세션 비정상 종료 시 .done 자체 미생성
- 대안: 하트비트 역전, SLA 감시

**아르고스**: 검증 관점
- 일반 작업 경로의 done.clear 생성이 비원자적 → L3 추가 전 멱등성 강화 필요
- 체인 중간 Phase와 L3 cron 충돌 위험 → 예외 처리 명시 필수
- UserPromptSubmit Hook이 CLAUDE.md 규칙보다 강제성 높음
- 테스트 시나리오 설계 완료 (동시 다건, 멱등성 등)

### 합의
- 3-Layer 방향 OK (4명 전원)
- L2는 UserPromptSubmit Hook으로 (야누스+아르고스)
- L3는 systemd Timer (야누스)
- 보안: 하드코딩 키 즉시 제거 (야누스+로키)
- 멱등성: O_EXCL 전 경로 적용 (로키+아르고스)

### 미해결 항목
- L4(SLA 감시) 필요성 판단
- finish-task.sh 통합 스크립트 vs qc_verify.py 통합

---

## Cycle 2

### Devil's Advocate (로키)

**1. 실패 시나리오**:
- L3 systemd Timer가 서버 재부팅/리셋 시 날아감
- L1의 qc_verify 통합이 단일장애점 (QC 에러 = 완료 통보 블록)
- L4의 30분 SLA가 오탐 양산 → 알람 피로

**2. 후회 이유**:
- 4개 레이어 = 4개 유지보수 부채
- 근본 원인(팀장 완료 선언 신뢰성) 미해결

**3. 더 단순한 대안**:
- `finish-task.sh` 단일 진입점 + systemd 폴백 = 2-Layer면 충분

**반박**:
- L2(Hook)는 구현 5줄, 유지보수 0 → 제거 불필요
- systemd --user enable → 부팅 자동 시작으로 해소
- QC 통합 대신 finish-task.sh로 분리 → DA 지적 수용
- L4(SLA) 보류 → DA 지적 수용

**판정**: DA 일부 수용. 4-Layer → 3-Layer로 축소. L4 보류. finish-task.sh 분리 채택.

### 비관습적 대안 (헤르메스)

**이벤트 소싱 + append-only JSONL + cursor 기반 구독**
- 최강 지지: 멱등성 완벽, 감사 로그 겸용, task-timer와 통합 가능
- 최강 반론: cursor 파일이 새로운 SPOF, 팀장 프롬프트 전면 수정 필요
- 노력: 중간
- 리스크: 중간
- **판정: 기각 (현 시점). 장기 로드맵(Phase 2)으로 기록.**

---

## 최종 합의 사항

### 1. 3-Layer Defense 채택

**L1 (Primary Push)**: `finish-task.sh` 단일 마무리 스크립트
- 내부: .done 생성(O_EXCL) → task-timer end → notify-completion.py 호출
- QC(qc_verify.py)와 분리 → QC 에러가 완료 통보를 블록하지 않음
- 팀장 프롬프트에 "작업 완료 시 finish-task.sh 실행" 한 줄로 단순화

**L2 (Active Pull)**: UserPromptSubmit Hook
- 매 메시지마다 `ls memory/events/*.done` 실행
- .done 발견 시 아누에게 컨텍스트 주입
- 구현: 셸 스크립트 ~10줄

**L3 (Safety Net)**: systemd User Timer (30초)
- done-watcher.sh: .done 파일 탐색 → O_EXCL로 done.clear 선점 → notify-completion.py 호출
- Type=oneshot: 동시 실행 원천 차단
- EnvironmentFile: .env.keys 공식 로드
- systemctl --user enable: 부팅 자동 시작
- heartbeat 파일 기록

### 2. 보안 수정 (즉시)
- notify-completion.py L16: 하드코딩 봇 키 fallback 제거
- 환경변수 미설정 시 에러 종료로 변경

### 3. 멱등성 강화
- done.clear 원자적 생성(O_EXCL)을 모든 경로에 적용
- 일반 작업 경로 포함 (현재 체인만 적용)

### 4. 기존 이슈 처리
- .done.false 파일 2건: 원인 조사 + 수동 처리
- .done.clear2/3 파일 6건: 정리
- dispatch.py _register_followup 데드 코드 삭제

### 5. L4(SLA 감시): 보류
- 오탐(알람 피로) 위험 → 3-Layer 안정화 후 재평가

## 미해결 항목
- 이벤트 소싱 방식: 장기 로드맵으로 기록
- .done.clear 30일 아카이빙 정책: 중기 과제
- done.false 발생 원인 정확한 조사

## 다음 단계
- 합의 사항을 dispatch 파일로 작성하여 1팀에 위임
- 구현 후 아르고스 설계의 테스트 시나리오로 검증
