tick 의 보완
진짜 시간-specific 한 task — 매일 7am 날씨, 일회성 reminder — 위해 heartbeat service 도 APScheduler 실행. job 이 <app-data>/cron_jobs.json 에 POST /api/heartbeat/cron 통해 등록. 아빠가 conversation 중 요청, 내가 cron entry 직접 생성.
같은 fallback chain
cron job은 같은 streaming guard와 headless fallback contract를 써. 현재 subscription chain은 Codex → Claude → Grok → Kimi고, 허용된 paid insurance는 명시적으로 켠 Gemini API뿐이야. trigger만 정해진 시간이라는 점이 일반 tick과 달라.
NOT macOS crontab
중요: cwkPippa 의 cron 이 pippa serve 안 APScheduler, crontab -l 아님. 아빠 macOS crontab 이 의도적으로 비어있음. 피파 cron 이 in-process 살아, JSON-persisted, server restart 시 reload. launchd 의 유일한 역할이 pippa serve 살아있게 하는 거 — schedule 자체가 in-process.
등록 row에는 schedule만 있는 게 아니야. soul, preferred brain, model과 effort override, prompt reference, notification policy가 함께 묶일 수 있어. recurring prompt 본문은 row 안에 숨기지 않고 Scheduler registry로 승격해서 Admin에서 보고 고치게 해. code와 data가 각자 맡을 자리를 지키는 거야.
재시작 복구도 두 층이 맡아. launchd는 service process를 다시 올리고, service startup은 JSON에 남은 job을 APScheduler에 재등록해. 둘 중 하나만 확인하면 "프로세스는 살아 있지만 일정은 사라진" 반쪽 복구를 놓쳐.
현재 unattended chain은 subscription·OAuth 성격과 운영 안정성을 기준으로 Codex → Claude → Grok → Kimi 순서야. Gemini는 interactive brain과 Family Council 자리는 지키지만 metered call을 반복할 수 있는 무인 chain에서는 빠져 있어. fallback 순서는 model 서열이 아니라 실패했을 때 누가 비용과 권한을 감당할지에 대한 운영 정책이야.