How to run a postmortem when AI wrote the code

Every incident review reaches the same point. Someone has traced the outage to a specific piece of code, everyone can see what it does wrong, and the next question is why it is like that.
For most of the history of incident reviews there was somebody to ask. They made a decision, usually under time pressure and with incomplete information, and understanding that decision was how you found a fix worth making. The answer was rarely carelessness. It was a missing piece of context, a deadline, an assumption that was reasonable at the time.
Now the answer is often that a model wrote it and somebody approved it in four minutes. Most postmortem templates have no field for that. So the review does one of two things, and neither leads anywhere useful. It stops early, with a finding that amounts to "the AI wrote a bug", which names no control anyone can change. Or it slowly turns to blaming the person who clicked approve, which produces a defensive meeting and a team that reviews more slowly for about three weeks.
There is a better question available: a small change in wording that leads to a better result.
Stop asking why it was written. Ask why it was accepted.
The generation step is not a control you own. Every model produces wrong output at some rate, and no process can make that rate zero. Treating that step as the cause is as useful as concluding that the cause was a typo.
The acceptance path, though, is entirely yours. It is made of the specification, the automated checks, the review process, the size of the change, and the check before deployment. Every one of those is a thing you built and can change, and a defect reached production because that path let it through.
So the review question is: which part of the acceptance path failed, and would it fail the same way tomorrow?
That has four common answers, and finding the right one matters because the fix is completely different for each.
The rule was never stated anywhere. The most common one, by a large margin. The system had a constraint that mattered (this list must be filtered by organisation, this total must round in a specific direction, this endpoint must never be reachable without a permission check) and only two people knew it, and neither of them read that pull request. A model cannot infer a rule that appears nowhere. Neither could a new hire. The fix is to write the rule down in a form a check can enforce, which is the substance of writing specs an agent can verify.
The rule was stated and nothing verified it. The requirement existed, in a ticket or a design document, and no automated check corresponded to it. This one is easy to fix and embarrassing to find, which is why it is worth looking for deliberately rather than waiting for it to appear.
Something verified it and the check could not fail. The worst case, because every check passed the whole time and those passing checks were misleading. Inherited and generated suites regularly contain assertions that would pass against an empty implementation. The test takes ten minutes: break the behaviour on purpose and confirm the suite notices. The list of these failures is in when evals give false confidence.
Everything was in place and the human missed it. This one happens and it should be recorded honestly, but the finding is almost never that the reviewer should have tried harder. It is usually that they were shown nine hundred lines at six in the evening. Attention does not grow with the amount of code, so the action is a limit on change size rather than an instruction to concentrate.
What you cannot reproduce, and what you can
Traditional incident analysis depends on rebuilding what happened. You interview the author, you read the commit, you understand the state of the world when the decision was made.
The interview is no longer possible, and nothing replaces it. Running the same prompt again gives you different code, so the prompt is evidence rather than a repeatable experiment. Anyone who says they reproduced how a model made a mistake has reproduced one example out of many possible outputs.
What is fully reproducible is the acceptance path. The same specification and the same suite will accept or reject the same code every time, deterministically. That is a real advantage over the human-authored case, where you could never repeat a tired reviewer's work at four in the afternoon. It also tells you where to focus the investigation: at the deterministic part, which is the part you can fix.
Capture this while it still exists
Most teams discover during their first postmortem of this kind that the evidence was never kept.
Five things are worth retaining, and they are cheap to log compared to what they save:
- The prompt or task description the work was generated from.
- The version of the specification it was written against.
- The model and version, since behaviour changes between them.
- Which checks ran, and what they returned.
- What the reviewer was actually shown, including the diff size.
If those are missing when you go looking, that gap is a legitimate first finding. Write it up as one. It is more useful than most of what usually ends up in the actions list, and it takes an afternoon to fix.
One practical warning: prompt and session history is often kept for a shorter time than application logs. A review that happens two weeks after the incident can find the evidence already deleted. Start within a few days.
A finding that blames nobody and still leads to a fix
Postmortems have long insisted on being blameless, and the reasoning is well understood: people hide information from processes that punish them, and hidden information is how the same incident happens twice.
Generated code makes blame both less available and more tempting, in an unhelpful combination. Less available, because the author is not a person. More tempting, because there is exactly one human name attached to the change, and it belongs to whoever approved it.
Avoid that, because blame does not help you prevent the next incident. If the outcome of the review is that one engineer approved something they should not have, nothing about your system changed. The next engineer will approve the next one, because the conditions that made it easy to approve are still there. Accountability belongs to the organisation that released the software, and the review's job is to find which control was missing. More on who is actually responsible is in who approves AI-written code.
What the pattern of defects tells you to look for
There is useful existing evidence about where these incidents come from.
Veracode's Spring 2026 research tested more than 150 models across 80 coding tasks in four languages. Generated code compiled and ran correctly over 95 percent of the time and passed security checks in roughly 55 percent. The differences between classes are the useful part: SQL injection passed at 82 percent, insecure cryptography at 86 percent, cross-site scripting at 15 percent, and log injection at 13 percent.
Read that as a guide to where your acceptance path is weakest. The classes that pass are the ones with an obvious pattern that a reviewer spots and a scanner catches. The classes that fail are the ones where no single line looks wrong and the defect only exists in the relationship between where a value came from and where it is used. That is precisely the analysis humans do worst when reading at normal speed, and it should be where you have the most automated checks.
The 2025 DORA report, from roughly 5,000 respondents, reaches the same conclusion by a different method: AI adoption shows a positive relationship with throughput and a continuing negative relationship with delivery stability, and the report's summary is that "AI doesn't fix a team; it amplifies what's already there". An incident in a team using these tools heavily is usually not a new failure mode. It is an old weakness that is now tested several times a day.
Actions that still work in a busy month
Judge each proposed action by one test: does it still work when the team is under pressure?
"Review generated code more carefully" fails that test immediately. So does "be more careful with permission logic". These are intentions, and intentions are the first thing people forget when a deadline is close.
Actions that last are the ones that change what reaches a person: a rule now stated in the specification, a check that fails when the rule breaks, an automatic limit on change size, a deploy step that requires the check to pass. None of them depend on anyone remembering anything.
Thanks to the teams who let us attend reviews that went badly before they went well. The pattern that repeated was that the first draft of every one of them named a person, and the version that actually prevented a recurrence named a missing check instead.
The old postmortem asked what someone was thinking. The new one asks what nobody wrote down.
Related guide: Enterprise AI coding governance.
Sources
- Veracode, Spring 2026 GenAI Code Security update: 150+ models across 80 tasks in four languages; over 95 percent syntactic correctness against roughly 55 percent security pass rate, with SQL injection at 82 percent, insecure cryptography at 86 percent, cross-site scripting at 15 percent, and log injection at 13 percent.
- 2025 DORA report announcement, Google Cloud: roughly 5,000 respondents; AI adoption relates positively to throughput and negatively to delivery stability, and amplifies a team's existing strengths and weaknesses.


