Repository navigation
v0.4.0
What's New
Reliability: scheduled runs no longer aborted by the daily timezone sync (#5)
Scheduled tasks could intermittently fail right at launch — a sub-second exit-1 with empty logs and no session ever created — when the daily tz-sync job fired in the same slot (commonly 3am). Two independent hazards are now closed:
- Live task torn down mid-run.
syncre-registering a task didlaunchctl unload+loadon its plist, killing the job's process tree if it was already running.syncnow checks a newisTaskRunningpredicate and defers a live task to the next cycle instead of tearing down its registration. - Torn read of a shared shim.
syncrewrites the executor shims in place, and launchd couldexecone mid-write. Plists and shims are now written atomically (write-temp-then-rename), so a concurrent reader always sees a whole file.
Configurable state directory
- config: The scheduler state directory can now be overridden with the
CLAUDE_SCHEDULER_STATE_DIRenvironment variable, making it possible to isolate or relocate scheduler state.
Bug Fixes
- darwin: Timezone offset is now computed correctly across month and year boundaries (previously the day-of-month approximation could land in the wrong month/year at the edges).
- executor:
claudeinvocations are retried on transient macOS keychain auth failures, so a momentary "not logged in" hiccup no longer fails an otherwise-healthy run.
Under the hood
- E2E suite migrated to agentry with per-scenario state isolation for deterministic runs; added coverage for the sync skip-running path,
isTaskRunning, atomic writes, and executor auth-retry. Full suite: 353 tests green.
Full Changelog: v0.3.1...v0.4.0