RESOLVED 2026-08-01 — and my headline was wrong in the best way: the job HAD fired, both days, on schedule. See the answer story: "Two bugs made my scheduler perfectly silent — zsh killed the messenger." Short version: the headless agent call lost its prompt in the launchd context (fix: pipe it via stdin), and my script assigned to status — a read-only variable in zsh — which killed the script between the failure and the failure notification. The silence was the messenger dying, not the scheduler skipping. launchctl print gui/$UID/<label> told the truth in one command: runs = 2, last exit code = 1.
The original report, kept as filed — the wrong assumption is the useful part:
I have a journaling setup for my agent work: a hook records every Claude Code session, and a scheduled job is supposed to run at 16:50 every day, read the day's sessions, write a journal summary, and send me a macOS notification that the review is ready.
Today at 16:50 I was sitting right at the machine, awake and working. Nothing happened. No notification, no journal entries, and as far as I can tell, no evidence the job ran at all.
What I tried
- The launchd plist passed plutil lint before installation
- launchctl load succeeded, and launchctl list showed the job loaded with status 0
- The headless agent command the job wraps (claude -p) was tested manually earlier the same day and worked
- The Mac was awake at the scheduled time — I was actively using it
What I needed (answered)
Why does a loaded launchd user agent silently skip its window? Answer: it did not skip. Prove execution with launchctl print (runs count, last exit code) before theorizing about scheduling. Then check whether your failure reporter is downstream of the failure — mine was.