AI Agents & Automation

Codex Ships. Claude Audits.

Brett Ridenour Brett Ridenour · Published September 2026

Last night Codex made changes to production. Not staging. Not a dev branch. The live Supabase database that Freebo customers depend on.

I asked for the changes. I approved the plan. I did not watch it happen — I was in another window, working on something else. When Codex reported back that the edits were done, I hit the wall I keep hitting with autonomous agents doing real work: I trust the report about as far as I trust a stand-up update from someone I’ve never met.

So I opened a fresh Claude Code session in the same repo and typed something close to this, sanitized:

just had codex make production changes to an operator’s product deposit config and disable an automation rule — can you double check that it did it right? look at supabase production and any other way to confirm it’s done right

Claude spent the next few minutes reading the actual state of production and comparing it to what I intended. It found nothing wrong. That’s the point of the post — not that Codex screwed up, but that I no longer trust an agent’s own self-report on a production change. A second agent, with no memory of the first agent’s plan, has to look at the world and confirm.

The setup

Both agents are running on the same machine. Same repo. Same MCP credentials.

  • Codex does the mechanical work — full-auto, sandbox_mode = "workspace-write", minimal approval prompts. It’s fast and it doesn’t waste tokens second-guessing.
  • Claude does the judgment work — long context, careful reads, the audit pass.

I already wrote about running them in parallel earlier this year. What I didn’t have then was a rule for when one of them ships something risky. That’s what this post is about.

Codex is configured to ship without asking. Claude is the auditor.

The rule

The “no memory” part matters. If I feed Claude the Codex transcript, Claude will nod along to Codex’s own summary of what happened. That’s not an audit. That’s a rubber stamp. What I want is a second reader who has to reconstruct the intent from my prompt to it and then go find evidence in the world.

What the auditor actually checks

Here’s the ordered set of things Claude walked through last night, in the order it did them without me asking. This is the shape I want every audit to have:

1
Read intent
Parse what I asked for in plain English. Convert to a concrete list of state changes.
2
Query prod
Hit Supabase directly. Read the exact rows the change should have touched.
3
Read the rules
Automation rules, cron state, feature flags — anything else that might have been toggled.
4
Cross-check
Compare observed state to intended state, field by field. Not paraphrase — actual values.
5
Report deltas
Report either 'all good' or 'here is what does not match, in this exact row.'

The audit loop the second agent runs after the first agent ships to prod.

The critical step is #4. It is very tempting for the auditor to say “looks fine, everything I checked lines up.” That’s a good vibe, not a good audit. What I want is the specific row, the specific field name, the specific value now in prod, next to the specific value I said I wanted. If the auditor can’t produce that comparison, it didn’t audit.

Why a git diff isn’t enough

Someone reading this will say: just diff the commit. This doesn’t work for three reasons.

First, not everything Codex does becomes a commit. Data changes don’t. Config toggles in dashboards don’t. Row-level edits made via SQL don’t. A lot of Codex’s most useful production work leaves zero footprint in git.

Second, code diffs don’t tell you what got deployed. A commit can land and not be live yet. A commit can be reverted by a hotfix on top. Reading code says what should be true. The audit needs to know what is true, right now, in the running system.

Third, code diffs don’t catch the automation-rule stuff. Turning off a scheduled job, disabling a webhook, muting a notification — those are stateful decisions that live in a control plane, not in the repo. If the first agent changed a rule and didn’t touch code, git won’t tell you.

The auditor has to look at the world. Not at the plan, not at the diff — at what production actually says right now, when queried fresh.

What the audit prompt looks like

The prompt I actually type is deliberately dumb. I want the auditor to reconstruct intent from scratch, not from a briefing. Here is a sanitized version:

Codex just made a change to [thing] in production. It was supposed to [intent]. Independently verify by reading production directly, and report back with the actual current state next to the intended state, field by field.

— the audit prompt template

Three things this prompt does on purpose:

  1. Says who did the change. So the auditor knows this is a verification pass, not a fresh implementation.
  2. Describes the intent, not the plan. No “Codex was going to run this SQL.” Just what the outcome was supposed to be, in English.
  3. Demands field-by-field comparison. Not “does it look right.” Actual values.

Every one of those is a lesson from an audit that felt fine but missed something. Vague prompts get vague audits.

Here’s what a good audit report looks like when it comes back. Sanitized, but the shape is what matters:

Field-by-field audit report from the second agent, sanitized.

Why I keep the models different

The first agent is Codex. The second is Claude. This is on purpose, and it’s not about “Claude is smarter” — I use both for real work every day. It’s that a different model has different failure modes.

If both agents were Codex, they’d share priors. They’d both under-check the same kinds of edge cases. They’d both accept the same shortcuts. Using a different model for the audit gives me an independent second opinion, in the sense that word actually means — trained on different data, tuned differently, wrong about different things. When they disagree, that’s information. When they agree, I have two independent looks confirming the same thing.

The larger shape

I keep noticing that the hard problems in agent work aren’t about capability. Both of these models can write a Supabase query. Both can read a schema. Both can compare two values.

The hard problem is trust — specifically, when to trust an agent to report on its own work. My working answer is: never, for anything that touches production. The report has to come from a fresh set of eyes, with a fresh read of the world, or it’s not a report. It’s a summary the agent wrote about itself.

The pattern is small, but it changes how I ship. Every production op now has two agents attached to it: the one that does the thing, and the one that goes and checks the thing got done. Neither is more important. Both are load-bearing. And the audit is the part I used to skip.

That’s the part I don’t skip anymore.