Code Review Standard
:::note Map + pointer
How we review a change β adapted from Google's Engineering Practices β "How to do a code review"
and mapped onto this platform's real review machinery. The decision of record is the rule
.claude/rules/code-review.md;
this page is its published map.
:::
The one principle above allβ
Approve a change once it definitely improves the overall code health of the system β even if it isn't perfect. There is no perfect code, only better code. The reviewer stops health from degrading; they do not block forward progress on polish.
A merely-preferred tweak β Nit: (non-blocking). Facts & data beat opinion; design is engineering, not
taste; linters/style-guide are authoritative; consistency wins unless it degrades health. Never
deadlock a change over a disagreement β resolve on principle or escalate.
Our three review layers (where this applies)β
Code here is largely written by AI agents, reviewed in three layers (bmad-compliance.md), scaled by
delivery path (A/B/C/E):
| Layer | What | Who |
|---|---|---|
| 1 β self-review | /bmad-build's own review + the test pyramid | the build agent |
| 2 β independent AI pass | /bmad-code-review in a FRESH context β no memory of writing it (the real "second pair of eyes") | a fresh agent |
| 3 β human review | CODEOWNERS approval that gates prod + CI (Trivy/kubeconform/SAST) | the owner |
Google's reviewer principles apply to layers 2 + 3. /bmad-walkthrough adds a risk-focused pass for
auth / schema / public-API / security diffs.
The reviewer checklist (priority order)β
Design (does it fit / belong here?) Β· Functionality (intent + users; edge cases, concurrency β backstopped by the live QA gate) Β· Complexity (no over-engineering / YAGNI) Β· Tests (right layers, in the same CL, fail when the code breaks) Β· Naming / Comments (comments say why, not what) Β· Style (linter-clean; keep style out of a logic CL) Β· Consistency Β· Documentation (updated in the same effort β the DoD gate) Β· Every line (read all of it; ask when unclear; pull a specialist) Β· Context (judge against the whole system) Β· Good things (call out what was done well β mentoring value).
How to review (order) + speedβ
- Broad view β should this change exist at all? If not, say so now, with an alternative.
- Main parts first β review the core logic + send major design feedback immediately; ask to split an over-large change.
- The rest in sequence β read the tests first to learn intent.
Speed: respond within one business day (respond β finish); fast responses beat fast turnaround;
LGTM + comments when you trust the author on the minors; never trade the standard for imagined velocity.
Writing commentsβ
- Comment on the code, not the person; explain why; it's the author's job to fix, so prefer pointing out the problem over prescribing.
- Label severity:
Nit:(trivial) Β·Optional:/Consider:(not required) Β·FYI:(informational). Unlabelled = expected to address. - Unclear code β ask for a rewrite, not an explanation in the thread β the next reader needs the clarity in the code, not the PR.
Pushbackβ
The author may be right (they're closer to the code) β concede if their reasoning holds on health grounds;
otherwise keep advocating, politely. "Clean it up in a later CL" β no: new complexity is cleaned up
before submission unless it's an emergency; genuinely out-of-scope problems get recorded (deferred-work.md
/ a filed issue + TODO(#issue)), not waved through.
The merge path β gh pr merge --admin is break-glass onlyβ
--admin bypasses branch protection (review + required checks). It is break-glass only β reflexive
use is how an unverified or broken change can reach main (it defeats the gate the review is supposed to be).
The default is a plain merge, because the rulesets already make it safe:
- Both repos'
mainruleset =required_approving_review_count: 0+ signed commits + no force-push, with code-owner review required only on CODEOWNERS paths (gitops: prod overlays,services/*/helm,apps/,helm-values/,.claude/, security; platform-docs: none). - So a PR touching no CODEOWNERS path merges on a normal
gh pr merge --squashβ no--admin. Most docs/non-gated PRs are exactly this. - A PR touching a CODEOWNERS path still needs the owner's approval. For a solo owner who can't
self-approve, the sanctioned path is a review-bot CODEOWNER that approves after CI (the
--adminelimination follow-up), not reflexive--admin.
Required check (done): an always-on merge-gate status check runs on every PR and blocks
unresolved git conflict markers β the exact failure that reached main via --admin in #1860. It's
required in the branch ruleset, so the plain-merge path can't ship that class of bug. (Scoped to
conflict markers only β zero false positives; template YAML stays with validate-manifests.)
--admin on gated PRs β accepted risk (solo, determined 2026-10-17)β
A second independent human approver does not exist (solo operator), so a CODEOWNERS-gated PR can't get a non-self approval β and we don't fake one (no review-bot, by choice). This is closed as an accepted risk, not a hidden gap (same determination style as the DORA tester-independence call):
- Non-gated PRs (the ~90%, all docs) β plain
gh pr merge --squash;merge-gate+ CI actually gate them.--adminis never used here. - Gated PRs (prod overlays,
services/*/helm,apps/,helm-values/,.claude/, security) β--adminas logged break-glass, only after the owner has confirmedmerge-gate+ CI are green (because--adminalso bypasses those checks β so the control is the owner looking first). - Compensating controls:
merge-gate/CI (machine) + the fresh-context/bmad-code-review(independent perspective) + the owner's pre-merge eyeball. - Revisit trigger: a second engineer joins, or a real-prod / real-PII claim β then add the review-bot or a human reviewer.
Don't double-count the gatesβ
Review (judgement) + CI (L0βL4) + the live QA gate (L5) + CODEOWNERS (enforcement) are distinct evidence β none replaces another.