Coding Standards
D9 Canonical Reference. This is the single source of truth for cross-language coding standards.
Language-specific reviewers (@typescript-reviewer, @python-reviewer, etc.) embed these rules.
Agents cite this skill as "See also: /coding-standards."
Naming Conventions
Variables & Functions
| Language |
Variables |
Functions |
Constants |
| TypeScript / JavaScript |
camelCase |
camelCase |
SCREAMING_SNAKE_CASE |
| Python |
snake_case |
snake_case |
SCREAMING_SNAKE_CASE |
| Go |
camelCase |
camelCase |
CamelCase (exported) |
| Rust |
snake_case |
snake_case |
SCREAMING_SNAKE_CASE |
| Java |
camelCase |
camelCase |
SCREAMING_SNAKE_CASE |
| C# |
camelCase |
PascalCase |
PascalCase |
| Swift |
camelCase |
camelCase |
camelCase |
Classes / Types / Interfaces
PascalCase — all languages, no exceptions.
Booleans
Prefix with is, has, can, should: isLoading, hasError, canEdit, shouldRefresh.
Collections
Plural nouns: users, errors, items — not userList, errorArray.
Avoid
- Single-letter variables outside loop counters (
i, j, k are OK in loops)
- Abbreviations that save under 3 characters:
usr → user, mgr → manager
- Redundant type names:
UserInterface, UserClass, UserObject → just User
Function Design
- Max length: 50 lines (firm guideline; > 80 lines is always a split target)
- Single responsibility: one function, one job — if "and" appears in the description, split it
- Max parameters: 3; beyond that, use an options/config object
- Cyclomatic complexity: ≤ 10; > 15 is a mandatory refactor target
- Nesting depth: ≤ 3 levels; use early returns to flatten
Early Return Pattern (preferred)
// BEFORE — deep nesting
function handle(input) {
if (input) {
if (input.valid) {
return process(input);
}
}
return null;
}
// AFTER — early returns
function handle(input) {
if (!input || !input.valid) return null;
return process(input);
}
Error Handling
- Never swallow errors silently:
catch (e) {} is always wrong
- Error messages must contain context:
"Failed to fetch user id=42" not "Error"
- Propagate or handle: either handle the error at the right level OR re-throw it — never both and never neither
- Typed errors (TypeScript):
class NotFoundError extends Error { constructor(id: string) ... } not generic new Error
- Python exceptions: catch specific exception types; bare
except: is forbidden
- Go errors: always check returned errors; use
errors.Is()/errors.As() for comparison
- Rust results: use
? for propagation; no .unwrap() in library code
Code Structure
Immutability-First
const over let (JS/TS); val over var (Swift/Kotlin); final where appropriate
- Mark fields
readonly when not reassigned after construction
- Prefer immutable data structures for function arguments
No Magic Numbers
// BAD
if (retries > 3) { ... }
setTimeout(fn, 5000);
// GOOD
const MAX_RETRIES = 3;
const POLL_INTERVAL_MS = 5000;
if (retries > MAX_RETRIES) { ... }
setTimeout(fn, POLL_INTERVAL_MS);
No Commented-Out Code
If it is dead → delete it (git history preserves it).
If it is needed soon → it should be in a branch.
If it explains a non-obvious decision → keep it as a comment, not commented-out code.
Anti-Patterns Reference
| Pattern |
Severity |
Reason |
| Mutable global state |
HIGH |
Unpredictable side effects; hides dependencies |
| Promise not awaited |
HIGH |
Unhandled async errors silently swallowed |
any in TypeScript |
MEDIUM |
Bypasses type safety across call boundaries |
console.log in production code |
LOW |
Log noise; potential data leak in sensitive contexts |
TODO without issue tracker reference |
LOW |
Becomes permanent tech debt |
| God Object |
HIGH |
Single class with too many responsibilities |
| Magic numbers inline |
MEDIUM |
Unclear intent; maintenance hazard |
| Copy-paste logic |
MEDIUM |
Silent divergence over time |
| Catching and re-throwing without context |
MEDIUM |
Stack traces lose meaning |
| Nested ternary operators |
MEDIUM |
Unreadable; use if/else or switch instead |
SOLID Principles Checklist
- Single Responsibility: does this class/function do exactly one thing?
- Open/Closed: extend via composition/interfaces, not inheritance modification?
- Liskov Substitution: can a subtype always replace the base type without breaking callers?
- Interface Segregation: no fat interfaces — clients should not depend on methods they don't use?
- Dependency Inversion: depend on abstractions (interfaces), not concretions?
See Also
@code-reviewer — applies these rules during code review
@typescript-reviewer, @python-reviewer, etc. — language-specific rules with these as baseline
@security-reviewer — security-specific standards (OWASP, secrets, crypto)
1---2name: coding-standards3description: Canonical cross-language coding standards reference. Shared rules embedded by reviewer agents. Activate when: viewing coding standards, checking naming rules, reviewing style baseline, consulting style guide, what are the rules.4---5
6# Coding Standards
7
8> **D9 Canonical Reference.** This is the single source of truth for cross-language coding standards.
9> Language-specific reviewers (`@typescript-reviewer`, `@python-reviewer`, etc.) embed these rules.
10> Agents cite this skill as "See also: /coding-standards."
11
12## Naming Conventions
13
14### Variables & Functions
15| Language | Variables | Functions | Constants |
16|----------|-----------|-----------|-----------|
17| TypeScript / JavaScript | `camelCase` | `camelCase` | `SCREAMING_SNAKE_CASE` |
18| Python | `snake_case` | `snake_case` | `SCREAMING_SNAKE_CASE` |
19| Go | `camelCase` | `camelCase` | `CamelCase` (exported) |
20| Rust | `snake_case` | `snake_case` | `SCREAMING_SNAKE_CASE` |
21| Java | `camelCase` | `camelCase` | `SCREAMING_SNAKE_CASE` |
22| C# | `camelCase` | `PascalCase` | `PascalCase` |
23| Swift | `camelCase` | `camelCase` | `camelCase` |
24
25### Classes / Types / Interfaces
26`PascalCase` — all languages, no exceptions.
27
28### Booleans
29Prefix with `is`, `has`, `can`, `should`: `isLoading`, `hasError`, `canEdit`, `shouldRefresh`.
30
31### Collections
32Plural nouns: `users`, `errors`, `items` — not `userList`, `errorArray`.
33
34### Avoid
35- Single-letter variables outside loop counters (`i`, `j`, `k` are OK in loops)
36- Abbreviations that save under 3 characters: `usr` → `user`, `mgr` → `manager`
37- Redundant type names: `UserInterface`, `UserClass`, `UserObject` → just `User`
38
39---
40
41## Function Design
42
43- **Max length:** 50 lines (firm guideline; > 80 lines is always a split target)
44- **Single responsibility:** one function, one job — if "and" appears in the description, split it
45- **Max parameters:** 3; beyond that, use an options/config object
46- **Cyclomatic complexity:** ≤ 10; > 15 is a mandatory refactor target
47- **Nesting depth:** ≤ 3 levels; use early returns to flatten
48
49### Early Return Pattern (preferred)
50```typescript
51// BEFORE — deep nesting
52function handle(input) {
53 if (input) {
54 if (input.valid) {
55 return process(input);
56 }
57 }
58 return null;
59}
60
61// AFTER — early returns
62function handle(input) {
63 if (!input || !input.valid) return null;
64 return process(input);
65}
66```
67
68---
69
70## Error Handling
71
72- **Never swallow errors silently:** `catch (e) {}` is always wrong
73- **Error messages must contain context:** `"Failed to fetch user id=42"` not `"Error"`
74- **Propagate or handle:** either handle the error at the right level OR re-throw it — never both and never neither
75- **Typed errors (TypeScript):** `class NotFoundError extends Error { constructor(id: string) ... }` not generic `new Error`
76- **Python exceptions:** catch specific exception types; bare `except:` is forbidden
77- **Go errors:** always check returned errors; use `errors.Is()`/`errors.As()` for comparison
78- **Rust results:** use `?` for propagation; no `.unwrap()` in library code
79
80---
81
82## Code Structure
83
84### Immutability-First
85- `const` over `let` (JS/TS); `val` over `var` (Swift/Kotlin); `final` where appropriate
86- Mark fields `readonly` when not reassigned after construction
87- Prefer immutable data structures for function arguments
88
89### No Magic Numbers
90```typescript
91// BAD
92if (retries > 3) { ... }
93setTimeout(fn, 5000);
94
95// GOOD
96const MAX_RETRIES = 3;
97const POLL_INTERVAL_MS = 5000;
98if (retries > MAX_RETRIES) { ... }
99setTimeout(fn, POLL_INTERVAL_MS);
100```
101
102### No Commented-Out Code
103If it is dead → delete it (git history preserves it).
104If it is needed soon → it should be in a branch.
105If it explains a non-obvious decision → keep it as a comment, not commented-out code.
106
107---
108
109## Anti-Patterns Reference
110
111| Pattern | Severity | Reason |
112|---------|----------|--------|
113| Mutable global state | HIGH | Unpredictable side effects; hides dependencies |
114| Promise not awaited | HIGH | Unhandled async errors silently swallowed |
115| `any` in TypeScript | MEDIUM | Bypasses type safety across call boundaries |
116| `console.log` in production code | LOW | Log noise; potential data leak in sensitive contexts |
117| `TODO` without issue tracker reference | LOW | Becomes permanent tech debt |
118| God Object | HIGH | Single class with too many responsibilities |
119| Magic numbers inline | MEDIUM | Unclear intent; maintenance hazard |
120| Copy-paste logic | MEDIUM | Silent divergence over time |
121| Catching and re-throwing without context | MEDIUM | Stack traces lose meaning |
122| Nested ternary operators | MEDIUM | Unreadable; use if/else or switch instead |
123
124---
125
126## SOLID Principles Checklist
127
128- **S**ingle Responsibility: does this class/function do exactly one thing?
129- **O**pen/Closed: extend via composition/interfaces, not inheritance modification?
130- **L**iskov Substitution: can a subtype always replace the base type without breaking callers?
131- **I**nterface Segregation: no fat interfaces — clients should not depend on methods they don't use?
132- **D**ependency Inversion: depend on abstractions (interfaces), not concretions?
133
134---
135
136## See Also
137
138- `@code-reviewer` — applies these rules during code review
139- `@typescript-reviewer`, `@python-reviewer`, etc. — language-specific rules with these as baseline
140- `@security-reviewer` — security-specific standards (OWASP, secrets, crypto)