`common/coding-style.md` has no `paths:` frontmatter, so it is loaded for every source file regardless of language. Its Naming Conventions section nevertheless prescribed `camelCase` for variables and functions, which is not idiomatic for several languages the package supports: `python/coding-style.md` mandates PEP 8 (`snake_case`) and `rust/coding-style.md` mandates `snake_case` for functions, methods and variables. Both carry `paths:` frontmatter, so for a .py or .rs file the agent is handed two opposite naming rules in the same context. README.md does state that language-specific rules take precedence, but that statement lives in the README rather than in the rule files the agent actually receives. Replace the casing list with the canonical `**Language note**` marker documented in rules/README.md, and keep only what is genuinely language-independent: descriptive names, boolean prefixes, and constants and types being visually distinct from values, and only where the language draws that distinction at all. The per-language examples name only languages whose own coding-style.md actually states a casing standard. Drop the "Custom hooks: camelCase with a use prefix" line and link to react/coding-style.md instead — it is React-specific and documented there both as the `useCamelCase` symbol rule and as the eslint-plugin-react-hooks enforcement note. react/coding-style.md is path-scoped, so a hook colocated outside `components/**` or `hooks/**` no longer receives the rule; see the PR description. Fixes #2830
3.1 KiB
Coding Style
Immutability (CRITICAL)
ALWAYS create new objects, NEVER mutate existing ones:
// Pseudocode
WRONG: modify(original, field, value) → changes original in-place
CORRECT: update(original, field, value) → returns new copy with change
Rationale: Immutable data prevents hidden side effects, makes debugging easier, and enables safe concurrency.
Core Principles
KISS (Keep It Simple)
- Prefer the simplest solution that actually works
- Avoid premature optimization
- Optimize for clarity over cleverness
DRY (Don't Repeat Yourself)
- Extract repeated logic into shared functions or utilities
- Avoid copy-paste implementation drift
- Introduce abstractions when repetition is real, not speculative
YAGNI (You Aren't Gonna Need It)
- Do not build features or abstractions before they are needed
- Avoid speculative generality
- Start simple, then refactor when the pressure is real
File Organization
MANY SMALL FILES > FEW LARGE FILES:
- High cohesion, low coupling
- 200-400 lines typical, with 800 lines as a soft maintainability ceiling for source files
- Test, generated, and vendored files may exceed the ceiling when their size is justified by their role
- Extract utilities from large modules
- Organize by feature/domain, not by type
Error Handling
ALWAYS handle errors comprehensively:
- Handle errors explicitly at every level
- Provide user-friendly error messages in UI-facing code
- Log detailed error context on the server side
- Never silently swallow errors
Input Validation
ALWAYS validate at system boundaries:
- Validate all user input before processing
- Use schema-based validation where available
- Fail fast with clear error messages
- Never trust external data (API responses, user input, file content)
Naming Conventions
Language note: This rule may be overridden by language-specific rules for languages where this pattern is not idiomatic. Casing in particular belongs to the language file — e.g. PEP 8 for Python,
snake_casefor Rust,camelCasefor Java and Kotlin. React hook naming lives in react/coding-style.md.
Language-independent:
- Descriptive names: the name says what the thing holds or does, without a comment.
- Booleans read as a claim: prefix with
is,has,shouldorcan. - Where the language draws the distinction, constants and types are visually
distinct from ordinary values (
UPPER_SNAKE_CASEandPascalCasein many languages) — whether it draws it at all is for the language file to say.
Code Smells to Avoid
Deep Nesting
Prefer early returns over nested conditionals once the logic starts stacking.
Magic Numbers
Use named constants for meaningful thresholds, delays, and limits.
Long Functions
Split large functions into focused pieces with clear responsibilities.
Code Quality Checklist
Before marking work complete:
- Code is readable and well-named
- Functions are small (<50 lines)
- Files are focused (<800 lines)
- No deep nesting (>4 levels)
- Proper error handling
- No hardcoded values (use constants or config)
- No mutation (immutable patterns used)