mirror of
https://github.com/affaan-m/ECC.git
synced 2026-09-17 23:28:04 +02:00
`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
100 lines
3.1 KiB
Markdown
100 lines
3.1 KiB
Markdown
# 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_case` for Rust, `camelCase`
|
|
> for Java and Kotlin. React hook naming lives in
|
|
> [react/coding-style.md](../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`, `should` or `can`.
|
|
- Where the language draws the distinction, constants and types are visually
|
|
distinct from ordinary values (`UPPER_SNAKE_CASE` and `PascalCase` in 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)
|