# task-2962 · 워처 export 함정 해소 + 알림 단일소유자 규약 (이중알림 차단)

## 배경 (codex↔ANU 합의)
- `.env.keys` 144줄 중 **58줄이 `export VAR=value`** → systemd `EnvironmentFile=`이 파싱 실패. 증상: `activity-watcher.service` 크래시 루프 + `done-watcher.sh` `COKACDIR_CHAT_ID: unbound variable`(set -u).
- **알림 로직 유닛 3개 공존** → 이중·삼중 알림 위험:
  - `done-watcher.service`(+timer): shell 에스컬레이션 + 성공알림 배치
  - `activity-watcher.service`: idle→성공알림 (★ `.done.notified`를 **읽기만 하고 안 씀** = 가장 위험한 고리)
  - `done-watcher-success.service`: 성공알림 + failed알림 + ANU폴백
- 현재 셋 다 "체크 → 전송 → 마커 생성" 순서라 **경쟁창** 존재.

## 작업
### 1. export 함정 근본해결
- systemd 유닛이 `.env.keys`를 `EnvironmentFile=` 대신 **`source` 래퍼**(예: `ExecStart=/bin/bash -c 'set -a; source .env.keys; set +a; exec <script>'`)로 로드, 또는 export 접두 정규화. `COKACDIR_CHAT_ID` 정의 확인·기본값 부여(누락 시 안전 분기).
- `activity-watcher.service` 크래시 루프 해소.

### 2. 알림 단일 소유자 + 원자적 선점 (codex 핵심)
- **성공 알림 소유자 1개 지정**(`done-watcher-success.service` 권장). 나머지(`done-watcher.sh`·`activity-watcher`)의 성공 알림 경로 **비활성**(에스컬레이션/idle 전환 등 고유 역할만 유지).
- 전송 전 **`.done.notified`를 `O_EXCL`로 원자적 선점**한 프로세스만 발송(체크→전송→마커 순서 폐기). notify-completion.py·done-watcher.py 전송 로직도 이 규약 적용.

### 3. 검증
- 테스트 `.done` 생성 → **회장 챗 알림 정확히 1건**(중복 0) 확인. 3개 유닛 동시 가동 상태에서 재현.
- FAIL 알림·에스컬레이션 기존 동작 회귀 없음.

## 범위/원칙
- ANU 폴백 118건 재활성은 **범위 밖**(회장 결정=비활성 유지). 단 재활성 시 필요한 **ANU 전용 워터마크** 설계 메모만 리포트에 남길 것.
- `done-watcher.service` 런타임 재시작은 **이 task 완료 후** 별도 판단(현재 보류). 이 task가 그 선행조건(단일소유자 규약).

## 완료 조건
- PR + 유닛 수정 + 실제 알림 1건 검증 스크린샷 + `memory/reports/task-2962.md` + `.done` + ANU 콜백.