Concerns (6 files): - coding-style.md (163 lines): patterns, anti-patterns, error handling, SOLID - naming.md (105 lines): naming conventions table per language - documentation.md (149 lines): docstrings, WHY vs WHAT, README standards - testing.md (134 lines): AAA pattern, mocking philosophy, TDD - git-workflow.md (118 lines): conventional commits, branch naming, PR format - project-structure.md (82 lines): directory layout, entry points, config placement Languages (4 files): - python.md (224 lines): uv, ruff, pyright, pytest, pydantic, idioms, anti-patterns - typescript.md (150 lines): strict mode, discriminated unions, satisfies, as const - nix.md (129 lines): flake structure, module patterns, alejandra, anti-patterns - shell.md (100 lines): set -euo pipefail, shellcheck, quoting, POSIX Frameworks (1 file): - n8n.md (42 lines): workflow design, node patterns, Error Trigger, security Context budget: 975 lines (concerns + python) < 1500 limit Refs: T6-T16 of rules-system plan
4.0 KiB
Coding Style
Critical Rules (MUST follow)
Always prioritize readability over cleverness. Never write code that requires mental gymnastics to understand. Always fail fast and explicitly. Never silently swallow errors or hide exceptions. Always keep functions under 20 lines. Never create monolithic functions that do multiple things. Always validate inputs at function boundaries. Never trust external data implicitly.
Formatting
Prefer consistent indentation throughout the codebase. Never mix tabs and spaces. Prefer meaningful variable names over short abbreviations. Never use single letters except for loop counters.
Correct:
const maxRetryAttempts = 3;
const connectionTimeout = 5000;
for (let attempt = 1; attempt <= maxRetryAttempts; attempt++) {
// process attempt
}
Incorrect:
const m = 3;
const t = 5000;
for (let i = 1; i <= m; i++) {
// process attempt
}
Patterns and Anti-Patterns
Never repeat yourself. Always extract duplicated logic into reusable functions. Prefer composition over inheritance. Never create deep inheritance hierarchies. Always use guard clauses to reduce nesting. Never write arrow-shaped code.
Correct:
def process_user(user):
if not user:
return None
if not user.is_active:
return None
return user.calculate_score()
Incorrect:
def process_user(user):
if user:
if user.is_active:
return user.calculate_score()
else:
return None
else:
return None
Error Handling
Always handle specific exceptions. Never use broad catch-all exception handlers. Always log error context, not just the error message. Never let errors vanish without trace.
Correct:
try:
data = fetch_resource(url)
return parse_data(data)
except NetworkError as e:
log_error(f"Network failed for {url}: {e}")
raise
except ParseError as e:
log_error(f"Parse failed for {url}: {e}")
return fallback_data
Incorrect:
try:
data = fetch_resource(url)
return parse_data(data)
except Exception:
pass
Type Safety
Always use type annotations where supported. Never rely on implicit type coercion. Prefer explicit type checks over duck typing for public APIs. Never assume type behavior.
Correct:
function calculateTotal(price: number, quantity: number): number {
return price * quantity;
}
Incorrect:
function calculateTotal(price, quantity) {
return price * quantity;
}
Function Design
Always write pure functions when possible. Never mutate arguments unless required. Always limit function parameters to 3 or fewer. Never pass objects to hide parameter complexity.
Correct:
def create_user(name: str, email: str) -> User:
return User(name=name, email=email, created_at=now())
Incorrect:
def create_user(config: dict) -> User:
return User(
name=config['name'],
email=config['email'],
created_at=config['timestamp']
)
SOLID Principles
Never let classes depend on concrete implementations. Always depend on abstractions. Always ensure classes are open for extension but closed for modification. Never change working code to add features. Prefer many small interfaces over one large interface. Never force clients to depend on methods they don't use.
Correct:
class EmailSender {
send(message: Message): void {
// implementation
}
}
class NotificationService {
constructor(private sender: EmailSender) {}
}
Incorrect:
class NotificationService {
sendEmail(message: Message): void { }
sendSMS(message: Message): void { }
sendPush(message: Message): void { }
}
Critical Rules (REPEAT)
Always write self-documenting code. Never rely on comments to explain complex logic. Always refactor when you see code smells. Never let technical debt accumulate. Always test edge cases explicitly. Never assume happy path only behavior. Never commit commented-out code. Always remove it or restore it.