“Disagree and commit” gets quoted in planning meetings and forgotten by the time anyone opens a pull request. Which is a shame, because the comment box is where most engineers actually practice disagreement, several times a day, usually badly. I include past me in that. I blocked PRs over things I should have shrugged at, and I rubber-stamped things I should have stopped, and the difference between those two mistakes is a judgment I had to learn on purpose.
The whole skill is matching the weight of your response to the stakes of the disagreement. There are three weights. Most people only use one.
Merge with a question#
This is the move I underused for years, and it’s the most valuable one. The code is fine. You’d have done it differently, but “differently” isn’t “wrong,” and the PR is not the place to relitigate taste. So you approve it, and you leave a comment that doesn’t block:
“Approving. Out of curiosity, did you consider pulling the retry logic into the client? Not blocking, just want to understand the call.”
You learn something or they do, and either way the code ships today. The trap here is the fake question, the one from the clean-question problem, where “did you consider X” actually means “you should have done X.” If you mean it as a block, block. If you genuinely want to understand, say so and mean it. Engineers can smell a passive-aggressive approval from across the repo, and it poisons the well for the real questions later.
Push back, but stay in Adult#
Some disagreements are worth the friction. The approach has a real cost the author probably didn’t see: a performance cliff at scale, a security edge, a maintenance burden that lands on someone who isn’t in the thread. Here you push, and how you push decides whether it lands.
The version that fails is the one written from what Transactional Analysis calls the Parent state, scolding from above: “this is not how we do things here.” The version that works comes from Adult: present, specific, aimed at the code. Name the concrete failure, not the character flaw. “This recomputes the whole list on every keystroke, which will be rough once a power user has a few thousand rows” is a sentence the author can do something with. “Why didn’t you memoize this?” is a sentence they have to defend against. Same technical point. One opens the fix, the other opens an argument.
And play it back first. “Looks like the goal was to keep the component stateless, which I’m on board with” tells the author you understood the intent before you came at the implementation. People don’t take notes while they’re bracing.
Block, and own it#
The rarest weight, and the one to spend carefully. A block says “this should not merge as written,” and every time you reach for it on something that didn’t warrant it, you spend down the credibility you’ll need when something actually does. Save it for the cases where the cost of being wrong is high and hard to reverse: data loss, a security hole, an API contract you’ll be stuck supporting, a migration that can’t be rolled back.
When you do block, own the weight of it. Don’t hide a hard stop inside a pile of nits so the author has to guess which comment is load-bearing. Say it plainly, up top: “Blocking on one thing, the rest are optional. This drops the foreign key constraint, and we’ll have orphaned rows in production by next week. Let’s fix that and the rest can ship as-is.” One clear blocker the author can act on beats fifteen comments they have to triage to find the one that matters.
The part that’s actually disagree-and-commit#
Here’s where the planning-meeting cliché finally earns its place. Sometimes you push back, you make your case from your calmest Adult self, and the author and the team go the other way anyway. The bar wasn’t met. It was a real disagreement, not a safety issue, and you lost it.
Then you commit. Not sulking-commit, where you approve with a curt “fine” and wait to be proven right. Actually commit: the decision is made, you help make it work, and you don’t relitigate it in the retro three weeks later when the thing you predicted comes half-true. You logged your concern. It’s in the thread. That’s the receipt, and it’s enough. The senior engineer who can argue hard and then genuinely let go is rare, and teams trust that person with bigger arguments precisely because they don’t have to fight to the death over small ones.
The comment box is a leadership instrument. Most of us were handed it with no manual and learned to use it as a weapon or a rubber stamp. It’s neither. It’s a dial, and the skill is knowing how far to turn it.
