Quick answer
A scheduled coding agent is an agent session that starts by itself: on a cron schedule, at a one-time reminder, or when a webhook arrives. On Nori these are called automations. Each run claims a fresh cloud machine at fire time, in the timezone you chose, gives the agent your prompt with the team's repositories and skillset, and delivers the result to a Slack thread, the web dashboard or a project. Every run is kept in the automation's history.
Why schedule an agent instead of a script
A cron job runs the same commands every time. That is right for a backup. It is wrong for work that needs judgment: reading last night's failures and deciding which are flaky, checking whether the docs still match the code, or looking at a new error and working out which commit caused it.
A scheduled agent gets a prompt, a machine and your repositories, and does that work the way a teammate would. It ends with something a person can act on: a pull request, a short report in Slack, or a note that nothing needed doing.
Many scheduling features are tied to one laptop or one long-lived session. If that machine sleeps or the session ends, the schedule stops silently. A Nori automation is stored by the platform, not by a session, so it fires whether or not anyone is online.
How it works
An automation has three parts: when it fires, who does the work, and where the result goes.
When: cron, reminder or webhook
- Cron schedule. Recurring work and polling. Standard five-field cron, evaluated as wall-clock time in an IANA timezone such as
Europe/Berlin, so 09:00 stays 09:00 across daylight saving changes. - One-time reminder. A single run at a set moment: "check the rollout error rate next Tuesday at 10:00".
- Webhook. An external system such as Sentry, Grafana, Alertmanager or CI sends a POST request, and a session starts within seconds with the payload attached to the prompt as untrusted data.
Who: the agent that runs
A run uses your organization's default agent, or a custom agent with its own model, skillset and integrations. That agent can be Jiro, Claude Code, Codex, Gemini CLI or any other harness Nori runs, on your own subscription, API keys or LLM gateway. Runs use organization credentials by default. An automation can instead run as its author, with that person's own integrations, for jobs such as a personal morning briefing.
Where: Slack, the web or a project
| Delivery | What happens on each run | Best for |
|---|---|---|
| Slack thread | Nori opens a thread in the channel you chose, with the prompt and the agent's final reply. People reply in the thread to keep working with the same agent. | Work a person should see and continue: triage, reviews, reports |
| Web (standalone) | The run happens in the background and appears in the dashboard with its transcript. Nothing is posted unless the prompt names a channel. | Maintenance that should stay quiet unless it finds something |
| Project | The run wakes the project's coordinator, which plans, delegates to subworkers and reports where the project already talks. | Keeping long-running work moving without a person prompting it |
What happens at fire time
- The schedule, reminder or webhook fires.
- Nori claims a fresh, isolated machine with the repositories cloned and the organization skillset and memories installed.
- The agent receives the prompt and is told that no person is present, so it finishes without asking questions.
- The agent does the work and writes a final reply.
- Nori delivers the reply, records the run in the automation's history, and releases the machine.
Because every run starts on a fresh machine, runs do not inherit leftover state from each other. What carries over is deliberate: branches, pull requests, shared memories and project documents.
Worked example: three automations for one team
Here is the set of automations a small product team might run. Each has a cron line, a timezone, a delivery target and the full prompt. Channel and repository names are illustrative.
# 1. Flaky test triage, weekdays at 07:30
schedule: 30 7 * * 1-5
timezone: America/New_York
delivery: Slack thread in #eng-ci
prompt: |
Look at CI runs on main in web-app for the last 24 hours.
List tests that failed and then passed on retry with no code change.
For the most frequent one, find the cause and open a PR that fixes
the test or the race it exposes. Reply with a table: test name,
failures, suspected cause, PR link if any. If nothing was flaky,
say so in one line.
# 2. Dependency updates, Mondays at 06:00
schedule: 0 6 * * 1
timezone: Europe/Berlin
delivery: Slack thread in #eng-maintenance
prompt: |
In billing-api, update patch and minor versions of all dependencies.
Run the full test suite. Open one PR titled
"chore: weekly dependency updates". In the PR body, list each bump
and link its changelog. If a bump breaks tests, leave it out and
name it in your reply with the failing test.
# 3. Docs drift check, first day of the month at 09:00
schedule: 0 9 1 * *
timezone: America/Los_Angeles
delivery: web (standalone)
prompt: |
Compare docs/api/*.md in web-app with the route handlers in
src/routes/. For every endpoint whose parameters or response
shape no longer match the docs, fix the docs and open one PR.
Post a two-line summary with the PR link in #eng-docs only if
you changed something.
A one-time reminder uses the same shape with a date instead of a cron line:
# Reminder: one run, then done
when: 2026-11-24 10:00
timezone: Europe/London
delivery: Slack thread in #launch-checkout-v2
prompt: |
The checkout-v2 flag went to 10% of users on November 17.
Compare the error rate for /api/checkout over the last 7 days
with the 7 days before. Reply with both numbers, the top three
new error types, and whether you recommend going to 50%.
The Monday run of the second automation would open a thread like this:
#eng-maintenance
Nori Mon 06:00
Automation: Weekly dependency updates (Mondays 06:00 Europe/Berlin)
Nori 06:14
PR opened: billing-api #511 "chore: weekly dependency updates"
9 packages updated, all tests pass.
Left out: sqlalchemy 2.0.36 -> 2.1.0. It breaks
test_invoice_query_uses_region_index (changed eager-load default).
Katrin 08:52
@nori do the sqlalchemy bump as its own PR and fix the test.
Nori 09:07
PR opened: billing-api #512 "chore: sqlalchemy 2.1.0".
Set the loader option explicitly in InvoiceQuery. Tests pass.
The reply at 08:52 is the important part. A scheduled run that delivers to Slack is not a report to read and forget. It is a session a person can pick up and continue, the same as if they had mentioned the agent in Slack themselves.
Run history and approvals
Unattended work needs a record and a gate.
- Run history. Each automation keeps its runs: when it fired, whether it succeeded, the agent's final reply and a link to the full transcript. When a nightly job reports nothing for a week, you can check that it ran and see what it looked at.
- Approvals. Admins create and change automations directly. When another member creates or edits one, the change waits for an admin to approve it, and the previous version keeps running in the meantime. Deleting an automation is reserved for admins.
- Dry runs. Test an automation before it goes live, or use Run now in the dashboard, to see exactly what a run would produce.
- Pause. Any automation can be paused without losing its configuration or history.
- Webhook secrets. Each webhook automation has its own URL and secret. Treat both as credentials and store them in the sending system's secret settings.
Pull requests opened by a scheduled run go through the same review and branch protection as any other pull request. The automation decides when work starts. Your repository rules still decide what merges.
What teams schedule first
- Morning triage. Failed CI on main, new error groups, or stale pull requests, summarized before standup.
- Weekly maintenance. Dependency updates, dead-code removal, documentation that drifted from the code.
- Event response. An error-tracker alert that becomes an investigated pull request. See how to turn a Sentry webhook into a reviewed fix PR.
- Project heartbeats. A daily wake-up for a project coordinator so a migration or rollout keeps moving.
- Follow-ups. One-time reminders set while shipping: check the metric in a week, remove the feature flag in a month.
The same pattern works outside application code. Data teams schedule health checks on new tables, and security teams schedule red-team and blue-team loops, with the same run history and approvals.
Frequently asked questions
What is the difference between a scheduled coding agent and a cron job?
A cron job runs fixed commands. A scheduled coding agent runs a prompt: it reads the current state of the repository or an alert, decides what to do, and returns a pull request or a report. On Nori each run gets its own fresh cloud machine.
Does a schedule keep running if nobody is online?
Yes. Automations are stored by the Nori platform, not by a laptop or a single session. At fire time Nori claims a fresh machine, runs the agent, delivers the result and releases the machine. No one needs to be signed in.
Which timezone do schedules use?
The one you set on the automation, as an IANA name such as America/New_York. Cron is evaluated as wall-clock time in that zone, so a 09:00 schedule stays at 09:00 local time when daylight saving time starts or ends.
Can a webhook start an agent session?
Yes. Each webhook automation has its own URL. When Sentry, Grafana, Alertmanager, CI or any other system sends a POST request, Nori starts a session within seconds and gives the agent the payload, marked as untrusted data, together with your prompt.
Who can create or change an automation?
Any member can propose one. Changes made by admins apply at once. Changes made by other members wait for an admin to approve them, and the previous version keeps running until then. Only admins can delete an automation.
Do scheduled runs cost extra?
No per-run fee. A run uses one of the machines in your plan while it works and your own Claude or ChatGPT subscription, API keys or LLM gateway for the model. Nori never charges for tokens.