Skip to content

Scheduler

The Scheduler is the Loop — the layer that lets an agent act on its own initiative rather than only in response to mail. Where the Gateway turns an incoming message into work, the Scheduler generates work on a clock. It's how Scout files The Scoop's low-stock report every morning without anyone emailing it.

Responsibilities

A responsibility is a standing duty an agent owns: an instruction plus a schedule. "Every morning at 8, check which flavors are low and email the ops team" is a responsibility — the instruction is the prompt, the schedule is a cron expression. Responsibilities are ordinary records, created and edited in the dashboard, so an operator can add or retune a duty without a deploy.

When a responsibility comes due it runs the owning agent through the very same inference cycle an email would trigger — the Harness — but through its proactive front door. There is no inbound message; the duty's own instructions become the opening turn. Same agent, same tools, same tool loop, different trigger.

The tick

The Loop runs on a simple heartbeat:

every minute


 find the responsibilities due this minute


 dispatch a run for each  ──►  Harness (proactive)  ──►  the agent acts

A recurring job fires once a minute, asks which active responsibilities are due right now, and dispatches a run for each. Every run is recorded, so the dashboard shows a history of when a duty fired and whether it succeeded — and, like any run, its tool activity is captured for observation and audit.

Deliberately minimal

The Scheduler does one thing — fire due duties — and intentionally leaves the rest to Rails:

  • No overlap guard. If a run is still going when the next tick fires, a second run can start. Keep a duty's cadence comfortably longer than its work takes.
  • No concurrency cap of its own. How many runs execute at once is bounded by your job queue's configuration, not by the Loop.
  • No stale recovery or minute-deduplication. A failed run is recorded and simply waits for its next scheduled minute.

This is a conscious trade: the Loop stays a thin, predictable dispatcher, and the durable concerns (retries, concurrency, backpressure) stay where your app already manages them — Active Job and your queue backend.

  • Scheduled work — giving Scout a responsibility, step by step.
  • Harness — the inference cycle both front doors share.
  • Personas — declaring an agent and the context its scheduled runs use.