# Loops and Autonomous Runs in Codex
Some coding work is the same step on repeat until a condition is met: run the tests, read the failure, patch the code, run the tests again. That pattern is exactly what Codex was built to automate, not as a one-shot request but as an agentic loop that keeps editing and running until the task is actually done.
You already know an agent plans, acts, and observes. In Codex that loop is grounded in a real workspace: a checkout of your repo, a shell, and the ability to run commands. Each turn looks like this:
1. Read the task and the current repo state.
2. Decide on an action (edit a file, run a command).
3. Execute it in the sandbox and capture the output.
4. Compare the result against the goal. If not met, loop.
The critical difference from a single prompt is the observe step. Codex sees stdout, exit codes, and stack traces, then feeds them back into the next decision. That is why "make the tests pass" works: the test output *is* the signal that drives the next edit.
Codex comes in two shapes that share this engine: the CLI/IDE agent that runs locally against your working tree, and Codex cloud, which runs the loop on OpenAI's infrastructure against a connected GitHub repo. The cloud version is where autonomous and scheduled runs live. See the Codex documentation for the current surface.
A single request is right when the change is bounded and you can eyeball the diff. 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.View full definition → for a loop when the task has a verifiable stop condition the agent can check itself:
ruff, mypy, tsc: each returns a clean exit code you can loop against.The common thread: there is a machine-checkable oracle. If "done" is subjective ("make the UI nicer"), a loop just burns budget chasing a target it can't measure. Keep those as interactive sessions.
Here is the canonical loop. You give Codex the goal, the command that verifies it, and a ceiling. Locally, that looks like a prompt plus a config; in cloud you set it up per task. This YAML is the kind of task spec you'd hand a scheduled Codex run:
task: Fix the failing tests in the billing module.
repo: acme/payments
branch: fix/billing-tests
setup:
- pip install -e ".[dev]"
verify:
command: pytest tests/billing -q
success_when: exit_code == 0
limits:
max_iterations: 8
max_wall_clock_minutes: 20
on_success:
open_pull_request: true
reviewers: [payments-team]The loop the agent actually runs is trivial in pseudocode, and worth seeing so you know exactly what it's optimizing:
for attempt in range(max_iterations):
result = run("pytest tests/billing -q")
if result.exit_code == 0:
commit("fix: billing tests green")
break
# Codex reads result.stdout, edits the relevant files,
# then the loop re-runs the same command.
apply_fix(diagnose(result.stdout))
else:
report("gave up after max_iterations; latest diff attached")Two things make this safe rather than a runaway. First, verify.command is the *only* definition of success, so the agent can't declare victory on vibes. Second, the loop terminates on either green tests or a hard cap. There is no path where it runs forever.
In Codex cloud you connect a GitHub repo, then start tasks that run without you sitting there. There are three ways to trigger one:
main, fix any flakes, open a PR" job is the classic use.codex, say) using the Responses API with tools, or orchestrate multi-step control with the Agents SDK.The mental model: an on-demand run is you pressing go. A scheduled run is a cron job that happens to be an agent. Both drop their work into a branch and a pull request, never straight onto main.
Say you're migrating a codebase off a deprecated logging call. You don't want to babysit 40 files. Schedule a nightly run:
> "For up to 6 files still using old_logger, replace it with structlog per docs/logging.md, run pytest for each touched module, and open one PR titled chore: migrate logging (batch). Skip files where tests fail after the change and note them in the PR description."
That spec has a batch size (cost control), a per-file verify step (correctness), and an explicit escape hatch for the hard cases (don't force a broken change). Over a week the backlog drains itself, one reviewable PR at a time.
An unattended loop needs more than one exit. Design for all of these:
max_iterations stops the "edit, still red, edit again" spiral. If eight attempts don't get tests green, more attempts rarely will.State every cap explicitly. The failure mode of autonomous runs is not usually a bad edit; it's an agent thrashing against a problem it can't solve while the meter runs.
Every Codex cloud run executes in an isolated container: a fresh environment with your repo, no access to your other systems unless you grant it. That isolation is your first cost and safety boundary, because a loop that can't touch production can't cause a production incident.
Control spend at two levels:
Also control what the loop can reach. Network access in the Codex environment is configurable; for a test-fixing job, the agent needs your repo and package installs, not the open internet. Narrow the environment to what the task requires. A loop with fewer capabilities is a loop with fewer ways to surprise you.
Knowledge check
1. What is the critical step that distinguishes an agentic loop in Codex from a single one-shot prompt?
2. Why does a task like 'make the tests pass' work well as an agentic loop rather than a single request?
3. According to the lesson, which situation is best suited to a single request rather than an agentic loop?
4. Select ALL correct answers. Which characteristics describe tasks that are good candidates for an agentic loop in Codex?
Select all the correct answers.
5. Select ALL correct answers about the two shapes of Codex described in the lesson.
Select all the correct answers.
The single most important safety property: an autonomous Codex run produces a pull request, not a merge. The loop's output lands on a branch and waits for a human. Your existing GitHub protections still apply, and you should lean on them:
Think of it as a funnelfunnelThe customer journey from awareness to purchase, typically Awareness, Interest, Consideration, Decision, Action, with prospects narrowing at each stage.View full definition →: the loop iterates freely inside the sandbox, but the exit is a narrow, reviewable gate. Freedom *inside*, control *at the boundary*.
Because the run logs every action, its PRs come with a trail: which commands it ran, what output it saw, and why it made each edit. When you review, check three things: does the diff match the stated goal, did the verify command genuinely pass (not get disabled or @skip'd), and is the change scoped to what you asked. A loop that "passes tests" by deleting the failing test is the classic cheat. Read for it.
A well-designed autonomous run reads like a contract. Goal, a machine-checkable definition of done, hard caps on iterations and time, a narrow environment, and a PR-only exit. Give Codex all five and you can leave it alone overnight with the same confidence you'd give a junior engineer working a well-specified ticket: it either finishes the ticket or tells you why it couldn't.