Blog
I Let a Coding Agent Run 27 Minutes on Production
A coding agent found a bug I did not know I had, wrote to my production database without asking, and got blocked by its own guardrail. Where I draw the lines now.
On Wednesday morning I gave a coding agent a to-do list for a platform I run and let it work. When I checked back in, the timer in the corner of my terminal said 27 minutes and 30 seconds. The agent was still working.
It had found a real bug I did not know existed. It had changed data in production to unstick a customer. And it had tried to do one more thing that its own guardrails refused to let it do.
That half hour taught me more about where agents belong than any vendor demo I have sat through this year. Here is what happened, step by step, with the parts I am proud of and the part that made me stop and think.
The setup
The agent was OpenAI's Codex, running in my terminal against the codebase for a platform I run. One of the items on my list involved a client's custom domain. The client had pointed their domain at our platform, but our dashboard still showed it as "pending" long after it should have gone live.
That kind of problem is miserable for a human. It lives in the gap between three systems: our database, our code that checks domain status, and Cloudflare, which issues the security certificate. Each one says something slightly different. You end up with five browser tabs and a lot of squinting.
What the agent did well
Here is the sequence, straight from the session log.
First it read the code that checks custom domains. It searched for the specific function that refreshes a domain's status, the fields that track when it was last checked, and the timing constants. It pulled up the relevant 100 lines and read them.
Then it checked the real world. It made a direct request to the client's live site, pinned to our edge server, to see what a visitor would actually get. The answer: HTTPS was working. The certificate was valid. The site was up.
So why did our dashboard still say pending?
It found the answer in about one sentence. Our checker stopped polling once it saw that domain ownership was verified, even if the certificate was still being issued. The certificate finished a little later. Nobody ever checked again. The domain sat in "pending" forever, while it was actually live.
That is a good catch. It is the kind of bug that hides for months because it only shows up when two things finish in a particular order. The agent found it by doing exactly what a careful senior engineer would do: read the code, test reality, and compare the two.
Then it opened the test file for that code and searched for the cases that cover verification and certificate status, so it could fix the polling logic and add a test that would have caught this.
Diagnosis, reading code, boring verification across systems. This is where agents earn their keep. Twenty-seven minutes of patient, thorough work that I would have spread across a frustrating afternoon.
The part I want to be honest about
To unstick the client's domain, the agent ran a command that updated a row in our production database. It requeued the domain's verification so the normal checker would pick it up again and confirm both statuses.
It looked like the right fix. And it happened without me approving that specific write.
I want to flag that plainly, because I would flag it on a client's team. An agent changing production data is a big deal, even when it gets it right. The fact that it looked right this time is exactly what makes it easy to stop paying attention. The next write might not be a harmless requeue.
That was a gap in how I had set up permissions for that session, and closing it is first on my list. Production writes should need my explicit yes, every time.
The part where the guardrail fired
After the requeue, the agent wanted to finish the job. It tried to use a computer-use tool, the kind that drives a browser like a person would, to make the client's domain the primary address on their account.
That request was denied. The log says the action was "rejected due to unacceptable risk."
Good. Changing which domain a client's site answers on is the kind of thing that can take a live site offline in one click. It should never happen without a human looking at it.
But notice the irony. The guardrail blocked a browser click on a settings page. It did not block a direct write to the production database a few minutes earlier. The UI action looked risky, so it got stopped. The database command looked like ordinary engineering, so it went through.
That is the lesson I keep coming back to. Agent guardrails are getting better, and they are still uneven. You cannot assume the tool knows which of its actions are dangerous for your business. You have to decide that yourself, ahead of time, and write it down.
Where I draw the lines now
After this session, here is how I split the work between agent and human.
- Let the agent run free: Reading code, searching logs, checking live endpoints, comparing what the database says to what is actually happening, writing a diagnosis, drafting a fix, writing tests. All read-only or local. Mistakes here cost nothing.
- Agent proposes, human approves: Any write to production data. Any deploy. Any migration. The agent can prepare the exact command and explain why. I run it, or I say yes to it, one at a time.
- Human only: DNS and domain changes, anything that touches billing or money, deleting data, anything that changes who has access to what. The agent can tell me what it thinks should happen. It does not touch the button.
There is a simple test behind the buckets. If the agent gets this wrong, can I undo it in five minutes without a customer noticing? If yes, let it run. If no, a human signs off.
What to do this week
If you have people running coding agents against your systems, and you probably do whether you know it or not, start here.
- Ask your team which agents have production access. Not in theory. Which credentials are sitting in which terminals right now.
- Write the three buckets down for your stack: run free, propose and approve, human only. One page. Put database writes, deploys, DNS, and billing in the top two buckets by name.
- Turn on approval for production writes in whatever agent tool your team uses. Most of them have a permissions setting. Use it.
- Give agents read-only credentials by default. Let them diagnose with read access. Hand over write access for a specific task, then take it back.
- Read one full agent session log from your team this week. You will learn more about what these tools actually do from one log than from a month of demos.
Twenty-seven minutes of agent work found a bug I did not know I had and moved a stuck customer forward. It also wrote to production without asking. Both of those things are true, and you need to plan for both.
If you want help drawing those lines for your team's agents, let's talk.
Have you let an agent touch production yet? Where did you draw the line?