Back to Research

How Codex works, and where it stops working

A practitioner view of how Codex work gets done: the read-plan-edit-verify loop, what the sandbox allows, and the tasks where it reliably falls over.

La Mare, landscape painting by Théodore Rousseau (1842).
Rogier MullerAugust 15, 20263 min read

The loop that makes Codex work

Strip away the interface and Codex work is one cycle repeating: read some files, decide on a step, run a command or make an edit, look at what came back, decide again. It keeps going until it thinks the task is done or until it hits an approval it needs from you.

Two things follow from that, and they explain most of what people find surprising.

First, the agent only knows what it read. It does not have your architecture in its head. If the constraint lives in a design doc in Notion, it does not exist. Second, the quality of every decision after step one depends on what the previous commands returned. A test suite that prints 800 lines of warnings before the result is actively harmful, because the useful signal is buried in noise the agent has to carry forward.

The sandbox decides what it can do to you

Codex CLI runs with a configurable level of access. Read-only means it inspects and proposes but changes nothing. A workspace-write mode lets it edit files inside the project directory. There is a full-access mode with approvals off, which is right for a throwaway container and wrong for a laptop with production credentials in the environment.

Set the default in ~/.codex/config.toml rather than relying on people to remember a flag under time pressure. Then be deliberate about when you raise it. The heuristic we teach: if the worst outcome of the run is a bad diff, let it write. If the worst outcome involves the network or a package manager, keep a human in the approval path.

What reliably does not work

Being specific here is more useful than a caveat paragraph.

  • Anything requiring knowledge of an internal library that changed recently. It will confidently call the old signature.
  • Debugging that needs a running system it cannot see. If reproducing the bug needs three services and a queue, it is guessing.
  • Large renames across a codebase with dynamic dispatch or string-based lookups. It gets the static call sites and misses the reflective ones.
  • Judging whether a change is a good idea. It will implement a bad plan very competently.
  • Long unattended runs on ambiguous tasks. Ambiguity does not resolve over time, it compounds.

Making the loop work better

Three changes give the most return, and none of them are prompt tricks. Put a short AGENTS.md at the repo root listing the build and test commands plus any directory that should be left alone. Make your test output quiet on success, because pytest -q or the equivalent gives the agent a clean signal instead of a wall of text. And give it a way to check its own work, so it stops when the check passes instead of when it runs out of ideas.

Teams that do those three things get noticeably better results from the same model. It is unglamorous and it is most of the job.

Where to start

Run one task you already know the answer to. Something you fixed last week. Watch the sequence of commands it chooses and note the first point where it went somewhere you would not have. That moment tells you what context was missing, and that missing context is what belongs in your AGENTS.md.

If you want help putting this into practice, talk to us.

Related training topics

Related research

Ready to start?

Transform how your team builds software.

Book a 15-minute sync