`##cron`: agents on a schedule
An agent that only works while you watch isn't autonomous — it's supervised. ##cron gives rysh agents a calendar: nightly triage, morning briefs.
Be honest about your "autonomous" agents: do they do anything when you're not looking?
For most setups, the answer is no. The agent works while the chat window is open and you're feeding it turns. Close the laptop and your tireless AI workforce is a parked process. That's not autonomy — that's supervised labor with good branding.
The oldest trick in operations fixes this, and it's older than most of us: cron. Unix figured out in the 1970s that the computer should work on a clock, not on your presence. Rysh applies that idea to agents: ##cron, the built-in scheduler for a workspace where panes are conversations.
The shape of it
##cron is part of rysh's ## command language — the little system shell you type straight into any pane. Schedule work, list what's scheduled, and check when each job ran:
##cron add nightly "0 3 * * *" --pane triage --mode prompt <prompt>
##cron list # what's scheduled, next run, last status
##cron run nightly # fire it now, without waiting
##cron logs nightly # when each run fired, and whether it was dispatched
The thing being scheduled doesn't have to be a shell one-liner (though bare text defaults to one). With --mode prompt it's a prompt to an agent in a pane — which changes what "scheduled job" means. A cron job that runs npm audit gives you a wall of CVEs at 6am. An agent on the same schedule reads that wall, checks which findings actually touch code paths you use, drafts the upgrade PR description, and leaves a summary in its pane. The clock triggers judgment, not just execution.
What to schedule
The patterns that fit are the unglamorous, compounding kind:
- Nightly dependency triage. Audit, cross-reference, summarize: "2 of 14 advisories affect us; here's the diff that fixes both."
- Morning briefs. Before standup: what merged yesterday, what's red in CI, which TODOs went stale.
- Slow-drift watchers. Disk usage, error-log anomalies, that one flaky test's failure rate — checked on a cadence, escalated only when the trend is real.
- Scheduled browser runs. Rysh's autonomous web recipes compose with scheduling — a scouting or checking task re-run on cadence, results kept per recipe (
##auto web results). (##auto web schedule <name>exists for exactly this pairing: it schedules the recipe on its ownschedule:key.)
None of these justify a human's morning. All of them justify an agent's 3am.
Where the results go — and why that's the good part
Here's what separates ##cron from "cron + a script that calls an API": the job runs in a pane, in a session.
Rysh sessions are daemons with persistent state. Detach with Ctrl+O d, and the session keeps living; each pane's recent output is persisted to JetStream KV on your machine. So a scheduled agent's work lands somewhere with a memory:
rysh attach ops # next morning
# the triage pane holds the run's output (the most recent 20 KB by default):
# what it ran, what it read, what it concluded — and ##cron logs nightly
# lists when each run fired
You don't get a notification that work happened. You get the workspace where it happened. And when a run should reach out, ##auto recipes — scheduled ones included — can carry a notify: key that pings a channel when the run ends and an on_success: key that chains the next recipe — so the 3am run doesn't wait politely until you attach.
The governance question you should be asking
"An agent acting on a schedule, with nobody watching" should raise your eyebrows. Good. Here's the honest answer.
A prompt fired by ##cron takes the same path as one you type — the gates live in the execution layer, not in your attention:
- Commands on the bash allowlist (git reads,
ls,grep, builds, tests) run free — which is why triage, briefs, and watchers are the natural cron workloads: they're mostly investigation. - Anything not on the list asks for approval — and an approval nobody answers within five minutes counts as a no, so at 3am the action simply doesn't happen. The gate is off only where you switched it off (a policy rule, a "yes, always" given earlier in that pane, an
@agent, which auto-approves unless its file setsauto_approve: false), and a scheduled run inherits that. - Every tool call shows in the pane's output.
##cron logsplus the pane's output is the record.
So the honest framing: ##cron doesn't remove the human from the loop — it time-shifts the loop. The agent does the hours of looking while you sleep; you do the seconds of deciding when you're back. That's the right division of labor between a clock, a model, and a person.
All of it on your machines — sessions run on your hardware with your Anthropic key, and the schedule keeps ticking while the session daemon runs, whether or not a TUI is attached.
Your agents have a clock now. Give them a shift.
Running agents on a schedule in a real team? We want to build this with you — become a design partner: rysh.ai/design-partner.
More in this series: Sessions that survive: attach, detach, and never lose an agent mid-task · ##auto web: autonomous browser recipes in one markdown file