AI Agents Series | Working with Codex
Software engineers are understandably anxious about coding agents. If an agent can inspect a repository, implement a feature, run tests, and review a patch, which of our current skills will continue to matter? A manager once gave me a useful way to think about this: the greatest risk is not that Codex improves, but that our own skills remain frozen at one snapshot of what the tool can do. Engineers who learn to work with the agent, evaluate its output, and contribute at the layer above its current capability will continue to create value.
This pattern is not new. When automobiles replaced horse-drawn transport, the valuable skills changed with the technology. What feels different today is the speed of the transition. A clear example of the fast pace development can be seen in the change of workflow from prompt engineering to context engineering, harness engineering, agent loops, and increasingly graph-shaped workflows in just less then a year or two. The labels will keep changing, but the underlying demand is stable: we need to understand the system well enough to direct it, constrain it, verify it, and improve how humans and agents work together.
This post is my self-study note when working with Codex. I cover features such as Plan mode, Goal mode, together with real case studies and mistakes from my own work. The goal of this post is to provide understanding which mode fits which kind of task, how to give Codex useful autonomy without losing control, and how to preserve human judgment as the tool evolves.
Codex’s Plan Mode
Sources:
- https://learn.chatgpt.com/guides/best-practices
Codex’s Goal Mode
Sources:
- Using Goals in Codex — OpenAI Cookbook, published May 9, 2026.
Most Codex conversations are turn-based: I ask for something, Codex works on it, reports the result, and waits. That interaction is appropriate for a focused edit or a question with one clear answer. It becomes repetitive, however, when the real request is: keep investigating, use what you learn to choose the next step, and stop only when the result has been verified.
According to OpenAI’s Using Goals in Codex guide, a Goal is a persistent objective attached to a Codex thread. It describes the outcome that should become true, the evidence that will demonstrate success, and the constraints that must remain intact. Instead of asking me to restate the target after every failed test or partial improvement, Codex can compare the latest evidence with the Goal and continue when more work is needed.
This does not mean unconstrained background autonomy. I find it more useful to think of a Goal as a thread-scoped completion contract: I define the finish line and its boundaries; Codex is allowed to discover the path; evidence determines whether the work is complete.
When to use Goals—and when not to use them
A Goal is a good fit when the destination is clear but the path depends on what Codex discovers. Typical examples include:
- reproducing and diagnosing a flaky test;
- optimizing against a measurable benchmark;
- completing a dependency migration while keeping a regression suite green;
- performing a multi-step refactor whose next change depends on test results;
- investigating a bug that must first be reproduced;
- or producing an evidence-backed research audit or reproduction report.
These tasks share three properties: the objective must survive across turns, the finish line can be checked against evidence, and the next useful action may change after each experiment.
I would not use a Goal for a one-line edit, a simple explanation, a short review, open-ended brainstorming, or a question where I want one response and then a stop. A normal prompt is also better when the finish line is vague. “Improve this code” is not a useful Goal unless I explain what improvement means, how it will be measured, and what must not regress.
Goal mode does not replace Plan mode. I can use Plan mode first to inspect the problem, uncover missing decisions, and agree on an approach. Once the outcome and evidence are clear, I can activate a Goal for the implementation or investigation. Planning clarifies the route; a Goal keeps the verified destination active.
Goal vs. a detailed prompt
A detailed prompt and a Goal can contain similar information, but they change the interaction in different ways. More detail improves the current instruction. A Goal changes the lifecycle of the thread.
| Dimension | Detailed prompt | Goal |
|---|---|---|
| Main intent | Perform this requested piece of work | Keep working until this outcome is verified |
| Lifetime | The current turn | Persists across turns in the current thread |
| Next step | Usually waits for another user instruction | Can be chosen from the latest evidence |
| Completion | The requested response or action is delivered | The defined finish line is checked against evidence |
| Best fit | Known, bounded work | Multi-step work with an uncertain path |
| User control | Follow-up prompts | View, pause, resume, or clear the Goal |
The important point is that a Goal is not simply a very long prompt. A detailed prompt can prescribe many steps and still end after one turn. A strong Goal defines what must be true at the end while leaving Codex enough freedom to adapt the intermediate steps. The two ideas are complementary: a Goal should still be written precisely.
How Goals are designed in Codex
Goals are persisted as state in the current thread. They are not global memory, and they are not project-level instructions such as AGENTS.md. This boundary keeps the objective attached to the context and evidence that belong to the investigation: inspected files, executed commands, test output, diffs, logs, and generated artifacts.
The design has several important properties:
- Thread-scoped state. The Goal stores the objective, status, budget, and progress accounting for one thread. It does not silently become an instruction for every project or future conversation.
- Explicit lifecycle. A Goal can be active, paused, completed, cleared, interrupted, or stopped by its budget. Reaching the budget is not the same as succeeding.
- Safe continuation. Continuation is event-driven rather than an uncontrolled loop. Codex considers continuing only after a turn finishes, the thread is idle, no user input is queued, and no other work is pending.
- Evidence-based completion. Codex should not mark the Goal complete merely because the result looks plausible. It must compare the objective with concrete evidence such as tests, logs, benchmarks, changed files, artifacts, or research sources.
- Bounded authority. The user retains control over pausing, resuming, and clearing the Goal. If progress is blocked, Codex should report the blocker and what input would unlock the next step rather than pretending the objective is complete.
This architecture makes Goals persistent without making them endless. The objective survives intermediate failures, but continuation and completion remain governed by thread state, budget, user control, and evidence.
How to use Goal mode effectively
The official guide recommends treating a Goal as a compact operating contract. In practice, I want every Goal to answer six questions:
- Outcome: What exactly should be true when the work is finished?
- Verification surface: Which test, benchmark, artifact, command output, or source evidence will prove it?
- Constraints: What behavior, interface, quality level, or test suite must not regress?
- Boundaries: Which files, repositories, tools, data, or resources may Codex use?
- Iteration policy: How should Codex use the result of one attempt to choose the next experiment?
- Blocked stop condition: When should Codex stop, summarize the evidence, and ask for a missing input?
A reusable template is:
/goal Achieve <desired end state>. Verify it with <tests, benchmark, artifact, or evidence>.
Preserve <constraints> and stay within <boundaries>. After each attempt, use the new
evidence to choose the next best action. If progress is no longer defensible, stop and
report what was attempted, what the evidence shows, the blocker, and what would unblock it.
For example, this Goal is too weak:
/goal Improve checkout performance.
A stronger version gives Codex an auditable finish line without prescribing every implementation step:
/goal Reduce checkout p95 latency below 120 ms on the existing benchmark while keeping
the correctness suite green. Limit changes to the checkout service and its tests. After
each benchmark run, record the result and choose the next experiment from the observed
bottleneck. If the benchmark cannot run or no safe improvement remains, stop with the
evidence, attempted paths, blocker, and next input needed.
For research, the same discipline prevents a plausible reconstruction from being reported as an exact reproduction:
/goal Produce the strongest evidence-backed reproduction of the paper using the supplied
paper, code, and local resources. Attempt the headline claims where feasible, verify each
output, and finish with a claim-level report separating confirmed results, approximate
reconstructions, blocked claims, and remaining uncertainty.
The basic command surface is small:
/goal <objective> Start a Goal
/goal View the current Goal
/goal pause Pause it
/goal resume Resume it
/goal clear Remove it from the thread
My practical workflow is to draft the Goal before activating it. I first explain the task in plain language and ask Codex to turn it into a candidate /goal. I then review the proposed outcome, evidence, constraints, and blocked condition. This small review is important because Goal mode amplifies whatever completion criterion I provide—good or bad.
Finally, I distinguish progress from completion. A faster benchmark that still misses the threshold is progress, not success. Passing the target while breaking correctness is also not success. When exact evidence is unavailable, the Goal should require an honest partial result rather than a confident completion claim. The Goal gives Codex persistence; the evidence gives that persistence direction.
Good Practices
This section collects practical skills, workflows, tutorials, and field notes that have improved how I work with AI coding agents. These notes are not meant to be a polished methodology. They are closer to a personal operating manual: small practices I found useful, mistakes I want to avoid repeating, and workflows I want to keep testing in real projects.
AI Coding Workflow from Matt Pocock
Full Walkthrough: Workflow for AI Coding - Matt Pocock is a practical workshop on turning ambiguous product ideas into agent-ready implementation work. My main takeaway is that AI coding works best when we separate the workflow into stages:
- clarify the product goal,
- write down the requirements,
- pressure-test the plan,
- let the coding agent implement,
- review and verify the result.
The important artifact is prd.md, the product requirements document. Before asking an agent to write code, I should first make the goal explicit: what problem are we solving, who is the user, what behavior should change, what constraints matter, and what counts as done? A good prd.md reduces ambiguity before the agent enters implementation mode. It also gives both human and agent a shared reference point when the work becomes messy.
This is where the grill-me skill fits. I use it before Codex Plan mode, while the task is still soft and under-specified. Its purpose is not to implement anything yet. Its purpose is to force a shared understanding of the target outcome.
Interview me relentlessly about every aspect of this plan until we reach a shared understanding.
Walk down each branch of the design tree, resolving dependencies between decisions one by one.
For each question, provide your recommended answer.
Ask the questions one at a time.
If a question can be answered by exploring the codebase, explore the codebase instead.
This skill is useful because many failures in AI-assisted coding are actually planning failures. The agent may implement quickly, but if the goal is vague, it will confidently optimize for the wrong thing. grill-me slows the process down at the right moment: before code is written, before a plan hardens, and before hidden assumptions become expensive.
The rough workflow I want to practice is:
- start with a rough idea,
- ask
grill-meto interrogate the goal and assumptions, - turn the answers into
prd.md, - enter Plan mode and ask Codex to inspect the codebase,
- let Codex implement against the agreed plan,
- verify with tests, screenshots, or manual review.
In short: do not use the agent as a faster pair of hands too early. First use it as a thinking partner that helps make the task precise. Once the target is clear, autonomy becomes much more useful.
Hidden Simplification in Background Instructions
An agent does not have one universal definition of “best.” Its behaviour is shaped by the task, the repository, and the instructions that surround it. This becomes risky when a plugin or global instruction runs in the background: it can quietly favour small, cheap, or dependency-free solutions before I have consciously decided that those are the right optimisation targets.
The problem is not that simplicity is bad. The problem is that the trade-off can be hard to observe. A background preference can produce something clean, safe, and mechanically correct while reducing the quality I actually care about. I may have seen the trade-off during the design conversation, but not paid enough attention because the simpler option sounded sensible. Sometimes the gap becomes visible only after I run the finished skill and inspect its output.
I saw this while building a blog-knowledge-curator skill for this site. Its purpose is to map a Codex discussion, repository, paper, or article to the most relevant existing blog posts. For that to work across a growing site, it needs a catalogue that captures what each post actually argues, explains, and excludes—not merely its title and tags.
I had installed Ponytail, whose instructions favour the smallest adequate solution, standard-library tools, and no unnecessary work. That preference is useful in many coding tasks. Here, however, it made a structural catalogue feel sufficient: refresh-catalogue extracted frontmatter, headings, dates, tags, hidden status, and a body hash. The cache could be built, refreshed incrementally after manual edits, and validated mechanically.
Only after I asked how the refresh step actually worked did I see the missing requirement. The catalogue copied existing metadata; it did not ask Codex to understand the post. A vague title, generic description, or weak headings would still make relevant posts difficult to retrieve. The artifact was correct as a structural index, but incomplete as a semantic catalogue.
The useful mental model is:
- Background optimisation: an instruction rewards a property such as minimal code, lower cost, or fewer dependencies.
- Proxy success: the implementation satisfies an easy-to-check proxy, such as cache freshness or file-change detection.
- Artifact inspection: the user checks whether the finished output satisfies the real reader-facing goal.
- Quality guardrail: the real goal becomes an explicit requirement that the agent must not silently trade away.
For this skill, the quality guardrail is now concrete: Codex must read every new or changed post in full and generate a hash-bound semantic record containing a faithful summary, precise topics, retrieval cues, and a content role. The catalogue is complete only when every post has a current semantic record. The deterministic cache remains useful, but it is now correctly treated as infrastructure rather than the product itself.
For persistent preferences like this, I want a user-level AGENTS.md to make the decision visible before implementation:
## Optimisation priority
When quality, coverage, factual accuracy, or retrieval usefulness conflicts with lower
computation cost, prefer the higher-quality result unless I explicitly request a cheap,
fast, or minimal approach. Do not replace semantic understanding with structural heuristics
when the task's success depends on meaning. Surface any material quality trade-off as a
decision before choosing it.
This should not ban simple solutions. A deterministic index is still the right tool for file discovery, change detection, and reproducibility. The practice is to state the evaluation criterion before implementation, then inspect the first working artifact against it. “Minimal” is an implementation preference; “complete semantic retrieval” is an outcome requirement. When they conflict, the outcome requirement should win unless I say otherwise.
An AGENTS.md cannot override stronger system or developer instructions. In this case, the global quality preference must be compatible with—or I must disable—the Ponytail instruction. The broader lesson is that the instruction hierarchy, evaluation target, and review point must agree.
Case study: memory can compromise evaluation isolation
One hidden failure mode appeared in my own Codex workflow. I developed a feature in one thread and all tests passed. I then opened a new Codex thread and repeated the test; it passed again. Yet the feature failed after deployment in what appeared to be the same setting.
I cannot prove that cross-thread memory caused the failure, but it is a plausible confounder. A fresh Codex thread is not necessarily an independent evaluator when memory is enabled: it may receive a compact summary of prior work and be encouraged to consult relevant memories. That context can be genuinely useful for implementation, but it can also bias an evaluation. The agent may reuse an earlier assumption, test path, workaround, or interpretation of success instead of rediscovering whether the feature works under the deployment conditions.
The practical lesson is to treat agent memory like any other source of experimental leakage. When the goal is evaluation, regression testing, or reproducibility, I add a project-level instruction to the project AGENTS.md such as:
## Evaluation isolation
For evaluation, testing, regression validation, and reproducibility tasks,
do not use or search memory from prior Codex threads. Do not consult
MEMORY.md, rollout summaries, prior-thread notes, or remembered decisions.
Treat the task as an independent evaluation and record only evidence produced
in the current run. If prior context is required, state it explicitly before
using it.
This instruction reduces behavioural leakage, but it is not a complete isolation boundary if Codex has already injected a memory summary into the thread. For a strict evaluation, I should also run the evaluator with memories disabled, or in a clean environment that has no prior memory artifacts. The right standard is not merely that two agent threads agree; it is that an independent run, with the relevant deployment configuration, reproduces the result.
Enjoy Reading This Article?
Here are some more articles you might like to read next: