ai-code-review
Perform a rigorous code review that enforces quality standards. Challenge assumptions, verify correctness, and ensure the code is simple, tested, and maintainable.
When to use
Use this skill when:
- Asked to review a pull request, diff, or set of changes
- Asked to review specific files or a feature implementation
- Performing a self-review before presenting code to the user
- Validating code quality as part of the execute phase
Instructions
Step 1: Run automated checks
Before any manual review, verify that automated quality gates pass.
- Linting. Run the project's configured linter (e.g.,
eslint, phpcs, phpstan, prettier --check, stylelint). Report every violation. Do not proceed until lint errors are addressed or explicitly acknowledged.
- Type checking. If the project uses static types (TypeScript, PHPStan, mypy), run the type checker. Zero type errors allowed.
- Unit tests. Run the test suite. All existing tests must pass. If new code lacks tests, flag it as a blocking issue (see Step 4).
- Build. If applicable, verify the project compiles/builds without errors or warnings.
If any automated check fails, stop the review and report the failures. Do not continue to manual review until the code is green.
Step 2: Review for complexity
Evaluate whether the code is as simple as it can be while still meeting requirements.
- Cyclomatic complexity. Flag any function or method with more than 10 branches. Suggest extraction or simplification.
- Function length. Flag functions longer than 40 lines. Each function should do one thing.
- Nesting depth. Flag nesting deeper than 3 levels. Suggest early returns, guard clauses, or extraction.
- Parameter count. Flag functions with more than 4 parameters. Suggest using an options object, builder, or splitting responsibilities.
- Cognitive load. Read the code as if seeing it for the first time. If you need to re-read a block to understand it, it is too complex. Suggest renaming, restructuring, or adding a clarifying comment only as a last resort.
- Duplication. Identify repeated logic (3+ occurrences or 5+ duplicated lines). Suggest extraction into a shared function, method, or module.
Step 3: Review for correctness
Verify the code does what it claims to do.
- Edge cases. Identify inputs or states the code does not handle: nulls, empty collections, boundary values, concurrent access, error paths.
- Error handling. Verify errors are caught, logged, and either recovered from or propagated meaningfully. No swallowed exceptions. No generic catch-all without re-throw.
- Side effects. Identify unexpected mutations, global state changes, or I/O hidden inside pure-looking functions.
- Security. Check for injection vulnerabilities (SQL, XSS, command), unsanitised user input, leaked secrets, and missing authorisation checks.
- Performance. Flag obvious inefficiencies: N+1 queries, unnecessary allocations in loops, missing pagination, unbounded collections in memory.
Step 4: Review for test coverage
Assess whether the code is adequately tested.
- New behaviour must have tests. Every new public function, method, endpoint, or behaviour path requires at least one test. Flag any that are missing.
- Test quality. Tests must assert meaningful outcomes, not just that code runs without crashing. Flag tests with no assertions or only trivial assertions.
- Edge case coverage. At minimum, tests should cover: happy path, one error/failure path, and one boundary condition.
- Test isolation. Tests must not depend on execution order, shared mutable state, or external services without mocking/faking.
- Naming. Test names must describe the scenario and expected outcome (e.g.,
should return 404 when order does not exist).
Step 5: Review for design and conventions
Verify the code fits the codebase and follows established patterns.
- Consistency. Does the code follow the naming conventions, file structure, and patterns already present in the project? Flag deviations.
- Separation of concerns. Is business logic mixed with infrastructure, presentation, or orchestration code? Flag violations.
- API design. Are public interfaces (function signatures, class APIs, HTTP endpoints) clear, minimal, and hard to misuse?
- Dependency direction. Do dependencies point in the correct direction per the project's architecture (e.g., hexagonal, layered)?
- SOLID principles. Flag classes or modules that violate single responsibility, have broken abstractions, or use inheritance where composition is cleaner.
Step 6: Challenge the engineer
Do not just find issues — actively challenge the design and approach.
- Ask "why". For any non-obvious design decision, ask the author to justify it. Examples:
- "Why is this a separate service instead of a method on the existing aggregate?"
- "Why was inheritance chosen over composition here?"
- "What happens if this external call fails?"
- Propose alternatives. When you identify a concern, do not just flag it — suggest a concrete alternative with reasoning.
- Question necessity. For every added dependency, abstraction, or layer: "Is this needed now, or is it speculative?" If speculative, recommend removal.
- Simulate failure. Pick a critical path and mentally (or actually) trace what happens when it fails. Report any unhandled failure mode.
- Demand justification for complexity. If something is complex, the author must prove that a simpler approach does not work. Complexity is not accepted by default.
Step 7: Produce the review summary
Output a structured review with clear severity levels.
## Review Summary
### Blocking (must fix before merge)
- [ ] Issue description — file:line — suggested fix
### Should fix (strongly recommended)
- [ ] Issue description — file:line — suggested fix
### Nitpick (optional improvements)
- [ ] Issue description — file:line — suggested fix
### Questions (need clarification)
- [ ] Question — file:line
### Positive observations
- What was done well
Severity rules:
- Blocking: failing tests, lint errors, type errors, missing tests for new code, security issues, broken functionality, data loss risk.
- Should fix: complexity violations, poor naming, missing error handling, design concerns, performance issues.
- Nitpick: style preferences beyond linter scope, minor readability improvements, documentation suggestions.
Step 8: Verify resolution
If the engineer addresses your feedback:
- Re-run automated checks (Step 1).
- Verify each blocking issue is resolved.
- Confirm "should fix" items are addressed or explicitly deferred with a reason.
- Approve only when all blocking items are resolved and no new issues are introduced.
Review principles
- Be strict, not hostile. The goal is quality, not gatekeeping. Every piece of feedback must be actionable and justified.
- No rubber-stamping. Never approve without thorough review. "Looks good" is not a valid review.
- Assume bugs exist. Review with the mindset that something is wrong — your job is to find it.
- Simpler is better. When in doubt, argue for the simpler solution.
- Code is read more than written. Optimise for the next person reading it, not the person writing it now.
1---2name: ai-code-review3description: Defines a strict code review process where the agent validates quality through linting, tests, complexity analysis, and critical challenge of design decisions.4---56# ai-code-review78Perform a rigorous code review that enforces quality standards. Challenge assumptions, verify correctness, and ensure the code is simple, tested, and maintainable.910## When to use1112Use this skill when:1314- Asked to review a pull request, diff, or set of changes15- Asked to review specific files or a feature implementation16- Performing a self-review before presenting code to the user17- Validating code quality as part of the execute phase1819## Instructions2021### Step 1: Run automated checks2223Before any manual review, verify that automated quality gates pass.24251. **Linting.** Run the project's configured linter (e.g., `eslint`, `phpcs`, `phpstan`, `prettier --check`, `stylelint`). Report every violation. Do not proceed until lint errors are addressed or explicitly acknowledged.262. **Type checking.** If the project uses static types (TypeScript, PHPStan, mypy), run the type checker. Zero type errors allowed.273. **Unit tests.** Run the test suite. All existing tests must pass. If new code lacks tests, flag it as a blocking issue (see Step 4).284. **Build.** If applicable, verify the project compiles/builds without errors or warnings.2930If any automated check fails, stop the review and report the failures. Do not continue to manual review until the code is green.3132### Step 2: Review for complexity3334Evaluate whether the code is as simple as it can be while still meeting requirements.35361. **Cyclomatic complexity.** Flag any function or method with more than 10 branches. Suggest extraction or simplification.372. **Function length.** Flag functions longer than 40 lines. Each function should do one thing.383. **Nesting depth.** Flag nesting deeper than 3 levels. Suggest early returns, guard clauses, or extraction.394. **Parameter count.** Flag functions with more than 4 parameters. Suggest using an options object, builder, or splitting responsibilities.405. **Cognitive load.** Read the code as if seeing it for the first time. If you need to re-read a block to understand it, it is too complex. Suggest renaming, restructuring, or adding a clarifying comment only as a last resort.416. **Duplication.** Identify repeated logic (3+ occurrences or 5+ duplicated lines). Suggest extraction into a shared function, method, or module.4243### Step 3: Review for correctness4445Verify the code does what it claims to do.46471. **Edge cases.** Identify inputs or states the code does not handle: nulls, empty collections, boundary values, concurrent access, error paths.482. **Error handling.** Verify errors are caught, logged, and either recovered from or propagated meaningfully. No swallowed exceptions. No generic catch-all without re-throw.493. **Side effects.** Identify unexpected mutations, global state changes, or I/O hidden inside pure-looking functions.504. **Security.** Check for injection vulnerabilities (SQL, XSS, command), unsanitised user input, leaked secrets, and missing authorisation checks.515. **Performance.** Flag obvious inefficiencies: N+1 queries, unnecessary allocations in loops, missing pagination, unbounded collections in memory.5253### Step 4: Review for test coverage5455Assess whether the code is adequately tested.56571. **New behaviour must have tests.** Every new public function, method, endpoint, or behaviour path requires at least one test. Flag any that are missing.582. **Test quality.** Tests must assert meaningful outcomes, not just that code runs without crashing. Flag tests with no assertions or only trivial assertions.593. **Edge case coverage.** At minimum, tests should cover: happy path, one error/failure path, and one boundary condition.604. **Test isolation.** Tests must not depend on execution order, shared mutable state, or external services without mocking/faking.615. **Naming.** Test names must describe the scenario and expected outcome (e.g., `should return 404 when order does not exist`).6263### Step 5: Review for design and conventions6465Verify the code fits the codebase and follows established patterns.66671. **Consistency.** Does the code follow the naming conventions, file structure, and patterns already present in the project? Flag deviations.682. **Separation of concerns.** Is business logic mixed with infrastructure, presentation, or orchestration code? Flag violations.693. **API design.** Are public interfaces (function signatures, class APIs, HTTP endpoints) clear, minimal, and hard to misuse?704. **Dependency direction.** Do dependencies point in the correct direction per the project's architecture (e.g., hexagonal, layered)?715. **SOLID principles.** Flag classes or modules that violate single responsibility, have broken abstractions, or use inheritance where composition is cleaner.7273### Step 6: Challenge the engineer7475Do not just find issues — actively challenge the design and approach.76771. **Ask "why".** For any non-obvious design decision, ask the author to justify it. Examples:78 - "Why is this a separate service instead of a method on the existing aggregate?"79 - "Why was inheritance chosen over composition here?"80 - "What happens if this external call fails?"812. **Propose alternatives.** When you identify a concern, do not just flag it — suggest a concrete alternative with reasoning.823. **Question necessity.** For every added dependency, abstraction, or layer: "Is this needed now, or is it speculative?" If speculative, recommend removal.834. **Simulate failure.** Pick a critical path and mentally (or actually) trace what happens when it fails. Report any unhandled failure mode.845. **Demand justification for complexity.** If something is complex, the author must prove that a simpler approach does not work. Complexity is not accepted by default.8586### Step 7: Produce the review summary8788Output a structured review with clear severity levels.8990```markdown91## Review Summary9293### Blocking (must fix before merge)94- [ ] Issue description — file:line — suggested fix9596### Should fix (strongly recommended)97- [ ] Issue description — file:line — suggested fix9899### Nitpick (optional improvements)100- [ ] Issue description — file:line — suggested fix101102### Questions (need clarification)103- [ ] Question — file:line104105### Positive observations106- What was done well107```108109**Severity rules:**110111- **Blocking:** failing tests, lint errors, type errors, missing tests for new code, security issues, broken functionality, data loss risk.112- **Should fix:** complexity violations, poor naming, missing error handling, design concerns, performance issues.113- **Nitpick:** style preferences beyond linter scope, minor readability improvements, documentation suggestions.114115### Step 8: Verify resolution116117If the engineer addresses your feedback:1181191. Re-run automated checks (Step 1).1202. Verify each blocking issue is resolved.1213. Confirm "should fix" items are addressed or explicitly deferred with a reason.1224. Approve only when all blocking items are resolved and no new issues are introduced.123124## Review principles125126- **Be strict, not hostile.** The goal is quality, not gatekeeping. Every piece of feedback must be actionable and justified.127- **No rubber-stamping.** Never approve without thorough review. "Looks good" is not a valid review.128- **Assume bugs exist.** Review with the mindset that something is wrong — your job is to find it.129- **Simpler is better.** When in doubt, argue for the simpler solution.130- **Code is read more than written.** Optimise for the next person reading it, not the person writing it now.