← writing

The vibecoder's pre-merge checklist

Twelve fast gates I run through before merging anything an AI wrote. None take more than a minute, all of them have saved me from shipping something I'd regret by Monday.

Last week a friend pinged me with a PR. Claude had written most of it, the tests were green, the diff was 600 lines, and he wanted a quick rubber stamp before lunch. I opened it, scrolled for ten seconds, and asked him three questions he couldn't answer. He closed the laptop, went back, and an hour later sent me a much smaller, much better PR. That conversation is the reason I keep a checklist taped to my monitor, and it's the reason I'm writing this one down for you.

Here are the 12 gates I run through before I let any AI-written code into main. None of them take more than a minute. Skipping them is how you end up with a codebase that looks fine and behaves like a haunted house. 🟠

  1. Did you read every line of the diff? Not skimmed, not "looks reasonable," actually read. If the diff is too big to read, the PR is too big to merge. Split it.

  2. Are the new dependencies necessary, or did the model reach for the npm shelf out of habit? Models love pulling in lodash for one util and date-fns for one format call. Check package.json, ask if a 10-line helper would have done it, and rip out anything that's there because of training data inertia rather than actual need.

  3. Are error messages helpful, or generic "Something went wrong"? Search the diff for that exact string and any cousins like "An error occurred" or "Failed to process." Every error should tell future-you what happened, what was attempted, and ideally what to try. Otherwise you're just writing a riddle for your 3am self.

  4. Is there at least one real test, not a mock-tests-itself test? If the test mocks the function under test, or mocks the database and then asserts the mock was called, you don't have a test, you have a fixture. Find one assertion that proves real behavior end to end.

  5. Are the names what you would name them, or what the model defaulted to? Watch out for handleData, processItem, UserService, utils.ts. These are placeholder names that survived to production. Rename them now while it's cheap.

  6. Did you delete the over-defensive try/catch blocks? Models wrap everything because they don't know which calls can throw, so they catch all of them. Most of those catches just log and rethrow, or swallow errors silently. Delete the ones that don't add value, keep the ones that translate an error into something the caller can act on.

  7. Is the happy path actually the common path, or did the model bury it under edge cases nobody hits? Read the function top to bottom. If the first 40 lines are guards for situations that happen once a year, restructure so the 99% case is what you see first. Future readers will thank you.

  8. Did you run it on a fresh terminal in a fresh shell? Your current shell has env vars, cached builds, and side effects from the last seven things you tried. Open a new tab, cd into the repo, and run the thing cold. Half the "works on my machine" bugs die right here.

  9. Are the logs you'd want at 3am actually there? When this breaks in production at the worst possible hour, what would you want to see? Request IDs, the input that caused the failure, the state of the relevant variables. Add those now, not after the incident.

  10. Did you remove the comments that just narrate the code? // increment counter above counter++ is noise. Models generate these because their training data is full of tutorials. Keep comments that explain why, delete comments that explain what.

  11. Is the README still accurate? If you changed a command, an env var, a script name, or a flag, the README is now lying. It takes 30 seconds to check, and a stale README is worse than no README because it teaches new contributors the wrong thing with confidence.

  12. Would you be embarrassed if a senior dev opened this PR cold? Imagine someone whose opinion you respect clicks the link with no context. Are you proud of what they'd see, or are you hoping they skim it? If it's the second one, you're not done.

That's the list. It's not exhaustive and it's not clever, it's just the 12 things I've watched myself and other people skip when the AI made the work feel easy. The whole point of AI assistance is that it gives you more time, so spend a fraction of that time on the gate.

Print it. Tape it to your monitor.

Want more like this?

Occasional, opinionated, no listicles.
all writing →