docs/book/src/contributing/pr-review-protocol.md
This is the procedure followed when reviewing a pull request in zeroclaw-labs/zeroclaw. It's loaded by the github-pr-review-session skill and read by human reviewers — it's authoritative for both.
The gh CLI is assumed available and authenticated.
Run all of these. The data informs every step that follows.
PR overview
gh pr view <number> --repo zeroclaw-labs/zeroclaw
Description, labels, linked issues, validation evidence.
Top-level conversation
gh pr view <number> --comments --repo zeroclaw-labs/zeroclaw
Inline threads (every reply chain)
gh api repos/zeroclaw-labs/zeroclaw/pulls/<number>/comments --paginate
Read full reply chains before drawing any conclusion about whether something is open or settled. Note author commitments made in replies — they're load-bearing.
Formal reviews
gh api repos/zeroclaw-labs/zeroclaw/pulls/<number>/reviews --paginate
Note which CHANGES_REQUESTED are still active (not superseded by a later APPROVED or DISMISSED). Check whether you've already reviewed this PR.
Relevant foundations documents
Always read FND-005 (Contribution Culture). For others, use the relevance table below — read what applies to the PR's scope. The ratified versions are local files; no API call needed.
| Foundation | Local file |
|---|---|
| Microkernel Architecture | docs/book/src/foundations/fnd-001-intentional-architecture.md |
| Documentation Standards | docs/book/src/foundations/fnd-002-documentation-standards.md |
| Team Governance | docs/book/src/foundations/fnd-003-governance.md |
| Engineering Infrastructure | docs/book/src/foundations/fnd-004-engineering-infrastructure.md |
| Contribution Culture | docs/book/src/foundations/fnd-005-contribution-culture.md |
| Zero Compromise in Practice | docs/book/src/foundations/fnd-006-zero-compromise-in-practice.md |
Diff
gh pr diff <number> --repo zeroclaw-labs/zeroclaw
Read the full diff. Cross-check author commitments from step 3 against what actually shipped. Cross-check against the local repository where the change lands.
Before you write a single line of review, name out loud:
The take-stock pass is what stops you from re-raising settled points and what surfaces who's actually waiting on what.
| Situation | Verdict flag |
|---|---|
| Your review is approving and no other reviewer holds an active block | --approve |
| Your review is rejecting on substantive grounds you'd block on personally | --request-changes |
| You have nothing new to block on but other reviewers hold active blocks | --comment |
You have specific findings but they're all [suggestion] / [question] | --comment |
You're a maintainer override-approving over another reviewer's CHANGES_REQUESTED | Don't. Get the other reviewer to dismiss or convert their review first. |
Findings in review bodies and inline comments use this scale (from FND-005):
Write as a thoughtful senior contributor who has read everything and cares about the outcome:
✅ The merge order is correct because…) builds shared judgment over time.RESOLVED ✅ explicitly so the author sees their work was registered.[blocking] / [suggestion] / [question] finding tied to a specific line. Anchor the feedback to the code so the author can resolve it inline.@-prefixed usernames in all review content (chat, body, inline). @WareWolf-MoonWall, not WareWolf-MoonWall.Write the review body to a file under tmp/review-<number>.md first — this is the source of truth for what was posted and lets the user inspect before publishing. Then:
gh pr review <number> --repo zeroclaw-labs/zeroclaw \
<--approve | --request-changes | --comment> \
--body-file tmp/review-<number>.md
Always show the full draft and get explicit approval from the human before posting. Continuation words like "next" or "move on" don't count as approval — only an unambiguous "yes" / "approve" / "go" does.
If a session-level handoff file exists (tmp/handoff.md), update it with the verdict, the head commit reviewed, and what remains open. The handoff is what lets a new session pick up cold without re-reading the whole conversation.
CHANGES_REQUESTED. Resolve the prior block first.maintainerCanModify: true allows it; even then, ask before pushing anything other than trivial fixups.