My Auto-Merge Shipped Unfixed Code Because 'Threads Resolved' Won a Race Against 'Fix Committed'

/ Article
[ Fig. 1 ]

My Auto-Merge Shipped Unfixed Code Because ‘Threads Resolved’ Won a Race Against ‘Fix Committed’

I built a CI backbone that auto-merges a pull request the instant two things are true: the build is green, and there are zero unresolved review threads. It felt airtight.

Then it shipped unfixed code.

The Race

Here’s what happened. A PR had three correctness issues flagged by the code reviewer. My workflow was a fix-PR loop: a reply node resolves the review threads, and a separate build node pushes the actual code fix.

The reply node moved first. It resolved all three threads. The build node hadn’t pushed yet.

But my auto-merge check doesn’t care about the build node. It sees “green” and “zero unresolved threads” and fires. Branch deleted. Code merged to dev.

The code fix? Never landed.

Why ‘Threads Resolved’ Is Not ‘Fix Landed’

The problem is simple: review threads and code are two different things. A thread being resolved means someone clicked a button. A fix landing means the code changed. There’s no mechanical connection between them.

In my case, the reply node resolved threads in a chat message - that’s a social action. The build node pushes code - that’s a technical action. Auto-merge was watching the social action and ignoring the technical one.

What I Do Now

After any merge, I check the merged main directly. Not the review threads, not the CI status - the actual code.

git show origin/main:<file> | grep <fix-signature>

If the fix signature is there, the fix landed. If it’s not, someone resolved a thread without fixing anything.

For correctness fixes - the kind that matter - I also stopped using fix-in-place on an auto-merge-armed PR. I open a fresh PR, verify the head manually, and merge it myself. It’s slower. It’s also the only way to be sure the thing I’m reviewing is the thing that ships.

The Short Version

If your auto-merge triggers on “green + zero unresolved threads,” you’ve given an agent the power to merge by resolving threads. That’s a social action. The code doesn’t know.

Reality-gate the merged main. Don’t trust the review state.