cosmicstack-labs/clean-code
Principles and practices for writing readable, maintainable, and testable code
npx skills add https://github.com/cosmicstack-labs/mercury-agent-skills --skill clean-code
Write code that humans can read, understand, and change with confidence.
Code is communication. Every name, structure, and abstraction should reveal intent. If you need a comment to explain *what* the code does, the code is failing at communication.
Small functions, small classes, small files. Each unit of code should have one clear responsibility and do it well. Composability beats complexity.
Leave the code cleaner than you found it. Every commit should improve the codebase incrementally — even if it's just renaming one variable or extracting one function.
If code is hard to test, it has a design problem. Testable code is modular, decoupled, and honest about its dependencies.
Use this rubric to evaluate code quality on a scale of 1-5 for each dimension:
| Dimension | 1 (Poor) | 3 (Adequate) | 5 (Excellent) |
|-----------|----------|---------------|----------------|
| Naming | Single-letter vars, ambiguous abbreviations | Descriptive but occasionally redundant | Reveals intent, consistent, searchable |
| Function Size | Monolithic 500+ line functions | 50-100 line functions with mixed concerns | <20 lines, one clear level of abstraction |
| Comments | Outdated or redundant comments | Comments explain *what* not *why* | Minimal comments, code is self-documenting |
| Error Handling | Silent catches, magic error codes | Basic try/catch, some error types | Rich error types, graceful degradation |
| Testing | No tests or brittle tests | Tests exist but tightly coupled to implementation | Tests specify behavior, not implementation |
| Duplication | Copy-paste everywhere | Some reuse, some DRY violations | DRY with well-abstracted patterns |
Target: 4+ in every dimension for production-grade code.
Rules:
isActive, hasPermission, shouldRetry). Avoid negated names like isNotDisabled.calculateTotal(), validateInput(), fetchUser()).UserAccount, PaymentProcessor, HttpClient).MAX_RETRY_COUNT, DEFAULT_TIMEOUT_MS).# Bad
def proc(d):
r = []
for i in d:
if i.get('a') == True:
r.append(i.get('n'))
return r
# Good
def extract_active_user_names(users):
active_users = [user for user in users if user['is_active']]
return [user['name'] for user in active_users]
Searchable names: Avoid single-letter variables except in trivial loops. Use names that can be found with grep.
Rules:
setX(), updateY()).// Bad: Mixed abstraction levels
function processOrder(order) {
const tax = order.total * 0.08; // Low-level calc
order.totalWithTax = order.total + tax; // Mutation
fs.writeFileSync(`orders/${order.id}.json`, JSON.stringify(order)); // Side effect
sendEmailNotification(order.userEmail, 'Order processed'); // Side effect
return order.totalWithTax;
}
// Good: Clear single responsibility
function calculateTotalWithTax(total, taxRate) {
return total + (total * taxRate);
}
When to comment:
// FIXME: This endpoint is rate-limited to 100 req/minWhen NOT to comment:
// Increment counter)Patterns:
# Prefer specific exception types
def get_user(user_id):
try:
return database.fetch_user(user_id)
except DatabaseConnectionError:
logger.error(f"Database unavailable when fetching user {user_id}")
raise ServiceUnavailableError("User service temporarily unavailable")
except UserNotFoundError:
logger.info(f"User {user_id} not found")
return None # Expected case, not exceptional
Guidelines:
Result[T, E] types (Rust, Swift) or Either (functional languages) instead of exceptions for expected failures.catch blocks are a code smell. At minimum, log and re-raise.The Testing Trophy (not pyramid):
E2E Tests (few)
Integration (some)
Unit Tests (many)
Static Analysis (all code)
Guidelines:
it() blocks rather than multiple asserts in one."foo" and 123 don't catch edge cases.# Bad: Tests implementation details
def test_get_user():
mock_db = MagicMock()
service = UserService(mock_db)
result = service._fetch_and_transform_user(42) # Testing private method
assert mock_db.execute.called_once_with("SELECT * FROM users WHERE id=42")
# Good: Tests behavior
def test_get_user_returns_user_when_found():
user_repo = InMemoryUserRepository([User(id=42, name="Alice")])
service = UserService(user_repo)
result = service.get_user(42)
assert result.name == "Alice"
def test_get_user_returns_none_when_not_found():
user_repo = InMemoryUserRepository([])
service = UserService(user_repo)
result = service.get_user(99)
assert result is None
| Smell | Symptom | Fix |
|-------|---------|-----|
| Long Method | >20 lines doing multiple things | Extract methods, compose |
| Switch/Types | Switch on type enum, then dispatch | Polymorphism or strategy pattern |
| Feature Envy | Method uses more of another class's data than its own | Move method to the right class |
| Shotgun Surgery | One change requires edits in many files | Consolidate related logic |
| Data Clumps | Same 3-4 fields appear together repeatedly | Extract into a value object |
| Primitive Obsession | Using strings/ints where types belong | Create domain types |
| Inappropriate Intimacy | Class knows too much about another's internals | Reduce coupling, use interfaces |
goto in C error handling is fine. Single-letter variables in math-heavy code are fine. Context matters.Take cosmicstack-labs/clean-code from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.