Clean Code Skill
Core Principles
1. Meaningful Names
# Bad
def calc(a, b):
return a * b
# Good
def calculate_total_price(unit_price: float, quantity: int) -> float:
return unit_price * quantity
2. Single Responsibility
# Bad - does too much
def process_user(user_data):
validate(user_data)
user = create_user(user_data)
send_welcome_email(user)
log_creation(user)
return user
# Good - each function does one thing
def create_user(user_data: UserData) -> User:
return User(**user_data)
def onboard_user(user_data: UserData) -> User:
user = create_user(user_data)
send_welcome_email(user)
log_user_creation(user)
return user
3. DRY (Don't Repeat Yourself)
# Bad
def get_active_users():
return [u for u in users if u.status == "active"]
def get_active_admins():
return [u for u in users if u.status == "active" and u.role == "admin"]
# Good
def filter_users(status: str | None = None, role: str | None = None) -> list[User]:
result = users
if status:
result = [u for u in result if u.status == status]
if role:
result = [u for u in result if u.role == role]
return result
Code Organization
Keep modules focused. Order contents consistently: imports (stdlib, third-party, local), constants, public API, private helpers. Use clear visibility markers (underscore prefix in Python, access modifiers in other languages). Group related functionality into cohesive modules rather than dumping everything into a single file.
Anti-Patterns to Avoid
| Anti-Pattern |
Problem |
Solution |
| God class |
Too many responsibilities |
Split into smaller classes |
| Long methods |
Hard to understand |
Extract methods |
| Deep nesting |
Complex control flow |
Early returns, extract methods |
| Magic numbers |
Unclear meaning |
Use named constants |
| Bare except |
Hides bugs |
Catch specific exceptions |
| Mutable defaults |
Shared state bugs |
Use None and create inside |
Quality Checklist
Common Rationalizations
| Excuse |
Why It's Wrong |
| "It's readable enough" |
"Enough" means someone will misread it eventually — clarity prevents incidents |
| "Refactoring for readability is gold-plating" |
Readability is maintainability — future you will thank present you |
| "Short variable names are faster to type" |
You type it once, readers parse it hundreds of times — optimize for reading |
| "DRY means never repeat anything" |
Wrong DRY creates coupling — duplicate until you see the real abstraction |
| "More abstractions = cleaner code" |
Premature abstraction is worse than duplication — wait for the third use |
| "That dead file is pre-existing, not my problem" |
If your change makes it verifiably unused, deleting it IS your problem (Constitution Art. VI.1) |
| "I'll fix the missing test in a separate PR" |
Forbidden when the test covers behavior you just changed — add it now (Constitution Art. VI.2) |
| "Świadome pominięcie" / "out of scope" |
Deferral of directly-adjacent fixes is forbidden; if a user decision is needed, ASK, don't bury it |
Language-Specific References
For detailed patterns, type hints, linting configuration, and idiomatic code per language:
- Python: type hints, docstrings, error handling, context managers, module/class structure, ruff/mypy config -- see reference/python.md
- TypeScript: strict tsconfig, ESLint setup, discriminated unions, type safety -- see reference/typescript.md
- PHP: PHPStan config, PSR-12, enums, constructor promotion -- see reference/php.md
- Go: gofmt, error handling, receiver naming, early returns -- see reference/go.md
- Dart/Flutter: null safety, named parameters, const constructors, dart analyze -- see reference/dart.md
1---2name: clean-code3description: "Code quality: meaningful names, SRP, DRY, small functions, guard clauses, refactoring. Triggers: clean code, naming, code smell, SRP, DRY, long function, god class, dead code."4effort: medium5user-invocable: false6allowed-tools: Read7---89# Clean Code Skill1011## Core Principles1213### 1. Meaningful Names1415```python16# Bad17def calc(a, b):18 return a * b1920# Good21def calculate_total_price(unit_price: float, quantity: int) -> float:22 return unit_price * quantity23```2425### 2. Single Responsibility2627```python28# Bad - does too much29def process_user(user_data):30 validate(user_data)31 user = create_user(user_data)32 send_welcome_email(user)33 log_creation(user)34 return user3536# Good - each function does one thing37def create_user(user_data: UserData) -> User:38 return User(**user_data)3940def onboard_user(user_data: UserData) -> User:41 user = create_user(user_data)42 send_welcome_email(user)43 log_user_creation(user)44 return user45```4647### 3. DRY (Don't Repeat Yourself)4849```python50# Bad51def get_active_users():52 return [u for u in users if u.status == "active"]5354def get_active_admins():55 return [u for u in users if u.status == "active" and u.role == "admin"]5657# Good58def filter_users(status: str | None = None, role: str | None = None) -> list[User]:59 result = users60 if status:61 result = [u for u in result if u.status == status]62 if role:63 result = [u for u in result if u.role == role]64 return result65```6667---6869## Code Organization7071Keep modules focused. Order contents consistently: imports (stdlib, third-party, local), constants, public API, private helpers. Use clear visibility markers (underscore prefix in Python, access modifiers in other languages). Group related functionality into cohesive modules rather than dumping everything into a single file.7273---7475## Anti-Patterns to Avoid7677| Anti-Pattern | Problem | Solution |78|--------------|---------|----------|79| God class | Too many responsibilities | Split into smaller classes |80| Long methods | Hard to understand | Extract methods |81| Deep nesting | Complex control flow | Early returns, extract methods |82| Magic numbers | Unclear meaning | Use named constants |83| Bare except | Hides bugs | Catch specific exceptions |84| Mutable defaults | Shared state bugs | Use `None` and create inside |8586---8788## Quality Checklist8990- [ ] Functions are small (<20 lines ideal)91- [ ] Names are descriptive and consistent92- [ ] Type hints on all public APIs93- [ ] Docstrings on all public functions/classes94- [ ] No magic numbers (use constants)95- [ ] No hardcoded strings (use enums/constants)96- [ ] Error handling is specific97- [ ] Resources are properly cleaned up98- [ ] No code duplication99- [ ] Tests cover critical paths100- [ ] **No dead code** — grep-verified zero references for every removed/renamed symbol; pre-existing dead code touched by this change is deleted too (Constitution Art. VI.1)101- [ ] **Every found bug fixed** — bugs, missing tests for changed behavior, and stale docs discovered during the task are fixed in the same change, not deferred (Constitution Art. VI.2)102103---104105## Common Rationalizations106107| Excuse | Why It's Wrong |108|--------|----------------|109| "It's readable enough" | "Enough" means someone will misread it eventually — clarity prevents incidents |110| "Refactoring for readability is gold-plating" | Readability is maintainability — future you will thank present you |111| "Short variable names are faster to type" | You type it once, readers parse it hundreds of times — optimize for reading |112| "DRY means never repeat anything" | Wrong DRY creates coupling — duplicate until you see the real abstraction |113| "More abstractions = cleaner code" | Premature abstraction is worse than duplication — wait for the third use |114| "That dead file is pre-existing, not my problem" | If your change makes it verifiably unused, deleting it IS your problem (Constitution Art. VI.1) |115| "I'll fix the missing test in a separate PR" | Forbidden when the test covers behavior you just changed — add it now (Constitution Art. VI.2) |116| "Świadome pominięcie" / "out of scope" | Deferral of directly-adjacent fixes is forbidden; if a user decision is needed, ASK, don't bury it |117118## Language-Specific References119120For detailed patterns, type hints, linting configuration, and idiomatic code per language:121122- **Python:** type hints, docstrings, error handling, context managers, module/class structure, ruff/mypy config -- see [reference/python.md](reference/python.md)123- **TypeScript:** strict tsconfig, ESLint setup, discriminated unions, type safety -- see [reference/typescript.md](reference/typescript.md)124- **PHP:** PHPStan config, PSR-12, enums, constructor promotion -- see [reference/php.md](reference/php.md)125- **Go:** gofmt, error handling, receiver naming, early returns -- see [reference/go.md](reference/go.md)126- **Dart/Flutter:** null safety, named parameters, const constructors, dart analyze -- see [reference/dart.md](reference/dart.md)