Review Changes
Review code changes in a feature branch and identify issues before merging.
Workflow
1. Determine Review Target
Remote PR: If user provides PR number or URL (e.g., "review PR #123", "review https://github.com/org/repo/pull/123"):
- Checkout the PR:
gh pr checkout <PR_NUMBER>
- Read PR context:
gh pr view <PR_NUMBER> --json title,body,comments
- Use the PR description and comments as additional context for the review
Local Changes: If no PR specified, review current branch against default branch (continue to step 2)
1.5 Load Repository Guidelines
Search for repository-specific coding guidelines. These take precedence over built-in guidelines.
Discovery order (highest to lowest priority):
CLAUDE.md, .claude/CLAUDE.md
CODE_GUIDELINES.md, .github/CODE_GUIDELINES.md, docs/CODE_GUIDELINES.md
STYLE_GUIDE.md, .github/STYLE_GUIDE.md, docs/STYLE_GUIDE.md
CONTRIBUTING.md, .github/CONTRIBUTING.md, docs/CONTRIBUTING.md
Extract review-relevant content (coding standards, error handling, testing, security, naming conventions). Skip non-review content (issue templates, code of conduct). User guidelines take precedence over built-in guidelines and are additive. When reviewing a remote PR, load guidelines from the remote repository.
2. Detect Branches
# Get current branch
git branch --show-current
# Detect default branch (try remote HEAD, fall back to main)
git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@' || echo "main"
3. Get Changed Files
# Assess scope first
git diff --stat <default-branch>...HEAD
# Get full diff
git diff <default-branch>...HEAD
Performance guardrails:
- Skip lock files,
.min.js, .min.css, generated files, compiled output
- If >30 changed files, prioritize source over tests/config; summarize skipped files
- If a single file has >500 lines changed, summarize rather than line-by-line review
- If total diff >3000 lines, select the ~20 most important files and summarize the rest
4. Analyze Changes
Use the diff as the primary input. Apply guidelines holistically across the diff rather than file-by-file. Only read full files when surrounding context is needed to understand a change.
Review process:
- Identify applicable guidelines: repository-specific (from step 1.5), general (below), and language-specific (from reference files)
- Check for critical issues first — report before scanning for minor ones
- For each issue found, record: guideline violated, file and line number, problem description, fix suggestion
- Skip inapplicable guidelines (no database operations → skip Database & Persistence)
5. Check Test Coverage
For each new or modified file containing business logic:
- Check if corresponding test file exists
- If tests exist, verify new code paths have coverage
- Flag missing tests for critical paths
6. Format Output
Present findings grouped by severity, ordered Critical → Major → Minor.
## Branch Review: `feature/xyz` → `main`
**Repository guidelines loaded:**
- `.github/CONTRIBUTING.md` - coding standards, testing requirements
*(These take precedence over built-in rules where they conflict)*
### 🔴 Critical (X issues)
**1. [Brief title]**
- **File**: `path/to/file.ts:42`
- **Problem**: Clear description of what's wrong
- **Fix**: Specific solution
### 🟠 Major (X issues)
**1. [Brief title]** `[repo]`
- **File**: `path/to/file.ts:87`
- **Problem**: Description
- **Fix**: Solution
### 🟡 Minor (X issues)
**1. [Brief title]**
- **File**: `path/to/file.ts:123`
- **Problem**: Description
- **Fix**: Solution
---
**Summary**: X critical, Y major, Z minor issues found.
[Ready to merge / Needs fixes before merge]
If no issues found in a category, omit that section. End with clear merge recommendation. Issues marked [repo] were flagged based on repository-specific guidelines. If no repository guidelines were loaded, omit the "Repository guidelines loaded" section.
Feedback tone: Be constructive — explain why a change is needed. Provide actionable suggestions. Assume positive intent. For approvals, acknowledge the specific value of the contribution.
General Guidelines
These apply to every review regardless of language.
API & Breaking Changes
- Removed or renamed public functions/methods without deprecation period
- Changed function signatures (new required parameters, changed return types)
- Modified response shapes in API endpoints (removed fields, changed types)
- Changed default values that alter existing behavior
- Database schema changes without migration scripts
Authentication & Authorization (Critical)
- Missing auth checks on new endpoints or routes
- Downgraded permissions (admin-only → public)
- Hardcoded credentials or API keys
- JWT/session issues: missing expiry, weak secrets, improper validation
- CORS misconfigurations: overly permissive origins (
* in production)
Database & Persistence
- Missing transactions for multi-step atomic operations
- N+1 query patterns: fetching related data in loops instead of joins/eager loading
- Missing indexes on frequently queried columns
- Unbounded queries:
SELECT * without LIMIT on large tables
- SQL injection: string concatenation in queries instead of parameterized queries
Concurrency (Critical for data corruption)
- Shared mutable state accessed without synchronization
- Missing locks/mutexes when modifying shared resources
- Check-then-act patterns without atomicity (TOCTOU)
- Deadlock potential: acquiring multiple locks in inconsistent order
Async Code
- After any
await, verify assumptions are still valid — state may have changed
- Flag when code returns success without verifying the expected outcome of an async operation
External API Handling
- Missing timeouts on HTTP requests
- No retry logic for transient failures
- Missing circuit breakers for repeatedly failing services
- Not distinguishing between 4xx and 5xx errors
- Missing rate limiting awareness (no backoff on 429)
Edge Cases & Boundaries
- Code assumes arrays/lists are non-empty
- Missing null/undefined checks on optional values
- Off-by-one errors in loops, incorrect range checks
- Type coercion issues leading to unexpected behavior
- Unicode/encoding issues: assuming ASCII, incorrect string length
Defensive Coding
- Using external input (APIs/users) without validation
- Not handling failure cases for operations that can fail
- Array access without verifying index is valid
- Code relying on undocumented behavior or ordering
Input Sanitization (Critical)
- Command injection: unsanitized input in shell commands — use argument arrays, not string interpolation
- Path traversal: user input in file paths escaping intended directories — resolve and validate paths
- XSS: user input rendered as HTML — escape or use safe APIs, validate URL protocols
- Log injection: unsanitized input forging log entries — use structured logging
- SQL injection: string concatenation in queries — use parameterized queries
Memory & Performance
- Unbounded collections (arrays/maps growing without limits)
- Memory leaks: event listeners not removed, closures holding references
- Large allocations in loops that could be reused
- Blocking synchronous I/O or CPU-heavy work on main thread
- Missing pagination: loading entire datasets
File System Operations
- Reading files without verifying they exist
- Writing files without ensuring parent directory exists
- Missing error handling on file operations
Logging & Observability
- Insufficient logging for important operations
- Excessive logging creating noise or performance issues
- Missing correlation IDs for cross-service tracing
- Critical: Logging sensitive data (PII, passwords, tokens)
- New features without observability hooks
Testing Quality
- Tests that don't assert anything meaningful
- Missing edge case coverage (only happy path)
- Flaky tests: race conditions, time dependencies, external dependencies
- Test pollution: shared state, missing cleanup
- Mocking too much: tests don't exercise real code paths
Accessibility
- Missing alt text on images
- Non-semantic HTML (divs for buttons, missing form labels)
- Interactive elements not reachable via keyboard
- Missing ARIA labels on icon-only buttons
- Color-only indicators
Code Style
- Prefer early returns over nested if statements — flat code is easier to read
Error Messages
- Error messages must be actionable, contextual, and specific
- Include identifiers (order IDs, user IDs) for debugging
- Don't expose stack traces or internal details to end users
- Include error codes for programmatic handling
Language-Specific Guidelines
Based on file extensions in the diff, load the relevant reference:
.ts, .js, .mjs, .cjs → Read references/typescript.md
.tsx, .jsx → Read references/react.md (also load typescript.md)
.py → Read references/python.md
.go → Read references/go.md
.rs → Read references/rust.md
.java, .kt → Read references/java-kotlin.md
Only load references for languages present in the changed files.
Severity Definitions
- Critical — Block the merge. Broken code, security vulnerabilities, data leaks, runtime failures that will crash production.
- Major — Should fix. Unhandled async, missing error handling, resource leaks, race conditions, missing validation.
- Minor — Nice to fix. Code clarity, consistency, performance, dead code, duplication, unresolved TODOs.
1---2name: review-changes3description: Review code changes in a feature branch before merging. Use when asked to review a branch, review changes, check a PR, or audit code before merge. Compares the current branch against the default branch (main/master) and categorizes issues by severity (Critical, Major, Minor) with actionable solutions.4license: MIT5---67# Review Changes89Review code changes in a feature branch and identify issues before merging.1011## Workflow1213### 1. Determine Review Target1415- **Remote PR**: If user provides PR number or URL (e.g., "review PR #123", "review https://github.com/org/repo/pull/123"):16 1. Checkout the PR: `gh pr checkout <PR_NUMBER>`17 2. Read PR context: `gh pr view <PR_NUMBER> --json title,body,comments`18 3. Use the PR description and comments as additional context for the review1920- **Local Changes**: If no PR specified, review current branch against default branch (continue to step 2)2122### 1.5 Load Repository Guidelines2324Search for repository-specific coding guidelines. These take precedence over built-in guidelines.2526**Discovery order** (highest to lowest priority):271. `CLAUDE.md`, `.claude/CLAUDE.md`282. `CODE_GUIDELINES.md`, `.github/CODE_GUIDELINES.md`, `docs/CODE_GUIDELINES.md`293. `STYLE_GUIDE.md`, `.github/STYLE_GUIDE.md`, `docs/STYLE_GUIDE.md`304. `CONTRIBUTING.md`, `.github/CONTRIBUTING.md`, `docs/CONTRIBUTING.md`3132Extract review-relevant content (coding standards, error handling, testing, security, naming conventions). Skip non-review content (issue templates, code of conduct). User guidelines take precedence over built-in guidelines and are additive. When reviewing a remote PR, load guidelines from the remote repository.3334### 2. Detect Branches3536```bash37# Get current branch38git branch --show-current3940# Detect default branch (try remote HEAD, fall back to main)41git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@' || echo "main"42```4344### 3. Get Changed Files4546```bash47# Assess scope first48git diff --stat <default-branch>...HEAD4950# Get full diff51git diff <default-branch>...HEAD52```5354**Performance guardrails:**551. Skip lock files, `.min.js`, `.min.css`, generated files, compiled output562. If >30 changed files, prioritize source over tests/config; summarize skipped files573. If a single file has >500 lines changed, summarize rather than line-by-line review584. If total diff >3000 lines, select the ~20 most important files and summarize the rest5960### 4. Analyze Changes6162Use the diff as the primary input. Apply guidelines holistically across the diff rather than file-by-file. Only read full files when surrounding context is needed to understand a change.6364**Review process:**651. Identify applicable guidelines: repository-specific (from step 1.5), general (below), and language-specific (from reference files)662. Check for critical issues first — report before scanning for minor ones673. For each issue found, record: guideline violated, file and line number, problem description, fix suggestion684. Skip inapplicable guidelines (no database operations → skip Database & Persistence)6970### 5. Check Test Coverage7172For each new or modified file containing business logic:73- Check if corresponding test file exists74- If tests exist, verify new code paths have coverage75- Flag missing tests for critical paths7677### 6. Format Output7879Present findings grouped by severity, ordered Critical → Major → Minor.8081```82## Branch Review: `feature/xyz` → `main`8384**Repository guidelines loaded:**85- `.github/CONTRIBUTING.md` - coding standards, testing requirements8687*(These take precedence over built-in rules where they conflict)*8889### 🔴 Critical (X issues)9091**1. [Brief title]**92- **File**: `path/to/file.ts:42`93- **Problem**: Clear description of what's wrong94- **Fix**: Specific solution9596### 🟠 Major (X issues)9798**1. [Brief title]** `[repo]`99- **File**: `path/to/file.ts:87`100- **Problem**: Description101- **Fix**: Solution102103### 🟡 Minor (X issues)104105**1. [Brief title]**106- **File**: `path/to/file.ts:123`107- **Problem**: Description108- **Fix**: Solution109110---111**Summary**: X critical, Y major, Z minor issues found.112[Ready to merge / Needs fixes before merge]113```114115If no issues found in a category, omit that section. End with clear merge recommendation. Issues marked `[repo]` were flagged based on repository-specific guidelines. If no repository guidelines were loaded, omit the "Repository guidelines loaded" section.116117**Feedback tone:** Be constructive — explain *why* a change is needed. Provide actionable suggestions. Assume positive intent. For approvals, acknowledge the specific value of the contribution.118119---120121## General Guidelines122123These apply to every review regardless of language.124125#### API & Breaking Changes126127- Removed or renamed public functions/methods without deprecation period128- Changed function signatures (new required parameters, changed return types)129- Modified response shapes in API endpoints (removed fields, changed types)130- Changed default values that alter existing behavior131- Database schema changes without migration scripts132133#### Authentication & Authorization (Critical)134135- Missing auth checks on new endpoints or routes136- Downgraded permissions (admin-only → public)137- Hardcoded credentials or API keys138- JWT/session issues: missing expiry, weak secrets, improper validation139- CORS misconfigurations: overly permissive origins (`*` in production)140141#### Database & Persistence142143- Missing transactions for multi-step atomic operations144- N+1 query patterns: fetching related data in loops instead of joins/eager loading145- Missing indexes on frequently queried columns146- Unbounded queries: `SELECT *` without `LIMIT` on large tables147- SQL injection: string concatenation in queries instead of parameterized queries148149#### Concurrency (Critical for data corruption)150151- Shared mutable state accessed without synchronization152- Missing locks/mutexes when modifying shared resources153- Check-then-act patterns without atomicity (TOCTOU)154- Deadlock potential: acquiring multiple locks in inconsistent order155156#### Async Code157158- After any `await`, verify assumptions are still valid — state may have changed159- Flag when code returns success without verifying the expected outcome of an async operation160161#### External API Handling162163- Missing timeouts on HTTP requests164- No retry logic for transient failures165- Missing circuit breakers for repeatedly failing services166- Not distinguishing between 4xx and 5xx errors167- Missing rate limiting awareness (no backoff on 429)168169#### Edge Cases & Boundaries170171- Code assumes arrays/lists are non-empty172- Missing null/undefined checks on optional values173- Off-by-one errors in loops, incorrect range checks174- Type coercion issues leading to unexpected behavior175- Unicode/encoding issues: assuming ASCII, incorrect string length176177#### Defensive Coding178179- Using external input (APIs/users) without validation180- Not handling failure cases for operations that can fail181- Array access without verifying index is valid182- Code relying on undocumented behavior or ordering183184#### Input Sanitization (Critical)185186- **Command injection**: unsanitized input in shell commands — use argument arrays, not string interpolation187- **Path traversal**: user input in file paths escaping intended directories — resolve and validate paths188- **XSS**: user input rendered as HTML — escape or use safe APIs, validate URL protocols189- **Log injection**: unsanitized input forging log entries — use structured logging190- **SQL injection**: string concatenation in queries — use parameterized queries191192#### Memory & Performance193194- Unbounded collections (arrays/maps growing without limits)195- Memory leaks: event listeners not removed, closures holding references196- Large allocations in loops that could be reused197- Blocking synchronous I/O or CPU-heavy work on main thread198- Missing pagination: loading entire datasets199200#### File System Operations201202- Reading files without verifying they exist203- Writing files without ensuring parent directory exists204- Missing error handling on file operations205206#### Logging & Observability207208- Insufficient logging for important operations209- Excessive logging creating noise or performance issues210- Missing correlation IDs for cross-service tracing211- **Critical**: Logging sensitive data (PII, passwords, tokens)212- New features without observability hooks213214#### Testing Quality215216- Tests that don't assert anything meaningful217- Missing edge case coverage (only happy path)218- Flaky tests: race conditions, time dependencies, external dependencies219- Test pollution: shared state, missing cleanup220- Mocking too much: tests don't exercise real code paths221222#### Accessibility223224- Missing alt text on images225- Non-semantic HTML (divs for buttons, missing form labels)226- Interactive elements not reachable via keyboard227- Missing ARIA labels on icon-only buttons228- Color-only indicators229230#### Code Style231232- Prefer early returns over nested if statements — flat code is easier to read233234#### Error Messages235236- Error messages must be actionable, contextual, and specific237- Include identifiers (order IDs, user IDs) for debugging238- Don't expose stack traces or internal details to end users239- Include error codes for programmatic handling240241---242243## Language-Specific Guidelines244245Based on file extensions in the diff, load the relevant reference:246247- `.ts`, `.js`, `.mjs`, `.cjs` → Read [references/typescript.md](references/typescript.md)248- `.tsx`, `.jsx` → Read [references/react.md](references/react.md) (also load typescript.md)249- `.py` → Read [references/python.md](references/python.md)250- `.go` → Read [references/go.md](references/go.md)251- `.rs` → Read [references/rust.md](references/rust.md)252- `.java`, `.kt` → Read [references/java-kotlin.md](references/java-kotlin.md)253254Only load references for languages present in the changed files.255256---257258## Severity Definitions259260- **Critical** — Block the merge. Broken code, security vulnerabilities, data leaks, runtime failures that will crash production.261- **Major** — Should fix. Unhandled async, missing error handling, resource leaks, race conditions, missing validation.262- **Minor** — Nice to fix. Code clarity, consistency, performance, dead code, duplication, unresolved TODOs.