Thinkr

Craft

Async PRD Review: Comments That Get Resolved

How to run an async PRD review that actually finishes: typed comments, who may resolve what, three valid resolutions, and a closed thread that leaves a record.

Galang Aulia · 5 min read
Craft

Async review usually fails at the end, not the start. Comments arrive. Some get answered, some get a thumbs-up, some get resolved by the author with no reply at all, and a week later nobody can say which concerns were dealt with and which were clicked away.

"Resolved", in a typical doc tool, means someone pressed a button. The thread collapses, the reasoning in it disappears from view, and the document may or may not have changed. Do that across forty comments and you have a spec that looks reviewed and a review nobody can reconstruct.

Three rules fix it: type every comment, decide who may resolve each type, and allow only three kinds of resolution. The side effect is the useful part. A thread resolved properly is a decision record, written at the moment the decision was made.

Type every comment

A comment without a type makes the author guess its weight. "Have we considered rate limits?" might be a blocker or idle curiosity, and the author will read it as whichever is more convenient.

Prefix every comment with one word:

TypeMeansResolved byNeeds
BlockerCannot build, or the launch would be wrongThe commenter, or the deciderA change, or a ruling
MajorWill cost a rework cycleThe authorA change or a written reason
MinorThe doc gets better; nothing breaksThe authorThe fix
QuestionThe reader cannot tell what is meantThe authorThe answer, in the doc

The severity scale is the one from reviewing someone else's PRD, with one addition. Questions get their own type because they are not judgements. They are a reader telling you a sentence can be read two ways, and the fix always belongs in the document, never only in the reply.

Who may resolve what

The rule that matters most: the author does not close their own blockers.

If the author can resolve a blocker by replying "addressed in v3", the review is a formality. The commenter closes it once they agree, or the named decider closes it if they do not. That one rule changes how blockers get raised, too. Reviewers who know their blocker will be checked file fewer of them, and mean the ones they file.

Majors and minors the author closes alone. Questions close when the answer is in the doc, and the reply says where.

Three valid resolutions

Every resolved comment ends with one of three replies:

  • Changed. The doc was edited, and the reply says where: "Section 4 now caps imports at 500 rows."
  • Declined. The author disagrees and says why in one line: "Keeping email-only invites; SSO provisioning is out of scope, see section 2."
  • Deferred. Real, but not now. It gets an owner and a date, and moves to an open-items list in the doc.

A resolution with no reply is not one of the three. Neither is "good point!", which says the author agreed and not what they did about it.

A resolved thread is a decision record

Look at what a properly closed thread contains: a concern, the alternative someone proposed, the decision, and the reason. That is the content of a decision log entry, written at the moment by the people involved.

And then resolving it usually hides it. The thread collapses out of the default view, and the reasoning goes with them. Six months on, somebody asks why imports cap at 500 and nobody can find the thread that answered it.

So add one write-back rule: anything that changes a requirement, or declines a blocker or a major, gets a line in the doc before the thread closes. Changes go into the requirement itself. Declines go into the decision log or a "considered and rejected" list. The thread can collapse after that, because nothing in it exists only there. It is the same rule as the async handoff: the thread is where you decide, and the document is where the decision lives.

An illustration of one thread, closed properly:

QUESTION (engineering) on "Invites expire":
  After how long, and what does the invitee see?
DESIGN: Could invites just never expire?
AUTHOR - Changed: section 5 now says 7 days, then a page offering to request a new invite.
AUTHOR - Declined: no expiry, because open invites to people who have left are a security risk.
Logged in the decision log, 10 Oct.

Two decisions, one reason each, both findable after the thread disappears.

Open a window, then close it

Async without a deadline does not end. It tapers. Comments trickle in for a fortnight while the author keeps editing, and the late comments are about a version that no longer exists.

Put three dates at the top: when the review opens, when comments close, and when the author will have replied to everything. Three to five working days suits most feature specs. If the review is also the pre-read for a meeting, close comments a day before it so the author can sort them.

At the close, the author posts a short summary at the top of the doc: how many comments were changed, declined and deferred, which blockers remain open, and the call, ship, revise or rethink. That summary is what someone opening the doc next month reads first.

What async is bad at

Disagreement. Text carries "this criterion is not testable, here is a version that is" perfectly. It carries "I think this feature should not exist" badly, because people soften, hedge or go quiet, and the objection resurfaces three weeks later as reluctance.

The rule: two rounds of replies without converging, and the thread goes live. A short call, then the outcome is written back into the thread and the doc. The call is not the record. The doc is.

Let the machine open the review

Mechanical comments are what clog an async review: undefined terms, missing states, untestable criteria. They are numerous and easy to resolve, and they bury the three comments that matter.

Our critique lands its findings in the same shape this post describes: comments on the line, marked blocker, major or minor, each with a suggested rewrite. Run it before the window opens and close what it finds, and the human comments that follow are the ones that need a human.

FAQ

How do you run an async PRD review? A window with a close date, typed comments, and a written resolution for every one.

Who resolves a comment? The author closes minors, majors and answered questions. Blockers close with the commenter or the decider.

How long should it stay open? Three to five working days, with the close date at the top.

When should it become a meeting? After two rounds of replies that do not converge.

New posts and release notes. No spam, unsubscribe anytime.

Stop shipping foggy PRDs.
Start the critique loop.

Three minutes to sign up. No credit card. Cancel by closing the tab.

Start freeSee pricing