plugins/autonomous-dev/skills/code-review/SKILL.md
This skill should be used when reviewing code or preparing code for review. It provides guidelines for what to look for in reviews, how to write constructive feedback, and standards for review comments.
npx skillsauth add akaszubski/anyclaude-local code-reviewInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Code review standards and best practices for providing constructive feedback.
Does it solve the stated problem?
# ❌ BAD: Doesn't handle the edge case mentioned in the issue
def divide(a, b):
return a / b # Issue #42 says we need to handle zero division
# ✅ GOOD: Solves the stated problem
def divide(a, b):
"""Divide two numbers with zero-division handling.
Closes #42
"""
if b == 0:
raise ValueError("Cannot divide by zero")
return a / b
Are there edge cases not handled?
Common edge cases to check:
Potential bugs or race conditions?
# ❌ BAD: Race condition
class Counter:
def __init__(self):
self.count = 0
def increment(self):
self.count += 1 # Not thread-safe!
# ✅ GOOD: Thread-safe
import threading
class Counter:
def __init__(self):
self.count = 0
self.lock = threading.Lock()
def increment(self):
with self.lock:
self.count += 1
Follows SOLID principles?
Example - Single Responsibility:
# ❌ BAD: Class does too much
class UserManager:
def create_user(self, data): ...
def send_email(self, user): ...
def log_activity(self, action): ...
def calculate_metrics(self): ...
# ✅ GOOD: Each class has one responsibility
class UserRepository:
def create_user(self, data): ...
class EmailService:
def send_welcome_email(self, user): ...
class ActivityLogger:
def log(self, action): ...
class MetricsCalculator:
def calculate_user_metrics(self): ...
Appropriate abstractions?
# ❌ BAD: Leaky abstraction
class Database:
def query(self, sql): # Exposes SQL details
return self.connection.execute(sql)
# ✅ GOOD: Clean abstraction
class UserRepository:
def find_by_email(self, email): # Hides implementation
return self._query_users(email=email)
Pattern usage correct?
Check if patterns are:
Sufficient test coverage?
Minimum requirements:
Tests cover edge cases?
# Example: Testing edge cases
def test_divide_by_zero_raises_error():
with pytest.raises(ValueError, match="Cannot divide by zero"):
divide(10, 0)
def test_divide_positive_numbers():
assert divide(10, 2) == 5
def test_divide_negative_numbers():
assert divide(-10, 2) == -5
def test_divide_fractional_result():
assert divide(5, 2) == 2.5
Tests are deterministic?
# ❌ BAD: Non-deterministic test (flaky)
def test_process_items():
items = get_random_items() # Different every time!
result = process(items)
assert len(result) > 0
# ✅ GOOD: Deterministic test
def test_process_items():
items = [{"id": 1}, {"id": 2}, {"id": 3}] # Fixed input
result = process(items)
assert len(result) == 3
Clear naming?
# ❌ BAD: Unclear names
def fn(x, y):
return x > y
# ✅ GOOD: Clear names
def is_price_above_threshold(price: float, threshold: float) -> bool:
return price > threshold
Self-documenting code?
# ❌ BAD: Needs comments to understand
def calc(d):
if d > 30:
return d * 0.9 # What does 30 mean? What does 0.9 mean?
return d
# ✅ GOOD: Self-documenting
BULK_DISCOUNT_THRESHOLD_DAYS = 30
BULK_DISCOUNT_RATE = 0.10
def calculate_rental_price(days_rented: int) -> float:
"""Calculate rental price with bulk discount for 30+ days."""
if days_rented >= BULK_DISCOUNT_THRESHOLD_DAYS:
discount_multiplier = 1 - BULK_DISCOUNT_RATE
return days_rented * discount_multiplier
return days_rented
Comments where necessary?
Good comments explain WHY, not WHAT:
# ❌ BAD: States the obvious
counter += 1 # Increment counter
# ✅ GOOD: Explains why
# Skip first batch - it's used for model warmup
counter += 1
Obvious inefficiencies?
# ❌ BAD: O(n²) when O(n) possible
def find_duplicates(items):
duplicates = []
for item in items:
for other in items: # Nested loop!
if item == other:
duplicates.append(item)
return duplicates
# ✅ GOOD: O(n) using set
def find_duplicates(items):
seen = set()
duplicates = set()
for item in items:
if item in seen:
duplicates.add(item)
seen.add(item)
return list(duplicates)
Unnecessary copies or allocations?
# ❌ BAD: Creates new list each iteration
def process_items(items):
result = []
for item in items:
result = result + [process(item)] # New list!
return result
# ✅ GOOD: Modifies in place
def process_items(items):
result = []
for item in items:
result.append(process(item)) # In-place append
return result
Appropriate data structures?
| Use Case | Wrong | Right | | -------------------------- | ---------------- | --------------------------------- | | Frequent membership checks | List (O(n)) | Set (O(1)) | | Ordered key-value pairs | Dict (unordered) | OrderedDict or dict (Python 3.7+) | | FIFO queue | List (O(n) pop) | deque (O(1) pop) | | Fixed-size numeric array | List | numpy.array |
Focus on the code, not the person:
# ❌ BAD: Attacks the person
You don't know how to write good code.
# ✅ GOOD: Focuses on the code
This approach doesn't handle edge cases. Consider adding validation.
Provide specific suggestions:
# ❌ BAD: Vague critique
This is wrong.
# ✅ GOOD: Specific suggestion with example
Consider using a set here instead of a list for O(1) lookups.
Currently this is O(n) on each iteration:
```python
if item in items: # O(n) with list
...
```
Suggested change:
items_set = set(items) # O(n) once
if item in items_set: # O(1) each time
...
### Provide Context
**Explain WHY the change is needed**:
```markdown
# ❌ BAD: No context
Fix this.
# ✅ GOOD: Explains the problem
This will fail if the file doesn't exist. Consider adding:
```python
if not path.exists():
raise FileNotFoundError(f"Training data not found: {path}")
This prevents cryptic errors later in the pipeline.
### Distinguish Severity
Use labels to indicate importance:
```markdown
**nit**: Consider renaming `x` to `model_id` for clarity
**suggestion**: This could be simplified using a dictionary lookup
**issue**: This will cause a memory leak - the cache is never cleared
**blocker**: This breaks backwards compatibility - needs migration path
Severity levels:
When unsure, ask instead of asserting:
# ❌ BAD: Assertive without understanding
This is inefficient and needs to be rewritten.
# ✅ GOOD: Asks first
Is there a reason we're loading the entire file into memory?
For large files, could we process it in chunks instead?
✅ Nice use of the strategy pattern here - makes it easy to add new methods.
✅ Great test coverage! The edge cases are well-handled.
✅ Clear naming throughout this module.
**suggestion**: Consider extracting this logic to a separate function for reusability.
Current:
```python
# Repeated logic in multiple places
if user.is_active and user.email_verified and not user.is_banned:
...
```
Suggested:
def can_user_access_feature(user):
return user.is_active and user.email_verified and not user.is_banned
if can_user_access_feature(user):
...
### Identifying Bugs
```markdown
**issue**: This will raise a `KeyError` if the key doesn't exist.
Suggested fix:
```python
# Instead of:
value = config['api_key']
# Use:
value = config.get('api_key')
if value is None:
raise ValueError("Missing required config: api_key")
### Performance Concerns
```markdown
**issue**: This query runs inside a loop, causing N+1 queries.
Current approach makes `len(users)` database queries:
```python
for user in users:
orders = db.query("SELECT * FROM orders WHERE user_id = ?", user.id)
Suggested batch query:
user_ids = [u.id for u in users]
all_orders = db.query("SELECT * FROM orders WHERE user_id IN (?)", user_ids)
orders_by_user = group_by(all_orders, 'user_id')
### Test Coverage
```markdown
**suggestion**: Add test for the error case.
Suggested test:
```python
def test_process_data_raises_error_on_empty_input():
with pytest.raises(ValueError, match="Input cannot be empty"):
process_data([])
---
## Responding to Review Feedback
### As the Author (Receiving Feedback)
**1. Read all comments before responding**
- Get full picture before reacting
- Understand reviewer's perspective
- Identify patterns in feedback
**2. Ask clarifying questions**
```markdown
# Good clarifying question
> "This should handle empty lists as well"
Thanks for catching this! Should it return an empty result or raise an error?
I'm leaning toward raising an error since empty input is likely a bug.
3. Acknowledge and implement
# ✅ Agree and done
> "Use a set for O(1) lookup"
Done! Changed to use a set. Performance improved 10x in my local tests.
4. Explain alternative approaches
# 💭 Alternative proposal
> "This could use a dictionary"
I considered that, but went with a dataclass instead because:
- Provides type hints
- Better IDE support
- Validates types at runtime
Thoughts?
5. Defer to separate PR when appropriate
# ✅ Agree but separate PR
> "We should also add retry logic"
Great idea! I'd prefer to address that in a separate PR since:
- This PR is already large
- Retry logic needs its own tests
- Unrelated to the current bug fix
Created #127 to track it.
1. Be patient and collaborative
2. Approve when issues are addressed
# ✅ Approval comment
Thanks for addressing the feedback! The refactoring looks much cleaner.
Approving.
3. Escalate blockers clearly
# ⛔ Clear blocker
I can't approve this yet due to the backwards compatibility break.
We need to either:
1. Add a migration path for existing users
2. Defer this change to v2.0.0
Happy to discuss the best approach.
pytest tests/black . && isort .ruff check .mypy src/print(), console.log(), etc.[PROJECT_NAME] code review standards:
Tools:
Books:
Articles:
Version: 1.0.0 Type: Knowledge skill (no scripts) See Also: git-workflow, testing-guide, python-standards
testing
Complete testing methodology - TDD, progression tracking, regression prevention, and test patterns
documentation
GenAI-powered semantic validation - detects outdated docs, version mismatches, and architectural drift
development
Security best practices, API key management, input validation. Use when handling secrets, user input, or security-sensitive code.
research
Research methodology and best practices for finding existing patterns