Scheduler
Decides when work is enqueued. The scheduler holds schedule definitions, walks them on a tick, and fires when one comes due, pushing either a one-off agent job into dispatch or a whole run into sequence.
It owns no execution of its own. Firing means handing work to another app.
Three ways to say when#
| Trigger | Meaning |
|---|---|
| once | fire at a specific date and time, then complete |
| cron | a cron expression, with a timezone |
| interval | every 30s, 5m, 2h, 1d |
A schedule has exactly one of these.
Cron expressions are taken literally, since the scheduler does no
natural-language parsing. /toryo-schedule translates your description into an
expression and shows you the result before submitting, which is where an
ambiguous "every morning" gets resolved into something you can check.
Policies for the awkward cases#
- Overlap, what to do when the previous run is still going. The default,
skip, records the skip and waits for the next slot.allowfires anyway. - Misfire, what to do when the scheduler was down across missed firings. The
default,
fire-once, fires a single catch-up run and resumes the normal cadence rather than replaying every missed slot at once.skipignores them.
Editing and running by hand#
A schedule can be edited in place: change the timing, the payload, or both, and it keeps its id and its run history. Changing only the payload leaves the next fire time alone.
Run now fires a schedule immediately regardless of its trigger or status, even a paused one, and records the manual fire in history. It does not advance the schedule's normal cadence, so a nightly job you triggered by hand still runs that night.
Every fire is recorded, including the ones that skipped or failed to enqueue, so "did this actually run last night?" is answerable.
The system maintenance lane#
Some schedules are toryo's own, and you do not create them. On first boot the
scheduler materializes an owner=system lane and keeps it healthy: a deleted or
edited system schedule is restored on the next pass, and it is protected from
deletion. These run directly, without spending a Claude session.
What runs there today:
| Job | Cadence |
|---|---|
| Memory decay | daily, 03:15 |
| Session-debugger report | daily, 03:30 |
| Orphaned-knowledge sweep | daily, 03:45 |
| Full code-index reindex, per project | weekly, Sunday 04:00 |
| Janitor garbage collection | on an interval |
There is no setup step for any of this. A fresh install has it.
Where things go wrong#
- A schedule never fires. Check that it is
activerather than paused or completed, and that the scheduler daemon is green intoryo foreman check. - A schedule fires but nothing runs. The fire is recorded separately from the job it enqueued, so look at the history entry, which names the dispatch job or the enqueue error.
- A recurring job silently skipped. That is the overlap policy: the previous run was still going.
Full command surface: CLI & contract reference.