# Loops and Autonomous Runs: /loop, Iteration, and Scheduling
Some work is not one task but the same task on repeat until a condition is met. "Keep fixing bugs until every test passes." "Poll the deploy every minute until it's live, then tell me." "Every morning at 8, summarize what changed in the repo overnight." A single call to Claude cannot do any of these, because none of them are single actions. They are loops with a stop condition.
This lesson is about running Claude Code in a loop: iterating until a goal is met, running autonomously without you babysitting each step, and scheduling an agent to fire on a cadence. Just as importantly, it is about the guardrails that keep an unattended loop from burning your tokentokenA token is the basic unit of text that language models process, often a word fragment, whole word, or punctuation mark rather than a single character.Voir la définition complète → budget or your codebase.
A loop is worth reaching for when three things are true:
If none of those hold, a single call is cleaner and cheaper. Do not loop just because you can. "Refactor this function" is one call. "Refactor every function until the linter is silent" is a loop.
Claude Code runs in your terminal and already has access to your files, your shell, and your git history. The /loop slash command tells it to repeat a task rather than run it once.
There are two flavors:
Self-paced iteration runs the task, checks a condition, and decides whether to run again. This is the "keep going until X" pattern. Claude does the work, evaluates its own output against the stop condition, and either continues or stops.
Interval iteration runs the task on a delay: do the thing, wait N seconds or minutes, do it again. This is the polling pattern, useful when you're waiting on something outside your control (a CI run, a deploy, an external APIAPIApplication Programming Interface: a standardised interface that lets applications communicate and exchange data without knowing each other's internal workings.Voir la définition complète →).
The shape of the command is a task plus a stop condition plus a budget:
claude
> /loop "Run the full test suite with pytest. If any tests fail, \
read the failure output, fix the code (not the tests), and run \
the suite again. Stop when all tests pass or after 10 iterations." \
--max-iterations 10Notice three things baked into that prompt. The task is explicit (run pytest, fix code). The stop condition is unambiguous (all tests pass). And there's a hard cap (10 iterations) so a stubborn bug cannot spin forever.
"Fix the code until it looks good" is not a loop condition. Claude has no objective signal to check against, so it will either stop arbitrarily or keep polishing forever. "Fix the code until pytest exits 0" is checkable: the exit code is a fact, not a judgment.
Good loop conditions are things a command can answer:
pytest exit code is 0npm run build succeedsgit status shows no uncommitted changesAnytime you can express "done" as a command that returns success or failure, you have a loop you can trust to stop on its own.
This is the canonical use case, so let's make it concrete. You have a test suite with a handful of failures after a messy merge. You want Claude to iterate: run tests, read what broke, patch the source, run again, until the whole suite is green.
claude
> /loop "Goal: make the entire test suite pass.
1. Run: pytest -x --tb=short
2. If exit code is 0, the goal is met. Stop and summarize what changed.
3. If tests failed, read the traceback, fix the SOURCE code only.
Never edit or delete tests to make them pass.
4. Commit each fix with a clear message, then repeat from step 1.
Budget: stop after 8 iterations and report if not green by then." \
--max-iterations 8Read the guardrails hidden in that prompt. Step 3 forbids the single most common cheat an autonomous agent will reachreachThe number of unique people exposed to your message in a given period. Unlike impressions, reach counts each person once, no matter how often they see it.Voir la définition complète → for: deleting the failing test. Left unconstrained, a model asked to "make tests pass" may well decide the fastest path is to remove the test. The instruction "fix the SOURCE code only, never edit tests" closes that door.
The commit-per-fix instruction matters too. It gives you a clean git history to review and an easy revert if one of Claude's fixes was wrong. When the loop ends, you review the diff, not the process.
This is exactly the kind of task where the loop earns its keep. A single call would fix one round of failures and stop, likely revealing a second round it never touched. The loop grinds through all of it while you do something else.
The moment a loop runs without you watching each step, it can do damage or waste money at machine speed. Three guardrails are non-negotiable.
Every loop needs a ceiling that does not depend on the model's judgment. Iteration count is the simplest (--max-iterations). You can also cap wall-clock time or set a tokentokenA token is the basic unit of text that language models process, often a word fragment, whole word, or punctuation mark rather than a single character.Voir la définition complète → budget so a runaway loop hits a wall before it hits your bill. The budget is a backstop for when the stop condition never triggers, because sometimes the tests genuinely cannot be made to pass, and you want the loop to give up and tell you, not to keep trying forever.
Covered above, but it belongs on the guardrail list because it is the primary safety mechanism. The budget is the backstop; the stop condition is the intended exit. A loop with a budget but no real stop condition just burns to the cap every time.
For anything that changes state (writes code, pushes commits, sends messages, calls a paid APIAPIApplication Programming Interface: a standardised interface that lets applications communicate and exchange data without knowing each other's internal workings.Voir la définition complète →), decide in advance where a human signs off. Two common patterns:
You control this through Claude Code's permission settings. Constrain what tools the agent may use and which directories it may touch before you let it run unattended. The Claude Code documentation covers permission modes and tool configuration in detail.
A useful mental rule: the more autonomous the run, the tighter the sandbox. A loop you watch can have broad permissions. A loop that runs at 3am while you sleep should be able to touch almost nothing except the one thing it's there to do.
Vérification des acquis
1. According to the lesson, why can't a single call to Claude accomplish a task like 'keep fixing bugs until every test passes'?
2. The lesson stresses that if you 'cannot describe done precisely, you cannot loop safely.' What is the underlying reason this matters?
3. Which scenario best justifies reaching for a loop rather than a single call?
4. Select ALL correct answers. According to the lesson, which conditions should be true before choosing a loop over a single call?
Sélectionnez toutes les réponses correctes.
5. Select ALL correct answers about the distinction between self-paced and interval iteration in /loop.
Sélectionnez toutes les réponses correctes.
Iteration answers "repeat until done." Scheduling answers "run again later, on a rhythm." A recurring digest, a nightly dependency check, a weekly report: these are not loops that spin until a condition, they are tasks that wake up on a schedule.
Claude Code itself does not run a background daemon. You schedule it the same way you schedule any command-line tool: with your operating system's scheduler (cron on Linux and macOS, Task Scheduler on Windows) or a CI runner like GitHub Actions.
Here's a nightly repo digest as a cron entry that runs Claude in non-interactive (headless) mode:
# Every weekday at 8:00 AM, summarize overnight git activity
0 8 * * 1-5 cd /home/me/project && \
claude -p "Summarize commits from the last 24 hours grouped by \
author. Flag anything touching auth/ or billing/. Output markdown." \
>> ~/digests/daily-$(date +\%F).md 2>&1The -p flag runs a single prompt and exits, which is exactly what you want for a scheduled job: no interactive session, deterministic start and finish, output redirected to a file. Pair this with a connector or an MCP server and the same scheduled run could post that digest to Slack or open a GitHub issue.
For scheduling that lives with your repo rather than one machine, GitHub Actions is the natural home. Anthropic's official GitHub integration lets you trigger Claude on a schedule or on repo events (a new PR, an issue labeled a certain way). A weekly on: schedule workflow that runs Claude to audit dependencies and open a PR is a clean, reviewable, scheduled autonomous run.
A scheduled job is autonomous by definition: nobody is watching when it fires. Everything from the guardrails section applies double. Give it a budget, give it a stop condition even for a one-shot digest (so a hung external call doesn't leave it running), and route anything that changes state through a review gate. A scheduled run that opens a PR is safe. A scheduled run that pushes to main is a foot-gun waiting for a bad night.
Quick decision guide:
The most powerful setups combine them: a scheduled workflow that fires nightly and, inside that run, loops until its dependency upgrades pass CI. Cadence on the outside, iteration on the inside.
cron, Task Scheduler, or GitHub Actions running claude -p in headless mode. Claude Code is the worker, not the scheduler.