The single highest-leverage convention in code review is prefixing every comment with its severity. Without it, the author must reverse-engineer your intent, and the safe default is to treat everything as blocking — which is how a two-nit review turns into another round trip.
Scanned 9/10/2026
Install to Claude Code
npx -y skills add snoodleboot-io/prompticorn --skill verbose --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Verbose?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/snoodleboot-io-verbose-54048ff6)More formats (shields.io, HTML) on the badges page.
# Code Review Practices (Verbose)
## Core Patterns
### Severity Labels Make Reviews Unblockable
The single highest-leverage convention in code review is prefixing every comment
with its severity. Without it, the author must reverse-engineer your intent, and
the safe default is to treat everything as blocking — which is how a two-nit
review turns into another round trip.
| Prefix | Meaning | Author may merge? |
|---|---|---|
| `blocking:` | Correctness, security, data loss, or a contract break | No |
| `question:` | I don't understand; the answer may become blocking | Answer first |
| `suggestion:` | A better approach; author's call | Yes |
| `nit:` | Style, naming, phrasing | Yes, ignore freely |
| `praise:` | Worth keeping and imitating | Yes |
Discipline for reviewers: you may only write `blocking:` if you can name what
breaks. "I'd have done it differently" is `suggestion:`. If your blocking rate
exceeds roughly one in five comments, you are inflating severity and the labels
stop carrying information.
### Rewriting Real Comments
Most bad review comments share one flaw: they describe the reviewer's reaction
rather than the change required.
```
❌ "This is hard to follow."
✅ "suggestion: `process()` on 40-95 does parse, validate, and persist.
Splitting out `_parse_payload` would let the validation tests drop the
DB fixture. Not blocking — fine as a follow-up."
❌ "Why did you do it this way?"
✅ "question: Curious why polling here rather than the existing webhook
on `OrderUpdated`. If it's because the webhook is unordered, worth a
comment in the code — the next person will ask the same thing."
❌ "Bug."
✅ "blocking: If `items` is empty, line 63 divides by `len(items)` and
raises ZeroDivisionError. Empty carts reach this path from the
abandoned-cart job."
❌ "We don't do it that way here."
✅ "suggestion: The other three handlers use the `@retryable` decorator
(see `payments/handlers.py:22`) rather than a manual loop. Matching
that gets you the metrics wiring for free."
```
Note what the good versions share: a line number, a concrete failure or concrete
alternative, and an explicit stance on whether it blocks.
### Size Drives Everything
Review effectiveness is a function of diff size, and the falloff is steep:
| PR size (changed lines) | Typical outcome |
|---|---|
| < 100 | Careful line-by-line reading; highest defect yield |
| 100-400 | Still effective; the practical target band |
| 400-800 | Reviewer skims; structural feedback only |
| > 800 | Approval rate goes up, comment density goes down |
The counterintuitive part: large PRs receive *fewer* comments per line, not
more. A reviewer's attention budget in one sitting is roughly 200-400 lines and
about 60 minutes; past that, defect detection falls off sharply. Treat these as
norms to calibrate against rather than hard thresholds — the shape of the curve
matters more than the exact number. So "LGTM" on a 1,200-line PR is not a signal
of quality, it is a signal of exhaustion.
Splitting is a design activity, not a formatting one. Cut along seams that each
leave the system working:
```
❌ One PR: "Add team billing" (1,400 lines)
✅ 1. Migration: add `billing_accounts` table, no readers yet (~90)
2. Repository + unit tests, unreferenced by any endpoint (~180)
3. Service layer wiring behind a disabled feature flag (~250)
4. Endpoint + flag enable (~200)
```
Each lands independently, each is reviewable in a sitting, and a rollback of
step 4 does not strand the schema.
### Latency Dominates Cycle Time
Measure the wall-clock life of a PR and the review *waiting* time usually
dwarfs both authoring and reviewing. A change that takes 3 hours to write and 25
minutes to review can easily take 3 days to merge. Every day it waits, the
branch drifts, the author context-switches, and the eventual re-read costs more.
Practical norms that move the number:
- First response within 4 business hours. "Looking this afternoon" counts.
- Review incoming PRs before starting new work of your own.
- Approve-with-comments for anything that is only `nit:` and `suggestion:`.
Trust the author to apply them; do not require another round.
- Escalate to a synchronous 10-minute call after the second round trip on the
same disagreement. Text is a bad medium for design arguments that have already
failed once.
### What Humans Should Review
Anything a machine can check should already be checked before a human looks.
Formatting, import ordering, lint rules, type errors, and test failures belong
in CI. Human attention is the scarce resource; spend it on judgment:
- **Problem fit** — is this solving the right problem, at the right layer?
- **Failure paths** — timeouts, retries, partial writes, concurrent callers.
What is the state of the world if this process dies at line 40?
- **Data lifecycle** — is the migration reversible? Is there a backfill? What
reads the old column?
- **Future cost** — will this make the next change harder? Review for the change
you would have to make later, not for the change you would have written.
- **Test meaning** — do the tests fail if the behavior regresses, or do they
merely execute the code? (See `test-coverage-categories`.)
Security-sensitive diffs get their own dedicated pass; see `secure-code-review`.
### Author-Side Practice
Reviews are largely won before anyone else reads the code.
Write the description for a reader who lacks your context:
```
❌ "Fixes the checkout bug."
✅ Why: Checkout 500s when a promo expires between cart load and submit.
~40/day, PRO-412.
What: Re-validate the promo at submit time rather than trusting the
cart snapshot.
Alternative rejected: locking the promo at cart creation — would hold
inventory for abandoned carts.
Risk: adds one read to the submit path (~3ms, measured).
Testing: new test for the expiry race; verified manually against staging.
```
Then read your own diff on the PR page and annotate it. Flag the file that is a
pure mechanical rename so the reviewer skips it. Explain the odd-looking early
return. Every self-comment you leave is a round trip you did not spend.
## Common Anti-Patterns
❌ **Unlabeled comments** — the author cannot tell a nit from a defect and
treats all of them as gates.
✅ Prefix every comment: `blocking:`, `question:`, `suggestion:`, `nit:`.
❌ **The rewrite review** — reviewer reconstructs the change as they would have
written it, and the author complies to get unblocked.
✅ Accept any design that is correct and maintainable. Reserve objections for
things that are wrong or that make future work harder.
❌ **Reviewing formatting by hand** — comments about spacing and naming style
that CI could enforce, crowding out substantive feedback.
✅ Move it into the linter. If the team argues about it twice, automate it.
❌ **The batched mega-review** — a week of work lands as one 1,500-line PR.
✅ Stack it. Four sequential PRs of 200-400 lines each, merged as they pass.
❌ **Silent approval on a big diff** — LGTM in 90 seconds on 900 lines.
✅ Say what you actually reviewed: "Read the service layer and migration
closely; skimmed the generated client. Someone should check the retry logic."
❌ **Resolving disagreements in DMs** — the decision exists only in two people's
memory, and a third engineer relitigates it next quarter.
✅ Have the conversation wherever it happens, then post the conclusion and its
reasoning back on the PR.
❌ **The drive-by blocker** — a reviewer with no context blocks on an
architectural objection to a design already agreed in review.
✅ Raise architecture at design time. If it genuinely must be reopened, say so
explicitly and take it off the PR thread.
❌ **Nitpicking a hotfix during an incident.**
✅ Review incident fixes for correctness and blast radius only; file the cleanup
as a follow-up ticket.
## Code Review Checklist
**As reviewer**
- [ ] Responded within 4 business hours of the request
- [ ] Every comment prefixed with a severity label
- [ ] Each `blocking:` names a concrete failure, not a preference
- [ ] Checked failure paths: timeout, retry, partial write, concurrency
- [ ] Checked the migration is reversible and the backfill is bounded
- [ ] Verified tests would actually fail on regression
- [ ] Left no comment a linter could have made
- [ ] Stated what you did and did not review if the diff is large
- [ ] Approved with comments when nothing is blocking
**As author**
- [ ] Diff under ~400 changed lines, or split with the stack explained
- [ ] Description covers why, what, alternatives rejected, risk, testing
- [ ] Self-reviewed the diff and annotated the non-obvious parts
- [ ] Mechanical changes (renames, generated files) separated or flagged
- [ ] Responded to every comment, including "won't fix, because…"
- [ ] Off-thread decisions written back onto the PR before merge
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!