Skip to main content
The scheduler lets your agents work on a schedule — sending periodic reports, running health checks, and even creating their own tasks from conversations. Think of it as a personal assistant’s calendar that agents manage themselves.

Three Scheduling Systems

Comis includes three complementary scheduling systems, each designed for a different kind of automated work.

Cron Jobs

Cron jobs are recurring tasks that run on a schedule, like “check email every morning” or “send a daily summary at 5pm.” Your agents create and manage cron jobs using the scheduling tools — you configure the limits, and they handle the details.
Agents can create their own cron jobs using the scheduling tools. You set the limits (how many jobs, how many run at once); they decide what to schedule and when.

Heartbeat Monitoring

The heartbeat system runs periodic health checks at regular intervals (every 5 minutes by default). This is how the monitoring sources — disk space, CPU, memory, systemd services, and security updates — get checked.
The heartbeat uses wake coalescing — all monitoring checks are batched together into a single heartbeat cycle rather than each running independently. This prevents multiple checks from overwhelming the system simultaneously.

Task Extraction

During a conversation, your agent might notice follow-up work — “I should check back on this tomorrow” or “remind the user about that deadline.” Task extraction lets agents automatically schedule these follow-ups.
Task extraction is on by default — the agent is fully capable out of the box and proactively schedules follow-ups it notices in conversation (only above confidenceThreshold). Set enabled: false to opt out if you prefer the agent never self-schedules.

Quiet Hours

Quiet hours prevent non-critical scheduled tasks from running during specified times — for example, overnight when you do not want notifications.
When quiet hours are active, cron jobs and heartbeat alerts are suppressed. They resume when the quiet window ends.
Critical tasks (like security alerts) bypass quiet hours by default. Set criticalBypass: false only if you want complete silence during quiet hours.

Wake-Gate Efficiency

A polling cron job — “check the build queue every five minutes,” “scan the inbox every ten” — usually finds nothing changed, and waking the model on every empty fire is pure waste. A wake-gate lets a job answer “nothing to do” before the model runs: a small sandboxed script inspects the world and returns a verdict, and only a verdict that says “wake” spends a model turn. A gate can also deliver a routine ✓ status straight to the channel with no model turn at all — and that routine status honors quiet hours, so an all-clear ping never lands overnight. The gate is an efficiency layer, not a suppression control, and its posture is designed to stay legible to an operator:
  • Fail-open. A gate that errors, times out, over-caps its output, or returns no verdict wakes the model. A broken gate can never silently drop a monitored job — the worst a misbehaving gate does is wake the model too often (spending turns), never too rarely (missing an alert).
  • Skip-rate. The share of a job’s fires the gate skipped. A high skip-rate is usually the gate working — most polls found nothing — not a fault. A gate at a 100% skip-rate on a monitor you expect to fire is the signal to inspect: it may be genuinely quiet, or its logic may have broken toward always-skip.
  • Net cost. A gate’s own tool calls (its web_fetch/read/grep cost) sit beside the model turns it saved. A gate whose tool-call cost exceeds the turns it avoids is not paying for itself — compare the two numbers directly.
These signals roll up per agent in the comis fleet health report (skip-rate, turns-saved, tool-call cost — counts only, never the gate’s gathered findings), and each per-fire decision is visible in the job’s run history via cron.runs. Because the gate runs under the agent’s own autonomy capabilities in the standard jail, it grants no new reach — see the capability model for the suppression bound. Scheduler-initiated gates are governed fleet-wide by the scheduler.cron.wakeGate toggle. It defaults to each agent’s autonomy script surface — where an agent may run orchestrate scripts, its cron jobs may run wake-gates. Set it to false to disable scheduler-initiated pre-run gates while still allowing model-initiated orchestrate: a scheduler gate is a distinct trust context (no human or model in the loop at fire time), and with the toggle off a gated job simply runs as it would with no gate. The toggle grants no capability — it only decides whether the pre-run script runs.

Safety

The scheduler includes several safety mechanisms to prevent runaway tasks:
  • Lock files prevent the same cron job from running twice simultaneously
  • maxConcurrentRuns limits how many jobs can execute at the same time (default: 3)
  • staleMs detects stuck tasks that have been running too long (default: 2 minutes)
  • maxJobs caps the total number of scheduled jobs (default: 100)
If a task exceeds the stale timeout, the scheduler marks it as stuck and releases the lock so it can run again on the next cycle.

Full Configuration Reference

Monitoring

The 5 health sources checked by heartbeat

Daemon

The process that runs the scheduler

Agent Lifecycle

How agents process messages and use tools

Scheduler View

View and manage scheduled tasks in the dashboard