You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: website/docs/practical-techniques/lesson-11-agent-friendly-code.md
+6-2Lines changed: 6 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -124,7 +124,7 @@ function createUser(password: string) {
124
124
125
125
// Critical section (agent barrier)
126
126
// === CRITICAL SECURITY SECTION ===
127
-
// NEVER store passwords in plain text or weak hashing (MD5, SHA1)
127
+
//C-001: NEVER store passwords in plain text or weak hashing (MD5, SHA1)
128
128
// MUST hash with bcrypt (10+ rounds) BEFORE persistence
129
129
// Do NOT modify hashing algorithm without security review
130
130
// Violations create CVE-level vulnerabilities
@@ -139,6 +139,8 @@ function createUser(password: string) {
139
139
140
140
This creates deliberate friction. An agent tasked with "add OAuth login" will work slower around password hashing code with heavy constraints—it must navigate all those NEVER/MUST directives carefully. That's the protection mechanism: forced caution for critical paths. But overuse is counterproductive. Mark too many functions as CRITICAL and agents struggle with routine work, slowing down legitimate changes as much as dangerous ones. Reserve this technique for code where accidental modification genuinely costs more than the development slowdown.
141
141
142
+
These constraint IDs (C-001, I-001) originate in [spec tables](/docs/practical-techniques/lesson-13-systems-thinking-specs#constraints-and-invariants-defining-correctness) and migrate into code during implementation. Once inlined, the code carries the constraint—not just the implementation, but the *rule* it enforces. This is what makes it safe to [delete the spec](/docs/practical-techniques/lesson-12-spec-driven-development) after implementation: the WHY has migrated into the codebase.
143
+
142
144
## The Knowledge Cache Anti-Pattern
143
145
144
146
You've extracted architectural knowledge from your codebase with an agent—clean diagrams, comprehensive API documentation, detailed component relationships. You save it as `ARCHITECTURE.md` and commit it. Now you have a cache invalidation problem: code changes (always), documentation doesn't (usually), and future agents find both during code research ([Lesson 5](/docs/methodology/lesson-5-grounding)). The diagram below shows the divergence.
@@ -181,7 +183,7 @@ sequenceDiagram
181
183
end
182
184
```
183
185
184
-
The moment you commit extracted knowledge, every code change requires documentation updates you'll forget. Source code is your single source of truth—code research tools (ChunkHound, semantic search, Explore) extract architectural knowledge dynamically every time, fresh and accurate. Document decisions and WHY (ADRs, high-level overviews, business domain concepts), not extracted WHAT that code research can regenerate on demand.
186
+
The moment you commit extracted knowledge, every code change requires documentation updates you'll forget. Source code is your single source of truth—code research tools (ChunkHound, semantic search, Explore) extract architectural knowledge dynamically every time, fresh and accurate. The distinction: **HOW** knowledge (implementation details, data flows, component relationships) is redundant with code—code research regenerates it on demand. **WHY** knowledge (rejected alternatives, business rationale, compliance mandates) can't be expressed in code. Commit the WHY as decision records—short documents capturing what was decided, why, and what alternatives were rejected. Let code research handle the HOW.
185
187
186
188
## Key Takeaways
187
189
@@ -191,6 +193,8 @@ The moment you commit extracted knowledge, every code change requires documentat
191
193
192
194
-**Comments as agent-critical sections (use sparingly)** - For genuinely high-risk code (authentication, cryptography, payments, PII), write comments as prompts using imperative directives (NEVER, MUST, ALWAYS) to create deliberate friction. This protection mechanism guards sensitive code from accidental modification. **Overuse is counterproductive**—if everything is marked CRITICAL, the signal becomes noise and legitimate work slows down.
193
195
196
+
-**Constraint IDs migrate from spec to code** — When specs use IDs like C-001 or I-001 ([Lesson 13](/docs/practical-techniques/lesson-13-systems-thinking-specs#constraints-and-invariants-defining-correctness)), agents inline them into code comments during implementation. The code then carries the constraint rule, making it safe to delete the spec ([Lesson 12](/docs/practical-techniques/lesson-12-spec-driven-development)).
197
+
194
198
-**You are the quality circuit breaker** - Code review ([Lesson 9](/docs/practical-techniques/lesson-9-reviewing-code)) prevents negative compounding. Accepting bad patterns lets them enter pattern context for future agents. Rejecting them breaks the negative feedback loop.
195
199
196
200
-**Avoid knowledge cache anti-patterns** - Code research tools (Explore, ChunkHound, semantic search) extract architectural knowledge dynamically from source code every time you need it. Saving extracted knowledge to .md files creates unnecessary caches that become stale, pollute future grounding with duplicated information, and create impossible cache invalidation problems. Trust the grounding process ([Lesson 5](/docs/methodology/lesson-5-grounding)) to re-extract knowledge on-demand from the single source of truth.
Copy file name to clipboardExpand all lines: website/docs/practical-techniques/lesson-12-spec-driven-development.md
+5-1Lines changed: 5 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -34,7 +34,9 @@ This is exactly the [Knowledge Cache Anti-Pattern](/docs/practical-techniques/le
34
34
35
35
Here's the key insight from [Lesson 5](/docs/methodology/lesson-5-grounding): **grounding tools already perform knowledge extraction.** When ChunkHound's [code research](https://chunkhound.github.io/code-research) processes 50,000 tokens of raw code and returns a 3,000-token synthesis, that synthesis IS a spec—extracted on-demand from the source of truth. You don't need to maintain spec files because you can regenerate them from code whenever needed.
36
36
37
-
**The solution: DELETE spec files after implementation.** The code is now the single source of truth. Specs are temporary scaffolding, not permanent artifacts.
37
+
But not all spec knowledge is equal. **HOW** knowledge—implementation details, data flows, edge cases—gets fully encoded in code during implementation. Once the code exists, the spec's HOW is redundant. **WHY** knowledge—rejected alternatives, business rationale for a constraint, compliance mandates—can't be expressed in code. A constraint comment like `// C-001: NEVER process duplicate webhook` ([Lesson 11](/docs/practical-techniques/lesson-11-agent-friendly-code#comments-as-context-engineering-critical-sections-for-agents)) tells the agent *what* to enforce, but not *why* you chose idempotency-via-database over idempotency-via-cache. That rationale is the **residual**—the part of the spec that doesn't migrate into code.
38
+
39
+
**The solution: DELETE the HOW spec after implementation.** The code is the single source of truth for implementation. For the small WHY residual (rejected alternatives, business context that drove constraints), have the agent diff the original spec against the final code—what's expressed in code is now redundant. The residual gets committed as a decision record ([Lesson 11](/docs/practical-techniques/lesson-11-agent-friendly-code#the-knowledge-cache-anti-pattern)). Everything else is regenerable from code via grounding tools.
38
40
39
41
## Mainstream SDD vs This Approach
40
42
@@ -90,6 +92,8 @@ If you've followed this course, you've been practicing SDD all along. Every time
90
92
91
93
...you were doing Spec Driven Development. The spec lived in your context window—RAM, not disk.
92
94
95
+
What makes this safe is [constraint migration](/docs/practical-techniques/lesson-11-agent-friendly-code#comments-as-context-engineering-critical-sections-for-agents): during implementation, the agent inlines spec constraints—with their IDs—into code comments. The WHY moves from spec to code. When you close the conversation, nothing is lost.
96
+
93
97
### When to Persist Specs
94
98
95
99
For single-session tasks, the context window is your spec file. But larger tasks need coordination across sessions:
Copy file name to clipboardExpand all lines: website/docs/practical-techniques/lesson-13-systems-thinking-specs.md
+15-1Lines changed: 15 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -208,6 +208,20 @@ Constraints limit *actions* (NEVER do X). Invariants describe *state* (X is alwa
208
208
209
209
The **Data** and **Stress** columns transform a constraint from a wish into a testable requirement. "NEVER process duplicates" is a policy. "NEVER process duplicates, verified with 10K events at 100 concurrent deliveries" is an engineering requirement with a verification plan. (Note that C-001 and C-002 trace back to [third-party assumptions](#third-party-assumptions)—they exist *because* of Stripe's delivery semantics and signing behavior, not as arbitrary security choices.)
210
210
211
+
During implementation, these IDs migrate into code as structured comments ([Lesson 11](/docs/practical-techniques/lesson-11-agent-friendly-code#comments-as-context-engineering-critical-sections-for-agents)):
212
+
213
+
```typescript
214
+
// C-001: NEVER process duplicate webhook — idempotency via unique constraint on stripe_event_id
215
+
// C-002: NEVER trust unsigned webhook — HMAC-SHA256 validation before any processing
if (awaitisDuplicate(req.body.id)) returnnewResponse(null, { status: 200 }) // C-001
219
+
// ...
220
+
}
221
+
```
222
+
223
+
The spec table is the authoritative source during design. The code comments become the authoritative source after implementation. This is what makes [deleting the spec](/docs/practical-techniques/lesson-12-spec-driven-development) safe—the constraints have migrated.
224
+
211
225
### Invariants
212
226
213
227
| ID | Condition | Scope | Manifested By |
@@ -334,7 +348,7 @@ Each loop through this cycle reveals what the spec missed. The first pass might
334
348
335
349
**You're done when the loop produces no new gaps:** the code passes all behavioral scenarios, the spec accounts for all constraints the code revealed, and the last pass surfaces nothing new. That's a testable termination condition. A simple feature converges in one loop. A complex architectural change might take five. But you discover which you're dealing with *by running the loop*, not by predicting it.
336
350
337
-
**Iteration speed is the multiplier.** Code generation is approaching post-scarcity[^1]—the scarce resource is your judgment about *what* to build. The engineer who runs ten hypothesis→experiment→verify loops per day outperforms the one who runs two with a more thorough upfront spec[^4][^5]. This is the same insight that made Agile outperform Waterfall, compressed from weeks-per-iteration to minutes. Use [exploration planning](/docs/methodology/lesson-3-high-level-methodology#phase-2-plan-strategic-decision) (Lesson 3) and [ArguSeek](/docs/methodology/lesson-5-grounding#arguseek-isolated-context--state) (Lesson 5) to research before each loop. For system-level work, start from the [full template](/prompts/specifications/spec-template). Validate through the [SDD workflow](/docs/practical-techniques/lesson-12-spec-driven-development)—gap-analyze, implement, then delete the spec.
351
+
**Iteration speed is the multiplier.** Code generation is approaching post-scarcity[^1]—the scarce resource is your judgment about *what* to build. The engineer who runs ten hypothesis→experiment→verify loops per day outperforms the one who runs two with a more thorough upfront spec[^4][^5]. This is the same insight that made Agile outperform Waterfall, compressed from weeks-per-iteration to minutes. Use [exploration planning](/docs/methodology/lesson-3-high-level-methodology#phase-2-plan-strategic-decision) (Lesson 3) and [ArguSeek](/docs/methodology/lesson-5-grounding#arguseek-isolated-context--state) (Lesson 5) to research before each loop. For system-level work, start from the [full template](/prompts/specifications/spec-template). Validate through the [SDD workflow](/docs/practical-techniques/lesson-12-spec-driven-development)—gap-analyze, implement, then delete the spec. What survives deletion: constraint IDs inlined in code ([Lesson 11](/docs/practical-techniques/lesson-11-agent-friendly-code#comments-as-context-engineering-critical-sections-for-agents)), and the small WHY residual (rejected alternatives, business rationale) committed as decision records.
338
352
339
353
:::info Template Sections Not Covered
340
354
The [full spec template](/prompts/specifications/spec-template) includes sections not taught in this lesson: **Background** (problem statement + baseline metrics), **Caching** (strategy/TTL/invalidation), **Endpoints** (REST contract details), **Cleanup Flows** (teardown/rollback sequences), **Code Traceability** (file:line evidence columns). Use these when the code pulls them from you—not before.
0 commit comments