Routines
What a routine is in RoutineOS, the four routine types, the folder layout, and the lifecycle from Discover to Retire.
What it is
A routine is an agent that runs on a schedule in the cloud, does one piece of recurring work, and reports to people. In RoutineOS a routine is also a folder: routine.toml, prompt.md, README.md, and for routines with a Desk, definition.json and dashboard/index.html.
The platform underneath is Claude scheduled tasks. Anthropic’s docs now call them “scheduled tasks (formerly routines)” (source: https://code.claude.com/docs/en/web-scheduled-tasks, fetched 2026-10-30). RoutineOS keeps the word routine for the thing you build; see Scheduling and Claude cloud routines.
Why it exists
A scheduled prompt is easy to start and hard to trust. It forgets what it found last week, has no safe place to put results, cannot ask permission, and cannot be corrected without someone editing the prompt. A RoutineOS routine gets memory (the store), a place to meet people (the Desk), permission (gates), steering (settings) and improvement (learning), with the same conventions every time.
How it works
The four types
[routine] type in routine.toml is one of four values. The type decides what new scaffolds.
| Type | Use when | Desk | Gate |
|---|---|---|---|
serverless |
It runs, writes a report, and nobody watches | no | no |
watch |
It monitors sources and a person checks the result, often on a phone | yes | optional |
approval-gated |
It sends, posts or deletes after a person says yes | optional | yes |
interactive |
A person steers it from a page (settings, requests) | yes | when acting externally |
new --type watch and new --type interactive also write definition.json and dashboard/index.html. The repository README lists watch as live and approval-gated, digest and tracker templates as coming soon.
The type is not the same as the routine’s kind (code, skill, workflow or hybrid). The kind describes where the logic lives and how work is split between code and the model; see Routine kinds.
The folder
| File | Required | What it holds |
|---|---|---|
routine.toml |
yes | [routine] name, type, schedule, first_run; [store]; [workspace]; [[setting]]; [gate]; [[action]] |
prompt.md |
yes | The work, in words, with the untrusted-data clause and a Push rule: line |
README.md |
yes | What the routine does, its settings and known risks |
definition.json |
with a Desk | Record types, identity, setting filters, views, Inbox and learning |
dashboard/index.html |
with a Desk | The Desk page |
app.toml, risks.md, CHANGELOG.md, lib/ |
with --app |
The app layer: integrations, budget, environment, risks, history |
The lifecycle
The RoutineOS skill takes every routine through the same stages. Each has exit evidence: the thing that must exist before moving on.
| Stage | What happens | Exit evidence |
|---|---|---|
| Discover (optional) | Interview, or read a brief the person already has | A written brief the person accepted |
| Design | Pick routines, the mix of code and model, store, gates, secrets pattern, cost; list risks | A design the person approved, risks listed |
| Build | Scaffold, write prompts and scripts, build the Desk | Lint passes; every external contact declared |
| Verify | Dry checks, then a real report-only first run | A run record exists and the person looked at the output |
| Deploy | Show the permission screen, create the routine and triggers, load seed data | The routine is listed on the account with the stated schedule |
| Operate | Read run records, watch health and cost, relay approvals | Health and cost visible on the Desk |
| Improve | Change or add routines and integrations without losing data | Change applied, verified, summarised in plain words |
| Retire | Pause or archive cleanly, remove secrets | Nothing scheduled; secrets deleted |
Done means live and tested
A routine is in one of three states:
- not live: it does not exist on the account or is not scheduled;
- live, not yet tested: scheduled, but the person has not checked a first run;
- live and tested: the first run happened and the person confirmed the output is what they wanted.
Only live and tested counts as finished. An agent saying a routine works is not evidence.
Worked example
Hiring Signals is a watch routine. Its routine.toml begins:
[routine]
name = "hiring-signals"
type = "watch"
schedule = "0 22 * * 1,4" # UTC, Monday and Thursday; minimum interval is 1 hour
first_run = "report-only"
[store]
adapter = "artifact-db"
[workspace]
enabled = true
template = "jobs-watch"
template_version = 1
It runs at 22:00 UTC on Mondays and Thursdays. Its first run reports only. It writes to the artifact database of its Desk. The workspace block records that it came from version 1 of the jobs-watch template.
Reference
[routine]
| Key | Type | Required | Notes |
|---|---|---|---|
name |
string | yes | Becomes the producer id |
type |
string | yes | serverless, watch, approval-gated or interactive |
schedule |
string | yes | Cron, UTC; runs at least one hour apart |
first_run |
string | no | report-only or live |
The full file is in the routine.toml reference.
Common pitfalls
- Local time in the schedule. Schedules are UTC.
0 22 * * 1,4is 09:00 on Tuesday and Friday in Melbourne during daylight saving time. - Choosing a type by the output. Choose by who acts. If the routine ever sends, it is
approval-gatedor it carries a gate. - Calling it done after deploy. Deploy makes it live, not tested. Check the first report-only run with the person.
- Several jobs in one routine. A routine that reads private data, reads untrusted content and sends externally should be split; see Routine kinds.