When a deploy goes wrong, nobody asks which tool wrote the offending line. They ask who approved it, who shipped it, and who is fixing it. That question doesn't change because an AI assistant produced the diff. What changes is how easy it becomes to approve something you haven't really understood — and that is where AI-generated code quality turns from a tooling topic into an accountability one.

The answer is still a person

An AI model has no on-call rotation, no customer relationship, and no context about what your business can't afford to break. The engineer who opens the pull request owns it, and the reviewer who approves it shares that ownership. Teams that get this right treat AI output as a draft from a fast, confident contributor who has never seen production: useful, often correct, and never self-verifying.

Plausible is not the same as correct

AI-generated code usually compiles, reads cleanly and passes the happy path. The failures tend to hide in what it didn't know: an unwritten business rule, a concurrency edge case, a dependency that doesn't exist, or an assumption about data that is only true in the sample it saw.

How AI-generated code tends to fail

  • Subtly wrong logic that looks right: off-by-one boundaries, timezone handling, rounding in money calculations, silent fallbacks that swallow errors.
  • Invented or outdated APIs and packages — calls to methods that don't exist, or deprecated ones that still happen to run.
  • Missing context: duplicated helpers that already exist in the codebase, or changes that quietly break an unwritten convention.
  • Insecure defaults: string-built queries, permissive CORS, missing authorization checks, secrets logged for debugging.
  • Over-engineering. More code than the problem needed means more surface area to review, test and maintain.

Code review is still the main control

Review gets harder, not easier, when the author didn't type the code. The author can't say "I chose this because…" unless they actually read it. A workable rule: you must be able to explain every line you submit, whether or not you wrote it.

  1. Keep pull requests small. A 1,500-line AI-generated diff gets skimmed, and skimmed reviews miss things.
  2. Ask the author to state the intent and what they verified by hand, not just "generated with AI."
  3. Review for behaviour and edge cases first, style second. Formatters and linters handle style.
  4. Check every new dependency: does it exist, is it maintained, and do we actually need it?
  5. Never let the tool that wrote the change be the only reviewer of it.

Tests are the contract the code has to meet

A test suite is the only objective answer to "does this still do what we agreed it should?" Be careful with one trap: asking the same AI to write the code and its tests. The tests tend to encode the same misunderstanding as the implementation, so both pass and both are wrong.

  • Write or at least review the test cases yourself — especially boundaries, failure paths and permissions.
  • Prefer tests that describe business behaviour over tests that mirror the implementation line by line.
  • Add a regression test for every bug, including bugs in AI-written code, so the same mistake can't return quietly.
  • Run the suite in CI on every pull request so a green check means the same thing for everyone.

Observability: assume something will slip through

No review process catches everything, so the goal shifts to noticing quickly and understanding fast. If you can't tell within minutes that a release changed behaviour, you are relying on customers to be your monitoring.

  • Structured logs with request IDs, so one failing request can be traced end to end.
  • Metrics on the signals that matter: error rate, latency, queue depth, and key business events such as signups or payments completed.
  • Alerts tied to user impact rather than raw noise, with a named owner who receives them.
  • Release markers on dashboards, so "it broke at 14:10" can be matched to "we deployed at 14:08."

Rollback: make being wrong cheap

The most underrated defence against any bad change, human or AI, is how fast you can undo it. If reverting takes an hour of careful manual steps, every deploy is a high-stakes event and people will rightly be nervous about shipping.

  • One-command or one-click rollback to the previous known-good version, practised before you need it.
  • Feature flags for risky changes, so you can switch behaviour off without redeploying.
  • Gradual rollouts such as a canary or a small percentage of traffic, so a mistake reaches a few users instead of all of them.
  • Backward-compatible database migrations, because code can be rolled back far more easily than data.

Security: treat generated code as untrusted input

Security review shouldn't depend on the author remembering to think about it. Automate what can be automated and keep humans focused on the judgment calls.

ControlWhat it catches
Dependency and vulnerability scanningHallucinated, abandoned or known-vulnerable packages
Static analysis and secret scanningInjection patterns, unsafe functions, keys committed by mistake
Authorization testsEndpoints that work but don't check who is asking
Least-privilege credentialsLimits the damage when something does go wrong
Human security review of sensitive pathsAuth, payments, file uploads and anything touching personal data

Be equally careful about what you paste into a prompt. Production data, customer details and secrets don't belong in a tool your organisation hasn't approved.

Making accountability explicit

Accountability works best when it is written down before an incident rather than argued about during one. A short team agreement is enough:

  • The person who opens the pull request is responsible for it, regardless of how the code was produced.
  • Every change has a named reviewer and a named owner for the service once it is live.
  • High-risk areas — payments, auth, data migrations — require a second human reviewer.
  • Incident reviews focus on the process gap (what let this through?), not on blaming a person or a tool.

A realistic bottom line

AI makes writing code cheaper. It does not make owning code cheaper. Reading, verifying, operating and fixing software still takes people who understand the system, and the faster code gets produced, the more those safeguards — review, tests, observability, rollback and security — matter. Use the speed, keep the accountability, and make sure the person who ships a change can always answer one question: why is this safe to run?

Using AI to ship faster without shipping more risk?

If you want a second pair of eyes on your review process, test coverage or release pipeline, I'm happy to talk through what would actually make production safer for your team.

Let's talk →
PG
Parth Ghanva
Full-Stack Engineer & Developer Experience Engineer