PR Reviewer
When to activate
- Before merging any PR — conduct a comprehensive review covering correctness, tests, security, performance, and architectural alignment
- A PR requires architectural or security sign-off before merge
- You need to identify logic bugs, edge cases, or design issues that tests may not catch
- Reviewing cross-cutting changes (shared utilities, base classes, middleware) that affect multiple systems
- PR introduces new patterns or significantly refactors existing code
- An author requests a detailed code review with specific focus areas
When NOT to use
- For draft or WIP PRs — wait until the author marks it ready for review
- For automated dependency updates (Dependabot) — those follow a different review path and are typically auto-approved with security scans
- For linting or style enforcement violations — these should be caught by pre-commit hooks and CI, not manual review
- When the PR is too large to review meaningfully in one pass (>500 lines without clear separation) — ask author for breakdown
- For subjective code style preferences that don't affect correctness — defer to team conventions and linters
- When you lack domain knowledge of the system being modified — ask the author for context or escalate rather than guessing
- For reviewing generated code or large auto-migrations without human intent signaling
Instructions
1. Establish Context & Scope
- Read the PR metadata: title, description, linked issues/tickets, and author notes
- Understand the intent: What problem does this solve? What feature does it add? What refactoring does it accomplish?
- Assess scope: Which files changed? How many lines? Are changes concentrated or scattered?
- Categorize the change type:
- New feature (requires 80%+ test coverage)
- Bug fix (requires regression test)
- Refactoring (requires 100% before/after parity, no new coverage needed)
- Performance optimization (requires benchmarks)
- Documentation or chores (minimal testing required)
- Architectural change (requires ADR before review)
- Flag red flags early: Large PRs, unrelated changes bundled, commits with unclear messages, or lack of description
2. Review Commit History
- Atomic commits: Each commit should represent one logical change. If a single feature spans multiple commits, they should build cleanly without breaking intermediate states
- Commit messages: Should explain why, not just what. Example: "Fix N+1 query in user profile endpoint by adding join" is better than "Fix profile query"
- Commit order: Changes should flow logically (dependencies first, then implementation, then tests)
- Red flags:
- Commits that undo previous commits in the same PR (indicates indecision or incomplete testing)
- Merge commits between PR creation and final review (rebase instead)
- Very long commit messages with multiple issues (should be split)
3. Examine Changed Code — Logic & Correctness
- Trace the happy path: Does the code do what it claims? Run through the logic step-by-step
- Test edge cases:
- Boundary conditions (empty collections, null values, zero/negative numbers)
- Off-by-one errors in loops or array access
- State mutations in wrong order
- Resource cleanup (file handles, database connections, event listeners)
- Error handling:
- Are all error paths captured? (no silent failures)
- Do error messages provide enough context for debugging?
- Is error recovery graceful (fallback, retry, rollback)?
- Are exceptions caught at the right level (not too broad)?
- Concurrency & async:
- Race conditions in parallel operations?
- Promise/callback chains properly ordered?
- Are timeouts or deadlocks possible?
- Is shared state protected (locks, immutability)?
- Input validation:
- Are all external inputs (API params, file content, user input) validated?
- Are assumptions about data shape documented and enforced?
- Do type systems (TypeScript, Python type hints) catch invalid inputs?
4. Examine Changed Code — Design & Architecture
- Responsibility separation: Does each function/class do one thing? Or is there hidden coupling?
- Architecture alignment: Does this change follow the existing patterns, or introduce new patterns without justification?
- ADR compliance: If this is an architectural decision, is there an ADR in
docs/adr/ (or PR description)?
- Testability: Is the code testable in isolation, or does it depend on external state/infrastructure in ways that make mocking hard?
- Abstraction levels:
- Is the abstraction right? (Too high = loses detail; too low = duplicates logic)
- Are implementation details hidden behind clean interfaces?
- Code reuse:
- Is there duplication with existing code? Suggest consolidation
- Are utilities placed in appropriate, discoverable locations?
- Complexity:
- Is there nested logic (deep callbacks, multiple conditionals) that could be flattened?
- Are helper functions extracted for clarity?
- Could this be solved more simply?
5. Security Review
Input & Data Handling:
- User input sanitized before use (no injection attacks)?
- SQL: parameterized queries or ORM (not string concatenation)?
- API: input validation on all endpoints?
- File uploads: size limits, type validation, sandboxing?
Authentication & Authorization:
- Are permission checks in place before sensitive operations?
- Does the code check
user.role or similar correctly?
- Are session/token expiries handled?
- Is there token/credential leakage in logs or error messages?
Secrets & Credentials:
- Hardcoded secrets (API keys, passwords, database URLs)?
- Credentials logged or exposed in error messages?
.env files committed (check git history)?
- Environment variables properly injected at runtime?
Dependencies & Supply Chain:
- New dependencies added? Check:
- CVE databases (npm audit, Snyk, pip audit)
- License compatibility (GPL conflicts with proprietary code?)
- Maintenance status (is the maintainer active?)
- Size & footprint (is this dependency pulling in unnecessary sub-dependencies?)
- Breaking changes in updated dependencies handled?
Web-Specific (if applicable):
- CORS headers correctly restricted (not
* in production)?
- CSRF tokens on state-changing operations?
- XSS protection (escaping user content, CSP headers)?
- HTTPS only (no hardcoded
http:// URLs)?
- Sensitive data in local storage or cookies marked
HttpOnly, Secure, SameSite?
6. Testing & Coverage
Coverage Thresholds:
- New code: minimum 80% line coverage (unit + integration)
- Critical paths (auth, payments, data mutations): 95%+
- Refactoring: 100% before/after parity (no new coverage debt)
- Bug fixes: at least one test case that fails without the fix
Test Quality:
- Tests actually exercise the new code, not just pass trivially (check for
assert statements)
- Are happy path, error path, and edge cases tested?
- Are mocks used appropriately (mocking external services, not internal logic)?
- Are fixtures realistic or do they hide issues?
- Is the test code maintainable and readable?
- Are integration tests used for API endpoints, database operations?
CI/CD:
- Do tests pass on CI (not just locally)?
- Are there any flaky tests (intermittent failures)?
- Is coverage report generated and uploaded?
7. Performance
Analysis Triggers:
- Changes to hot paths (request handlers, loops, sorting algorithms)
- New database queries or bulk operations
- Memory-intensive operations (JSON parsing, large data structures)
- Client-side rendering logic (if React, Vue, etc.)
Review Steps:
- Are there obvious inefficiencies (N+1 queries, nested loops, unnecessary copies)?
- Are algorithms efficient (O(n²) sorting on large collections)?
- Are database queries optimized (indexes, joins, pagination)?
- Are there benchmarks in
tests/perf/ showing before/after?
Red Flags:
10% latency regression compared to main branch baseline
- Memory leaks (listener cleanup, event emitter cleanup)
- Unbounded growth (caches without eviction, queues without limits)
8. Architectural Decision Records (ADRs)
When ADR is Required:
- API contract changes (new endpoints, breaking changes)
- Authentication or authorization redesign
- Data model or schema changes
- Integration with new external services
- Switching databases or major libraries (React → Vue, SQL → NoSQL)
- Performance optimizations that trade off simplicity or maintainability
ADR Checklist:
If ADR is Missing:
- Request it before approval (architectural changes cannot merge without ADR)
- Offer to draft a template if the author is unsure
9. Code Quality & Style
Consistency:
- Does code follow the team's existing style (naming, formatting, patterns)?
- Are linting rules (ESLint, Prettier, Black) applied?
- Language idioms used correctly (e.g., Pythonic code, JavaScript conventions)?
Documentation:
- Complex logic explained in comments (the why, not the what)?
- Public APIs documented (function signatures, parameters, return values)?
- Non-obvious behavior documented?
- Examples provided for non-trivial behavior?
- Changelog or migration guide updated (if breaking changes)?
Naming:
- Function/variable names clear and descriptive (avoid single letters except
i in loops)?
- Abbreviations used sparingly (prefer
userCount over uc)?
- Boolean variables named to read naturally (
isActive, not active)?
Structure:
- Functions reasonably sized (max 30 lines is a heuristic)?
- No deeply nested blocks (refactor into helper functions)?
- Related code grouped together?
10. Provide Feedback
Categorize comments:
Blocking (REQUEST_CHANGES):
- Logic bugs that will cause failures
- Security vulnerabilities
- Missing tests for critical paths
- Architectural changes without ADR
- Performance regressions >10%
Important but not blocking (COMMENT):
- Code quality improvements
- Edge cases to handle
- Simpler alternatives to consider
- Missing documentation
Praise (inline or summary):
- Good error handling, thoughtful design, clear code
- Builds trust and morale
Format for Comments:
- Be specific: quote the line or function name, explain the issue
- Suggest a fix when possible (even if you don't write it)
- Use collaborative language: "Consider...", "What about...?" (not "This is wrong")
- For blocking issues: "This needs..." or "Before merge..."
- Keep tone collegial — assume good intent and technical growth
Example Comments:
// BLOCKING
Line 45: `users.map(u => db.query(...))` will create N+1 queries.
Move the query outside the loop or batch with `.batch()`.
// SUGGESTION
The error message on line 78 doesn't include the input that failed.
Consider: throw new Error(`Invalid user ID: ${userId}`);
// PRAISE
Good error handling in the retry loop. The exponential backoff
is well-tuned and won't overwhelm the server.
11. Re-Review After Changes
- If the author makes significant changes, re-review those sections
- Verify that blocking feedback was actually addressed (not just acknowledged)
- Approve only when you're confident in the change
- Request a new review round if changes are substantial (don't just rubber-stamp)
12. Final Decision
Return one of three decisions:
- APPROVE: All checks pass. Ready to merge.
- REQUEST_CHANGES: Blocking issues found. Author must address before merge.
- COMMENT: Suggestions or non-blocking findings. Author can merge after addressing or acknowledging.
Output Format
# PR Review — [PR Title]
## Summary
[1–2 paragraph overview of what changed and assessment]
## Test Coverage
- [ ] Tests added: [description]
- [ ] Coverage target: [X%] (change type: new feature | refactor | bug fix)
- [ ] Coverage met: YES / NO
- **Status:** PASS / FAIL [reason if failed]
## Security Scan
- [ ] New dependencies: [if any, list with versions]
- [ ] Audit results: [npm audit / pip audit output or "clear"]
- [ ] Secrets check: PASS / FAIL [if credentials found, list files]
- **Status:** PASS / FAIL [reason if failed]
## Architecture & ADR
- [ ] Architectural change? YES / NO
- [ ] ADR required? YES / NO
- [ ] ADR present? YES / NO / Not needed
- **Status:** PASS / FAIL [reason if failed]
## Performance
- [ ] Performance-sensitive code changed? YES / NO
- [ ] Benchmarks included? YES / NO / Not applicable
- [ ] Regression vs. baseline: [+X% or "none detected"]
- **Status:** PASS / FAIL [reason if failed]
## Code Quality
- [ ] Logical correctness: PASS / FAIL
- [ ] Error handling complete: PASS / FAIL
- [ ] Backward compatible: PASS / FAIL
- [ ] Readable and documented: PASS / FAIL
- **Status:** PASS / FAIL [reason if failed]
## Line-Level Findings
### Blocking Issues
[Each blocking finding: file:line, code snippet, explanation, suggested fix]
### Suggestions
[Each improvement: file:line, code snippet, explanation, suggested fix]
### Praise
[What was done well]
## Decision
**APPROVE** | **REQUEST_CHANGES** | **COMMENT**
[Summary of reasons and next steps]
Example: Real PR Review
PR: "Add rate limiting middleware to API"
Review Output:
# PR Review — Add rate limiting middleware to API
## Summary
This PR adds a middleware that limits requests per IP to 100/minute,
implementing a security hardening feature for the REST API. Two commits
(middleware logic + tests) are clean and atomic. Implementation is solid,
but missing one production consideration.
## Test Coverage
- Tests added: Happy path (under limit), hitting limit, Redis failure
- Coverage target: 80% (new feature)
- Coverage met: YES (92%)
- **Status:** PASS
## Security Scan
- New dependencies: redis@4.6.0 (already in package.json)
- Audit results: clear (npm audit passed)
- Secrets check: PASS
- **Status:** PASS
## Architecture & ADR
- Architectural change? NO
- ADR required? NO
- **Status:** PASS
## Performance
- Performance-sensitive code changed? YES
- Benchmarks included? NO
- Regression vs. baseline: ~2ms added per request (acceptable)
- **Status:** PASS
## Code Quality
- Logical correctness: PASS
- Error handling complete: PASS (Redis failure handled gracefully)
- Backward compatible: PASS
- Readable and documented: PASS
- **Status:** PASS
## Line-Level Findings
### Blocking Issues
**File: middleware/rate-limit.ts, Line 34**
```javascript
const clientIp = request.ip;
The middleware reads request.ip directly. If deployed behind a load
balancer or CDN (likely), all proxied requests will be counted as coming
from the load balancer's IP. Need to parse X-Forwarded-For header
or use Cloud Run's X-Cloudrun-User-IP header.
Suggested fix:
const clientIp = request.headers['x-forwarded-for']?.split(',')[0]
|| request.headers['x-cloudrun-user-ip']
|| request.ip;
Suggestions
File: middleware/rate-limit.ts, Line 15
Consider adding a config option to disable rate limiting for internal
traffic (e.g., health checks, other services in the cluster). This
prevents your own monitoring from hitting the limit unnecessarily.
Example:
const internalIps = process.env.INTERNAL_IPS?.split(',') || [];
if (internalIps.includes(clientIp)) return next();
Praise
Good error handling in the Redis failure case (lines 50–56). Failing
open is the right call here — a missing rate limiter is better than
blocking all traffic.
Decision
REQUEST_CHANGES
The Redis client IP parsing needs updating to work correctly behind
proxies. After that fix, this is ready to merge. Excellent work on
the security posture.
## Integration with Claude Code
Use this skill via the CLI:
```bash
/code-review --effort high --comment
Flags:
--effort high: Full review covering all aspects (logic, security, tests, performance, architecture)
--comment: Automatically post findings as inline GitHub PR comments
--fix: Apply non-breaking suggestions directly to the working tree (conflicts excluded)
Example Workflow:
# Review and post comments
/code-review --effort high --comment
# Review and optionally apply fixes
/code-review --effort high --fix
# Review-only (no posting)
/code-review --effort high
In Workflows:
If using this skill in an automated workflow (e.g., PR gate), configure as:
- name: Review PR Before Merge
agent: pr-reviewer
on:
event: pull_request.ready_for_review
config:
effort: high
blocks_merge: true
task: |
Conduct a comprehensive review of the PR.
Flag BLOCKING issues (logic bugs, security, missing tests, ADR).
Return APPROVE, REQUEST_CHANGES, or COMMENT decision.
Common Patterns & Checklists
Full-Stack Feature (Frontend + Backend)
Bug Fix
Refactoring
Dependency Update
1---2name: pr-reviewer3description: PR Reviewer4---5# PR Reviewer67## When to activate89- Before merging any PR — conduct a comprehensive review covering correctness, tests, security, performance, and architectural alignment10- A PR requires architectural or security sign-off before merge11- You need to identify logic bugs, edge cases, or design issues that tests may not catch12- Reviewing cross-cutting changes (shared utilities, base classes, middleware) that affect multiple systems13- PR introduces new patterns or significantly refactors existing code14- An author requests a detailed code review with specific focus areas1516## When NOT to use1718- For draft or WIP PRs — wait until the author marks it ready for review19- For automated dependency updates (Dependabot) — those follow a different review path and are typically auto-approved with security scans20- For linting or style enforcement violations — these should be caught by pre-commit hooks and CI, not manual review21- When the PR is too large to review meaningfully in one pass (>500 lines without clear separation) — ask author for breakdown22- For subjective code style preferences that don't affect correctness — defer to team conventions and linters23- When you lack domain knowledge of the system being modified — ask the author for context or escalate rather than guessing24- For reviewing generated code or large auto-migrations without human intent signaling2526## Instructions2728### 1. Establish Context & Scope2930- **Read the PR metadata**: title, description, linked issues/tickets, and author notes31- **Understand the intent**: What problem does this solve? What feature does it add? What refactoring does it accomplish?32- **Assess scope**: Which files changed? How many lines? Are changes concentrated or scattered?33- **Categorize the change type**:34 - New feature (requires 80%+ test coverage)35 - Bug fix (requires regression test)36 - Refactoring (requires 100% before/after parity, no new coverage needed)37 - Performance optimization (requires benchmarks)38 - Documentation or chores (minimal testing required)39 - Architectural change (requires ADR before review)40- **Flag red flags early**: Large PRs, unrelated changes bundled, commits with unclear messages, or lack of description4142### 2. Review Commit History4344- **Atomic commits**: Each commit should represent one logical change. If a single feature spans multiple commits, they should build cleanly without breaking intermediate states45- **Commit messages**: Should explain _why_, not just _what_. Example: "Fix N+1 query in user profile endpoint by adding join" is better than "Fix profile query"46- **Commit order**: Changes should flow logically (dependencies first, then implementation, then tests)47- **Red flags**: 48 - Commits that undo previous commits in the same PR (indicates indecision or incomplete testing)49 - Merge commits between PR creation and final review (rebase instead)50 - Very long commit messages with multiple issues (should be split)5152### 3. Examine Changed Code — Logic & Correctness5354- **Trace the happy path**: Does the code do what it claims? Run through the logic step-by-step55- **Test edge cases**:56 - Boundary conditions (empty collections, null values, zero/negative numbers)57 - Off-by-one errors in loops or array access58 - State mutations in wrong order59 - Resource cleanup (file handles, database connections, event listeners)60- **Error handling**:61 - Are all error paths captured? (no silent failures)62 - Do error messages provide enough context for debugging?63 - Is error recovery graceful (fallback, retry, rollback)?64 - Are exceptions caught at the right level (not too broad)?65- **Concurrency & async**:66 - Race conditions in parallel operations?67 - Promise/callback chains properly ordered?68 - Are timeouts or deadlocks possible?69 - Is shared state protected (locks, immutability)?70- **Input validation**:71 - Are all external inputs (API params, file content, user input) validated?72 - Are assumptions about data shape documented and enforced?73 - Do type systems (TypeScript, Python type hints) catch invalid inputs?7475### 4. Examine Changed Code — Design & Architecture7677- **Responsibility separation**: Does each function/class do one thing? Or is there hidden coupling?78- **Architecture alignment**: Does this change follow the existing patterns, or introduce new patterns without justification?79- **ADR compliance**: If this is an architectural decision, is there an ADR in `docs/adr/` (or PR description)?80- **Testability**: Is the code testable in isolation, or does it depend on external state/infrastructure in ways that make mocking hard?81- **Abstraction levels**: 82 - Is the abstraction right? (Too high = loses detail; too low = duplicates logic)83 - Are implementation details hidden behind clean interfaces?84- **Code reuse**:85 - Is there duplication with existing code? Suggest consolidation86 - Are utilities placed in appropriate, discoverable locations?87- **Complexity**:88 - Is there nested logic (deep callbacks, multiple conditionals) that could be flattened?89 - Are helper functions extracted for clarity?90 - Could this be solved more simply?9192### 5. Security Review9394**Input & Data Handling:**95- User input sanitized before use (no injection attacks)?96- SQL: parameterized queries or ORM (not string concatenation)?97- API: input validation on all endpoints?98- File uploads: size limits, type validation, sandboxing?99100**Authentication & Authorization:**101- Are permission checks in place before sensitive operations?102- Does the code check `user.role` or similar correctly?103- Are session/token expiries handled?104- Is there token/credential leakage in logs or error messages?105106**Secrets & Credentials:**107- Hardcoded secrets (API keys, passwords, database URLs)?108- Credentials logged or exposed in error messages?109- `.env` files committed (check git history)?110- Environment variables properly injected at runtime?111112**Dependencies & Supply Chain:**113- New dependencies added? Check:114 - CVE databases (npm audit, Snyk, pip audit)115 - License compatibility (GPL conflicts with proprietary code?)116 - Maintenance status (is the maintainer active?)117 - Size & footprint (is this dependency pulling in unnecessary sub-dependencies?)118- Breaking changes in updated dependencies handled?119120**Web-Specific (if applicable):**121- CORS headers correctly restricted (not `*` in production)?122- CSRF tokens on state-changing operations?123- XSS protection (escaping user content, CSP headers)?124- HTTPS only (no hardcoded `http://` URLs)?125- Sensitive data in local storage or cookies marked `HttpOnly`, `Secure`, `SameSite`?126127### 6. Testing & Coverage128129**Coverage Thresholds:**130- New code: minimum 80% line coverage (unit + integration)131- Critical paths (auth, payments, data mutations): 95%+132- Refactoring: 100% before/after parity (no new coverage debt)133- Bug fixes: at least one test case that fails without the fix134135**Test Quality:**136- Tests actually exercise the new code, not just pass trivially (check for `assert` statements)137- Are happy path, error path, and edge cases tested?138- Are mocks used appropriately (mocking external services, not internal logic)?139- Are fixtures realistic or do they hide issues?140- Is the test code maintainable and readable?141- Are integration tests used for API endpoints, database operations?142143**CI/CD:**144- Do tests pass on CI (not just locally)?145- Are there any flaky tests (intermittent failures)?146- Is coverage report generated and uploaded?147148### 7. Performance149150**Analysis Triggers:**151- Changes to hot paths (request handlers, loops, sorting algorithms)152- New database queries or bulk operations153- Memory-intensive operations (JSON parsing, large data structures)154- Client-side rendering logic (if React, Vue, etc.)155156**Review Steps:**157- Are there obvious inefficiencies (N+1 queries, nested loops, unnecessary copies)?158- Are algorithms efficient (O(n²) sorting on large collections)?159- Are database queries optimized (indexes, joins, pagination)?160- Are there benchmarks in `tests/perf/` showing before/after?161162**Red Flags:**163- >10% latency regression compared to main branch baseline164- Memory leaks (listener cleanup, event emitter cleanup)165- Unbounded growth (caches without eviction, queues without limits)166167### 8. Architectural Decision Records (ADRs)168169**When ADR is Required:**170- API contract changes (new endpoints, breaking changes)171- Authentication or authorization redesign172- Data model or schema changes173- Integration with new external services174- Switching databases or major libraries (React → Vue, SQL → NoSQL)175- Performance optimizations that trade off simplicity or maintainability176177**ADR Checklist:**178- [ ] ADR file exists in `docs/adr/YYYY-MM-DD-decision-title.md`179- [ ] Status is "Proposed" or "Accepted" (not "Deprecated")180- [ ] Decision and rationale clearly explain the choice181- [ ] Alternatives considered and rejected (with reasoning)182- [ ] Consequences (positive and negative) listed183- [ ] ADR is linked in PR description or committed184185**If ADR is Missing:**186- Request it before approval (architectural changes cannot merge without ADR)187- Offer to draft a template if the author is unsure188189### 9. Code Quality & Style190191**Consistency:**192- Does code follow the team's existing style (naming, formatting, patterns)?193- Are linting rules (ESLint, Prettier, Black) applied?194- Language idioms used correctly (e.g., Pythonic code, JavaScript conventions)?195196**Documentation:**197- Complex logic explained in comments (the _why_, not the _what_)?198- Public APIs documented (function signatures, parameters, return values)?199- Non-obvious behavior documented?200- Examples provided for non-trivial behavior?201- Changelog or migration guide updated (if breaking changes)?202203**Naming:**204- Function/variable names clear and descriptive (avoid single letters except `i` in loops)?205- Abbreviations used sparingly (prefer `userCount` over `uc`)?206- Boolean variables named to read naturally (`isActive`, not `active`)?207208**Structure:**209- Functions reasonably sized (max 30 lines is a heuristic)?210- No deeply nested blocks (refactor into helper functions)?211- Related code grouped together?212213### 10. Provide Feedback214215**Categorize comments:**216217- **Blocking** (REQUEST_CHANGES):218 - Logic bugs that will cause failures219 - Security vulnerabilities220 - Missing tests for critical paths221 - Architectural changes without ADR222 - Performance regressions >10%223224- **Important but not blocking** (COMMENT):225 - Code quality improvements226 - Edge cases to handle227 - Simpler alternatives to consider228 - Missing documentation229230- **Praise** (inline or summary):231 - Good error handling, thoughtful design, clear code232 - Builds trust and morale233234**Format for Comments:**235- Be specific: quote the line or function name, explain the issue236- Suggest a fix when possible (even if you don't write it)237- Use collaborative language: "Consider...", "What about...?" (not "This is wrong")238- For blocking issues: "This needs..." or "Before merge..."239- Keep tone collegial — assume good intent and technical growth240241**Example Comments:**242243```244// BLOCKING245Line 45: `users.map(u => db.query(...))` will create N+1 queries. 246Move the query outside the loop or batch with `.batch()`.247248// SUGGESTION249The error message on line 78 doesn't include the input that failed.250Consider: throw new Error(`Invalid user ID: ${userId}`);251252// PRAISE253Good error handling in the retry loop. The exponential backoff 254is well-tuned and won't overwhelm the server.255```256257### 11. Re-Review After Changes258259- If the author makes significant changes, re-review those sections260- Verify that blocking feedback was actually addressed (not just acknowledged)261- Approve only when you're confident in the change262- Request a new review round if changes are substantial (don't just rubber-stamp)263264### 12. Final Decision265266Return one of three decisions:267268- **APPROVE**: All checks pass. Ready to merge.269- **REQUEST_CHANGES**: Blocking issues found. Author must address before merge.270- **COMMENT**: Suggestions or non-blocking findings. Author can merge after addressing or acknowledging.271272## Output Format273274```markdown275# PR Review — [PR Title]276277## Summary278[1–2 paragraph overview of what changed and assessment]279280## Test Coverage281- [ ] Tests added: [description]282- [ ] Coverage target: [X%] (change type: new feature | refactor | bug fix)283- [ ] Coverage met: YES / NO284- **Status:** PASS / FAIL [reason if failed]285286## Security Scan287- [ ] New dependencies: [if any, list with versions]288- [ ] Audit results: [npm audit / pip audit output or "clear"]289- [ ] Secrets check: PASS / FAIL [if credentials found, list files]290- **Status:** PASS / FAIL [reason if failed]291292## Architecture & ADR293- [ ] Architectural change? YES / NO294- [ ] ADR required? YES / NO295- [ ] ADR present? YES / NO / Not needed296- **Status:** PASS / FAIL [reason if failed]297298## Performance299- [ ] Performance-sensitive code changed? YES / NO300- [ ] Benchmarks included? YES / NO / Not applicable301- [ ] Regression vs. baseline: [+X% or "none detected"]302- **Status:** PASS / FAIL [reason if failed]303304## Code Quality305- [ ] Logical correctness: PASS / FAIL306- [ ] Error handling complete: PASS / FAIL307- [ ] Backward compatible: PASS / FAIL308- [ ] Readable and documented: PASS / FAIL309- **Status:** PASS / FAIL [reason if failed]310311## Line-Level Findings312313### Blocking Issues314[Each blocking finding: file:line, code snippet, explanation, suggested fix]315316### Suggestions317[Each improvement: file:line, code snippet, explanation, suggested fix]318319### Praise320[What was done well]321322## Decision323**APPROVE** | **REQUEST_CHANGES** | **COMMENT**324325[Summary of reasons and next steps]326```327328## Example: Real PR Review329330**PR**: "Add rate limiting middleware to API"331332**Review Output:**333334```markdown335# PR Review — Add rate limiting middleware to API336337## Summary338This PR adds a middleware that limits requests per IP to 100/minute,339implementing a security hardening feature for the REST API. Two commits340(middleware logic + tests) are clean and atomic. Implementation is solid,341but missing one production consideration.342343## Test Coverage344- Tests added: Happy path (under limit), hitting limit, Redis failure345- Coverage target: 80% (new feature)346- Coverage met: YES (92%)347- **Status:** PASS348349## Security Scan350- New dependencies: redis@4.6.0 (already in package.json)351- Audit results: clear (npm audit passed)352- Secrets check: PASS353- **Status:** PASS354355## Architecture & ADR356- Architectural change? NO357- ADR required? NO358- **Status:** PASS359360## Performance361- Performance-sensitive code changed? YES362- Benchmarks included? NO363- Regression vs. baseline: ~2ms added per request (acceptable)364- **Status:** PASS365366## Code Quality367- Logical correctness: PASS368- Error handling complete: PASS (Redis failure handled gracefully)369- Backward compatible: PASS370- Readable and documented: PASS371- **Status:** PASS372373## Line-Level Findings374375### Blocking Issues376**File: middleware/rate-limit.ts, Line 34**377```javascript378const clientIp = request.ip;379```380The middleware reads `request.ip` directly. If deployed behind a load 381balancer or CDN (likely), all proxied requests will be counted as coming 382from the load balancer's IP. Need to parse `X-Forwarded-For` header 383or use Cloud Run's `X-Cloudrun-User-IP` header.384385Suggested fix:386```javascript387const clientIp = request.headers['x-forwarded-for']?.split(',')[0] 388 || request.headers['x-cloudrun-user-ip'] 389 || request.ip;390```391392### Suggestions393**File: middleware/rate-limit.ts, Line 15**394Consider adding a config option to disable rate limiting for internal 395traffic (e.g., health checks, other services in the cluster). This 396prevents your own monitoring from hitting the limit unnecessarily.397398Example:399```javascript400const internalIps = process.env.INTERNAL_IPS?.split(',') || [];401if (internalIps.includes(clientIp)) return next();402```403404### Praise405Good error handling in the Redis failure case (lines 50–56). Failing 406open is the right call here — a missing rate limiter is better than 407blocking all traffic.408409## Decision410**REQUEST_CHANGES**411412The Redis client IP parsing needs updating to work correctly behind 413proxies. After that fix, this is ready to merge. Excellent work on 414the security posture.415```416417## Integration with Claude Code418419Use this skill via the CLI:420421```bash422/code-review --effort high --comment423```424425**Flags:**426- `--effort high`: Full review covering all aspects (logic, security, tests, performance, architecture)427- `--comment`: Automatically post findings as inline GitHub PR comments428- `--fix`: Apply non-breaking suggestions directly to the working tree (conflicts excluded)429430**Example Workflow:**431432```bash433# Review and post comments434/code-review --effort high --comment435436# Review and optionally apply fixes437/code-review --effort high --fix438439# Review-only (no posting)440/code-review --effort high441```442443**In Workflows:**444445If using this skill in an automated workflow (e.g., PR gate), configure as:446447```yaml448- name: Review PR Before Merge449 agent: pr-reviewer450 on:451 event: pull_request.ready_for_review452 config:453 effort: high454 blocks_merge: true455 task: |456 Conduct a comprehensive review of the PR.457 Flag BLOCKING issues (logic bugs, security, missing tests, ADR).458 Return APPROVE, REQUEST_CHANGES, or COMMENT decision.459```460461## Common Patterns & Checklists462463### Full-Stack Feature (Frontend + Backend)464465- [ ] Tests in both frontend and backend (>80% each)466- [ ] API contract documented (OpenAPI or similar)467- [ ] ADR written for data model changes468- [ ] Database migration tested (if applicable)469- [ ] E2E tests added (user journey)470- [ ] Performance profiled (API response time, client-side render)471- [ ] Documentation updated (API docs, user guide)472473### Bug Fix474475- [ ] Root cause identified and explained476- [ ] Regression test added (would fail without the fix)477- [ ] No breaking changes introduced478- [ ] Edge cases considered479480### Refactoring481482- [ ] All original tests passing (100% before/after parity)483- [ ] No new features mixed in484- [ ] Behavior unchanged (black-box tests validate)485- [ ] Performance not degraded486- [ ] Code is simpler or more maintainable (justify refactor goal)487488### Dependency Update489490- [ ] Breaking changes handled (migration guide if needed)491- [ ] All tests passing492- [ ] Performance regression checked493- [ ] Changelog or release notes updated