AdvantageWorks Team 11 min read

Production-Ready AI Code: A Definition of Done

Two software engineers reviewing source code and a green pull request on a monitor during a code review

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.

Engineer reviewing a highlighted code diff next to a secrets manager and a security scan results panel

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?

Engineer watching production observability graphs and a deployment timeline near a deploy console with a rollback control

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.

Frequently asked questions

No. AI-generated code is not production-ready by default, even when it compiles, passes review-by-glance, and makes the demo work. 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.

The gap is real and measurable. Veracode's 2025 analysis of more than 100 large language models found security flaws in 45 percent of the code they produced, and GitClear's 2025 report on 211 million lines of change found copy-pasted code blocks rising sharply as refactoring fell. Production-ready means the code fits your architecture, is tested and evaluated, is observable, respects data boundaries, has a rollback path, has a named human owner, and measurably improves a real workflow. How fast it was generated is not part of that bar.

A Definition of Done is the quality bar that applies to every change, while acceptance criteria describe what success looks like for one specific feature or story. The Definition of Done covers cross-cutting concerns - tests, security, observability, rollback - that hold for all work. Acceptance criteria spell out the functional behavior a single item must deliver to the user.

For AI-generated code the distinction matters more, not less. Acceptance criteria tell you the feature does what was asked. The Definition of Done tells you it is safe to keep. A change can satisfy its acceptance criteria - the happy path works in the demo - and still fail the Definition of Done because it pulled in an untrusted dependency, logged customer data, or has no rollback path. Both are needed, and the Definition of Done is the one AI velocity puts under the most pressure.

A Definition of Done for AI-generated code drops the assumption that a human reasoned about the change, and adds explicit gates for the failures that assumption used to cover. A traditional checklist - code reviewed, tests pass, docs updated - works because the author could explain every line. AI produces plausible, well-formatted code that reads as if someone reasoned about it whether or not anyone did, so it passes review-by-glance precisely because it looks competent.

The updated definition makes the implicit explicit through criteria a glance cannot confirm: architecture fit and dependency hygiene (no hallucinated or abandoned packages), tests written or verified by a human rather than generated to assert the code is what it is, eval sets for model-driven features, observability, bounded data egress, a fast rollback path, a named human owner, and measurable workflow impact. It treats the author as someone who could not explain a single line if you asked.

The biggest security risks in AI-generated code are hallucinated dependencies, hardcoded secrets, injection surfaces, and customer data leaking into logs or third-party endpoints. These are the exact mistakes that are easy to ship and expensive to discover, and AI raises their base rate because nothing in a prompt tells the model what your trust boundaries are.

Hallucinated dependencies are the standout case. A 2025 USENIX Security study of 576,000 code samples across 16 models found that roughly 20 percent of recommended packages did not exist, and attackers register those invented names - an attack called slopsquatting - and wait for someone to install them. The acceptance criteria are concrete: secrets flow through your existing secret management and never inline, user-influenced input never reaches a query or shell without your stack's protections, and PII stays inside the trust boundary it belongs to, including the boundary between your systems and any model context you send out.

You test AI-written code by having a human decide what the behavior should be first, then confirming the tests exercise that intended behavior rather than the implementation that happens to exist. Asking an assistant to write code and then write its own tests usually produces green checks and a closed loop that proves nothing - the tests assert the code does what the code does, so if the behavior is wrong, the tests are confidently wrong with it.

Two distinct things have to be true. First, traditional testing: unit and integration tests that a human has verified cover the real intended behavior, not just the happy path. Second, for features that themselves use a model, evals - correctness becomes a distribution of behavior across many inputs, measured against a curated eval set with a defined pass bar, where a score drop is treated like a failing test. The demo is what looked right when you tried it. The eval set is the definition.

A specific, named human owns AI-generated code - the person who can explain what it does, is accountable when it breaks, and will maintain it as the system evolves. "The AI wrote it" never closes the ownership question, and AI cannot reliably write or sign off on its own Definition of Done.

Self-review is a known weakness: when a model checks its own output in the same context, it tends to confirm its original answer regardless of whether that answer was correct, so it cannot be the gate on its own work. The Definition of Done has to be written by the team in plain language and agreed before the code exists, then a human confirms each criterion at merge. When AI output outruns the team's ability to genuinely own it, the honest fix is to add human capacity to meet the bar - by hiring or by bringing in a fractional team - not to lower it.