A concrete checklist for AI-generated code: spec match, real tests, error handling, independent review, a red-team pass, observability, and docs.
A model that produces working code is solving a narrower problem than the one your team actually has. It is optimizing for something like: this satisfies the prompt, and it did not throw an error in the handful of cases someone happened to try. Shipping software is a harder target. It has to satisfy a spec the model may have only partially understood, survive inputs nobody typed during the demo, fail in ways that are recoverable rather than silent, and stay legible to whoever touches it next, human or otherwise.
The gap between "it runs" and "it ships" is where AI-assisted engineering teams lose the most time, usually in production, usually at the worst hour. Closing that gap does not require slowing down. It requires an explicit, repeatable definition of done that gets applied to every AI-generated change the same way, whether the diff is five lines or five hundred. This post lays out that definition: seven criteria to check before any AI-written feature is allowed to merge.
"It Runs" Is Not "It Ships"
Treating a working demo as the finish line is how AI-generated code accumulates into a codebase that nobody, including the model that wrote parts of it, can safely change six months later. A feature that compiles and passes a quick manual test has cleared a low bar: it has not thrown an exception under the exact conditions someone happened to try. It has not been checked against the requirement it was supposed to satisfy, the inputs it will actually receive, or the person who will have to modify it next.
A Definition of Done for AI-Assisted Features
Use the list below as a literal checklist rather than a set of aspirations. A change is not done until every item on it is true, not once most of them are true or the demo went well in the meeting. This is the reasoning behind what TLM Forge enforces on every change: a spec audit before code gets written, independent review of both the plan and the output, and a gate that blocks shipping until the checklist is actually satisfied, applied the same way regardless of deadline pressure.
- Matches the spec: the change does what was actually required, not what the model inferred from a short prompt.
- Has behavior-level tests that pass: tests assert on real outcomes and edge cases, not just that a function executed without an error.
- Handles errors and edge cases: empty inputs, timeouts, partial failures, and bad data all have a defined, tested behavior.
- Passed an independent review: someone, human or agent, who did not write the code checked it before merge.
- Passed a security and red-team pass: someone actively tried to break or misuse the feature, not just read it for style.
- Has observability where it matters: logs, metrics, or traces exist for the failure modes that will actually happen in production.
- Is documented enough for the next engineer: intent and tradeoffs are legible without reverse-engineering them from the diff.
Matches the Spec, Not Just the Prompt
AI coding tools are very good at producing code that satisfies a prompt and inconsistent at producing code that satisfies the requirement behind that prompt. A short prompt underspecifies edge cases, error contracts, and interactions with existing behavior, and a model fills those gaps with a plausible-sounding default instead of asking a clarifying question. This is why a spec audit has to happen before code is written, not after: it forces the ambiguous parts of a requirement into the open while they are still cheap to fix. Checking whether the result matches the spec after the fact usually means checking it against a spec that was never actually written down, which is not really a check at all.
Tests, Error Handling, and the Unhappy Path
A passing test suite is not evidence of correctness when the same pass that wrote the code also wrote, or approved, the tests. Behavior-level tests assert on what a feature is supposed to do for a real caller, across the cases the spec's requirements actually describe, including the ones that are inconvenient to set up. The same discipline applies to error handling: a try/catch block that silently swallows an exception is not error handling, it is error hiding. Every failure mode a feature can hit, including empty or malformed input, a downstream timeout, a partial write, a duplicate request, or concurrent access to the same resource, needs a defined and tested outcome, not an assumption that it will not happen in production.
If you cannot describe what a feature does when its slowest dependency times out, the feature is not finished being specified, and the AI could not have finished implementing it either.
Independent Review and the Red-Team Pass
Code review exists because the party that wrote something, human or model, is the worst-positioned to spot what it got wrong. Familiarity with your own output suppresses exactly the kind of scrutiny that catches real problems. Independent, multi-agent review that checks the plan and the diff against the original spec, from a perspective that did not write the code, catches classes of bugs that self-review reliably misses. A red-team pass is a distinct step from that review: it assumes an adversarial user and actively tries to break, misuse, or extract data from the feature, instead of just reading it for correctness and style. Skipping from a quick glance at the diff straight to merge is how prompt injection paths, missing auth checks, and IDOR bugs end up shipping behind a green CI badge.
A green test suite and an approving comment are not the same thing as a change that has actually been reviewed for what it does wrong. Review and red-teaming are two separate gates, not one.
Observability and Documentation Close the Loop
A feature that fails silently in production is functionally identical to a feature that was never tested for that failure mode in the first place. Logging and metrics for the paths that actually matter (auth failures, payment retries, a queue that is backing up) turn a multi-day outage nobody noticed into an alert somebody acts on in minutes. Documentation does the equivalent job across time instead of across systems: the next engineer, whether that is a teammate six months from now or another AI session with no memory of this one, needs the intent and the tradeoffs written down, not just the final diff. Tools like MemX address one slice of that problem for AI-assisted workflows, giving an assistant a private, persistent memory of a project's context across sessions instead of starting from zero on the next prompt, but persistent memory is not a substitute for writing down why a decision was made in the code or the pull request itself. A convergence gate exists precisely so none of this depends on someone remembering to check seven boxes under deadline pressure.
| Definition-of-Done Criterion | Looks Done | Actually Production-Ready |
|---|---|---|
| Spec match | Code satisfies the prompt as written | Code satisfies the underlying requirement, edge cases included |
| Tests | CI shows green | Tests assert on behavior and cover the cases the spec describes |
| Error handling | Nothing crashed during the demo | Every failure mode has a defined, tested outcome |
| Review | The author re-read their own diff | An independent reviewer who did not write the code signed off |
| Security | Nothing looked obviously wrong | A dedicated red-team pass tried to break it and found nothing critical |
| Observability | It worked when someone watched the demo | Logs and metrics exist for when it fails unattended |
| Documentation | Variable and function names are clear | The next engineer can extend it without reverse-engineering intent |
Frequently asked questions
01Does adding a definition of done slow down AI-assisted development?
It changes where the time goes more than it adds time overall. Catching a missing edge case or an authorization gap during review costs minutes. Catching the same issue in production costs an incident, a rollback, and the time it takes to rebuild trust in AI-generated changes.
02Who should perform the independent review, a human or another AI agent?
Either can work, and many teams use both: a separate model or agent session that did not write the original code, plus a human for anything touching security, sensitive data, or a decision the team has not made before. What matters is independence from the authoring pass, not a specific job title.
03What is the minimum version of this checklist a small team should actually enforce?
Spec match, behavior-level tests, and one independent review pass are the non-negotiable floor. Security review, observability, and documentation depth can scale with what the feature touches, but skipping the floor is how small teams end up with the largest AI-generated messes to clean up later.