| name | code-review |
| description | Quality and semantic review — catches what automated tools miss |
| version | 0.1.0 |
| level | 3 |
| triggers | ["review this","code review","review the code","pre-merge review","/code-review"] |
| context_files | ["context/security-standards.md"] |
| steps | [{"name":"Scope","description":"List files under review. State what this review covers and what it does not."},{"name":"Semantic Review","description":"Check for semantic anti-patterns — code that is syntactically correct but logically wrong"},{"name":"Logic Review","description":"Trace the critical paths. Does the code actually do what it claims to do?"},{"name":"Error Handling","description":"What happens on every failure path? Are errors silenced, swallowed, or lost?"},{"name":"Test Coverage","description":"Do the tests actually exercise the behavior, or do they just cover lines?"},{"name":"Readability","description":"Will the next developer understand this code without asking the author?"},{"name":"Security Pass","description":"Flag anything that warrants a full security-gate run (do not duplicate security-gate)"},{"name":"Verdict","description":"APPROVE / REQUEST CHANGES / BLOCK — with specific, actionable feedback. Then write the current ISO timestamp to `.claude/context/.review-done` (signals stop-review-gate that review completed)."}] |
Code Review Skill
Quality and semantic review. Separate from security-gate (which is an OWASP pass) — this reviews logic, correctness, and maintainability.
What Claude Gets Wrong Without This Skill
Without explicit semantic review, Claude's code review focuses on what it can see at a glance — naming, formatting, obvious bugs. It misses logical errors that are invisible unless you trace execution, tests that assert the wrong thing, and anti-patterns that only become problems under load or edge cases.
Semantic Anti-Patterns to Actively Check
These are the patterns that pass linting, pass type checking, and still cause production incidents:
Silent failure
try:
result = process(data)
except Exception:
pass
Boolean parameter flags
render_page(user, True)
render_page(user, include_draft=True)
Mutable default arguments
def append_item(item, items=[]):
items.append(item)
return items
def append_item(item, items=None):
if items is None:
items = []
Late error detection
Code that validates input halfway through execution after already modifying state. Validate first, act second.
Asymmetric error handling
Some code paths return None on failure, others raise exceptions, others return False. Callers must handle all three.
Test that tests the mock
mock_service.process.return_value = {"status": "ok"}
result = handler.run()
assert result == {"status": "ok"}
Implicit ordering dependency
Code that works only if methods are called in a specific order, with no enforcement of that order.
Callback hell / pyramid of doom
Deeply nested conditionals or callbacks that make control flow impossible to follow.
Logic Tracing Protocol
For critical paths (auth, payment, data writes), trace the execution manually:
- Identify entry point
- Follow the happy path — does it reach the expected outcome?
- Follow the primary failure path — is the error handled correctly?
- Follow the edge case path — what happens with empty input, null, zero, max value?
Verdict Format
APPROVE: Ready to merge. State any minor observations that do not require changes.
REQUEST CHANGES:
Issue: [description]
Location: [file:line]
Category: [semantic / logic / error-handling / test / readability]
Fix: [specific recommendation]
Blocking: No
BLOCK:
Issue: [description]
Location: [file:line]
Category: [category]
Impact: [what breaks or could break]
Fix: [specific recommendation]
Blocking: YES
Adversarial Mode (/code-review --adversarial)
Standard mode asks: "What is wrong with this code?"
Adversarial mode asks: "Why is this the wrong approach entirely?"
Use adversarial mode when you want the implementation challenged, not just inspected. The output argues against the code. The user decides whether the argument holds.
Trigger: user invokes with --adversarial flag or asks for adversarial review.
Questions to answer:
- Wrong abstraction? Is the chosen abstraction level correct, or does it leak internals / hide too much?
- Tests testing the right thing? Are tests asserting behavior or implementation details? Would a rewrite break the tests even if behavior is preserved?
- Over-engineered? Is this solving a problem that doesn't exist yet? What is the simplest version that satisfies the actual requirement?
- Hidden assumption? What assumption does this code make that, if wrong, causes it to fail entirely?
- Complete rewrite trigger? What real-world scenario would force a complete rewrite of this approach?
- Early-termination risk? Is there a reasoning gap in this code that would cause an agent or process to exit early before the task is complete? (e.g., missing error branches that return prematurely, incomplete state machines, loops that exit on the wrong condition)
Scoring rubric (after answering all questions):
| Dimension | Score (1-5) | Notes |
|---|
| Correctness | | Does the implementation match the stated requirement? |
| Completeness | | Are all cases handled, or are paths missing? |
| Feasibility | | Is the approach viable under real-world constraints (load, edge cases, ops burden)? |
Score 1 = fundamentally broken; 5 = no concerns. Scores of 1-2 on any dimension = ARGUMENT HOLDS.
Nudge step (mandatory):
After scoring, identify the single assumption in the implementation most likely to be wrong.
Challenge it explicitly:
Nudge: The implementation assumes [specific assumption]. If this is false, [specific consequence].
Second-pass question: [one question the author must answer to validate or invalidate this assumption]
GAA Loop (Generator-Attacker-Analyzer):
Run adversarial mode as a structured 3-role loop:
- Generator -- the existing implementation (the code under review)
- Attacker -- the adversarial pass above; finds counterexamples and failure cases
- Analyzer -- for each surviving challenge, add a specific constraint that closes the gap
Loop until no new counterexample survives (max 2 iterations). On the second loop, if the same challenge reappears unresolved, escalate to BLOCK regardless of original verdict.
Output format:
ADVERSARIAL VERDICT: [ARGUMENT HOLDS / ARGUMENT WEAK]
Scores: Correctness [N]/5 | Completeness [N]/5 | Feasibility [N]/5
Challenge 1 — [abstraction / tests / complexity / assumption / fragility / early-termination]:
[Specific argument against the implementation]
Evidence: [file:line]
Analyzer constraint: [what must change to close this gap]
Challenge 2 — ...
Nudge: [assumption] — [consequence if false]
Second-pass question: [question]
User decision required: Accept / Reject each challenge.
Do not produce both standard and adversarial output in the same run. They are separate passes.
Anti-Patterns
Do not combine code-review with security-gate. They are separate passes. Flag security concerns and recommend running security-gate — do not attempt both in one pass.
Do not issue REQUEST CHANGES without specific locations and fixes. "This could be cleaner" is not actionable feedback.
Do not approve code with untraced critical paths. If you did not trace auth, payment, or data write paths, say so in the scope limitations.
Mandatory Checklist
- Verify all semantic anti-patterns were actively checked (not assumed absent)
- Verify critical paths were traced (auth, payment, data writes — wherever applicable)
- Verify every REQUEST CHANGES or BLOCK issue has a file:line and specific fix
- Verify tests were checked for what they actually assert, not just that they exist
- Verify verdict is one of: APPROVE / REQUEST CHANGES / BLOCK
- Verify scope limitations were stated (what was not reviewed)