Claude Code routines — scheduled agents in the cloud
A routine is a prompt Anthropic runs on a schedule, in an isolated checkout, ending in a pull
request. It is one of two places a scheduled agent job can live, and picking the wrong one is the
expensive mistake.
|
Cloud routine — this skill |
Local scheduled job |
| Runs on |
Anthropic's infrastructure, isolated checkout |
your machine, via the OS scheduler |
| Needs |
a repo it can reach and a prompt |
a machine that is awake |
| Config |
the dashboard. Nothing on disk. |
files you own and can diff |
| Can reach |
the repo, plus whatever you granted |
anything the machine can |
| Managed with |
/schedule, or the RemoteTrigger tool |
a registrar (→ cronsole-windows-jobs) |
| Cronsole sees it as |
CLAUDE_CODE |
WINDOWS_TASK_SCHEDULER |
Choose the cloud when the work needs no local state — no installed dependencies, no .env, no
local service, no machine that has to be on. Choose local when it does, or when the work must
touch that machine.
1. The three constraints that shape everything
- Nothing lives locally. There is no config file and no prompt on disk. The routine's entire
definition is in the dashboard, which means the prompt is the only artifact — there is no
version history behind it and nothing to diff when a run goes wrong. Keep your own copy of every
prompt in the repo it acts on, or in a notes folder. Nothing else will.
- You cannot enumerate the fleet from a fresh session.
CronList is session-scoped and shows
nothing from another session. Use /schedule, or RemoteTrigger with {action: "list"}. Do not
read its silence as an empty fleet.
- Deleting is dashboard-only. No API surface Cronsole has can remove a routine. The reversible
move is to turn one off and leave it.
2. Build one
| Step |
What |
| 1 |
Pick the routine type → references/routine-types.md. Four shapes cover almost everything worth scheduling. |
| 2 |
Write the prompt. It is the whole product — same file, § "The prompt contract". |
| 3 |
Pick a branch prefix, and register it with whatever merges your PRs, in the same change. |
| 4 |
Pick a UTC time. Routines fire in UTC; any local fleet you are avoiding shifts twice a year. |
| 5 |
Create it with /schedule, or RemoteTrigger. |
| 6 |
Track it in Cronsole → references/cronsole-side.md. |
| 7 |
Verify by reading the run's step list, never its status. |
Keep a fleet inventory
A cloud fleet has no local record at all, so a routine you forget about keeps running, keeps
opening PRs, and keeps costing money. Write down — anywhere you will actually look — each routine's
name, repo, branch prefix, fire time and whether it is on. The dashboard is the source of truth and
your inventory is not, which is exactly why it drifts and exactly why it is worth keeping.
3. The four rules a cloud prompt must follow
The first three are the universal unattended-agent rules. The fourth is what the cloud adds.
- Never offer a choice. Nobody answers a question at 14:00 UTC on a Saturday. A prompt that asks
"which repositories should I include?" does not fail — it stalls, and the run is over before
anything happened. Give the parameter, or tell the agent to pick and say which it picked.
- Demand explicit failure reporting. An agent that cannot finish a step narrates success
instead.
completed means the agent finished its turn — never that the job was done. End every
prompt with: "If any step fails, say so explicitly in your final message and name the step that
failed, rather than summarizing what you would have produced."
- State the verification, and forbid a PR when it fails. Revert, leave the tree clean, say what
blocked it.
- Carry the one-open-PR rule in the prompt itself. A local runner can enforce this in code by
adopting an open branch. A cloud routine branches by hand and gets no such help, so its prompt
must say: check for an open PR on this prefix first; if one exists, commit onto that branch and
comment on the PR rather than cutting a new one.
Why rule 4 exists: two runs a day apart both branched from the base while the first PR sat
unmerged. Each read a work list missing the other's changes, picked the same item, and
reimplemented it. The two PRs shared nine identical files and one had to be closed. Code fixed the
local case; the cloud case is only ever fixed in prose.
4. Cronsole's side, in one paragraph
CLAUDE_CODE is a dual-mode connector, and what it can do depends on the install, not on the
platform. With a readable Claude Code session on the Cronsole backend's host it uses the
undocumented OAuth /v1/code/triggers API and gets a real sync plus create, setStatus,
updateSchedule and run. Without one it falls back to the documented per-routine fire token:
run only, and syncTasks returns the routines you declared in config — which is not a sync and
is documented as not being one. So unsupportedVerbs is a getter, and a capability matrix read
on one machine does not describe another. Neither mode can delete. Full detail, and what every
reading on screen means, in references/cronsole-side.md.
5. Anti-patterns
- Putting a job in the cloud that needs a specific machine. No local state reaches it. If the
work needs installed dependencies, a
.env, a running service or a local path, it is a local job.
- Creating a routine without registering its branch prefix with whatever reviews and merges its
PRs. It will open them forever and nothing will ever merge them.
- Trusting
completed. Read the step list.
- Assuming
CronList shows the fleet. It is session-scoped and shows nothing.
- Trying to delete a routine from Cronsole. No verb exists in either mode, by enumeration.
Disconnecting the Claude source removes its tracked tasks along with the declaration — that is
not a delete, and it is not reversible without re-declaring.
- Keeping the prompt only in the dashboard. It is the only artifact and it has no history.
- Copying a prompt between routines. The infrastructure is generic; the prompt is not.
Related
| For |
See |
| Scheduled agent jobs on a local machine |
the cronsole-windows-jobs skill |
| Cronsole's own create/schedule/manage rules |
Cronsole's cronsole skill → references/task-authoring.md |
| Choosing a model tier for a routine |
the task-router skill |
1---2name: cronsole-claude-routines3description: Design, create and track a Claude Code cloud routine — a scheduled agent run on Anthropic's infrastructure that opens a pull request — and connect it to Cronsole's CLAUDE_CODE source. Use whenever the user wants a recurring cloud agent, a scheduled Claude routine, a weekly drift check, or a docs/catalog refresh that runs by itself; whenever they want to list, pause, edit, retire or debug an existing routine; whenever a routine "ran" but opened nothing, or Cronsole shows no Claude routines, cannot pause one, or reports them all UNKNOWN. Also use to decide whether a scheduled agent job belongs in the cloud or on a local machine before building it.4---56# Claude Code routines — scheduled agents in the cloud78A **routine** is a prompt Anthropic runs on a schedule, in an isolated checkout, ending in a pull9request. It is one of two places a scheduled agent job can live, and picking the wrong one is the10expensive mistake.1112| | **Cloud routine — this skill** | **Local scheduled job** |13|:---|:---|:---|14| Runs on | Anthropic's infrastructure, isolated checkout | your machine, via the OS scheduler |15| Needs | a repo it can reach and a prompt | a machine that is awake |16| Config | the dashboard. **Nothing on disk.** | files you own and can diff |17| Can reach | the repo, plus whatever you granted | anything the machine can |18| Managed with | `/schedule`, or the `RemoteTrigger` tool | a registrar (→ `cronsole-windows-jobs`) |19| Cronsole sees it as | `CLAUDE_CODE` | `WINDOWS_TASK_SCHEDULER` |2021**Choose the cloud when the work needs no local state** — no installed dependencies, no `.env`, no22local service, no machine that has to be on. **Choose local** when it does, or when the work must23touch that machine.2425---2627## 1. The three constraints that shape everything28291. **Nothing lives locally.** There is no config file and no prompt on disk. The routine's entire30 definition is in the dashboard, which means **the prompt is the only artifact** — there is no31 version history behind it and nothing to diff when a run goes wrong. **Keep your own copy of every32 prompt** in the repo it acts on, or in a notes folder. Nothing else will.332. **You cannot enumerate the fleet from a fresh session.** `CronList` is session-scoped and shows34 nothing from another session. Use `/schedule`, or `RemoteTrigger` with `{action: "list"}`. Do not35 read its silence as an empty fleet.363. **Deleting is dashboard-only.** No API surface Cronsole has can remove a routine. The reversible37 move is to **turn one off** and leave it.3839---4041## 2. Build one4243| Step | What |44|:---|:---|45| 1 | **Pick the routine type** → [`references/routine-types.md`](references/routine-types.md). Four shapes cover almost everything worth scheduling. |46| 2 | **Write the prompt.** It is the whole product — same file, § "The prompt contract". |47| 3 | **Pick a branch prefix**, and register it with whatever merges your PRs, in the same change. |48| 4 | **Pick a UTC time.** Routines fire in UTC; any local fleet you are avoiding shifts twice a year. |49| 5 | **Create it** with `/schedule`, or `RemoteTrigger`. |50| 6 | **Track it in Cronsole** → [`references/cronsole-side.md`](references/cronsole-side.md). |51| 7 | **Verify by reading the run's step list**, never its status. |5253### Keep a fleet inventory5455A cloud fleet has **no local record at all**, so a routine you forget about keeps running, keeps56opening PRs, and keeps costing money. Write down — anywhere you will actually look — each routine's57name, repo, branch prefix, fire time and whether it is on. The dashboard is the source of truth and58your inventory is not, which is exactly why it drifts and exactly why it is worth keeping.5960---6162## 3. The four rules a cloud prompt must follow6364The first three are the universal unattended-agent rules. The fourth is what the cloud adds.65661. **Never offer a choice.** Nobody answers a question at 14:00 UTC on a Saturday. A prompt that asks67 *"which repositories should I include?"* does not fail — it **stalls**, and the run is over before68 anything happened. Give the parameter, or tell the agent to pick and say which it picked.692. **Demand explicit failure reporting.** An agent that cannot finish a step **narrates success70 instead**. `completed` means *the agent finished its turn* — never that the job was done. End every71 prompt with: *"If any step fails, say so explicitly in your final message and name the step that72 failed, rather than summarizing what you would have produced."*733. **State the verification, and forbid a PR when it fails.** Revert, leave the tree clean, say what74 blocked it.754. **Carry the one-open-PR rule in the prompt itself.** A local runner can enforce this in code by76 adopting an open branch. **A cloud routine branches by hand and gets no such help**, so its prompt77 must say: *check for an open PR on this prefix first; if one exists, commit onto that branch and78 comment on the PR rather than cutting a new one.*7980> Why rule 4 exists: two runs a day apart both branched from the base while the first PR sat81> unmerged. Each read a work list missing the other's changes, picked the same item, and82> reimplemented it. The two PRs shared nine identical files and one had to be closed. Code fixed the83> local case; the cloud case is only ever fixed in prose.8485---8687## 4. Cronsole's side, in one paragraph8889`CLAUDE_CODE` is a **dual-mode** connector, and **what it can do depends on the install, not on the90platform**. With a readable Claude Code session on the Cronsole backend's host it uses the91undocumented OAuth `/v1/code/triggers` API and gets a real sync plus `create`, `setStatus`,92`updateSchedule` and `run`. Without one it falls back to the documented per-routine fire token:93`run` only, and `syncTasks` returns **the routines you declared in config** — which is not a sync and94is documented as not being one. So `unsupportedVerbs` is a **getter**, and a capability matrix read95on one machine does not describe another. **Neither mode can delete.** Full detail, and what every96reading on screen means, in [`references/cronsole-side.md`](references/cronsole-side.md).9798---99100## 5. Anti-patterns101102- **Putting a job in the cloud that needs a specific machine.** No local state reaches it. If the103 work needs installed dependencies, a `.env`, a running service or a local path, it is a local job.104- **Creating a routine without registering its branch prefix** with whatever reviews and merges its105 PRs. It will open them forever and nothing will ever merge them.106- **Trusting `completed`.** Read the step list.107- **Assuming `CronList` shows the fleet.** It is session-scoped and shows nothing.108- **Trying to delete a routine from Cronsole.** No verb exists in either mode, by enumeration.109 Disconnecting the Claude source removes its *tracked tasks* along with the declaration — that is110 not a delete, and it is not reversible without re-declaring.111- **Keeping the prompt only in the dashboard.** It is the only artifact and it has no history.112- **Copying a prompt between routines.** The infrastructure is generic; the prompt is not.113114---115116## Related117118| For | See |119|:---|:---|120| Scheduled agent jobs on a local machine | the `cronsole-windows-jobs` skill |121| Cronsole's own create/schedule/manage rules | Cronsole's `cronsole` skill → `references/task-authoring.md` |122| Choosing a model tier for a routine | the `task-router` skill |