Skip to main content
Module 5: The Fable 5 Era 7 / 8
Advanced Session 31 Autonomy Loops Cron Scheduling

Scheduled Autonomy: Loops, Wakeups & Cron

Master Claude Code's scheduled autonomy: /loop dynamic mode, ScheduleWakeup timing, prompt-cache economics, and cron jobs for standing automation.

July 8, 2026 17 min read

What You’ll Learn

In Session 11 you saw agents that operate without a human in the loop. This session covers the missing dimension: time. An agent that watches a deploy or runs a nightly audit must decide not just what to do, but when to wake up and do it — and in the Fable 5 era, that decision has real economics attached.

By the end, you’ll understand:

  • How /loop works, and what “dynamic mode” means
  • The ScheduleWakeup tool: delay clamping, self-scheduling, and stop semantics
  • Prompt-cache economics — why a 300-second sleep is the worst of both worlds
  • What to poll (external state) and what never to poll (harness-tracked work)
  • Standing cron jobs vs one-shot wakeups
  • Why foreground sleeps are blocked, and what to use instead (Monitor, background Bash)

The Problem

Say you push a commit and want Claude Code to merge the PR once CI goes green. CI takes about eight minutes. What does the agent do for those eight minutes?

The naive options are all bad:

Option 1: Busy-wait          Option 2: sleep 480       Option 3: poll every 60 s
┌──────────────────┐         ┌──────────────────┐      ┌──────────────────┐
│ Check. Check.    │         │ Block the whole  │      │ 8 wake-ups, 8    │
│ Check. Check...  │         │ session on a     │      │ full turns, for  │
│ Burns tokens     │         │ foreground sleep │      │ one bit of info  │
│ continuously     │         │ (blocked anyway) │      │ ("done yet?")    │
└──────────────────┘         └──────────────────┘      └──────────────────┘

There’s a subtler problem underneath: sleeping is not free either. Anthropic’s prompt cache has a TTL of roughly five minutes. Wake within the TTL and the next turn reads your accumulated context from cache — cheap. Sleep past it and the entire context is re-read uncached, at full price, on every wake.

So scheduled autonomy is really two problems: a mechanism problem (how does an agent resume itself?) and an economics problem (which intervals are cheap, and which are traps?). The Fable 5-era harness answers both.

How It Works

/loop and Dynamic Mode

/loop runs a task repeatedly. You can give it a fixed interval, or run it in dynamic mode — no fixed interval at all. In dynamic mode, the model paces itself using a tool called ScheduleWakeup: at the end of each iteration it schedules its own resumption, passing the same loop prompt back to itself.

Dynamic loop lifecycle:

  ┌────────────┐   ScheduleWakeup    ┌────────────┐
  │ Iteration N │ ──(delaySeconds)──▶ │   sleep    │
  └────────────┘                     └─────┬──────┘
        ▲                                  │ harness re-invokes
        │            same loop prompt      │ with the loop prompt
        └──────────────────────────────────┘

  Exit: ScheduleWakeup with stop: true → loop ends

The interval is a decision the model makes each round, not a config value. A CI watch and a nightly tidy-up job need completely different pacing, and only the agent in the loop knows which situation it’s in.

ScheduleWakeup Semantics

Two fields matter:

  • delaySeconds — clamped to the range [60, 3600]. Ask for 10 seconds, you get 60. Ask for two hours, you get 3600. The floor stops runaway tight-looping; the ceiling guarantees the loop checks in at least hourly.
  • stop: true — ends the loop. When the goal is reached (or is unreachable), the agent stops scheduling and the loop terminates cleanly.
ScheduleWakeup(delaySeconds: 270)   # resume in 4.5 minutes
ScheduleWakeup(stop: true)          # goal reached — end the loop

The Prompt-Cache Cliff

Here is the number that should drive every delay you choose: the prompt cache lives for about five minutes (300 seconds). That single fact splits the delay range into three regimes:

delaySeconds chosen
 60 ──────── 270 ─ 300 ─────────── 1200 ──────── 1800 ────── 3600
 │  WARM ZONE  │ CLIFF │  DEAD ZONE  │   COMMITTED SLEEP ZONE   │
 │  cache hit  │ worst │ cache miss, │  cache miss, but one     │
 │  every wake │ of    │ yet you're  │  miss buys 20–60 min     │
 │             │ both  │ still waking│  of silence — worth it   │
 │             │       │ frequently  │                          │
  • Under ~270 s — you wake before the cache expires; every wake reads context warm. This is the regime for active polling, and ~270 (not 290) leaves margin under the cliff.
  • ~300 s — the worst-of-both choice: just long enough to lose the cache, so every wake pays a full uncached read — while still waking every five minutes.
  • 1200 s and up — committed sleep. The wake is a cache miss, but one miss buys 20–60 minutes of not running at all. For idle ticks, 1200–1800 s is the sane default.

The anti-pattern is the dead zone between the cliff and a committed sleep: cold-read prices at warm-poll frequency. Pick a regime deliberately — this is Session 21’s cost-optimization thinking applied to the time axis.

Poll External State — Never Harness-Tracked Work

The second discipline: know what deserves polling at all.

