code-conventions
Code Conventions (Universal)
Section titled “Code Conventions (Universal)”Applies to ALL languages and frameworks. Kit-specific rules extend this in code-conventions-{kit}.md.
Generic conventions (summary)
Section titled “Generic conventions (summary)”SOLID; self-documenting names (is/has/can/should booleans, verb functions); one responsibility per file, ≤200 lines, guard clauses over nesting, composition over inheritance, immutability by default; no magic numbers / empty catch / merged-TODO; stdlib→external→internal import order; test public behavior with independent, descriptively-named tests. Full enumerated lists: docs/code-conventions.md.
Data-Driven Over Hardcoded
Section titled “Data-Driven Over Hardcoded”- NEVER hardcode mappings (command→skill / role / agent, keyword→module) in hooks or scripts. Always read from registry files at runtime so new skills/agents/modules auto-discover with no code change.
- Test: deleting a static map should break nothing because the data comes from files. If it breaks → you’re hardcoding.
No Duplicated Logic
Section titled “No Duplicated Logic”- Before writing a utility, search shared modules (
telemetry-utils.cjs,lib/); if a pattern appears in 2+ files, extract immediately — not “later”. - Each
.claude/path resolution must useresolveClaudeDir()— no inlinepath.join(cwd, '.claude'). null/undefinedguards where data flows between systems.
No Derived Fields — SSOT for Data
Section titled “No Derived Fields — SSOT for Data”- NEVER store a value computable from other columns. If
C = f(A, B)andA/Bare stored, computeCat the query/use site. - Exception — materialized for performance only: IF profiling proves a real bottleneck AND source columns rarely change AND it’s kept in sync via trigger/constraint/CI AND the formula is documented inline.
Modular Boundaries — Seam Where It Earns Its Keep
Section titled “Modular Boundaries — Seam Where It Earns Its Keep”- Decompose by feature/vertical slice, not by layer; draw a module seam only when it passes the seam-worth test — it hides more complexity than its interface adds, has ≥3 real uses OR is a stable domain/third-party edge, and only name/type coupling crosses it — the same seam that yields an independently-ownable, parallelizable unit. Parallelism is a benefit of a good seam, never a reason to draw one. See
coding-guidelines.md§2 (YAGNI — the calibration guard),contract-first-integration.md,library-third-party-decoupling.md(day-one seam for third-party/library edges). Full test + guards:docs/code-conventions.md.
Living Document
Section titled “Living Document”If unsure about a convention not covered here, ask the user and update this file.