Scheduled runs
Run a saved job every morning, on weekdays, or at another recurring time. Jazz installs the schedule through launchd on macOS or cron on Linux.
Schedule your first job
From a repository you want to summarize, create an agent named daily-helper with
jazz agent create. Choose a tool-capable model and the coder persona.
Create workflows/daily-standup-prep/WORKFLOW.md in that repository:
---
name: daily-standup-prep
description: "Summarize yesterday's repository activity"
agent: daily-helper
schedule: "0 9 * * 1-5"
autoApprove: read-only
maxIterations: 20
maxDurationMs: 300000
---
Inspect git commits from the last day and the current working tree. Summarize
completed work, uncommitted changes, and anything needing my attention.
Do not modify files.
Test it from the same repository, then install the schedule:
jazz workflow run daily-standup-prep --auto-approve
jazz workflow schedule daily-standup-prep
jazz workflow scheduled
jazz workflow history daily-standup-prep
The test should produce a summary grounded in your commits and working tree. The schedule runs at 09:00 on weekdays in the machine’s timezone. The agent and its provider credentials must remain available on that machine.
To send the result to your phone or chat, configure a
notification target and add
deliver: <target-name> to the frontmatter. To stop the schedule:
jazz workflow unschedule daily-standup-prep
Use the daemon scheduler
For an always-on host without launchd or cron, switch to in-process mode and run the daemon. It checks due schedules once per minute:
jazz config set scheduler.mode in-process
jazz daemon
You can also select /settings → Scheduler in the jazz home screen. See
Scheduler configuration.
Platform requirements
- launchd doesn’t do cron arithmetic.
StartCalendarIntervalaccepts plain integers and wildcards only: no step values (*/15), no ranges (1-5), no lists (1,3,5). Jazz expands what it can into multiple entries and rejects what it can’t with an explicit error rather than silently scheduling the wrong thing. - Schedulers start with a minimal environment. launchd jobs don’t inherit your shell’s
PATH, so Jazz writes an explicit one into the plist. If a workflow shells out to a tool installed somewhere unusual, use an absolute path.
Approval policy
The workflow’s autoApprove: tier decides what can run without asking. Calls above
that tier are declined.
autoApprove | Auto-approves | Good for |
|---|---|---|
false | Nothing | The agent receives a decline for every gated tool |
read-only | Reads, search, web, todos, work state, subagents, read-only commands | Digests, reports, watchdogs |
low-risk | + memory writes, reminders, triggers, low-risk commands | Digests that track state |
high-risk | + file writes, shell, git commit and push | Jobs requiring unrestricted tool use |
Skills such as email, calendar, and Obsidian run commands through execute_command.
Their mutations may require a higher tier. Prefer human approval or a narrowly scoped
command grant; see email and calendar setup.
Pick the lowest tier that lets the job finish. See Approvals for policy details.
Sleep, missed runs, and catch-up
macOS and Linux behave differently here, and the difference decides whether you need catch-up at all.
launchd fires on wake. Missed sleep slots are combined into one run when the Mac wakes. A powered-off machine misses its slots.
cron skips missed slots. If a Linux machine is asleep or off at the scheduled time, the job does not run.
Either way, catch-up is explicit rather than automatic:
jazz workflow catchup # list what missed its slot, pick, run
It is age-bounded: a missed run older than 24 hours is skipped (and recorded in
jazz workflow history as skipped), and per-workflow maxCatchUpAge overrides that. The
separate catchUpOnRestart flag covers the in-process daemon, meaning a slot missed because the
daemon was stopped rather than because the machine was asleep.
If the schedule really cannot be missed
- Pick a forgiving time. Hourly, or 9 AM instead of 6 AM, gives the machine more chances to be awake.
- Keep the machine awake while a daemon runs:
caffeinate -i jazz daemon --foregroundon macOS,systemd-inhibit --what=sleep jazz daemon --foregroundon Linux. - Wake it on purpose. macOS can schedule a wake or power-on:
sudo pmset repeat wakeorpoweron MTWRFSU 05:55:00for a 6 AM job. - Run it somewhere always on, such as a home server, a VPS, or a Raspberry Pi.
Debugging a scheduled run
History keeps the last 20 runs of each schedule. A run whose process died before it finished
(a crash, a reboot mid-run) shows as interrupted once a daemon or CLI starts again.
jazz workflow scheduled <name> # is it actually installed, and under which labels?
jazz workflow history <name> # did it run? what did it do?
tail -f ~/.jazz/logs/<name>.log # stdout
tail -f ~/.jazz/logs/<name>.error.log # stderr
jazz workflow run <name> --auto-approve # reproduce it by hand, same policy
Log files rotate at 10 MB and are deleted 14 days after their last write, so a workflow that has not run for two weeks has no log left. See sizes and retention.
jazz workflow run <name> --auto-approve reproduces the scheduled approval policy
in the terminal.
Most scheduled-run failures are one of three things: the machine was asleep (see above), a
tool was declined by the policy tier, or a binary the workflow shells out to isn’t on the
minimal PATH.
Related
- Workflows: the file format and frontmatter
- Starting runs: the other unattended shapes, and when to pick which
- Guides: scheduled recipes with install steps
- Headless: for dynamic prompts instead of a fixed workflow file