agile-context-engineering 0.3.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +18 -0
- package/.claude-plugin/plugin.json +10 -0
- package/CHANGELOG.md +7 -1
- package/LICENSE +51 -51
- package/README.md +330 -318
- package/agents/ace-code-discovery-analyst.md +245 -245
- package/agents/ace-code-integration-analyst.md +248 -248
- package/agents/ace-code-reviewer.md +375 -375
- package/agents/ace-product-owner.md +365 -361
- package/agents/ace-project-researcher.md +606 -606
- package/agents/ace-research-synthesizer.md +228 -228
- package/agents/ace-technical-application-architect.md +315 -315
- package/agents/ace-wiki-mapper.md +449 -445
- package/bin/install.js +605 -195
- package/hooks/ace-check-update.js +71 -62
- package/hooks/ace-statusline.js +107 -89
- package/hooks/hooks.json +14 -0
- package/package.json +7 -5
- package/shared/lib/ace-core.js +361 -0
- package/shared/lib/ace-core.test.js +308 -0
- package/shared/lib/ace-github.js +753 -0
- package/shared/lib/ace-story.js +400 -0
- package/shared/lib/ace-story.test.js +250 -0
- package/{agile-context-engineering → shared}/utils/questioning.xml +110 -110
- package/{agile-context-engineering → shared}/utils/ui-formatting.md +299 -299
- package/{commands/ace/execute-story.md → skills/execute-story/SKILL.md} +116 -138
- package/skills/execute-story/script.js +291 -0
- package/skills/execute-story/script.test.js +261 -0
- package/{agile-context-engineering/templates/product/story.xml → skills/execute-story/story-template.xml} +451 -451
- package/skills/execute-story/walkthrough-template.xml +255 -0
- package/{agile-context-engineering/workflows/execute-story.xml → skills/execute-story/workflow.xml} +1221 -1219
- package/skills/help/SKILL.md +71 -0
- package/skills/help/script.js +315 -0
- package/skills/help/script.test.js +183 -0
- package/{agile-context-engineering/workflows/help.xml → skills/help/workflow.xml} +544 -533
- package/{commands/ace/init-coding-standards.md → skills/init-coding-standards/SKILL.md} +91 -83
- package/{agile-context-engineering/templates/wiki/coding-standards.xml → skills/init-coding-standards/coding-standards-template.xml} +531 -531
- package/skills/init-coding-standards/script.js +50 -0
- package/skills/init-coding-standards/script.test.js +70 -0
- package/{agile-context-engineering/workflows/init-coding-standards.xml → skills/init-coding-standards/workflow.xml} +381 -386
- package/skills/map-cross-cutting/SKILL.md +126 -0
- package/{agile-context-engineering/templates/wiki → skills/map-cross-cutting}/system-cross-cutting.xml +197 -197
- package/skills/map-cross-cutting/workflow.xml +330 -0
- package/skills/map-guide/SKILL.md +126 -0
- package/{agile-context-engineering/templates/wiki → skills/map-guide}/guide.xml +137 -137
- package/skills/map-guide/workflow.xml +320 -0
- package/skills/map-pattern/SKILL.md +125 -0
- package/{agile-context-engineering/templates/wiki → skills/map-pattern}/pattern.xml +159 -159
- package/skills/map-pattern/workflow.xml +331 -0
- package/{commands/ace/map-story.md → skills/map-story/SKILL.md} +180 -165
- package/{agile-context-engineering/templates/wiki → skills/map-story/templates}/decizions.xml +115 -115
- package/skills/map-story/templates/guide.xml +137 -0
- package/skills/map-story/templates/pattern.xml +159 -0
- package/skills/map-story/templates/system-cross-cutting.xml +197 -0
- package/{agile-context-engineering/templates/wiki → skills/map-story/templates}/system.xml +381 -381
- package/{agile-context-engineering/templates/wiki → skills/map-story/templates}/tech-debt-index.xml +125 -125
- package/{agile-context-engineering/templates/wiki → skills/map-story/templates}/walkthrough.xml +255 -255
- package/{agile-context-engineering/workflows/map-story.xml → skills/map-story/workflow.xml} +1046 -1046
- package/{commands/ace/map-subsystem.md → skills/map-subsystem/SKILL.md} +155 -140
- package/skills/map-subsystem/script.js +51 -0
- package/skills/map-subsystem/script.test.js +68 -0
- package/skills/map-subsystem/templates/decizions.xml +115 -0
- package/skills/map-subsystem/templates/guide.xml +137 -0
- package/{agile-context-engineering/templates/wiki → skills/map-subsystem/templates}/module-discovery.xml +174 -174
- package/skills/map-subsystem/templates/pattern.xml +159 -0
- package/{agile-context-engineering/templates/wiki → skills/map-subsystem/templates}/subsystem-architecture.xml +343 -343
- package/{agile-context-engineering/templates/wiki → skills/map-subsystem/templates}/subsystem-structure.xml +234 -234
- package/skills/map-subsystem/templates/system-cross-cutting.xml +197 -0
- package/skills/map-subsystem/templates/system.xml +381 -0
- package/skills/map-subsystem/templates/walkthrough.xml +255 -0
- package/{agile-context-engineering/workflows/map-subsystem.xml → skills/map-subsystem/workflow.xml} +1173 -1178
- package/skills/map-sys-doc/SKILL.md +125 -0
- package/skills/map-sys-doc/system.xml +381 -0
- package/skills/map-sys-doc/workflow.xml +336 -0
- package/{commands/ace/map-system.md → skills/map-system/SKILL.md} +103 -92
- package/skills/map-system/script.js +75 -0
- package/skills/map-system/script.test.js +73 -0
- package/{agile-context-engineering/templates/wiki → skills/map-system/templates}/system-architecture.xml +254 -254
- package/{agile-context-engineering/templates/wiki → skills/map-system/templates}/system-structure.xml +177 -177
- package/{agile-context-engineering/templates/wiki → skills/map-system/templates}/testing-framework.xml +283 -283
- package/{agile-context-engineering/templates/wiki → skills/map-system/templates}/wiki-readme.xml +296 -296
- package/{agile-context-engineering/workflows/map-system.xml → skills/map-system/workflow.xml} +667 -672
- package/{commands/ace/map-walkthrough.md → skills/map-walkthrough/SKILL.md} +140 -127
- package/skills/map-walkthrough/walkthrough.xml +255 -0
- package/{agile-context-engineering/workflows/map-walkthrough.xml → skills/map-walkthrough/workflow.xml} +457 -457
- package/{commands/ace/plan-backlog.md → skills/plan-backlog/SKILL.md} +93 -83
- package/{agile-context-engineering/templates/product/product-backlog.xml → skills/plan-backlog/product-backlog-template.xml} +231 -231
- package/skills/plan-backlog/script.js +121 -0
- package/skills/plan-backlog/script.test.js +83 -0
- package/{agile-context-engineering/workflows/plan-backlog.xml → skills/plan-backlog/workflow.xml} +1348 -1356
- package/{commands/ace/plan-feature.md → skills/plan-feature/SKILL.md} +99 -89
- package/{agile-context-engineering/templates/product/feature.xml → skills/plan-feature/feature-template.xml} +361 -361
- package/skills/plan-feature/script.js +131 -0
- package/skills/plan-feature/script.test.js +80 -0
- package/{agile-context-engineering/workflows/plan-feature.xml → skills/plan-feature/workflow.xml} +1487 -1495
- package/{commands/ace/plan-product-vision.md → skills/plan-product-vision/SKILL.md} +91 -81
- package/{agile-context-engineering/templates/product/product-vision.xml → skills/plan-product-vision/product-vision-template.xml} +227 -227
- package/skills/plan-product-vision/script.js +51 -0
- package/skills/plan-product-vision/script.test.js +69 -0
- package/{agile-context-engineering/workflows/plan-product-vision.xml → skills/plan-product-vision/workflow.xml} +337 -342
- package/{commands/ace/plan-story.md → skills/plan-story/SKILL.md} +139 -159
- package/skills/plan-story/script.js +295 -0
- package/skills/plan-story/script.test.js +240 -0
- package/skills/plan-story/story-template.xml +458 -0
- package/{agile-context-engineering/workflows/plan-story.xml → skills/plan-story/workflow.xml} +1301 -944
- package/{commands/ace/research-external-solution.md → skills/research-external-solution/SKILL.md} +120 -138
- package/{agile-context-engineering/templates/product/external-solution.xml → skills/research-external-solution/external-solution-template.xml} +832 -832
- package/skills/research-external-solution/script.js +229 -0
- package/skills/research-external-solution/script.test.js +134 -0
- package/{agile-context-engineering/workflows/research-external-solution.xml → skills/research-external-solution/workflow.xml} +657 -659
- package/{commands/ace/research-integration-solution.md → skills/research-integration-solution/SKILL.md} +121 -135
- package/{agile-context-engineering/templates/product/story-integration-solution.xml → skills/research-integration-solution/integration-solution-template.xml} +1015 -1015
- package/skills/research-integration-solution/script.js +223 -0
- package/skills/research-integration-solution/script.test.js +134 -0
- package/{agile-context-engineering/workflows/research-integration-solution.xml → skills/research-integration-solution/workflow.xml} +711 -713
- package/{commands/ace/research-story-wiki.md → skills/research-story-wiki/SKILL.md} +101 -116
- package/skills/research-story-wiki/script.js +223 -0
- package/skills/research-story-wiki/script.test.js +138 -0
- package/{agile-context-engineering/templates/product/story-wiki.xml → skills/research-story-wiki/story-wiki-template.xml} +194 -194
- package/{agile-context-engineering/workflows/research-story-wiki.xml → skills/research-story-wiki/workflow.xml} +473 -475
- package/{commands/ace/research-technical-solution.md → skills/research-technical-solution/SKILL.md} +131 -147
- package/skills/research-technical-solution/script.js +223 -0
- package/skills/research-technical-solution/script.test.js +134 -0
- package/{agile-context-engineering/templates/product/story-technical-solution.xml → skills/research-technical-solution/technical-solution-template.xml} +1025 -1025
- package/{agile-context-engineering/workflows/research-technical-solution.xml → skills/research-technical-solution/workflow.xml} +761 -763
- package/{commands/ace/review-story.md → skills/review-story/SKILL.md} +99 -109
- package/skills/review-story/script.js +249 -0
- package/skills/review-story/script.test.js +169 -0
- package/skills/review-story/story-template.xml +451 -0
- package/{agile-context-engineering/workflows/review-story.xml → skills/review-story/workflow.xml} +279 -281
- package/{commands/ace/update.md → skills/update/SKILL.md} +65 -56
- package/{agile-context-engineering/workflows/update.xml → skills/update/workflow.xml} +33 -18
- package/agile-context-engineering/src/ace-tools.js +0 -2881
- package/agile-context-engineering/src/ace-tools.test.js +0 -1089
- package/agile-context-engineering/templates/_command.md +0 -54
- package/agile-context-engineering/templates/_workflow.xml +0 -17
- package/agile-context-engineering/templates/config.json +0 -0
- package/agile-context-engineering/templates/product/integration-solution.xml +0 -0
- package/commands/ace/help.md +0 -93
|
@@ -1,531 +1,531 @@
|
|
|
1
|
-
<coding-standards>
|
|
2
|
-
|
|
3
|
-
<purpose>
|
|
4
|
-
Template for `.docs/wiki/system-wide/coding-standards.md` — prescriptive rules that
|
|
5
|
-
ALL code in this project MUST follow. These are NOT descriptive conventions (observed patterns)
|
|
6
|
-
but MANDATED STANDARDS that prevent common AI and developer mistakes.
|
|
7
|
-
|
|
8
|
-
This template is paradigm-aware. It contains modular sections that the generating agent
|
|
9
|
-
assembles based on the project's detected language(s), paradigm(s), and user preferences.
|
|
10
|
-
|
|
11
|
-
Complements system-structure.md (which shows physical layout) and system-architecture.md
|
|
12
|
-
(which shows conceptual design). Coding standards tell you HOW to write code, not WHERE
|
|
13
|
-
it goes or WHY the architecture exists.
|
|
14
|
-
|
|
15
|
-
Output: `.docs/wiki/system-wide/coding-standards.md`
|
|
16
|
-
</purpose>
|
|
17
|
-
|
|
18
|
-
<!-- ═══════════════════════════════════════════════════════════════════════ -->
|
|
19
|
-
<!-- TEMPLATE SECTIONS -->
|
|
20
|
-
<!-- The generating agent assembles applicable sections into the output doc -->
|
|
21
|
-
<!-- ═══════════════════════════════════════════════════════════════════════ -->
|
|
22
|
-
|
|
23
|
-
<template>
|
|
24
|
-
|
|
25
|
-
<!-- ─────────────────────────────────────────────────────────────────── -->
|
|
26
|
-
<!-- UNIVERSAL — Always included regardless of language or paradigm -->
|
|
27
|
-
<!-- ─────────────────────────────────────────────────────────────────── -->
|
|
28
|
-
|
|
29
|
-
<universal-standards always-include="true">
|
|
30
|
-
# Coding Standards
|
|
31
|
-
|
|
32
|
-
## Mandatory Rules — Zero Tolerance
|
|
33
|
-
|
|
34
|
-
These rules apply to ALL code. No exceptions. No "just this once."
|
|
35
|
-
|
|
36
|
-
### No Dead Code
|
|
37
|
-
- **NEVER leave commented-out code** — Git has history. Delete it.
|
|
38
|
-
- **NEVER leave unused imports, variables, functions, or classes**
|
|
39
|
-
- **NEVER leave unreachable code paths**
|
|
40
|
-
- Dead code in a complex codebase misleads developers and AI agents into basing
|
|
41
|
-
new implementations on obsolete, unused code. It is actively harmful.
|
|
42
|
-
|
|
43
|
-
### No Hardcoded Values
|
|
44
|
-
- **NEVER hardcode** magic strings, color codes, URLs, config values, numeric
|
|
45
|
-
thresholds, or any value that could change or has semantic meaning
|
|
46
|
-
- ALL values come from: constants, configuration, environment, or parameters
|
|
47
|
-
- Reference: consult `system-structure.md` (`.docs/wiki/system-wide/system-structure.md`)
|
|
48
|
-
and `[subsystem]-structure.md` (`.docs/wiki/subsystems/[subsystem-name]/structure.md`)
|
|
49
|
-
for where constants should live in this project
|
|
50
|
-
|
|
51
|
-
### No Silent Failures
|
|
52
|
-
- **NEVER silently swallow errors** — When an operation fails, LET IT FAIL
|
|
53
|
-
- Do NOT catch exceptions and return fake/placeholder/garbage objects
|
|
54
|
-
- Do NOT hide errors by returning empty lists or default values
|
|
55
|
-
- Do NOT pretend an operation succeeded when it didn't
|
|
56
|
-
- Fail fast. Propagate up. Log with context if needed, then rethrow or return the error.
|
|
57
|
-
|
|
58
|
-
### No Unimplemented Code
|
|
59
|
-
- **NEVER leave empty TODO comments** — If it needs doing, do it now or create a tracked issue
|
|
60
|
-
- **NEVER leave stub implementations** — No `throw NotImplemented`, no `pass`, no `...`
|
|
61
|
-
- If code exists in the codebase, it must be complete and functional
|
|
62
|
-
|
|
63
|
-
### Defensive Programming — Zero Tolerance for Permissive Code
|
|
64
|
-
|
|
65
|
-
**WE USE DEFENSIVE PROGRAMMING + FAIL-FAST. PERMISSIVE PROGRAMMING IS BANNED.**
|
|
66
|
-
|
|
67
|
-
Permissive programming ("be liberal in what you accept") has caused catastrophic bugs.
|
|
68
|
-
It hides errors, delays failures, and makes debugging impossible. Every parameter must
|
|
69
|
-
be validated. Every error must be surfaced. No exceptions.
|
|
70
|
-
|
|
71
|
-
**MANDATORY — Do This:**
|
|
72
|
-
- **Validate EVERY input at the boundary** — check types, ranges, formats, required
|
|
73
|
-
fields BEFORE processing
|
|
74
|
-
- **Fail fast and loud** — if something is wrong, return an error immediately with a
|
|
75
|
-
clear message explaining WHAT is wrong and WHY
|
|
76
|
-
- **Read the function you're calling** — check its constructor/signature to know EXACTLY
|
|
77
|
-
what parameters it requires before writing the caller
|
|
78
|
-
- **Required means required** — if a function needs a value, the caller MUST provide it.
|
|
79
|
-
No nullable wrappers. No default fallbacks that mask missing data
|
|
80
|
-
- **Return errors, not defaults** — if a value is missing or invalid, return an error
|
|
81
|
-
string/throw, do NOT return `""`, `0`, `null`, `[]`, or any placeholder
|
|
82
|
-
- **Validate on BOTH client and server** — server validates before processing/pushing,
|
|
83
|
-
client validates as a redundant safety net. Both layers reject garbage
|
|
84
|
-
- **Surface errors visibly** — errors must reach whoever can fix them (the LLM, the user,
|
|
85
|
-
the developer). Log them, display them, return them. Never swallow them
|
|
86
|
-
|
|
87
|
-
**ABSOLUTELY FORBIDDEN — Never Do This:**
|
|
88
|
-
- `string? param = null` when the value is actually required — use `string param` and validate
|
|
89
|
-
- `return ""` or `return null` or `return []` when an operation fails — return an error with context
|
|
90
|
-
- `.optional()` or `.nullable()` on schema fields that the consuming function REQUIRES
|
|
91
|
-
- Fallback defaults that hide missing data (e.g., `value ?? defaultValue` to mask a null
|
|
92
|
-
that should never be null)
|
|
93
|
-
- `try/catch` that swallows exceptions and returns empty objects
|
|
94
|
-
- Silently stripping, transforming, or cleaning invalid data to make it pass validation
|
|
95
|
-
- Writing a caller without reading the callee's actual parameter signature first
|
|
96
|
-
- Using Postel's Law ("be liberal in what you accept") as justification for accepting garbage
|
|
97
|
-
|
|
98
|
-
**The Principle:**
|
|
99
|
-
**Garbage in → ERROR out. Never garbage in → silence.**
|
|
100
|
-
|
|
101
|
-
### No Assumptions
|
|
102
|
-
- **Use LSPs first when available** — Check diagnostics, go-to-definition, and find-references before guessing. The LSP knows the codebase better than a text search.
|
|
103
|
-
- **NEVER assume** libraries, classes, models, methods, or APIs exist
|
|
104
|
-
- **ALWAYS verify by reading the codebase** before building on something
|
|
105
|
-
- **ALWAYS search for existing implementations** before writing new code
|
|
106
|
-
- If similar code exists, refactor it to support the new requirement instead of duplicating
|
|
107
|
-
|
|
108
|
-
### No Code Duplication
|
|
109
|
-
- Before writing new code, search for existing implementations
|
|
110
|
-
- If you find code that does 80% of what you need, refactor it — don't duplicate it
|
|
111
|
-
- Duplication is a maintainability debt that compounds with every copy
|
|
112
|
-
|
|
113
|
-
## File Organization
|
|
114
|
-
|
|
115
|
-
- **One primary [construct] per file** — One class, one module, one component.
|
|
116
|
-
Do not declare multiple classes, interfaces, or significant types in a single file.
|
|
117
|
-
[Construct name adapts: "class" for OOP, "module export" for FP, "component" for React,
|
|
118
|
-
"struct + impl" for Rust, "type + functions" for Go]
|
|
119
|
-
|
|
120
|
-
- **Maximum file length: [N] lines** — If a file approaches this limit, it has too many
|
|
121
|
-
responsibilities. Refactor by extracting. If you're following single responsibility,
|
|
122
|
-
you should rarely get close to this limit.
|
|
123
|
-
|
|
124
|
-
## Engineering Principles
|
|
125
|
-
|
|
126
|
-
- **DRY (Don't Repeat Yourself)** — Every piece of knowledge must have a single,
|
|
127
|
-
unambiguous, authoritative representation within the system. If you change one thing
|
|
128
|
-
and have to change it in multiple places, the design is wrong. Extract shared logic.
|
|
129
|
-
|
|
130
|
-
- **KISS (Keep It Simple, Stupid)** — The simplest solution that works is the best
|
|
131
|
-
solution. Avoid over-engineering, excessive abstractions, and clever tricks.
|
|
132
|
-
Code is read far more often than it is written — optimize for clarity.
|
|
133
|
-
|
|
134
|
-
- **YAGNI (You Aren't Gonna Need It)** — Do NOT implement functionality until it is
|
|
135
|
-
actually needed. Do not design for hypothetical future requirements. Do not add
|
|
136
|
-
configuration points, extension hooks, or abstractions "just in case."
|
|
137
|
-
|
|
138
|
-
- **Separation of Concerns** — Each unit of code (function, class, module) should
|
|
139
|
-
address one concern. Mixing concerns creates code that is hard to test, hard to
|
|
140
|
-
change, and hard to understand.
|
|
141
|
-
|
|
142
|
-
- **Principle of Least Surprise** — Code should behave as other developers would
|
|
143
|
-
expect. Method names should describe what they do. Side effects should be obvious.
|
|
144
|
-
Conventions should be consistent across the codebase.
|
|
145
|
-
|
|
146
|
-
- **Fail Fast** — Detect and report errors as early as possible. Validate inputs
|
|
147
|
-
at boundaries. Assert invariants. The further an error propagates from its source,
|
|
148
|
-
the harder it is to diagnose.
|
|
149
|
-
|
|
150
|
-
## Code Quality Mindset
|
|
151
|
-
|
|
152
|
-
- **Think like an architect operating within a complex codebase** — Every coding
|
|
153
|
-
decision must consider: will this be easy to extend? Can another developer understand it?
|
|
154
|
-
Does it follow existing patterns?
|
|
155
|
-
|
|
156
|
-
- **No hacks, no shortcuts** — Especially when fixing bugs. The pressure to
|
|
157
|
-
"just make it work" is strongest during bug fixes. Resist. Fix it properly.
|
|
158
|
-
|
|
159
|
-
- **No over-engineering** — Don't add features, abstractions, or configurability
|
|
160
|
-
beyond what's needed. Three similar lines of code is better than a premature abstraction.
|
|
161
|
-
The right amount of complexity is the minimum needed for the current task.
|
|
162
|
-
|
|
163
|
-
- **All code must be testable** — Structure code so it can be tested in isolation.
|
|
164
|
-
[Paradigm-specific testability guidance goes in the paradigm section]
|
|
165
|
-
</universal-standards>
|
|
166
|
-
|
|
167
|
-
<!-- ─────────────────────────────────────────────────────────────────── -->
|
|
168
|
-
<!-- OOP MODULE — Include when project uses object-oriented paradigm -->
|
|
169
|
-
<!-- ─────────────────────────────────────────────────────────────────── -->
|
|
170
|
-
|
|
171
|
-
<paradigm-oop include-when="Project uses OOP as primary or significant paradigm (C#, Java, TypeScript with classes, Python with classes, Kotlin, Swift, Dart, Ruby, PHP)">
|
|
172
|
-
## Object-Oriented Programming Standards
|
|
173
|
-
|
|
174
|
-
### SOLID Principles — Non-Negotiable
|
|
175
|
-
|
|
176
|
-
- **Single Responsibility Principle** — Each class has ONE reason to change.
|
|
177
|
-
If you can describe a class purpose with "and", it does too much. Split it.
|
|
178
|
-
|
|
179
|
-
- **Open/Closed Principle** — Open for extension, closed for modification.
|
|
180
|
-
Use abstractions and composition to add behavior without changing existing code.
|
|
181
|
-
|
|
182
|
-
- **Liskov Substitution Principle** — Derived classes must be fully substitutable
|
|
183
|
-
for their base classes. No surprises, no broken contracts.
|
|
184
|
-
|
|
185
|
-
- **Interface Segregation Principle** — No client should depend on interfaces it
|
|
186
|
-
doesn't use. Prefer many small, focused interfaces over few large ones.
|
|
187
|
-
|
|
188
|
-
- **Dependency Inversion Principle** — Depend on abstractions, not concretions.
|
|
189
|
-
High-level modules must not depend on low-level modules.
|
|
190
|
-
|
|
191
|
-
### Code Against Abstractions
|
|
192
|
-
|
|
193
|
-
- **ALWAYS code against interfaces** — Every service, repository, and significant
|
|
194
|
-
collaborator must have an interface. This enables testing, swapping implementations,
|
|
195
|
-
and respecting DIP.
|
|
196
|
-
|
|
197
|
-
- **Dependency injection for ALL services** — No instantiating dependencies directly
|
|
198
|
-
inside other services. Wire dependencies through constructors. Register in the
|
|
199
|
-
DI container.
|
|
200
|
-
Reference: consult `system-structure.md` (`.docs/wiki/system-wide/system-structure.md`)
|
|
201
|
-
and `[subsystem]-structure.md` (`.docs/wiki/subsystems/[subsystem-name]/structure.md`)
|
|
202
|
-
for where DI configuration lives in this project
|
|
203
|
-
|
|
204
|
-
### OOP Best Practices
|
|
205
|
-
|
|
206
|
-
- **Composition over inheritance** — Prefer composing behaviors via injected
|
|
207
|
-
collaborators over deep inheritance hierarchies. Inheritance creates tight coupling.
|
|
208
|
-
|
|
209
|
-
- **Encapsulation** — Keep internal state private. Expose behavior through methods,
|
|
210
|
-
not raw data through public fields and getters.
|
|
211
|
-
|
|
212
|
-
- **Polymorphism over conditionals** — When you see `if/switch` checking a type
|
|
213
|
-
discriminator, consider whether polymorphism is the proper solution.
|
|
214
|
-
|
|
215
|
-
- **Small, focused classes** — A class should be easily describable in one sentence.
|
|
216
|
-
If the description needs "and", extract a collaborator.
|
|
217
|
-
|
|
218
|
-
### Design Patterns — Use Where They Fit
|
|
219
|
-
|
|
220
|
-
Apply proven patterns to solve recurring design problems. Do NOT force patterns
|
|
221
|
-
where a simpler solution exists — a pattern used without justification is an anti-pattern.
|
|
222
|
-
|
|
223
|
-
- **Strategy** — Encapsulate interchangeable algorithms behind an interface. Use when
|
|
224
|
-
behavior varies by context and you want to swap implementations without modifying callers.
|
|
225
|
-
|
|
226
|
-
- **Repository** — Mediate between domain and data mapping layers using a collection-like
|
|
227
|
-
interface. Keeps domain logic ignorant of persistence details.
|
|
228
|
-
|
|
229
|
-
- **Factory / Abstract Factory** — Encapsulate object creation when construction is
|
|
230
|
-
complex or the concrete type depends on runtime conditions. Avoid when a simple
|
|
231
|
-
constructor call is sufficient.
|
|
232
|
-
|
|
233
|
-
- **Observer / Event** — Decouple producers from consumers when one action must trigger
|
|
234
|
-
multiple reactions. Use for cross-cutting concerns like logging, notifications, or
|
|
235
|
-
cache invalidation.
|
|
236
|
-
|
|
237
|
-
- **Decorator** — Add behavior to objects dynamically without modifying their class.
|
|
238
|
-
Prefer over inheritance when combining behaviors in varying combinations.
|
|
239
|
-
|
|
240
|
-
- **Adapter** — Convert one interface to another so incompatible classes can work together.
|
|
241
|
-
Use at system boundaries to integrate external libraries or legacy code.
|
|
242
|
-
|
|
243
|
-
- **Command** — Encapsulate a request as an object, enabling undo, queuing, logging,
|
|
244
|
-
or deferred execution. Use when operations need to be treated as first-class objects.
|
|
245
|
-
|
|
246
|
-
- **Template Method** — Define the skeleton of an algorithm in a base class, letting
|
|
247
|
-
subclasses override specific steps. Use sparingly — composition is often better.
|
|
248
|
-
|
|
249
|
-
**WARNING:** Do NOT use patterns preemptively. A pattern is justified ONLY when the
|
|
250
|
-
problem it solves actually exists in your code. "We might need it later" is not
|
|
251
|
-
justification — that violates YAGNI.
|
|
252
|
-
|
|
253
|
-
### OOP Anti-Patterns — Never Do These
|
|
254
|
-
|
|
255
|
-
- **God Class** — A class that knows too much and does too much. If a class name
|
|
256
|
-
contains "Manager", "Handler", "Processor", or "Service" and it's over 300 lines,
|
|
257
|
-
it's probably a God Class. Split it by responsibility.
|
|
258
|
-
|
|
259
|
-
- **Anemic Domain Model** — Domain objects reduced to mere data containers (getters
|
|
260
|
-
and setters only) with all logic in separate "service" classes. This is procedural
|
|
261
|
-
programming disguised as OOP. Put behavior where the data is.
|
|
262
|
-
|
|
263
|
-
- **Feature Envy** — A method that uses more data from another class than its own.
|
|
264
|
-
This means the method belongs in the other class. Move it.
|
|
265
|
-
|
|
266
|
-
- **Tight Coupling** — Classes directly instantiating or depending on concrete
|
|
267
|
-
implementations instead of abstractions. Makes testing impossible and changes ripple
|
|
268
|
-
across the codebase. Code against interfaces.
|
|
269
|
-
|
|
270
|
-
- **Poltergeist / Useless Classes** — Classes with no real responsibility that merely
|
|
271
|
-
delegate to other classes or add unnecessary abstraction layers. Every class must
|
|
272
|
-
justify its existence with real behavior.
|
|
273
|
-
|
|
274
|
-
- **Singleton Abuse** — Using Singleton as a convenient global variable. Singletons
|
|
275
|
-
hide dependencies, prevent testing, create concurrency issues, and violate DIP.
|
|
276
|
-
Use dependency injection instead.
|
|
277
|
-
|
|
278
|
-
- **Premature Abstraction** — Creating interfaces, base classes, or generic frameworks
|
|
279
|
-
before having two concrete use cases. Wait until duplication emerges, then abstract.
|
|
280
|
-
Wrong abstractions are worse than duplication.
|
|
281
|
-
</paradigm-oop>
|
|
282
|
-
|
|
283
|
-
<!-- ─────────────────────────────────────────────────────────────────── -->
|
|
284
|
-
<!-- FUNCTIONAL MODULE — Include when project uses functional paradigm -->
|
|
285
|
-
<!-- ─────────────────────────────────────────────────────────────────── -->
|
|
286
|
-
|
|
287
|
-
<paradigm-functional include-when="Project uses FP as primary or significant paradigm (Elixir, Haskell, Clojure, F#, Elm, OCaml, or FP style in TypeScript/JavaScript/Python/Kotlin/Scala)">
|
|
288
|
-
## Functional Programming Standards
|
|
289
|
-
|
|
290
|
-
### Core Principles
|
|
291
|
-
|
|
292
|
-
- **Pure functions by default** — Functions should be deterministic: same input →
|
|
293
|
-
same output, no side effects. Isolate side effects at the boundaries
|
|
294
|
-
(IO, database, API calls, user interaction).
|
|
295
|
-
|
|
296
|
-
- **Immutability by default** — Do not mutate data. Create new values from old ones.
|
|
297
|
-
Mutable state is opt-in and must be justified with a comment explaining why.
|
|
298
|
-
|
|
299
|
-
- **Function composition over imperative flow** — Build complex behavior by composing
|
|
300
|
-
small, focused functions. Prefer pipelines and transformations over step-by-step
|
|
301
|
-
mutation.
|
|
302
|
-
|
|
303
|
-
### Data Modeling
|
|
304
|
-
|
|
305
|
-
- **Make illegal states unrepresentable** — Use discriminated unions / sum types /
|
|
306
|
-
algebraic data types to model domain states. The type system should prevent
|
|
307
|
-
invalid state combinations at compile time.
|
|
308
|
-
|
|
309
|
-
- **Pattern matching over conditionals** — Use pattern matching to destructure data
|
|
310
|
-
and handle variants. It's exhaustive, self-documenting, and catches missing cases.
|
|
311
|
-
|
|
312
|
-
- **Data transformation pipelines** — Prefer `map`, `filter`, `reduce`, pipe operators,
|
|
313
|
-
or function composition over loops with mutable accumulators.
|
|
314
|
-
|
|
315
|
-
### Error Handling
|
|
316
|
-
|
|
317
|
-
- **Result/Either types for expected failures** — Reserve exceptions for truly
|
|
318
|
-
exceptional, unrecoverable conditions. Expected failures (validation, not-found,
|
|
319
|
-
conflict) should be expressed in the return type.
|
|
320
|
-
|
|
321
|
-
- **Railway-oriented error handling** — Chain operations that can fail without nested
|
|
322
|
-
try/catch. Let the error path carry failures through the pipeline.
|
|
323
|
-
|
|
324
|
-
### Module Design
|
|
325
|
-
|
|
326
|
-
- **Modules as namespaces with clear purpose** — Group related functions into modules.
|
|
327
|
-
Each module has a single, focused responsibility.
|
|
328
|
-
|
|
329
|
-
- **Explicit dependencies** — Functions receive dependencies as parameters.
|
|
330
|
-
No hidden global state, no module-level singletons with side effects.
|
|
331
|
-
|
|
332
|
-
- **Public API at module boundary** — Export only what consumers need.
|
|
333
|
-
Keep internal helpers private.
|
|
334
|
-
</paradigm-functional>
|
|
335
|
-
|
|
336
|
-
<!-- ─────────────────────────────────────────────────────────────────── -->
|
|
337
|
-
<!-- SYSTEMS MODULE — Include for Rust, Go, C, C++ -->
|
|
338
|
-
<!-- ─────────────────────────────────────────────────────────────────── -->
|
|
339
|
-
|
|
340
|
-
<paradigm-systems include-when="Project uses systems languages (Rust, Go, C, C++)">
|
|
341
|
-
## Systems Programming Standards
|
|
342
|
-
|
|
343
|
-
### Rust (include if Rust project)
|
|
344
|
-
|
|
345
|
-
- **Respect the borrow checker** — Do not fight it with unnecessary `clone()` or
|
|
346
|
-
`Rc<RefCell<>>`. If the borrow checker complains, rethink your data flow.
|
|
347
|
-
|
|
348
|
-
- **`Result<T, E>` for all fallible operations** — Use the `?` operator for
|
|
349
|
-
propagation. Reserve `panic!` for unrecoverable invariant violations only.
|
|
350
|
-
|
|
351
|
-
- **No unnecessary `unwrap()`** — Every `unwrap()` is a potential panic. Use `?`,
|
|
352
|
-
`unwrap_or`, `unwrap_or_else`, `map`, or proper match/if-let handling.
|
|
353
|
-
|
|
354
|
-
- **Traits for polymorphism** — Use traits to define behavior contracts. Use
|
|
355
|
-
`dyn Trait` for dynamic dispatch only when static dispatch won't work.
|
|
356
|
-
|
|
357
|
-
- **Derive what you can** — Use `#[derive(...)]` for standard traits. Implement
|
|
358
|
-
manually only when custom behavior is needed.
|
|
359
|
-
|
|
360
|
-
### Go (include if Go project)
|
|
361
|
-
|
|
362
|
-
- **Accept interfaces, return structs** — Function parameters should use interfaces
|
|
363
|
-
for flexibility. Return concrete types for clarity.
|
|
364
|
-
|
|
365
|
-
- **Check every error** — Never ignore `err` returns. Use `fmt.Errorf("context: %w", err)`
|
|
366
|
-
for wrapping. Use sentinel errors or custom types for typed error handling.
|
|
367
|
-
|
|
368
|
-
- **Package-level organization** — Each package has a clear, focused purpose.
|
|
369
|
-
Avoid mega-packages. Package name should describe what it provides, not what it contains.
|
|
370
|
-
|
|
371
|
-
- **No unnecessary interfaces** — Define interfaces where they're consumed, not where
|
|
372
|
-
they're implemented. Don't create interfaces for single implementations.
|
|
373
|
-
|
|
374
|
-
- **Short names for small scopes** — `i`, `ctx`, `err`, `db` for local variables.
|
|
375
|
-
Longer, descriptive names for package-level and exported identifiers.
|
|
376
|
-
|
|
377
|
-
### C/C++ (include if C/C++ project)
|
|
378
|
-
|
|
379
|
-
- **RAII in C++** — Acquire resources in constructors, release in destructors.
|
|
380
|
-
Use smart pointers (`unique_ptr`, `shared_ptr`) instead of raw `new/delete`.
|
|
381
|
-
|
|
382
|
-
- **Bounds checking** — Validate array indices and buffer sizes. Use safe alternatives
|
|
383
|
-
(`std::array`, `std::vector`, `std::string`) over raw C arrays and `char*`.
|
|
384
|
-
|
|
385
|
-
- **No raw `new/delete` in C++** — Use smart pointers and containers.
|
|
386
|
-
Manual memory management is a bug waiting to happen.
|
|
387
|
-
</paradigm-systems>
|
|
388
|
-
|
|
389
|
-
<!-- ─────────────────────────────────────────────────────────────────── -->
|
|
390
|
-
<!-- LANGUAGE-SPECIFIC CONVENTIONS — Generated from codebase detection -->
|
|
391
|
-
<!-- ─────────────────────────────────────────────────────────────────── -->
|
|
392
|
-
|
|
393
|
-
<language-conventions generate-from="codebase detection or user input">
|
|
394
|
-
## Language and Framework Conventions
|
|
395
|
-
|
|
396
|
-
[Generate this section from detected language, frameworks, and existing configs.
|
|
397
|
-
Check .prettierrc, .eslintrc, ruff.toml, .editorconfig, etc. for existing rules.
|
|
398
|
-
Examine 5-10 representative source files for naming patterns.]
|
|
399
|
-
|
|
400
|
-
### Naming Conventions
|
|
401
|
-
[Document project's actual naming patterns. Be prescriptive:
|
|
402
|
-
- File naming: kebab-case.ts, PascalCase.cs, snake_case.py, etc.
|
|
403
|
-
- Functions/methods: camelCase, snake_case, PascalCase depending on language
|
|
404
|
-
- Variables: language convention
|
|
405
|
-
- Constants: UPPER_SNAKE_CASE universally
|
|
406
|
-
- Types/interfaces: PascalCase universally, with/without prefix based on project]
|
|
407
|
-
|
|
408
|
-
### Import / Dependency Organization
|
|
409
|
-
[Document the project's import ordering and grouping.
|
|
410
|
-
Check for linter rules enforcing import order.]
|
|
411
|
-
|
|
412
|
-
### Framework-Specific Rules
|
|
413
|
-
[Only include if project uses a framework with its own patterns:
|
|
414
|
-
- React: hooks rules, component patterns, state management approach
|
|
415
|
-
- Angular: module structure, service patterns, change detection
|
|
416
|
-
- ASP.NET: controller patterns, middleware, model binding
|
|
417
|
-
- Django: app structure, view patterns, ORM usage
|
|
418
|
-
- Spring: bean patterns, annotation usage
|
|
419
|
-
Generate based on what's actually detected, not a generic list.]
|
|
420
|
-
</language-conventions>
|
|
421
|
-
|
|
422
|
-
<!-- ─────────────────────────────────────────────────────────────────── -->
|
|
423
|
-
<!-- PROJECT-SPECIFIC RULES — From user interview -->
|
|
424
|
-
<!-- ─────────────────────────────────────────────────────────────────── -->
|
|
425
|
-
|
|
426
|
-
<project-specific-rules generate-from="user interview">
|
|
427
|
-
## Project-Specific Rules
|
|
428
|
-
|
|
429
|
-
[Rules from the user interview that don't fit neatly in other sections.
|
|
430
|
-
These capture the team's hard-won lessons and specific pain points.
|
|
431
|
-
|
|
432
|
-
This is often the MOST VALUABLE section because it's unique to this project.
|
|
433
|
-
Write these with the same emphatic, direct tone as the universal rules.
|
|
434
|
-
|
|
435
|
-
Examples of what might go here:
|
|
436
|
-
- "If a method has LESS than 7 parameters, keep them on ONE line"
|
|
437
|
-
- "All API responses must use the shared ApiResponse wrapper"
|
|
438
|
-
- "Never use library X for Y — use Z instead"
|
|
439
|
-
- "All database queries must go through the repository pattern"
|
|
440
|
-
- Specific patterns, conventions, or constraints unique to this project]
|
|
441
|
-
</project-specific-rules>
|
|
442
|
-
|
|
443
|
-
</template>
|
|
444
|
-
|
|
445
|
-
<guidelines>
|
|
446
|
-
|
|
447
|
-
**Assembly rules for the generating agent:**
|
|
448
|
-
|
|
449
|
-
1. **ALWAYS include universal-standards** — These apply to every project regardless
|
|
450
|
-
of language or paradigm. Adapt the [bracketed placeholders] to the detected language.
|
|
451
|
-
|
|
452
|
-
2. **Include paradigm modules based on detection AND user preference:**
|
|
453
|
-
- Project uses OOP → include paradigm-oop
|
|
454
|
-
- Project uses FP → include paradigm-functional
|
|
455
|
-
- Project uses systems language → include paradigm-systems
|
|
456
|
-
- Project uses multi-paradigm → include whichever modules the user prefers
|
|
457
|
-
- User explicitly declines a paradigm → respect that, do not include it
|
|
458
|
-
|
|
459
|
-
3. **Generate language-conventions from codebase analysis** — Read actual config files,
|
|
460
|
-
examine source files, document what's in use. Be prescriptive, not descriptive.
|
|
461
|
-
|
|
462
|
-
4. **Include project-specific-rules from interview** — Capture the user's pain points
|
|
463
|
-
and custom rules. These are the most unique and valuable part of the document.
|
|
464
|
-
|
|
465
|
-
5. **Tone: DIRECT and EMPHATIC** — Use bold for emphasis, caps for critical words.
|
|
466
|
-
This is not a suggestion document — it's a mandate. AI agents (especially Claude)
|
|
467
|
-
respect authoritative, unambiguous instructions more than polite suggestions.
|
|
468
|
-
Match the tone of the universal-standards section.
|
|
469
|
-
|
|
470
|
-
6. **Length: 150-350 lines** — Enough to be comprehensive, short enough to be loaded
|
|
471
|
-
as context without waste. Universal (~60 lines) + one paradigm module (~40 lines) +
|
|
472
|
-
language conventions (~40 lines) + project-specific (~30 lines) = ~170 lines typical.
|
|
473
|
-
Two paradigm modules or extensive project rules may push to ~300.
|
|
474
|
-
|
|
475
|
-
7. **Be prescriptive** — "NEVER do X" not "We typically avoid X". "ALWAYS do Y" not
|
|
476
|
-
"It's recommended to do Y". Standards are mandates, not suggestions.
|
|
477
|
-
|
|
478
|
-
8. **Include rationale for non-obvious rules** — "No dead code" needs a why
|
|
479
|
-
(misleads AI and developers into building on obsolete code). "Use camelCase" doesn't
|
|
480
|
-
need a why (it's a convention, not a principle).
|
|
481
|
-
|
|
482
|
-
9. **Use concrete examples for ambiguous rules** — When a rule could be misinterpreted,
|
|
483
|
-
show a brief good/bad example inline.
|
|
484
|
-
|
|
485
|
-
10. **Cross-reference project structure** — Reference actual file paths for constants
|
|
486
|
-
directories, DI configuration, shared utilities, etc. Use backtick formatting for paths.
|
|
487
|
-
|
|
488
|
-
**What does NOT belong in coding-standards.md:**
|
|
489
|
-
- File/directory structure (that's system-structure.md / subsystem-structure.md)
|
|
490
|
-
- Architecture decisions and patterns (that's system-architecture.md)
|
|
491
|
-
- Technology stack choices (that's system-architecture.md tech-stack section)
|
|
492
|
-
- Test framework setup and patterns (that's a separate testing doc)
|
|
493
|
-
- Deployment, CI/CD, or infrastructure concerns
|
|
494
|
-
|
|
495
|
-
**What DOES belong:**
|
|
496
|
-
- Rules about HOW to write code (quality, style, patterns)
|
|
497
|
-
- Rules about code organization WITHIN files (not directory layout)
|
|
498
|
-
- Rules about naming, formatting, error handling, testability
|
|
499
|
-
- Rules about paradigm adherence (SOLID, FP principles, systems idioms)
|
|
500
|
-
- Rules that prevent known AI mistakes (the highest-value rules)
|
|
501
|
-
- Rules that maintain codebase integrity at scale
|
|
502
|
-
|
|
503
|
-
</guidelines>
|
|
504
|
-
|
|
505
|
-
<evolution>
|
|
506
|
-
|
|
507
|
-
This document evolves when coding standards change — not with every feature or fix.
|
|
508
|
-
|
|
509
|
-
**Update triggers:**
|
|
510
|
-
- New language or paradigm added to the project
|
|
511
|
-
- New framework that introduces its own coding patterns
|
|
512
|
-
- Team discovers a recurring mistake → add a rule to prevent it
|
|
513
|
-
- Existing rule proven too strict or too loose → adjust it
|
|
514
|
-
- Architecture shift that changes how code should be written
|
|
515
|
-
- Onboarding feedback reveals ambiguous or missing rules
|
|
516
|
-
|
|
517
|
-
**NOT an update trigger:**
|
|
518
|
-
- New features (should follow existing standards)
|
|
519
|
-
- Bug fixes (should already follow standards)
|
|
520
|
-
- Dependency updates (unless they fundamentally change coding patterns)
|
|
521
|
-
- New files or directories (that's structure docs)
|
|
522
|
-
|
|
523
|
-
**After update:**
|
|
524
|
-
1. Review all paradigm modules — still accurate?
|
|
525
|
-
2. Review project-specific rules — any new pain points to capture?
|
|
526
|
-
3. Check line count — still under 350 lines?
|
|
527
|
-
4. Verify cross-references to file paths are still valid
|
|
528
|
-
|
|
529
|
-
</evolution>
|
|
530
|
-
|
|
531
|
-
</coding-standards>
|
|
1
|
+
<coding-standards>
|
|
2
|
+
|
|
3
|
+
<purpose>
|
|
4
|
+
Template for `.docs/wiki/system-wide/coding-standards.md` — prescriptive rules that
|
|
5
|
+
ALL code in this project MUST follow. These are NOT descriptive conventions (observed patterns)
|
|
6
|
+
but MANDATED STANDARDS that prevent common AI and developer mistakes.
|
|
7
|
+
|
|
8
|
+
This template is paradigm-aware. It contains modular sections that the generating agent
|
|
9
|
+
assembles based on the project's detected language(s), paradigm(s), and user preferences.
|
|
10
|
+
|
|
11
|
+
Complements system-structure.md (which shows physical layout) and system-architecture.md
|
|
12
|
+
(which shows conceptual design). Coding standards tell you HOW to write code, not WHERE
|
|
13
|
+
it goes or WHY the architecture exists.
|
|
14
|
+
|
|
15
|
+
Output: `.docs/wiki/system-wide/coding-standards.md`
|
|
16
|
+
</purpose>
|
|
17
|
+
|
|
18
|
+
<!-- ═══════════════════════════════════════════════════════════════════════ -->
|
|
19
|
+
<!-- TEMPLATE SECTIONS -->
|
|
20
|
+
<!-- The generating agent assembles applicable sections into the output doc -->
|
|
21
|
+
<!-- ═══════════════════════════════════════════════════════════════════════ -->
|
|
22
|
+
|
|
23
|
+
<template>
|
|
24
|
+
|
|
25
|
+
<!-- ─────────────────────────────────────────────────────────────────── -->
|
|
26
|
+
<!-- UNIVERSAL — Always included regardless of language or paradigm -->
|
|
27
|
+
<!-- ─────────────────────────────────────────────────────────────────── -->
|
|
28
|
+
|
|
29
|
+
<universal-standards always-include="true">
|
|
30
|
+
# Coding Standards
|
|
31
|
+
|
|
32
|
+
## Mandatory Rules — Zero Tolerance
|
|
33
|
+
|
|
34
|
+
These rules apply to ALL code. No exceptions. No "just this once."
|
|
35
|
+
|
|
36
|
+
### No Dead Code
|
|
37
|
+
- **NEVER leave commented-out code** — Git has history. Delete it.
|
|
38
|
+
- **NEVER leave unused imports, variables, functions, or classes**
|
|
39
|
+
- **NEVER leave unreachable code paths**
|
|
40
|
+
- Dead code in a complex codebase misleads developers and AI agents into basing
|
|
41
|
+
new implementations on obsolete, unused code. It is actively harmful.
|
|
42
|
+
|
|
43
|
+
### No Hardcoded Values
|
|
44
|
+
- **NEVER hardcode** magic strings, color codes, URLs, config values, numeric
|
|
45
|
+
thresholds, or any value that could change or has semantic meaning
|
|
46
|
+
- ALL values come from: constants, configuration, environment, or parameters
|
|
47
|
+
- Reference: consult `system-structure.md` (`.docs/wiki/system-wide/system-structure.md`)
|
|
48
|
+
and `[subsystem]-structure.md` (`.docs/wiki/subsystems/[subsystem-name]/structure.md`)
|
|
49
|
+
for where constants should live in this project
|
|
50
|
+
|
|
51
|
+
### No Silent Failures
|
|
52
|
+
- **NEVER silently swallow errors** — When an operation fails, LET IT FAIL
|
|
53
|
+
- Do NOT catch exceptions and return fake/placeholder/garbage objects
|
|
54
|
+
- Do NOT hide errors by returning empty lists or default values
|
|
55
|
+
- Do NOT pretend an operation succeeded when it didn't
|
|
56
|
+
- Fail fast. Propagate up. Log with context if needed, then rethrow or return the error.
|
|
57
|
+
|
|
58
|
+
### No Unimplemented Code
|
|
59
|
+
- **NEVER leave empty TODO comments** — If it needs doing, do it now or create a tracked issue
|
|
60
|
+
- **NEVER leave stub implementations** — No `throw NotImplemented`, no `pass`, no `...`
|
|
61
|
+
- If code exists in the codebase, it must be complete and functional
|
|
62
|
+
|
|
63
|
+
### Defensive Programming — Zero Tolerance for Permissive Code
|
|
64
|
+
|
|
65
|
+
**WE USE DEFENSIVE PROGRAMMING + FAIL-FAST. PERMISSIVE PROGRAMMING IS BANNED.**
|
|
66
|
+
|
|
67
|
+
Permissive programming ("be liberal in what you accept") has caused catastrophic bugs.
|
|
68
|
+
It hides errors, delays failures, and makes debugging impossible. Every parameter must
|
|
69
|
+
be validated. Every error must be surfaced. No exceptions.
|
|
70
|
+
|
|
71
|
+
**MANDATORY — Do This:**
|
|
72
|
+
- **Validate EVERY input at the boundary** — check types, ranges, formats, required
|
|
73
|
+
fields BEFORE processing
|
|
74
|
+
- **Fail fast and loud** — if something is wrong, return an error immediately with a
|
|
75
|
+
clear message explaining WHAT is wrong and WHY
|
|
76
|
+
- **Read the function you're calling** — check its constructor/signature to know EXACTLY
|
|
77
|
+
what parameters it requires before writing the caller
|
|
78
|
+
- **Required means required** — if a function needs a value, the caller MUST provide it.
|
|
79
|
+
No nullable wrappers. No default fallbacks that mask missing data
|
|
80
|
+
- **Return errors, not defaults** — if a value is missing or invalid, return an error
|
|
81
|
+
string/throw, do NOT return `""`, `0`, `null`, `[]`, or any placeholder
|
|
82
|
+
- **Validate on BOTH client and server** — server validates before processing/pushing,
|
|
83
|
+
client validates as a redundant safety net. Both layers reject garbage
|
|
84
|
+
- **Surface errors visibly** — errors must reach whoever can fix them (the LLM, the user,
|
|
85
|
+
the developer). Log them, display them, return them. Never swallow them
|
|
86
|
+
|
|
87
|
+
**ABSOLUTELY FORBIDDEN — Never Do This:**
|
|
88
|
+
- `string? param = null` when the value is actually required — use `string param` and validate
|
|
89
|
+
- `return ""` or `return null` or `return []` when an operation fails — return an error with context
|
|
90
|
+
- `.optional()` or `.nullable()` on schema fields that the consuming function REQUIRES
|
|
91
|
+
- Fallback defaults that hide missing data (e.g., `value ?? defaultValue` to mask a null
|
|
92
|
+
that should never be null)
|
|
93
|
+
- `try/catch` that swallows exceptions and returns empty objects
|
|
94
|
+
- Silently stripping, transforming, or cleaning invalid data to make it pass validation
|
|
95
|
+
- Writing a caller without reading the callee's actual parameter signature first
|
|
96
|
+
- Using Postel's Law ("be liberal in what you accept") as justification for accepting garbage
|
|
97
|
+
|
|
98
|
+
**The Principle:**
|
|
99
|
+
**Garbage in → ERROR out. Never garbage in → silence.**
|
|
100
|
+
|
|
101
|
+
### No Assumptions
|
|
102
|
+
- **Use LSPs first when available** — Check diagnostics, go-to-definition, and find-references before guessing. The LSP knows the codebase better than a text search.
|
|
103
|
+
- **NEVER assume** libraries, classes, models, methods, or APIs exist
|
|
104
|
+
- **ALWAYS verify by reading the codebase** before building on something
|
|
105
|
+
- **ALWAYS search for existing implementations** before writing new code
|
|
106
|
+
- If similar code exists, refactor it to support the new requirement instead of duplicating
|
|
107
|
+
|
|
108
|
+
### No Code Duplication
|
|
109
|
+
- Before writing new code, search for existing implementations
|
|
110
|
+
- If you find code that does 80% of what you need, refactor it — don't duplicate it
|
|
111
|
+
- Duplication is a maintainability debt that compounds with every copy
|
|
112
|
+
|
|
113
|
+
## File Organization
|
|
114
|
+
|
|
115
|
+
- **One primary [construct] per file** — One class, one module, one component.
|
|
116
|
+
Do not declare multiple classes, interfaces, or significant types in a single file.
|
|
117
|
+
[Construct name adapts: "class" for OOP, "module export" for FP, "component" for React,
|
|
118
|
+
"struct + impl" for Rust, "type + functions" for Go]
|
|
119
|
+
|
|
120
|
+
- **Maximum file length: [N] lines** — If a file approaches this limit, it has too many
|
|
121
|
+
responsibilities. Refactor by extracting. If you're following single responsibility,
|
|
122
|
+
you should rarely get close to this limit.
|
|
123
|
+
|
|
124
|
+
## Engineering Principles
|
|
125
|
+
|
|
126
|
+
- **DRY (Don't Repeat Yourself)** — Every piece of knowledge must have a single,
|
|
127
|
+
unambiguous, authoritative representation within the system. If you change one thing
|
|
128
|
+
and have to change it in multiple places, the design is wrong. Extract shared logic.
|
|
129
|
+
|
|
130
|
+
- **KISS (Keep It Simple, Stupid)** — The simplest solution that works is the best
|
|
131
|
+
solution. Avoid over-engineering, excessive abstractions, and clever tricks.
|
|
132
|
+
Code is read far more often than it is written — optimize for clarity.
|
|
133
|
+
|
|
134
|
+
- **YAGNI (You Aren't Gonna Need It)** — Do NOT implement functionality until it is
|
|
135
|
+
actually needed. Do not design for hypothetical future requirements. Do not add
|
|
136
|
+
configuration points, extension hooks, or abstractions "just in case."
|
|
137
|
+
|
|
138
|
+
- **Separation of Concerns** — Each unit of code (function, class, module) should
|
|
139
|
+
address one concern. Mixing concerns creates code that is hard to test, hard to
|
|
140
|
+
change, and hard to understand.
|
|
141
|
+
|
|
142
|
+
- **Principle of Least Surprise** — Code should behave as other developers would
|
|
143
|
+
expect. Method names should describe what they do. Side effects should be obvious.
|
|
144
|
+
Conventions should be consistent across the codebase.
|
|
145
|
+
|
|
146
|
+
- **Fail Fast** — Detect and report errors as early as possible. Validate inputs
|
|
147
|
+
at boundaries. Assert invariants. The further an error propagates from its source,
|
|
148
|
+
the harder it is to diagnose.
|
|
149
|
+
|
|
150
|
+
## Code Quality Mindset
|
|
151
|
+
|
|
152
|
+
- **Think like an architect operating within a complex codebase** — Every coding
|
|
153
|
+
decision must consider: will this be easy to extend? Can another developer understand it?
|
|
154
|
+
Does it follow existing patterns?
|
|
155
|
+
|
|
156
|
+
- **No hacks, no shortcuts** — Especially when fixing bugs. The pressure to
|
|
157
|
+
"just make it work" is strongest during bug fixes. Resist. Fix it properly.
|
|
158
|
+
|
|
159
|
+
- **No over-engineering** — Don't add features, abstractions, or configurability
|
|
160
|
+
beyond what's needed. Three similar lines of code is better than a premature abstraction.
|
|
161
|
+
The right amount of complexity is the minimum needed for the current task.
|
|
162
|
+
|
|
163
|
+
- **All code must be testable** — Structure code so it can be tested in isolation.
|
|
164
|
+
[Paradigm-specific testability guidance goes in the paradigm section]
|
|
165
|
+
</universal-standards>
|
|
166
|
+
|
|
167
|
+
<!-- ─────────────────────────────────────────────────────────────────── -->
|
|
168
|
+
<!-- OOP MODULE — Include when project uses object-oriented paradigm -->
|
|
169
|
+
<!-- ─────────────────────────────────────────────────────────────────── -->
|
|
170
|
+
|
|
171
|
+
<paradigm-oop include-when="Project uses OOP as primary or significant paradigm (C#, Java, TypeScript with classes, Python with classes, Kotlin, Swift, Dart, Ruby, PHP)">
|
|
172
|
+
## Object-Oriented Programming Standards
|
|
173
|
+
|
|
174
|
+
### SOLID Principles — Non-Negotiable
|
|
175
|
+
|
|
176
|
+
- **Single Responsibility Principle** — Each class has ONE reason to change.
|
|
177
|
+
If you can describe a class purpose with "and", it does too much. Split it.
|
|
178
|
+
|
|
179
|
+
- **Open/Closed Principle** — Open for extension, closed for modification.
|
|
180
|
+
Use abstractions and composition to add behavior without changing existing code.
|
|
181
|
+
|
|
182
|
+
- **Liskov Substitution Principle** — Derived classes must be fully substitutable
|
|
183
|
+
for their base classes. No surprises, no broken contracts.
|
|
184
|
+
|
|
185
|
+
- **Interface Segregation Principle** — No client should depend on interfaces it
|
|
186
|
+
doesn't use. Prefer many small, focused interfaces over few large ones.
|
|
187
|
+
|
|
188
|
+
- **Dependency Inversion Principle** — Depend on abstractions, not concretions.
|
|
189
|
+
High-level modules must not depend on low-level modules.
|
|
190
|
+
|
|
191
|
+
### Code Against Abstractions
|
|
192
|
+
|
|
193
|
+
- **ALWAYS code against interfaces** — Every service, repository, and significant
|
|
194
|
+
collaborator must have an interface. This enables testing, swapping implementations,
|
|
195
|
+
and respecting DIP.
|
|
196
|
+
|
|
197
|
+
- **Dependency injection for ALL services** — No instantiating dependencies directly
|
|
198
|
+
inside other services. Wire dependencies through constructors. Register in the
|
|
199
|
+
DI container.
|
|
200
|
+
Reference: consult `system-structure.md` (`.docs/wiki/system-wide/system-structure.md`)
|
|
201
|
+
and `[subsystem]-structure.md` (`.docs/wiki/subsystems/[subsystem-name]/structure.md`)
|
|
202
|
+
for where DI configuration lives in this project
|
|
203
|
+
|
|
204
|
+
### OOP Best Practices
|
|
205
|
+
|
|
206
|
+
- **Composition over inheritance** — Prefer composing behaviors via injected
|
|
207
|
+
collaborators over deep inheritance hierarchies. Inheritance creates tight coupling.
|
|
208
|
+
|
|
209
|
+
- **Encapsulation** — Keep internal state private. Expose behavior through methods,
|
|
210
|
+
not raw data through public fields and getters.
|
|
211
|
+
|
|
212
|
+
- **Polymorphism over conditionals** — When you see `if/switch` checking a type
|
|
213
|
+
discriminator, consider whether polymorphism is the proper solution.
|
|
214
|
+
|
|
215
|
+
- **Small, focused classes** — A class should be easily describable in one sentence.
|
|
216
|
+
If the description needs "and", extract a collaborator.
|
|
217
|
+
|
|
218
|
+
### Design Patterns — Use Where They Fit
|
|
219
|
+
|
|
220
|
+
Apply proven patterns to solve recurring design problems. Do NOT force patterns
|
|
221
|
+
where a simpler solution exists — a pattern used without justification is an anti-pattern.
|
|
222
|
+
|
|
223
|
+
- **Strategy** — Encapsulate interchangeable algorithms behind an interface. Use when
|
|
224
|
+
behavior varies by context and you want to swap implementations without modifying callers.
|
|
225
|
+
|
|
226
|
+
- **Repository** — Mediate between domain and data mapping layers using a collection-like
|
|
227
|
+
interface. Keeps domain logic ignorant of persistence details.
|
|
228
|
+
|
|
229
|
+
- **Factory / Abstract Factory** — Encapsulate object creation when construction is
|
|
230
|
+
complex or the concrete type depends on runtime conditions. Avoid when a simple
|
|
231
|
+
constructor call is sufficient.
|
|
232
|
+
|
|
233
|
+
- **Observer / Event** — Decouple producers from consumers when one action must trigger
|
|
234
|
+
multiple reactions. Use for cross-cutting concerns like logging, notifications, or
|
|
235
|
+
cache invalidation.
|
|
236
|
+
|
|
237
|
+
- **Decorator** — Add behavior to objects dynamically without modifying their class.
|
|
238
|
+
Prefer over inheritance when combining behaviors in varying combinations.
|
|
239
|
+
|
|
240
|
+
- **Adapter** — Convert one interface to another so incompatible classes can work together.
|
|
241
|
+
Use at system boundaries to integrate external libraries or legacy code.
|
|
242
|
+
|
|
243
|
+
- **Command** — Encapsulate a request as an object, enabling undo, queuing, logging,
|
|
244
|
+
or deferred execution. Use when operations need to be treated as first-class objects.
|
|
245
|
+
|
|
246
|
+
- **Template Method** — Define the skeleton of an algorithm in a base class, letting
|
|
247
|
+
subclasses override specific steps. Use sparingly — composition is often better.
|
|
248
|
+
|
|
249
|
+
**WARNING:** Do NOT use patterns preemptively. A pattern is justified ONLY when the
|
|
250
|
+
problem it solves actually exists in your code. "We might need it later" is not
|
|
251
|
+
justification — that violates YAGNI.
|
|
252
|
+
|
|
253
|
+
### OOP Anti-Patterns — Never Do These
|
|
254
|
+
|
|
255
|
+
- **God Class** — A class that knows too much and does too much. If a class name
|
|
256
|
+
contains "Manager", "Handler", "Processor", or "Service" and it's over 300 lines,
|
|
257
|
+
it's probably a God Class. Split it by responsibility.
|
|
258
|
+
|
|
259
|
+
- **Anemic Domain Model** — Domain objects reduced to mere data containers (getters
|
|
260
|
+
and setters only) with all logic in separate "service" classes. This is procedural
|
|
261
|
+
programming disguised as OOP. Put behavior where the data is.
|
|
262
|
+
|
|
263
|
+
- **Feature Envy** — A method that uses more data from another class than its own.
|
|
264
|
+
This means the method belongs in the other class. Move it.
|
|
265
|
+
|
|
266
|
+
- **Tight Coupling** — Classes directly instantiating or depending on concrete
|
|
267
|
+
implementations instead of abstractions. Makes testing impossible and changes ripple
|
|
268
|
+
across the codebase. Code against interfaces.
|
|
269
|
+
|
|
270
|
+
- **Poltergeist / Useless Classes** — Classes with no real responsibility that merely
|
|
271
|
+
delegate to other classes or add unnecessary abstraction layers. Every class must
|
|
272
|
+
justify its existence with real behavior.
|
|
273
|
+
|
|
274
|
+
- **Singleton Abuse** — Using Singleton as a convenient global variable. Singletons
|
|
275
|
+
hide dependencies, prevent testing, create concurrency issues, and violate DIP.
|
|
276
|
+
Use dependency injection instead.
|
|
277
|
+
|
|
278
|
+
- **Premature Abstraction** — Creating interfaces, base classes, or generic frameworks
|
|
279
|
+
before having two concrete use cases. Wait until duplication emerges, then abstract.
|
|
280
|
+
Wrong abstractions are worse than duplication.
|
|
281
|
+
</paradigm-oop>
|
|
282
|
+
|
|
283
|
+
<!-- ─────────────────────────────────────────────────────────────────── -->
|
|
284
|
+
<!-- FUNCTIONAL MODULE — Include when project uses functional paradigm -->
|
|
285
|
+
<!-- ─────────────────────────────────────────────────────────────────── -->
|
|
286
|
+
|
|
287
|
+
<paradigm-functional include-when="Project uses FP as primary or significant paradigm (Elixir, Haskell, Clojure, F#, Elm, OCaml, or FP style in TypeScript/JavaScript/Python/Kotlin/Scala)">
|
|
288
|
+
## Functional Programming Standards
|
|
289
|
+
|
|
290
|
+
### Core Principles
|
|
291
|
+
|
|
292
|
+
- **Pure functions by default** — Functions should be deterministic: same input →
|
|
293
|
+
same output, no side effects. Isolate side effects at the boundaries
|
|
294
|
+
(IO, database, API calls, user interaction).
|
|
295
|
+
|
|
296
|
+
- **Immutability by default** — Do not mutate data. Create new values from old ones.
|
|
297
|
+
Mutable state is opt-in and must be justified with a comment explaining why.
|
|
298
|
+
|
|
299
|
+
- **Function composition over imperative flow** — Build complex behavior by composing
|
|
300
|
+
small, focused functions. Prefer pipelines and transformations over step-by-step
|
|
301
|
+
mutation.
|
|
302
|
+
|
|
303
|
+
### Data Modeling
|
|
304
|
+
|
|
305
|
+
- **Make illegal states unrepresentable** — Use discriminated unions / sum types /
|
|
306
|
+
algebraic data types to model domain states. The type system should prevent
|
|
307
|
+
invalid state combinations at compile time.
|
|
308
|
+
|
|
309
|
+
- **Pattern matching over conditionals** — Use pattern matching to destructure data
|
|
310
|
+
and handle variants. It's exhaustive, self-documenting, and catches missing cases.
|
|
311
|
+
|
|
312
|
+
- **Data transformation pipelines** — Prefer `map`, `filter`, `reduce`, pipe operators,
|
|
313
|
+
or function composition over loops with mutable accumulators.
|
|
314
|
+
|
|
315
|
+
### Error Handling
|
|
316
|
+
|
|
317
|
+
- **Result/Either types for expected failures** — Reserve exceptions for truly
|
|
318
|
+
exceptional, unrecoverable conditions. Expected failures (validation, not-found,
|
|
319
|
+
conflict) should be expressed in the return type.
|
|
320
|
+
|
|
321
|
+
- **Railway-oriented error handling** — Chain operations that can fail without nested
|
|
322
|
+
try/catch. Let the error path carry failures through the pipeline.
|
|
323
|
+
|
|
324
|
+
### Module Design
|
|
325
|
+
|
|
326
|
+
- **Modules as namespaces with clear purpose** — Group related functions into modules.
|
|
327
|
+
Each module has a single, focused responsibility.
|
|
328
|
+
|
|
329
|
+
- **Explicit dependencies** — Functions receive dependencies as parameters.
|
|
330
|
+
No hidden global state, no module-level singletons with side effects.
|
|
331
|
+
|
|
332
|
+
- **Public API at module boundary** — Export only what consumers need.
|
|
333
|
+
Keep internal helpers private.
|
|
334
|
+
</paradigm-functional>
|
|
335
|
+
|
|
336
|
+
<!-- ─────────────────────────────────────────────────────────────────── -->
|
|
337
|
+
<!-- SYSTEMS MODULE — Include for Rust, Go, C, C++ -->
|
|
338
|
+
<!-- ─────────────────────────────────────────────────────────────────── -->
|
|
339
|
+
|
|
340
|
+
<paradigm-systems include-when="Project uses systems languages (Rust, Go, C, C++)">
|
|
341
|
+
## Systems Programming Standards
|
|
342
|
+
|
|
343
|
+
### Rust (include if Rust project)
|
|
344
|
+
|
|
345
|
+
- **Respect the borrow checker** — Do not fight it with unnecessary `clone()` or
|
|
346
|
+
`Rc<RefCell<>>`. If the borrow checker complains, rethink your data flow.
|
|
347
|
+
|
|
348
|
+
- **`Result<T, E>` for all fallible operations** — Use the `?` operator for
|
|
349
|
+
propagation. Reserve `panic!` for unrecoverable invariant violations only.
|
|
350
|
+
|
|
351
|
+
- **No unnecessary `unwrap()`** — Every `unwrap()` is a potential panic. Use `?`,
|
|
352
|
+
`unwrap_or`, `unwrap_or_else`, `map`, or proper match/if-let handling.
|
|
353
|
+
|
|
354
|
+
- **Traits for polymorphism** — Use traits to define behavior contracts. Use
|
|
355
|
+
`dyn Trait` for dynamic dispatch only when static dispatch won't work.
|
|
356
|
+
|
|
357
|
+
- **Derive what you can** — Use `#[derive(...)]` for standard traits. Implement
|
|
358
|
+
manually only when custom behavior is needed.
|
|
359
|
+
|
|
360
|
+
### Go (include if Go project)
|
|
361
|
+
|
|
362
|
+
- **Accept interfaces, return structs** — Function parameters should use interfaces
|
|
363
|
+
for flexibility. Return concrete types for clarity.
|
|
364
|
+
|
|
365
|
+
- **Check every error** — Never ignore `err` returns. Use `fmt.Errorf("context: %w", err)`
|
|
366
|
+
for wrapping. Use sentinel errors or custom types for typed error handling.
|
|
367
|
+
|
|
368
|
+
- **Package-level organization** — Each package has a clear, focused purpose.
|
|
369
|
+
Avoid mega-packages. Package name should describe what it provides, not what it contains.
|
|
370
|
+
|
|
371
|
+
- **No unnecessary interfaces** — Define interfaces where they're consumed, not where
|
|
372
|
+
they're implemented. Don't create interfaces for single implementations.
|
|
373
|
+
|
|
374
|
+
- **Short names for small scopes** — `i`, `ctx`, `err`, `db` for local variables.
|
|
375
|
+
Longer, descriptive names for package-level and exported identifiers.
|
|
376
|
+
|
|
377
|
+
### C/C++ (include if C/C++ project)
|
|
378
|
+
|
|
379
|
+
- **RAII in C++** — Acquire resources in constructors, release in destructors.
|
|
380
|
+
Use smart pointers (`unique_ptr`, `shared_ptr`) instead of raw `new/delete`.
|
|
381
|
+
|
|
382
|
+
- **Bounds checking** — Validate array indices and buffer sizes. Use safe alternatives
|
|
383
|
+
(`std::array`, `std::vector`, `std::string`) over raw C arrays and `char*`.
|
|
384
|
+
|
|
385
|
+
- **No raw `new/delete` in C++** — Use smart pointers and containers.
|
|
386
|
+
Manual memory management is a bug waiting to happen.
|
|
387
|
+
</paradigm-systems>
|
|
388
|
+
|
|
389
|
+
<!-- ─────────────────────────────────────────────────────────────────── -->
|
|
390
|
+
<!-- LANGUAGE-SPECIFIC CONVENTIONS — Generated from codebase detection -->
|
|
391
|
+
<!-- ─────────────────────────────────────────────────────────────────── -->
|
|
392
|
+
|
|
393
|
+
<language-conventions generate-from="codebase detection or user input">
|
|
394
|
+
## Language and Framework Conventions
|
|
395
|
+
|
|
396
|
+
[Generate this section from detected language, frameworks, and existing configs.
|
|
397
|
+
Check .prettierrc, .eslintrc, ruff.toml, .editorconfig, etc. for existing rules.
|
|
398
|
+
Examine 5-10 representative source files for naming patterns.]
|
|
399
|
+
|
|
400
|
+
### Naming Conventions
|
|
401
|
+
[Document project's actual naming patterns. Be prescriptive:
|
|
402
|
+
- File naming: kebab-case.ts, PascalCase.cs, snake_case.py, etc.
|
|
403
|
+
- Functions/methods: camelCase, snake_case, PascalCase depending on language
|
|
404
|
+
- Variables: language convention
|
|
405
|
+
- Constants: UPPER_SNAKE_CASE universally
|
|
406
|
+
- Types/interfaces: PascalCase universally, with/without prefix based on project]
|
|
407
|
+
|
|
408
|
+
### Import / Dependency Organization
|
|
409
|
+
[Document the project's import ordering and grouping.
|
|
410
|
+
Check for linter rules enforcing import order.]
|
|
411
|
+
|
|
412
|
+
### Framework-Specific Rules
|
|
413
|
+
[Only include if project uses a framework with its own patterns:
|
|
414
|
+
- React: hooks rules, component patterns, state management approach
|
|
415
|
+
- Angular: module structure, service patterns, change detection
|
|
416
|
+
- ASP.NET: controller patterns, middleware, model binding
|
|
417
|
+
- Django: app structure, view patterns, ORM usage
|
|
418
|
+
- Spring: bean patterns, annotation usage
|
|
419
|
+
Generate based on what's actually detected, not a generic list.]
|
|
420
|
+
</language-conventions>
|
|
421
|
+
|
|
422
|
+
<!-- ─────────────────────────────────────────────────────────────────── -->
|
|
423
|
+
<!-- PROJECT-SPECIFIC RULES — From user interview -->
|
|
424
|
+
<!-- ─────────────────────────────────────────────────────────────────── -->
|
|
425
|
+
|
|
426
|
+
<project-specific-rules generate-from="user interview">
|
|
427
|
+
## Project-Specific Rules
|
|
428
|
+
|
|
429
|
+
[Rules from the user interview that don't fit neatly in other sections.
|
|
430
|
+
These capture the team's hard-won lessons and specific pain points.
|
|
431
|
+
|
|
432
|
+
This is often the MOST VALUABLE section because it's unique to this project.
|
|
433
|
+
Write these with the same emphatic, direct tone as the universal rules.
|
|
434
|
+
|
|
435
|
+
Examples of what might go here:
|
|
436
|
+
- "If a method has LESS than 7 parameters, keep them on ONE line"
|
|
437
|
+
- "All API responses must use the shared ApiResponse wrapper"
|
|
438
|
+
- "Never use library X for Y — use Z instead"
|
|
439
|
+
- "All database queries must go through the repository pattern"
|
|
440
|
+
- Specific patterns, conventions, or constraints unique to this project]
|
|
441
|
+
</project-specific-rules>
|
|
442
|
+
|
|
443
|
+
</template>
|
|
444
|
+
|
|
445
|
+
<guidelines>
|
|
446
|
+
|
|
447
|
+
**Assembly rules for the generating agent:**
|
|
448
|
+
|
|
449
|
+
1. **ALWAYS include universal-standards** — These apply to every project regardless
|
|
450
|
+
of language or paradigm. Adapt the [bracketed placeholders] to the detected language.
|
|
451
|
+
|
|
452
|
+
2. **Include paradigm modules based on detection AND user preference:**
|
|
453
|
+
- Project uses OOP → include paradigm-oop
|
|
454
|
+
- Project uses FP → include paradigm-functional
|
|
455
|
+
- Project uses systems language → include paradigm-systems
|
|
456
|
+
- Project uses multi-paradigm → include whichever modules the user prefers
|
|
457
|
+
- User explicitly declines a paradigm → respect that, do not include it
|
|
458
|
+
|
|
459
|
+
3. **Generate language-conventions from codebase analysis** — Read actual config files,
|
|
460
|
+
examine source files, document what's in use. Be prescriptive, not descriptive.
|
|
461
|
+
|
|
462
|
+
4. **Include project-specific-rules from interview** — Capture the user's pain points
|
|
463
|
+
and custom rules. These are the most unique and valuable part of the document.
|
|
464
|
+
|
|
465
|
+
5. **Tone: DIRECT and EMPHATIC** — Use bold for emphasis, caps for critical words.
|
|
466
|
+
This is not a suggestion document — it's a mandate. AI agents (especially Claude)
|
|
467
|
+
respect authoritative, unambiguous instructions more than polite suggestions.
|
|
468
|
+
Match the tone of the universal-standards section.
|
|
469
|
+
|
|
470
|
+
6. **Length: 150-350 lines** — Enough to be comprehensive, short enough to be loaded
|
|
471
|
+
as context without waste. Universal (~60 lines) + one paradigm module (~40 lines) +
|
|
472
|
+
language conventions (~40 lines) + project-specific (~30 lines) = ~170 lines typical.
|
|
473
|
+
Two paradigm modules or extensive project rules may push to ~300.
|
|
474
|
+
|
|
475
|
+
7. **Be prescriptive** — "NEVER do X" not "We typically avoid X". "ALWAYS do Y" not
|
|
476
|
+
"It's recommended to do Y". Standards are mandates, not suggestions.
|
|
477
|
+
|
|
478
|
+
8. **Include rationale for non-obvious rules** — "No dead code" needs a why
|
|
479
|
+
(misleads AI and developers into building on obsolete code). "Use camelCase" doesn't
|
|
480
|
+
need a why (it's a convention, not a principle).
|
|
481
|
+
|
|
482
|
+
9. **Use concrete examples for ambiguous rules** — When a rule could be misinterpreted,
|
|
483
|
+
show a brief good/bad example inline.
|
|
484
|
+
|
|
485
|
+
10. **Cross-reference project structure** — Reference actual file paths for constants
|
|
486
|
+
directories, DI configuration, shared utilities, etc. Use backtick formatting for paths.
|
|
487
|
+
|
|
488
|
+
**What does NOT belong in coding-standards.md:**
|
|
489
|
+
- File/directory structure (that's system-structure.md / subsystem-structure.md)
|
|
490
|
+
- Architecture decisions and patterns (that's system-architecture.md)
|
|
491
|
+
- Technology stack choices (that's system-architecture.md tech-stack section)
|
|
492
|
+
- Test framework setup and patterns (that's a separate testing doc)
|
|
493
|
+
- Deployment, CI/CD, or infrastructure concerns
|
|
494
|
+
|
|
495
|
+
**What DOES belong:**
|
|
496
|
+
- Rules about HOW to write code (quality, style, patterns)
|
|
497
|
+
- Rules about code organization WITHIN files (not directory layout)
|
|
498
|
+
- Rules about naming, formatting, error handling, testability
|
|
499
|
+
- Rules about paradigm adherence (SOLID, FP principles, systems idioms)
|
|
500
|
+
- Rules that prevent known AI mistakes (the highest-value rules)
|
|
501
|
+
- Rules that maintain codebase integrity at scale
|
|
502
|
+
|
|
503
|
+
</guidelines>
|
|
504
|
+
|
|
505
|
+
<evolution>
|
|
506
|
+
|
|
507
|
+
This document evolves when coding standards change — not with every feature or fix.
|
|
508
|
+
|
|
509
|
+
**Update triggers:**
|
|
510
|
+
- New language or paradigm added to the project
|
|
511
|
+
- New framework that introduces its own coding patterns
|
|
512
|
+
- Team discovers a recurring mistake → add a rule to prevent it
|
|
513
|
+
- Existing rule proven too strict or too loose → adjust it
|
|
514
|
+
- Architecture shift that changes how code should be written
|
|
515
|
+
- Onboarding feedback reveals ambiguous or missing rules
|
|
516
|
+
|
|
517
|
+
**NOT an update trigger:**
|
|
518
|
+
- New features (should follow existing standards)
|
|
519
|
+
- Bug fixes (should already follow standards)
|
|
520
|
+
- Dependency updates (unless they fundamentally change coding patterns)
|
|
521
|
+
- New files or directories (that's structure docs)
|
|
522
|
+
|
|
523
|
+
**After update:**
|
|
524
|
+
1. Review all paradigm modules — still accurate?
|
|
525
|
+
2. Review project-specific rules — any new pain points to capture?
|
|
526
|
+
3. Check line count — still under 350 lines?
|
|
527
|
+
4. Verify cross-references to file paths are still valid
|
|
528
|
+
|
|
529
|
+
</evolution>
|
|
530
|
+
|
|
531
|
+
</coding-standards>
|