# Dev Request: 가희 잔액 리마인더 발송 신뢰성 보강

## 배경

관리자님이 2026-08-01에 "7/25일날 왜 가희 계좌갱신 문자 안보냈어?"라고 확인했다.

조사 결과:

- 대상 코드: `/Users/snowoyh/.openclaw/agents/budget/workspace/skills/whooing-sync/scripts/gahee_reminder.py`
- 상태 파일: `/Users/snowoyh/.openclaw/agents/budget/workspace/state/gahee_reminder.json`
- launchd: `ai.openclaw.budget.whooing-sync`, 매시 0/15/30/45분 실행
- 상태 파일 mtime이 `2026-07-25 10:00:03 +0900`
- 상태 파일에 `last_sent_month: "2026-07"`가 저장되어 있음
- `_maybe_send_reminder()`는 `imsg send`가 returncode 0일 때만 `last_sent_month`를 저장함
- 현재 터미널에서는 `imsg chats --json`이 `permissionDenied(path: "/Users/snowoyh/Library/Messages/chat.db", underlying: authorization denied (code: 23))`로 실패해 실제 Messages DB 검증 불가

즉 자동화는 7/25 10:00에 발송 성공으로 처리했지만, 실제 수신자 단말 배달 여부를 확인하지 못하고 중복 방지 상태만 남긴 것으로 보인다.

## 목표

가희 잔액 리마인더가 "발송 명령 성공"과 "실제 추적 가능 상태"를 구분하도록 보강한다.

## 요구사항

1. `gahee_reminder.py`에 발송 시각/결과 로그를 상태파일에 남긴다.
   - 예: `last_send_attempt_at`, `last_send_ok_at`, `last_send_returncode`, `last_send_stdout`, `last_send_stderr`
   - 민감한 수신자 번호는 상태/로그/텔레그램 알림에 원문 노출하지 말고 마스킹한다.

2. `imsg send` 실패 시 현재처럼 텔레그램 알림을 보내되, 실패 원인을 더 남긴다.
   - returncode
   - stderr 앞부분
   - `permissionDenied`, timeout, command missing 등을 구분 가능하게

3. `last_sent_month`는 정말 `imsg send` returncode 0일 때만 유지한다.
   - 이 동작은 이미 그렇게 보이지만, 리팩터 중 깨지지 않게 확인한다.

4. 가능하면 `last_sent_at`도 명시적으로 저장한다.
   - 현재는 `last_sent_month`만 있어 `_poll_replies()`가 발신일 00:00부터 잡는 fallback을 쓴다.
   - 발신 직후 polling watermark가 애매해지는 문제를 줄이려면 `last_sent_at`을 UTC ISO로 저장하고 `_poll_replies()` fallback에도 활용한다.

5. 발신 직후 polling이 우리 발신 메시지를 답신처럼 오인하지 않도록 확인/보강한다.
   - `_msg_from_gahee()`는 `is_from_me` 또는 `from_me`가 없으면 True를 반환한다.
   - `imsg history` 빌드가 outgoing 메시지에 해당 필드를 안 줄 경우, 우리 발신 안내문이 포맷 오류로 처리될 수 있다.
   - 가능한 경우 sender/handle 필드도 활용하거나, `last_sent_at` 이후의 inbound만 보도록 보수적으로 처리한다.

6. 수동 점검 CLI 또는 dry-run 출력이 있으면 좋다.
   - 예: `python3 gahee_reminder.py --status` 또는 기존 구조에 맞는 최소 진단 출력
   - 필수는 아니지만, 다음달 25일 전에 상태 확인이 쉬워지는 방향이면 좋다.

## 검증

- 기존 `whooing_sync.py` 호출 경로에서 import/run이 깨지지 않아야 한다.
- `python3 -m py_compile`로 관련 스크립트 문법 확인.
- 가능하면 `gahee_reminder.py`의 dry-run 또는 작은 단위 테스트로 25일 10시 이후 발송 게이트가 상태를 어떻게 바꾸는지 확인.
- 실제 가희님께 테스트 문자는 관리자님 명시 승인 없이 보내지 말 것.

## 보고 포인트

- 어떤 필드를 상태파일에 추가했는지
- 실패 시 관리자님이 어디서 원인을 볼 수 있는지
- 7/25 건은 "발송 명령 성공 처리됨, 실제 배달 확인 불가"로 보는 게 맞는지