Work the harness itself tracks — background Bash commands, spawned agents, running workflows (the machinery from Session 8) — re-invokes the agent automatically when it finishes. Polling it is pure waste: the harness would have told you anyway. The only wakeup worth scheduling against harness-tracked work is a long fallback, a single distant check in case something hangs.

What deserves polling is external state: CI runs, deploy rollouts, remote queues — things that change outside the harness’s view. Match the delay to how fast that state changes: an eight-minute pipeline doesn’t need a 60-second poll; a queue that drains hourly doesn’t need a five-minute one.

Cron Jobs vs One-Shot Wakeups

ScheduleWakeup is a one-shot: it fires once, and the loop must re-schedule each round. For standing jobs — a nightly report, a periodic health check — the harness has cron tools: CronCreate, CronList, and CronDelete manage recurring scheduled jobs that persist independently of any loop.

Both mechanisms drive autonomous loops, and the harness marks those turns with sentinel prompts — <<autonomous-loop>> for cron mode, <<autonomous-loop-dynamic>> for ScheduleWakeup mode — so the agent knows it’s running as an unattended loop rather than answering a human. You’ll see these sentinels in transcripts; you don’t need to manage them yourself.

No Foreground Sleeps

Two supporting rules complete the picture:

  • Foreground sleeps are blocked. You can’t park a turn on sleep 480. To wait on a condition, use the Monitor tool — an until-loop over a status — instead of blocking the session.
  • Background Bash runs a command detached via run_in_background (no & needed). It keeps running across turns and re-invokes the agent when it exits — which is exactly why you never poll it.

Hands-On Example

Let’s pace a real CI watch. You’ve pushed a commit; the pipeline historically takes about eight minutes. The loop’s job: wake up, check the PR’s checks, merge when green, and stop.

First, compare the three candidate schedules:

Pipeline duration: ~480 s (8 min)

Strategy A: 60 s polls        W─W─W─W─W─W─W─W─✓     8 wakes, all warm
                              8 turns for 1 bit of information

Strategy B: one 480 s sleep   ────────cold────✓      1 wake, full uncached
                              context re-read at the moment you act

Strategy C: two 270 s sleeps  ───warm───┬──warm──✓   2 wakes, BOTH cached
                              (270 s)   (540 s ≈ 9 min — CI done)

Strategy C wins: each sleep stays under the ~300 s cache TTL, so both wakes read context warm, and two turns is a quarter of Strategy A’s overhead. The loop iterations look like this:

# Iteration 1 (t = 0): just pushed. CI will take ~8 min.
gh pr checks 142        # → pending
# Too early to poll tightly. Sleep just under the cache TTL.
# ScheduleWakeup(delaySeconds: 270)

# Iteration 2 (t = 270 s): warm wake — context read from cache.
gh pr checks 142        # → still running (expected; ~4.5 min elapsed)
# ScheduleWakeup(delaySeconds: 270)

# Iteration 3 (t = 540 s): warm wake again. ~9 min elapsed.
gh pr checks 142        # → all checks passed
gh pr merge 142 --squash
# Goal reached:
# ScheduleWakeup(stop: true)

Two judgment calls worth noticing:

  1. If the pipeline took 25 minutes instead, warm polling stops making sense. Commit to the other regime — a single delaySeconds: 1500 sleep. One cache miss buys the whole wait.
  2. If the “pipeline” were a local test suite launched with background Bash, you wouldn’t schedule polls at all — the harness re-invokes you when the command exits. At most, set one distant fallback (delaySeconds: 1800) in case it hangs.

And when the loop finally acts, the norms from Session 11 apply: reversible, in-scope actions (merging the PR you were asked to merge) proceed without asking; destructive or scope-changing decisions are where an autonomous loop stops and reports instead.

What Changed

BeforeFable 5 Era
Autonomy meant a foreground session you babysatLoops schedule their own wakeups with ScheduleWakeup
Fixed polling intervals, chosen onceDelay chosen per iteration, per cost regime
sleep 480 in the shellForeground sleeps blocked; Monitor waits on conditions
Poll everything, including your own background tasksHarness-tracked work auto re-invokes; poll only external state
Recurring jobs wired up in external cronCronCreate/CronList/CronDelete standing jobs in-harness
Sleep duration was an afterthoughtThe ~5-minute cache TTL makes it a priced decision

Key Insight

An agent that knows when to wake is cheaper than one that never sleeps.

Everything in this session — clamps, TTLs, sentinels — serves one idea: in scheduled autonomy, the interval is part of the answer. A loop that sleeps 300 seconds and one that sleeps 270 look almost identical, but sit on opposite sides of a price cliff. The ~5-minute cache TTL leaves exactly two good regimes — stay warm (under ~270 s, actively converging) or commit to the sleep (1200 s+, idling) — and the cheapest schedule of all is no schedule, because harness-tracked work reports back on its own.

Fixed cron answers “run this every night.” Dynamic wakeups answer the harder question — “how long is this particular wait worth?” — and that judgment is what you gain by letting the model hold the clock.

Next Session

Session 32 closes the module with The New Tool Belt: Artifacts, Tasks & Typed Outputs — the user-facing tools of the Fable 5 era: hosted Artifacts pages, the task system that replaced TodoWrite, typed review findings, and how background work surfaces as tracked tasks.