Morning briefing job
A cron job that wakes an agent every weekday morning, has it read the state of your workspace, and leaves a written briefing waiting for you.
What you build
A scheduled job that runs before you sit down. Every weekday at 08:30 the daemon dispatches an agent into your workspace, the agent reads what changed and what is still open, and it writes a briefing you read instead of reconstructing.
Nothing about it is interactive. The scheduler fires on its own clock, the run is recorded in
automation_runs whether or not anyone is watching, and a failed run retries on a backoff you set.
Use it when you want the state of a project summarized on a fixed rhythm rather than on demand.
The artifact
Config-backed jobs live in config.toml. This is the whole definition.
[[automation.jobs]]
scope = "workspace"
workspace = "/Users/you/src/checkout-api"
name = "morning-briefing"
agent = "operator"
prompt = """
Write this morning's briefing for the checkout-api workspace.
Cover, in this order:
1. What changed in the working tree and on the current branch since yesterday.
2. Any session that stopped with an error, and the stop reason.
3. Open tasks under .compozy/tasks that are still pending.
4. Anything that needs a decision from a person today.
Keep it under 300 words. Lead with what needs attention, not with what is fine.
"""
schedule = { mode = "cron", expr = "30 8 * * 1-5" }
retry = { strategy = "backoff", max_retries = 2, base_delay = "5m" }
fire_limit = { max = 4, window = "24h" }Schedules are evaluated in the automation timezone, which defaults to UTC — set it explicitly if
08:30 should mean your local morning.
Run it
Before loading this definition or creating the dynamic job, make sure operator is an effective
agent definition for this workspace. The scheduler stores the agent name, but the dispatcher resolves
the agent and its provider when it starts the session. Configure the provider and its credentials first,
then inspect the resolved definition:
compozy agent info operator --workspace /Users/you/src/checkout-apiFor a custom automation agent, create a workspace-local or global definition before this step and make sure its effective runtime has a configured provider. See Agent definitions for the resolution cascade.
Create the same job dynamically, without editing config:
job="$(
compozy automation jobs create \
--name morning-briefing \
--scope workspace \
--workspace /Users/you/src/checkout-api \
--schedule "30 8 * * 1-5" \
--catch-up-policy run_once_on_catchup \
--misfire-grace-seconds 120 \
--agent operator \
--prompt "Write this morning's briefing for the checkout-api workspace." \
-o json
)"
job_id="$(printf '%s' "$job" | jq -er '.id')"Then confirm it registered, fire it once by hand instead of waiting for tomorrow, and read the run
history. This uses jq to read the generated ID from the create response; a job name is not accepted
by the trigger or run-history commands.
compozy automation jobs get "$job_id" -o json
compozy automation jobs trigger "$job_id"
compozy automation runs --job-id "$job_id" -o jsonHow it works
The scheduler owns the clock
Compozy keeps durable scheduler state, so a job does not silently skip because the daemon
restarted. catch-up-policy run_once_on_catchup runs a single make-up execution after downtime
instead of replaying every missed fire, and the misfire grace window bounds how late a fire may
still count.
The dispatcher applies the limits
Every fire passes the fire-limit and concurrency checks before a run is created. fire_limit
caps this job at 4 runs per day no matter what triggers it; the global automation concurrency
limit defaults to 5 active jobs across the daemon.
The run is a real session
An agent target starts an agent session with the prompt. It is durable and inspectable like any other session — you can open it later and read exactly what the agent saw and did.
Failure is retried, then recorded
With strategy = "backoff" a failed run is redispatched up to max_retries times starting at
base_delay. When retries are exhausted the run lands in history as failed rather than
disappearing.
Point it at a Loop instead
Set target_kind = "loop" and a loop_target to run a published Loop on the schedule instead
of a bare prompt. Scheduled jobs pass static loop_target.inputs only — a clock fire has no
activation envelope, so input_mapping is rejected.
Next steps
Jobs and scheduling
Every job field, the cron/every/at schedule modes, catch-up policy, retries, and the run history model.
React to session end
The event-driven counterpart: run work when something happens instead of when the clock says so.
Software-delivery loop
A Loop worth scheduling: deliver every authored task for a slug behind acceptance and verification gates.
compozy automation jobs
Generated reference for every flag on the jobs command, including filters, cursors, and output shapes.
Software-delivery loop
Take every authored task under one slug from pending to verified implementation, in dependency order, behind an acceptance gate and your own verification command.
Webhook to agent run
Turn a signed HTTP request from CI into an agent run — the trigger, the HMAC signature calculated end to end, and the filters that decide when it fires.