The demo ran clean. The feature worked, the pull request was green, and the engineer who prompted it merged in an afternoon what used to take three days. Six weeks later a customer record showed up in an application log it was never supposed to touch, and the dependency that serialized it turned out to be a package no one on the team had ever heard of. The code passed every check the team had. The checks were written for a world where a human reasoned about every line.
That gap is the whole problem. AI coding assistants have collapsed the cost of producing code, but they have not changed what it takes for code to be safe to run in production. Most engineering organizations now ship model-generated logic against a Definition of Done that predates the model. The velocity is real and visible. The risk is real and invisible, and it lands on whoever signs off on the incident review.
So here is the executive question worth answering precisely. When is AI-generated code actually done? Not "merged," not "it works in the demo," but done in the sense that you would defend it to a board after an outage. The short version, which the rest of this article turns into concrete criteria: if it cannot ship safely, it is not done. Speed is not the finish line. Production-readiness is.
Production-ready AI-generated code meets the same bar as your best human-written code. It fits the architecture, is tested and evaluated, is observable in production, respects data boundaries, has a rollback path, has a named human owner, and measurably improves a real workflow. How fast it was produced is not part of the definition.
Why your old Definition of Done fails for AI code
A traditional Definition of Done assumes a person reasoned their way to the change. The review step works because a human author can explain why each decision was made, and a human reviewer is checking that reasoning. "Code reviewed, tests pass, docs updated" is a reasonable checklist when the author understood the code before it existed.
AI inverts that. The model produces plausible, well-formatted code that reads as if someone reasoned about it, whether or not anyone did. It passes review-by-glance precisely because it looks like competent work. Underneath, it can carry patterns a careful author would never have chosen: near-duplicate logic copied across files instead of factored once, insecure defaults, or a dependency the model invented or half-remembered.
The research points one way. Analyses of large code corpora through 2024 and 2025, including GitClear's annual code-quality reports and academic work on the security of LLM-generated code, describe rising code duplication, more copy-pasted blocks, and a non-trivial rate of security-relevant defects in generated output. The exact figures vary by study and should be read as a direction, not a constant. The direction is enough. AI raises the base rate of the specific failures a glance-level review is worst at catching. The finish line did not stay where it was. It moved, and the old definition does not know it.
"Done" is an executive question, not a ticket checkbox
For a CTO or COO, "done" has never really meant "moved to the Done column." It means the organization can stand behind what shipped. That distinction matters more, not less, once a tool can generate code faster than anyone can carefully read it.
Reframed at that altitude, done has three properties a ticket status cannot capture. It is shippable safely, which means the blast radius of a mistake is known and contained. It is owned, which means a specific person is accountable for maintaining it. And it is tied to impact, which means it moved a real metric rather than just adding lines to the repository. A Definition of Done an executive can actually rely on writes those three properties down as criteria the team checks before merge, not aspirations stated in a wiki.
The rest of this article is that definition: eight criteria, each one a question you can ask of any change before it counts as done.
The 8 acceptance criteria for production-ready AI code
Treat the table below as the spine. Each criterion is a gate. A change that fails any one of them is not done, regardless of how clean the diff looks or how quickly it arrived.
| Criterion | What "good" looks like |
|---|---|
| 1. Architecture fit | Matches existing patterns, service boundaries, and approved dependencies. No rogue libraries, no hallucinated or abandoned packages. |
| 2. Tests | Meaningful coverage of the new behavior, written or verified by a human, not generated tests that merely assert the generated code is what it is. |
| 3. Evals | For AI-driven features, behavior is measured against a defined eval set with a pass bar, not judged by vibes in a demo. |
| 4. Logging and observability | The change is traceable in production. When it fails, the failure surfaces in logs, metrics, or traces. |
| 5. Data boundaries | No PII, secrets, or customer data crosses a trust boundary it should not. Model-context boundaries are respected. |
| 6. Rollback path | The change can be reverted safely and quickly. The blast radius of a bad deploy is understood in advance. |
| 7. Named owner | A specific human owns this code and will maintain it. "The AI wrote it" is not an owner. |
| 8. Measurable workflow impact | It improves a real, named workflow against a metric, not just "lines merged" or "tickets closed." |
The next sections expand the criteria that carry the most risk for an executive owner. Watch for the same shape in each one: a change that sails through a naive Definition of Done but fails this one, and the incident it sets up.
Architecture fit and dependency hygiene
The first place AI code goes wrong is the import block. Models are trained to produce code that looks idiomatic, and "idiomatic" sometimes means reaching for a library that solves the problem in general but is wrong for your stack, unmaintained, or simply does not exist. Hallucinated package names are a known failure mode, and they carry a nasty second-order risk. An attacker can register the hallucinated name and wait for someone to install it.
Architecture fit means a human confirms three things before the change counts. The dependencies are ones you already trust or have deliberately approved. The code follows the patterns the rest of the service uses rather than introducing a parallel way of doing the same thing. And the change respects existing service boundaries instead of quietly coupling two systems that were kept apart on purpose. None of this is exotic. It is the review you already do, applied with the assumption that the author could not explain a single line if you asked.
Consider a concrete miss. An AI-generated change adds a date-parsing utility by pulling in an unfamiliar package. Tests pass, because the happy path works. A naive Definition of Done is satisfied. This definition is not, because criterion one was never checked, and the team has just inherited a dependency no one chose and no one watches.
Testing and evals: proving behavior, not just generating tests
Ask an assistant to write code and then ask it to write the tests, and you will usually get green checks. You will also get a closed loop that proves nothing. The tests assert that the code does what the code does. If the behavior is wrong, the tests are confidently wrong with it.
Two distinct things have to be true here, and they get conflated all the time. First, traditional testing: a human decides what the new behavior should be and confirms the unit and integration tests actually exercise that intended behavior, not just the implementation that happens to exist. Second, and specific to AI-driven features, evals. If the feature itself uses a model, correctness is not a fixed assertion. It is a distribution of behavior across many inputs. You measure it against a curated eval set with a defined pass bar, and you treat a drop in that score the way you would treat a failing test. "It looked right when I tried it" is the demo. The eval set is the definition.
Security and data boundaries
This is the criterion most likely to end up in a board deck, so it gets the most scrutiny. AI raises the base rate of the exact security mistakes that are cheap to ship and expensive to discover. A secret hardcoded because the model saw that pattern in its training data. An injection surface left open because the generated query concatenated a string. Customer data written to a log or sent to a third-party endpoint because nothing in the prompt said not to.
The acceptance criterion is concrete. Secrets are handled through your existing secret management, never inline. User-influenced input never reaches a query, a shell, or a template without the protection your stack already mandates. And data egress is bounded: PII and customer data stay inside the trust boundary they belong to, including the boundary between your systems and any model context you send out. The second worked example makes the failure vivid. An AI-generated change adds a debug log line that includes the full request object to help with troubleshooting. The request object contains a customer email and a session token. Every existing test passes. The naive Definition of Done is met. Criterion five is violated, and you now have a logged-credential incident waiting to be found.
Observability, rollback, and blast radius
Production-readiness, stripped to its operational core, is two questions. Can you see it fail, and can you undo it?
Observability is the first. A change is not done if its failure mode is silent. The behavior it introduces has to be visible in the signals your team already watches, through a log, a metric, or a trace, so a problem announces itself instead of waiting for a customer to report it. This matters more for AI-generated code because the author cannot tell you where it is likely to break. The instrumentation is how you make up for that missing intuition.
Rollback is the second, and it is a first-class part of done, not an afterthought. Before a change ships, the team should be able to answer two things plainly. How do we revert this, and what is the worst that happens if it is wrong. A change with a known, fast rollback and a small blast radius can ship with confidence even when certainty is imperfect. A change that cannot be cleanly reverted, or whose failure would cascade across systems, is not done until that is no longer true, no matter how well it tested.
Ownership and "adopted by the team"
Code that ships but that no one understands, trusts, or will maintain is a liability wearing the costume of a deliverable. The faster code is generated, the easier it is to merge something nobody on the team can actually own, and the more this criterion earns its place on the list.
Ownership is specific and human. A named person can explain what the code does, is responsible for it when it breaks, and will carry it forward as the system evolves. "Adopted by the team" is the same idea at the group level. The change has been reviewed and understood by people who will live with it, not waved through because the assistant seemed confident. This is also where a capacity problem usually hides. When AI output is outrunning the team's ability to genuinely own it, the honest answer is not to lower the bar but to add the human capacity to meet it, whether by hiring or by bringing in a fractional agentic team that can own the work to this standard. Either way, "the AI wrote it" never closes the ownership question. A person does.
Making "done" measurable
A definition only changes behavior when it becomes a gate, so the last step is to turn these eight criteria into something the team actually runs. The cheapest place to start is the pull request template: eight checkboxes, one per criterion, that the author affirms and a reviewer confirms. From there, the criteria that can be automated should move into CI, where dependency allow-lists, secret scanning, and eval-set thresholds become checks that block a merge rather than reminders someone might read.
Then make the eighth criterion real with a number. Pick the workflow the change was supposed to improve and measure it: cycle time, defect-escape rate, incident frequency, the time it takes a new engineer to ship safely. Production-readiness as a capability shows up there, in whether the metric moves and stays moved, not in how many lines the assistant produced this quarter.
Key takeaways
- Speed is not part of the definition of done. If AI-generated code cannot ship safely, it is not done, no matter how fast it arrived or how clean the diff looks.
- Your old Definition of Done assumes a human reasoned about the change. AI breaks that assumption by producing plausible code that passes review-by-glance while hiding clones, insecure patterns, and invented dependencies.
- Production-ready AI code clears eight criteria: architecture fit, tests, evals, logging and observability, data boundaries, rollback path, a named owner, and measurable workflow impact.
- "Done" is an executive property, not a ticket status. It means shippable safely, owned by a specific human, and tied to a metric the organization can stand behind.
- Make the definition a gate. Put the eight criteria in your PR template, automate what you can in CI, and measure the workflow each change was meant to improve.
If your team has turned on AI assistants faster than it has updated what "done" means, that gap is worth closing deliberately before the next incident closes it for you. Book a Discovery Sprint and we will help you turn this definition into a working acceptance gate your engineering leads can run, measure, and defend.