How to verify AI-generated code before it ships
To verify AI-generated code, check it against a statement of required behavior that the AI could not edit. Keep that statement outside the test suite, review test changes before code changes, focus effort on high-risk paths, run the relevant tests where the agent cannot skip them, confirm those tests really fail when the behavior breaks, and keep the evidence with the change.
Why AI-generated code needs a different kind of check
Traditional review assumes the tests were written by someone other than the person who changed the code, or at least at a different time. AI coding agents break that assumption. Claude Code, Cursor, Copilot’s agent mode, and Codex can all edit the implementation and the tests that judge it in a single change. When they do, a green test run proves only that the code agrees with its own tests.
The research so far points in the same direction:
- Google’s 2024 DORA report estimated that every 25% increase in AI adoption was associated with a 7.2% decrease in software delivery stability, even as code review speed and documentation improved.
- In the 2025 Stack Overflow Developer Survey, more developers said they distrust the accuracy of AI tools (46%) than trust it (33%), and 66% named “AI solutions that are almost right, but not quite” as their top frustration.
- Veracode’s 2025 GenAI Code Security Report tested more than 100 language models on 80 coding tasks and found security vulnerabilities in 45% of cases.
“Almost right” is the core problem. Code that is obviously broken gets caught. Code that compiles, passes its tests, and quietly changes a business rule does not, unless something independent of the AI knows what the rule was supposed to be.
How to verify AI-generated code in six steps
This process works with any language, test framework, or coding assistant. The tools only change how much of it is automated.
1. Write down what must not change
Before you can check whether an AI broke something, you need a record of what “working” means that the AI cannot quietly rewrite. Tests are a poor place for that record when the same agent edits them. Keep a short, reviewed list of the behaviors that matter, such as “free-plan users can create at most 5 projects” or “users can only read invoices that belong to their own account”, in a file that needs a human owner to approve changes.
Five to twenty statements are enough for most products. Give each one a stable ID so tests and pull requests can refer to it.
2. Read the test diff before the code diff
If a change that was supposed to fix or add a feature also modifies existing tests, review those test edits first. A changed expected value, a deleted test case, a new .skip, or a mock that replaces the code under test is the AI deciding what correct behavior is. That is the decision a human most needs to confirm. Our guide on why agents change tests to make them pass lists the patterns to look for.
3. Scale verification to risk
Not every AI-generated change deserves the same scrutiny. A copy change to a marketing page and a change to the authorization middleware are different risks. Rank the change by what it touches, not by how many lines it has:
| Risk | Typical AI changes | Minimum check |
|---|---|---|
| Critical | Auth, permissions, billing, data deletion, migrations, secrets | Human review of every line, requirement-linked tests, mutation check, CI gate |
| High | Business rules, shared utilities, API contracts, input validation | Targeted tests for affected requirements, test-diff review, CI gate |
| Medium | New features behind existing boundaries, UI state logic | Relevant unit and end-to-end tests, normal review |
| Low | Copy, styles, docs, isolated refactors with unchanged tests | Type check, lint, existing suite |
4. Run targeted tests outside the agent
The agent saying “all tests pass” is not evidence. Run the tests yourself, or better, run them somewhere the agent cannot skip: a CI job on the pull request, or a hook that runs before the agent can finish. Prioritize the tests linked to the requirements the change could affect. If you use Claude Code, a Stop hook can refuse to let a turn end while tests are failing.
5. Test the tests
AI-written tests often execute code without asserting what it should do. Coverage reports count those tests as protection. Mutation testing does not: it deliberately breaks the code, for example by flipping a comparison or deleting a guard, and checks that at least one test fails. A test that keeps passing against broken code is not protecting anything. See mutation testing in TypeScript and JavaScript for a walkthrough.
6. Keep the evidence and make the decision explicit
A release decision should be auditable later. Keep the test output, the list of requirements that were checked, and, when behavior genuinely changed, the name of the person who approved the new behavior. When something breaks in production, that record tells you whether the check was missing, wrong, or skipped.
A checklist for your pull request template
Paste this into your pull request template for any change written mostly by an AI:
## AI-generated change checklist
- [ ] Requirements this change touches are listed (IDs or links)
- [ ] Test changes reviewed before implementation changes
- [ ] No expected values changed without an approved behavior change
- [ ] No tests skipped, deleted, or replaced with mocks of the code under test
- [ ] Auth, billing, and data-access paths reviewed line by line
- [ ] Targeted tests ran in CI (link to run)
- [ ] Mutation check run for critical paths (link to report)
- [ ] Behavior changes approved by: @ownerAutomating the process with MaruCheck
Everything above can be done by hand. MaruCheck is a free, open-source CLI that automates it for JavaScript and TypeScript repositories. It runs locally or in your CI runner, so no source code is uploaded. Each step maps to a command:
| Step | Command |
|---|---|
| Record what must not change | maru contract create --from requirements.md, then maru contract approve |
| Score the diff’s risk | maru risk --diff |
| Build a requirement-linked test plan | maru plan --diff |
| Run targeted tests and detect behavior drift | maru verify --diff |
| Test the tests | maru mutate --diff |
| Gate every pull request | maru ci init |
Frequently asked questions
- How do you verify AI-generated code?
- Verify AI-generated code by checking it against a requirement the AI could not edit. Write down the approved behavior separately from the tests, review any test changes as carefully as code changes, run targeted tests for the risky paths, confirm the tests actually fail when the behavior breaks, and keep the evidence with the pull request.
- Is a passing test suite enough to trust AI-written code?
- Not on its own. A coding agent can change the implementation and the tests that judge it in the same change, so a passing suite can only prove the code agrees with its tests. It cannot prove the tests still describe what the product promised before the change.
- What are the most common problems in AI-generated code?
- Treat AI-generated code like code from a fast, confident contributor who has not read the requirements. Its common failures are plausible-looking logic errors, removed edge-case guards, weakened or rewritten tests, invented APIs, and security mistakes. Veracode's 2025 study found security flaws in 45% of the AI coding tasks it tested.
- Can I verify code from Copilot, Cursor, and Claude Code the same way?
- Yes. Verification depends on the diff, not on which assistant wrote it. The same process works for code from GitHub Copilot, Cursor, Claude Code, OpenAI Codex, Windsurf, or a human. Open-source tools such as MaruCheck run locally against the Git diff, so they work with any editor or agent.
Related guides
Why AI coding agents change tests to make them pass
Why Claude Code, Cursor, and other coding agents edit, weaken, or skip tests to get a green run, how to spot it in a diff, and five controls that stop it.
GUIDEHow to review an AI-generated pull request
A reviewer's checklist for AI-written pull requests: what to read first, failure patterns that look correct, and what evidence to require before approving.
GUIDEMutation testing in TypeScript and JavaScript
What mutation testing is, how to read a mutation score, running StrykerJS with Jest or Vitest, and mutation-testing only the code an AI just changed.
GUIDEAI code review tools vs. verification: what each one catches
AI review bots, static analysis, tests, mutation testing, and independent verification compared: what each catches in AI-generated code and what it misses.
Last updated