Time itself becomes another launch trigger

What You’ll Learn

  • Why scheduling should reuse the agent loop
  • How to implement cron-based task triggering
  • How scheduled tasks differ from on-demand tasks

The Problem

When the agent can run background tasks, scheduling is the natural next step. But scheduling shouldn’t require a separate orchestration system.

The Solution

A cron scheduler that feeds the same agent loop — just triggered by a timer instead of a user.

User-triggered:                    Cron-triggered:
+--------+                         +--------+
| user   | ---> agent_loop(...)    | timer  | ---> agent_loop(prompt)
+--------+                         +--------+

How It Works

  1. A scheduler runs in its own thread, checking cron entries.

  2. When a cron fires, it injects a message into the main loop.

class CronScheduler:
    def __init__(self, agent_loop_fn):
        self.crons = []
        self.loop_fn = agent_loop_fn
        self.thread = threading.Thread(target=self._tick, daemon=True)
        self.thread.start()

    def add(self, schedule: str, prompt: str):
        self.crons.append({"schedule": parse_cron(schedule),
                            "prompt": prompt})

    def _tick(self):
        while True:
            now = datetime.now()
            for cron in self.crons:
                if cron["schedule"].matches(now):
                    self.loop_fn(cron["prompt"])
            time.sleep(30)
  1. Cron entries can be created by the agent itself — an agent that schedules its own future work.

What Changed From s13

ComponentBefore (s13)After (s14)
TriggersUser onlyUser + timer
SchedulingNoneCron expressions
Self-schedulingNoneAgent adds its own crons

Try It

cd learn-claude-code
python agents/s14_cron_scheduler.py
  1. Schedule a daily code review at 9 AM
  2. Set up a cron to check for dependency updates every Monday
  3. List all scheduled tasks and remove one

Key Takeaway

Scheduling is not a separate system — it just feeds the same agent loop from a timer. When background execution exists, time becomes another launch trigger.