Review comments that land

The same concern can read as a gift or an attack — the wording decides which.

The idea

A review comment has one job: get a good change made without bruising the person who made it. The shape that works is observation, then concrete impact, then a question or a suggested fix — and a severity label so the author knows whether to drop everything or file it under later. Describe the code, not the coder; say what it costs, not just that you dislike it; and hold the merge only when the concern actually earns it.

Assemble a comment below and watch the “how it lands” gauge move. Flip between a security bug and a style nit to see when blocking is right — and when it just slows the team.

Interactive · the pull request

1 · how you open
2 · the impact
3 · the ask
4 · severity label
5 · merge decision
nit
clarity 0 tone 0
No decision yet.
Build the comment part by part. The gauge scores how clearly it lands and how collaborative it reads; the decision check tells you whether holding the merge is the right call here.

How it works

Four moves turn a reaction into a comment an author will act on:

1. OBSERVE   describe the code, not the person
             "I noticed this concatenates name into the SQL string"
             (not "you wrote this unsafely")

2. IMPACT    say what it costs, concretely
             "that opens a SQL-injection path"
             (not "this is bad" — and not "we'll get hacked, disaster!")

3. ASK       a question or a suggested fix beats an order
             "could we use a parameterized query — db.query('… ?', [name])?"

4. LABEL     blocking | suggestion | nit   -> so the author can triage
             block only correctness, security, or data loss
             everything else is a suggestion or a nit that can merge

Pushing back, including on someone senior: anchor on the code and its impact, not authority. “Help me understand the trade-off — with untrusted input, doesn’t this concat allow ?” invites a technical answer and gives them room to reconsider without losing face. Ask, cite the concrete risk, and stay open to being wrong — seniority is not the argument, the injection path is.

When to use it

Label itWhen
blocking — hold the mergeCorrectness, security, data loss, or a broken contract. Something that must not ship.
suggestion — author’s callA cleaner approach worth considering, but the code is correct as-is.
nit — optional polishNaming, formatting, small readability. Merge with or without it; fix-forward is fine.

Watch out for

Worked example

An interviewer asks, “A senior engineer’s PR concatenates user input into a SQL query. How do you comment?” The weak answer blocks with “this is insecure, fix it.” The strong answer is a full comment: “blocking (security): I noticed this builds the query by concatenating name into the SQL string. With untrusted input that opens a SQL-injection path — a crafted name could read or drop rows. Could we switch to a parameterized query, e.g. db.query('… name = ?', [name])? Happy to pair if useful.” It observes, names the concrete impact, offers a fix, labels the severity honestly, and — because it is a security defect, not a preference — holds the merge. Being junior is irrelevant; the injection path is the argument.

Check yourself

A teammate’s PR is correct but uses a variable named x where retryCount would read better. Best move?

You are junior and a staff engineer’s change looks like it drops rows on a failed migration. How do you push back?