Codex as a Teammate, Not Autocomplete
The developers who get the most from an AI coding agent don't prompt better. They scope better, test better, and review better.
By Chuck McCullough, software architect and educator with more than 30 years designing, building, and teaching enterprise software systems.
An AI coding agent can feel like having a junior developer on the team. It is capable, fast, and useful, but still dependent on context, constraints, feedback, and review. The shift I want engineers to make is to stop asking an AI to write code and start running a reliable engineering workflow with an agent inside it. A feature tour teaches people where the buttons are. A workflow teaches them how to start with intent, give the agent the right context, constrain the change, verify the result, review the diff, and improve the system for next time.
That workflow matters even more because the tools are evolving so quickly. What required close supervision a year ago may now be safe to delegate for longer stretches, but only if you know how to plan the work, set guardrails, and review checkpoints. The same iterative, test-driven, review-focused practices that make a human engineer reliable also make an AI agent reliable.
The best mental model is an agentic teammate with tool access, bounded authority, and a need for review. Codex can reason about a codebase, make edits, run commands, create tests, and explain its work, but it does not own the product judgment or the architectural risk. Pair programmer, junior developer, and build agent are all useful metaphors, and the mistake is turning any one of them into the whole truth. Treat Codex like a human senior engineer and you may skip review. Treat it like autocomplete and you will underuse its ability to inspect, test, and iterate. Treat it like an unattended build script and you may hand it too much authority where judgment still matters. The best users do not just prompt better; they scope better, test better, review better, and encode what they learn into repository instructions, checklists, and repeatable practices.
Start by reading, not editing
When Codex meets an unfamiliar codebase, it should first establish the map: repository layout, README or developer docs, package or build files, test commands, entry points, existing conventions, and any agent guidance such as AGENTS.md. Then it should inspect the specific files related to the task, not the entire codebase indiscriminately.
Before any edits, I verify three things: that Codex found the right subsystem, that it understands the current behavior and the desired behavior, and that the proposed change is scoped to the right files. This matters most in unfamiliar repositories, because the first failure mode is not bad syntax. It is a plausible change in the wrong layer. Existing repositories are imperfect artifacts. They carry years of evolving patterns, dead code, and inconsistent conventions, so Codex has to understand that the first pattern it sees is not automatically the pattern it should follow.
The explanations Codex gives are only worth acting on when they are grounded. A trustworthy explanation points to concrete evidence. It names files, functions, command outputs, tests, call paths, configuration, and observed behavior, and it distinguishes what it saw from what it inferred. It also admits uncertainty, something like, I found this pattern in two routes, but I have not verified the background job path yet. Plausible narration is usually too smooth. It describes the system without showing where the claims came from, ignores exceptions, or confidently describes architecture that is not reflected in the code. The practical test is simple. Ask Codex to cite the files and lines that support its explanation, then ask what would disconfirm it. If it can answer both, you are closer to something you can act on. Correct explanations and hallucinations can look alike at first glance; the difference is that a correct explanation can be traced back to the codebase and a hallucination cannot.
Scope the work to a focused feature slice
A well-scoped task has a goal, relevant context, constraints, and a definition of done. For example: “Add CSV export to the reports page using the existing export service. Do not introduce a new dependency. Done when the new unit tests pass and the UI exposes the existing download pattern.” A focused feature slice is the smallest useful change that crosses the necessary layers without becoming a rewrite. It might be one UI affordance, one API path, one service method, and tests for that behavior.
You have asked for too much when the task mixes multiple product decisions, touches unrelated subsystems, requires broad architecture discovery, or cannot be reviewed as one coherent diff. When I ask for too much, agents tend to go down an expensive detour. They start solving a problem they manufactured, which creates more problems, and you can end up fixing something you did not have in the first place. Scope down to a slice, then iterate.
Deciding what to delegate follows the same instinct. I look at blast radius, reversibility, test coverage, and judgment load. Safe delegation tasks are narrow, easy to review, well covered by tests, and reversible: small bug fixes, test additions, documentation, code cleanup, local scripts, and feature slices with clear acceptance criteria. Direct human implementation is better when the work involves ambiguous product decisions, security-sensitive behavior, data migrations, production incidents, novel architecture, compliance constraints, or weak observability. Codex can still help explore options, but the human should drive.
Senior engineers still need to own the decisions that affect long-term coupling, data ownership, security boundaries, operational behavior, and public contracts. Codex can propose options, weigh tradeoffs, and implement the chosen path, but the team decides the architecture. On a recent project I chose a Blazor application because the product was highly interactive and I wanted the logic and UI components to stay primarily in C# and Razor. Codex did a strong job overall, but I had to be explicit that JavaScript should be used only as an intentional interop choice, not as a parallel client-side architecture. The way to express a constraint is to be concrete. Point Codex to the existing pattern and say whether to follow it, extend it, or avoid it: “Use the existing ReportExportService, do not add a second export pipeline,” or “Keep validation in the domain layer, not the controller.” Durable constraints belong in AGENTS.md, architecture notes, tests, linters, and review checklists, so the agent sees them before each task.
Write the test before the implementation hardens
TDD keeps me honest as a human engineer. It forces me to think about the behavior I want before I start coding, and it gives me a safety net for regressions. That does not change when an agent writes the code. If anything it matters more, because the agent may not share my understanding of the system. When an agent writes the code, tests become the contract that keeps speed from turning into drift. Without them, Codex can produce something that looks reasonable, compiles, and works for the happy path while missing the actual requirement.
Lightweight TDD does not mean ceremony. It means expressing the expected behavior before the implementation hardens around the agent’s first guess. A failing test, a reproduction script, or a clear acceptance check gives Codex a target to work toward and gives me a neutral way to review the result. To keep the agent from writing tests that merely confirm its own implementation, start the tests from user-visible behavior, a bug reproduction, or a business rule, not from the existing code. Ask for the test cases first, review them, and only then allow implementation, and include edge cases that would fail if the implementation took an easy shortcut.
Even when generated code passes the tests, it can still feel wrong. Then I review the shape of the solution: coupling, layer placement, unnecessary abstraction, dependency changes, security assumptions, and whether the implementation matches the local style. Passing tests are necessary, but they do not replace design review. Think of architecture as the box a feature has to live in. A slice needs to fit neatly in that box alongside the others, and design is the engineering effort of finding an elegant way to do that.
Legacy code makes this harder. A codebase with very few tests may not be ready for classic unit testing right away, because code written without tests tends to have a different shape: more hidden coupling, fewer seams, more global state, and less separation between business logic and infrastructure. Use Codex in read-first mode before edit mode. Have it map the relevant behavior, identify seams where tests can be added, and propose the smallest safe change, and keep permissions conservative until you have some executable checks. Characterization comes first. Give Codex examples, logs, fixtures, screenshots, API responses, or current behavior, then ask it to write tests that capture that behavior, and review them before refactoring. If the tests are meaningful, they become guardrails. If they simply mirror implementation details, they become decoration.
This is why the classic TDD argument still matters: tests are not just a verification tool; they are a design force. When that force was absent for years, you cannot sprinkle unit tests on top and expect the codebase to behave as if it had been test-driven from the start. A legacy codebase without tests is a bit like buying a car with 100,000 miles and no record of oil changes. You can probably still drive it, but you should not pretend it carries the same risk as a well-maintained one. The missing tests are deferred maintenance, and earlier shortcuts have raised the cost and risk of every future change. (You can’t retrofit those missing oil changes.)
Featured: Build AI Agents with OpenAI Codex
A hands-on Packt workshop where you practice these workflows on a real starter project, from reading an unfamiliar codebase to shipping an end-to-end capstone.
Register with code DEEPENG40 →
Online, Saturday and Sunday, July 25 and 26.
Debug by checking assumptions, then know when to reset
When Codex gives a plausible but incorrect diagnosis, I start with the assumptions. A wrong diagnosis usually comes from a mistaken belief about how the system works, what changed, or what the failure means. Then I inspect the failing test and logs to ground the conversation in evidence, and after that the diff, to see whether the attempted fix actually addressed the observed failure. The prompt matters too, but usually after you know what was misunderstood. The best recovery prompt is not try again. It is: pause, list the assumptions behind the last diagnosis, compare them against the failing output, and propose the next smallest verification step.
To avoid the endless try-another-fix loop, set a rule that after one or two failed fixes Codex must stop changing code and return to diagnosis. Ask it to summarize what it changed, what evidence supported the change, what evidence contradicted it, and what it still does not know. A good reset point is a clean diff plus a fresh reproduction. Revert or set aside speculative edits, rerun the failing command, and ask for a hypothesis-driven plan before more changes. Make the next step observational: inspect, reproduce, isolate, then edit.
Review for whether it fits, not just whether it works
Review Codex-generated work with the same seriousness as human work, but with extra attention to plausibility risk. Agentic code can look polished while quietly changing a boundary, adding a dependency, broadening permissions, or testing the implementation rather than the requirement. The highest-risk areas are coupling, security assumptions, data handling, dependency changes, migrations, and tests that are too shallow. I also watch for architecture by convenience, where Codex solves the immediate problem by creating a parallel helper, a duplicate abstraction, or a special case the existing system did not need.
This comes back to design. Poor human-led design can produce a different solution for every user story, and agents are no different, except that they can create the mess much more efficiently. If Codex is allowed to invent a new helper, pattern, service, or exception for every slice, the codebase fills up with solutions that do not work well together. That is why review has to ask not only does this work, but also does this fit. When generated code works but does not match the internal style or architecture, treat it like any other code that fails review. Ask Codex to revise the change to follow the existing pattern, and point it to the specific file or convention it should match. Then update the durable guidance if the issue is likely to recur, in AGENTS.md, a review checklist, a lint rule, a template, or a test. The goal is not to scold the agent; it is to make the expected path easier to follow next time.
Standardize the workflow before you scale it
For a team, standardize repository instructions and review expectations first. Prompts are useful, but durable guidance is what makes behavior repeatable across engineers and sessions. A strong starting point is an AGENTS.md that includes build commands, test commands, style conventions, architecture constraints, and what done means, paired with a lightweight review checklist. Allowed task types come next. Start with low-risk, high-feedback work: tests, small bug fixes, documentation, refactors with strong coverage, local tooling, and narrow feature slices. Draw hard boundaries around secrets, regulated data, security-sensitive authorization logic, production incident response, destructive operations, and changes that require business or architectural judgment, until the team has mature controls.
For anything beyond low-risk local work, do not let Codex write production code before a review policy is in place. The policy does not need to be heavyweight, but the team should agree on what Codex is allowed to change, what checks must run, who reviews the diff, and which areas are off limits. Without that, you are relying on individual judgment under speed pressure, which may work for a demo but is not a production practice. I have a related concern. Management may treat AI as a replacement for developer judgment. We have seen versions of this before, where organizations substituted cheaper labor for experienced engineering judgment and then paid the cost in quality, maintainability, and rework. AI can produce plausible code quickly, but it still needs experienced review to catch nuance, architecture fit, and risk. There are scenarios where Codex is the perfect resource for the problem; the key is knowing the difference.
One of the biggest changes over the last year is that prompt engineering is less of the whole story. It still matters, but the best teams are not just prompting Codex to write code. They are prompting it to run a workflow they have already defined and standardized. The prompt is the entry point. The workflow includes planning, repository guidance, permissions, tests, review, rollback discipline, and team conventions. It is less about clever wording and more about engineering control. That is also the real difference between someone who can prompt Codex and someone who can run a safe workflow. The first can get an answer or a diff. The second can turn intent into scoped work, give the right context, set boundaries, verify behavior, review risk, and feed the lessons back into the team’s process.
When the stack is fixed, point Codex at it rather than at generic code generation. On a Python project that means pyproject.toml, dependency management, test commands, linting, formatting, type checking, and package layout, with the agent working in small slices and running the relevant checks. Python especially benefits from tests around edge cases, because dynamic typing can hide integration mistakes until runtime, and I still review dependency changes, packaging changes, security-sensitive code, and data handling by hand.
Measure the work honestly
Managers should avoid measuring only lines of code, number of prompts, or raw tickets closed. Agentic workflows can increase output volume, but volume is not the same as value. Better metrics combine throughput with quality and review health: cycle time for small changes, escaped defects, review rework, test coverage movement, incident rates, lead time from idea to verified change, and developer satisfaction. I would also track whether teams are improving their reusable guidance, because good AGENTS.md files, checklists, and skills compound over time.
A July 2025 METR study found that, in one setting, 16 experienced open-source developers working on familiar mature repositories took 19% longer when early-2025 AI tools were allowed, even though they believed the tools made them faster. I treat that as a cautionary snapshot rather than a permanent verdict, because the tools and workflows are changing quickly. My own experience matches the caution behind it, though I would frame the issue as supervision cost. If I give an agent a small task, it is safer and easier to review, but the interval is often too short for me to do meaningful parallel work, and I end up waiting for the agent instead of coding. The better pattern is to collaboratively create and approve a plan made of small, reviewable steps, then let the agent execute against that plan for a longer period. That gives me a real delegation window without turning the work into one large, unsafe prompt.
The habit to drop
If there is one habit to stop immediately, it is accepting the first plausible diff. Treat the first result as a draft that earned the right to be reviewed, not as finished work. Ask what changed, why it changed, how it was verified, and what risk remains. The habit to build instead is pausing before acceptance. Read the tests. Read the diff. Run the checks. Ask Codex to review its own work against your standards. Serious agentic development is fast, but it is not careless. For complex tasks I ask Codex to create a plan first, review that plan, refine it with the agent, and then ask it to implement. That keeps me in control, gives the agent enough runway to work autonomously, and creates a recovery point if the work starts to drift.
These are the ten workflows I walk through hands-on in Build AI Agents with OpenAI Codex, a Packt workshop on July 25 and 26, where the point is to practice them on a real starter project rather than read about them. We cover reading an unfamiliar codebase, scoping a feature slice, writing tests first, debugging and resetting, reviewing for fit, and preparing work for team handoff, then run it end to end in a capstone.


