opencode-agile-agent 1.0.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/README.md +71 -0
- package/bin/cli.js +434 -0
- package/bin/validate-templates.js +58 -0
- package/package.json +52 -0
- package/templates/.opencode/ARCHITECTURE.md +368 -0
- package/templates/.opencode/README.md +391 -0
- package/templates/.opencode/agents/api-designer.md +312 -0
- package/templates/.opencode/agents/backend-specialist.md +214 -0
- package/templates/.opencode/agents/code-archaeologist.md +260 -0
- package/templates/.opencode/agents/database-architect.md +212 -0
- package/templates/.opencode/agents/debugger.md +302 -0
- package/templates/.opencode/agents/developer.md +523 -0
- package/templates/.opencode/agents/devops-engineer.md +253 -0
- package/templates/.opencode/agents/documentation-writer.md +247 -0
- package/templates/.opencode/agents/explorer-agent.md +239 -0
- package/templates/.opencode/agents/feature-lead.md +302 -0
- package/templates/.opencode/agents/frontend-specialist.md +186 -0
- package/templates/.opencode/agents/game-developer.md +391 -0
- package/templates/.opencode/agents/mobile-developer.md +264 -0
- package/templates/.opencode/agents/orchestrator.md +463 -0
- package/templates/.opencode/agents/penetration-tester.md +256 -0
- package/templates/.opencode/agents/performance-optimizer.md +292 -0
- package/templates/.opencode/agents/pr-reviewer.md +468 -0
- package/templates/.opencode/agents/product-manager.md +225 -0
- package/templates/.opencode/agents/product-owner.md +264 -0
- package/templates/.opencode/agents/project-planner.md +248 -0
- package/templates/.opencode/agents/qa-automation-engineer.md +276 -0
- package/templates/.opencode/agents/security-auditor.md +260 -0
- package/templates/.opencode/agents/seo-specialist.md +266 -0
- package/templates/.opencode/agents/system-analyst.md +428 -0
- package/templates/.opencode/agents/test-engineer.md +229 -0
- package/templates/.opencode/config.template.json +129 -0
- package/templates/.opencode/rules/coding-standards.md +250 -0
- package/templates/.opencode/rules/git-conventions.md +149 -0
- package/templates/.opencode/skills/api-patterns/SKILL.md +162 -0
- package/templates/.opencode/skills/brainstorming/SKILL.md +255 -0
- package/templates/.opencode/skills/clean-code/SKILL.md +351 -0
- package/templates/.opencode/skills/code-philosophy/SKILL.md +512 -0
- package/templates/.opencode/skills/frontend-design/SKILL.md +237 -0
- package/templates/.opencode/skills/intelligent-routing/SKILL.md +195 -0
- package/templates/.opencode/skills/parallel-agents/SKILL.md +274 -0
- package/templates/.opencode/skills/plan-writing/SKILL.md +251 -0
- package/templates/.opencode/skills/systematic-debugging/SKILL.md +210 -0
- package/templates/.opencode/skills/testing-patterns/SKILL.md +252 -0
- package/templates/.opencode/workflows/brainstorm.md +110 -0
- package/templates/.opencode/workflows/create.md +108 -0
- package/templates/.opencode/workflows/debug.md +128 -0
- package/templates/.opencode/workflows/deploy.md +160 -0
- package/templates/.opencode/workflows/enhance.md +253 -0
- package/templates/.opencode/workflows/orchestrate.md +130 -0
- package/templates/.opencode/workflows/plan.md +163 -0
- package/templates/.opencode/workflows/review.md +135 -0
- package/templates/.opencode/workflows/status.md +102 -0
- package/templates/.opencode/workflows/test.md +146 -0
- package/templates/AGENTS.template.md +426 -0
|
@@ -0,0 +1,512 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: code-philosophy
|
|
3
|
+
description: Internal logic and data flow philosophy (The 5 Laws of Elegant Defense). Understand deeply to ensure code guides data naturally and prevents errors. Use when writing, reviewing, or refactoring code.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Code Philosophy: The 5 Laws of Elegant Defense
|
|
7
|
+
|
|
8
|
+
Internal logic and data flow philosophy that ensures code guides data naturally and prevents errors before they happen.
|
|
9
|
+
|
|
10
|
+
## Philosophy Overview
|
|
11
|
+
|
|
12
|
+
> **Code is written once but read many times.**
|
|
13
|
+
>
|
|
14
|
+
> Every line must justify its existence in terms of **clarity**, **correctness**, and **performance**.
|
|
15
|
+
|
|
16
|
+
These 5 laws form the foundation of defensive programming that produces maintainable, robust, and readable code.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Law 1: Guard Clauses — Handle Unhappy Path First
|
|
21
|
+
|
|
22
|
+
### The Problem
|
|
23
|
+
|
|
24
|
+
Traditional nested conditionals bury the happy path deep inside multiple levels of indentation, making code hard to read and maintain.
|
|
25
|
+
|
|
26
|
+
### The Solution
|
|
27
|
+
|
|
28
|
+
Reject invalid states at the **top** of every function with early returns. The happy path should be the last thing you see, not buried in an `else` branch.
|
|
29
|
+
|
|
30
|
+
### Examples
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
// ❌ BAD — deeply nested, hard to follow
|
|
34
|
+
function process(data: Data | null) {
|
|
35
|
+
if (data) {
|
|
36
|
+
if (data.items.length > 0) {
|
|
37
|
+
if (data.isValid) {
|
|
38
|
+
// ... actual logic deep inside
|
|
39
|
+
return transform(data);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// ✅ GOOD — guard at the top, logic flows clearly
|
|
47
|
+
function process(data: Data | null) {
|
|
48
|
+
if (!data) return null;
|
|
49
|
+
if (data.items.length === 0) return null;
|
|
50
|
+
if (!data.isValid) return null;
|
|
51
|
+
|
|
52
|
+
// ... actual logic at the top level
|
|
53
|
+
return transform(data);
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Benefits
|
|
58
|
+
|
|
59
|
+
- **Readability**: Main logic at top level, not nested
|
|
60
|
+
- **Early Exit**: Fail fast, no deep nesting
|
|
61
|
+
- **Clear Intent**: Each guard shows what we're checking
|
|
62
|
+
|
|
63
|
+
### Checklist
|
|
64
|
+
|
|
65
|
+
- [ ] Are all edge cases (null, empty, unauthorized) handled at the top?
|
|
66
|
+
- [ ] Is the happy path visible without scrolling?
|
|
67
|
+
- [ ] Can I understand the function's purpose from the guards?
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Law 2: Parsed State — Trust Your Types at the Boundary
|
|
72
|
+
|
|
73
|
+
### The Problem
|
|
74
|
+
|
|
75
|
+
Untrusted data (API responses, route params, user input) used directly throughout the codebase leads to scattered defensive checks and type uncertainty.
|
|
76
|
+
|
|
77
|
+
### The Solution
|
|
78
|
+
|
|
79
|
+
Validate and parse untrusted data **at the entry point**. Once inside the system, types should be trusted — no defensive `typeof` checks scattered throughout.
|
|
80
|
+
|
|
81
|
+
### Examples
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
// ❌ BAD — raw API data used directly everywhere
|
|
85
|
+
const id = route.params.id; // string | string[]
|
|
86
|
+
const user = await api.get(`/users/${id}`); // any
|
|
87
|
+
// ... later in the code
|
|
88
|
+
if (typeof user.name === 'string') { // defensive check
|
|
89
|
+
displayName.value = user.name;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// ✅ GOOD — parse at the boundary, use confidently
|
|
93
|
+
const id = String(route.params.id); // parsed to string
|
|
94
|
+
|
|
95
|
+
interface User {
|
|
96
|
+
id: string;
|
|
97
|
+
name: string;
|
|
98
|
+
email: string;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const user = await api.get<User>(`/users/${id}`); // typed
|
|
102
|
+
// ... later in the code
|
|
103
|
+
displayName.value = user.name; // confident, no check needed
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### With Validation Libraries
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
import { z } from 'zod';
|
|
110
|
+
|
|
111
|
+
// Define schema at the boundary
|
|
112
|
+
const UserSchema = z.object({
|
|
113
|
+
id: z.string(),
|
|
114
|
+
name: z.string(),
|
|
115
|
+
email: z.string().email(),
|
|
116
|
+
age: z.number().min(0).max(150).optional(),
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
// Parse and validate at entry point
|
|
120
|
+
function handleApiResponse(data: unknown): User {
|
|
121
|
+
return UserSchema.parse(data); // throws on invalid
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Now use confidently everywhere
|
|
125
|
+
const user = handleApiResponse(rawData);
|
|
126
|
+
console.log(user.name); // type-safe, no checks needed
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Benefits
|
|
130
|
+
|
|
131
|
+
- **Trust**: Once parsed, types are reliable
|
|
132
|
+
- **Clarity**: No scattered `typeof` checks
|
|
133
|
+
- **Safety**: Validation happens once, at the boundary
|
|
134
|
+
|
|
135
|
+
### Checklist
|
|
136
|
+
|
|
137
|
+
- [ ] Is all external data (API, router, events) parsed before use?
|
|
138
|
+
- [ ] Are there defensive type checks that could be removed?
|
|
139
|
+
- [ ] Do types accurately represent what the code expects?
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Law 3: Purity — Functions Should Be Predictable
|
|
144
|
+
|
|
145
|
+
### The Problem
|
|
146
|
+
|
|
147
|
+
Functions that mutate external state or have hidden side effects are hard to test, debug, and reuse. You can't predict the output from the input alone.
|
|
148
|
+
|
|
149
|
+
### The Solution
|
|
150
|
+
|
|
151
|
+
A function that **only computes from its inputs and returns a result** — with no hidden mutations — is easy to test, debug, and reuse.
|
|
152
|
+
|
|
153
|
+
### Examples
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
// ❌ BAD — mutates external state as a side effect
|
|
157
|
+
function applyDiscount(cart: Cart) {
|
|
158
|
+
cart.total = cart.total * 0.9; // hidden mutation
|
|
159
|
+
cart.items.forEach(item => {
|
|
160
|
+
item.discounted = true; // another mutation
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Usage
|
|
165
|
+
applyDiscount(myCart);
|
|
166
|
+
// What happened? We don't know from the call.
|
|
167
|
+
// Cart is mutated somewhere else.
|
|
168
|
+
|
|
169
|
+
// ✅ GOOD — returns a new value, no side effects
|
|
170
|
+
function applyDiscount(total: number): number {
|
|
171
|
+
return total * 0.9;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function applyDiscountToCart(cart: Cart): Cart {
|
|
175
|
+
return {
|
|
176
|
+
...cart,
|
|
177
|
+
total: applyDiscount(cart.total),
|
|
178
|
+
items: cart.items.map(item => ({ ...item, discounted: true })),
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Usage
|
|
183
|
+
const discountedCart = applyDiscountToCart(myCart);
|
|
184
|
+
// Clear: we get a new cart, original unchanged
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### When Mutations Are OK
|
|
188
|
+
|
|
189
|
+
Mutations are acceptable in **controlled, explicit** contexts:
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
// ✅ OK — mutation inside Pinia action (controlled)
|
|
193
|
+
export const useCartStore = defineStore('cart', () => {
|
|
194
|
+
const items = ref<CartItem[]>([]);
|
|
195
|
+
|
|
196
|
+
function addItem(item: CartItem) {
|
|
197
|
+
items.value.push(item); // mutation in action
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return { items, addItem };
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
// ✅ OK — mutation in local state (contained)
|
|
204
|
+
function setup() {
|
|
205
|
+
const count = ref(0);
|
|
206
|
+
|
|
207
|
+
function increment() {
|
|
208
|
+
count.value++; // local mutation
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return { count, increment };
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Benefits
|
|
216
|
+
|
|
217
|
+
- **Testability**: Pure functions are trivial to test
|
|
218
|
+
- **Predictability**: Same input → same output, always
|
|
219
|
+
- **Reusability**: No hidden dependencies
|
|
220
|
+
|
|
221
|
+
### Checklist
|
|
222
|
+
|
|
223
|
+
- [ ] Do functions avoid mutating props, external refs, or store state?
|
|
224
|
+
- [ ] Can I predict the output from the input alone?
|
|
225
|
+
- [ ] Are side effects explicit and controlled?
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Law 4: Fail Loud — Invalid States Must Scream
|
|
230
|
+
|
|
231
|
+
### The Problem
|
|
232
|
+
|
|
233
|
+
Silent failures cause mysterious bugs. When an invalid state is reached, the code continues with undefined or null values, leading to crashes later with useless stack traces.
|
|
234
|
+
|
|
235
|
+
### The Solution
|
|
236
|
+
|
|
237
|
+
When an invalid state is reached, **throw a clear descriptive error immediately**. Don't let bad data silently propagate.
|
|
238
|
+
|
|
239
|
+
### Examples
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
// ❌ BAD — silent failure, undefined propagates
|
|
243
|
+
const user = store.users.find(u => u.id === id);
|
|
244
|
+
doSomethingWith(user); // might crash later with useless stack trace
|
|
245
|
+
|
|
246
|
+
// ✅ GOOD — fails immediately with context
|
|
247
|
+
const user = store.users.find(u => u.id === id);
|
|
248
|
+
if (!user) {
|
|
249
|
+
throw new Error(`User with id "${id}" not found in store`);
|
|
250
|
+
}
|
|
251
|
+
doSomethingWith(user); // safe, user exists
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### With Error Boundaries
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
// Component level
|
|
258
|
+
<template>
|
|
259
|
+
<ErrorBoundary>
|
|
260
|
+
<UserProfile :userId="userId" />
|
|
261
|
+
</ErrorBoundary>
|
|
262
|
+
</template>
|
|
263
|
+
|
|
264
|
+
// Store level
|
|
265
|
+
async function fetchUser(id: string): Promise<User> {
|
|
266
|
+
const response = await api.get<User>(`/users/${id}`);
|
|
267
|
+
|
|
268
|
+
if (!response.data) {
|
|
269
|
+
throw new Error(`User ${id} not found (API returned empty)`);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
return response.data;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// API level
|
|
276
|
+
api.interceptors.response.use(
|
|
277
|
+
response => response,
|
|
278
|
+
error => {
|
|
279
|
+
// Transform API errors to descriptive messages
|
|
280
|
+
const message = error.response?.data?.message
|
|
281
|
+
|| error.message
|
|
282
|
+
|| 'Unknown API error';
|
|
283
|
+
|
|
284
|
+
throw new Error(`API Error: ${message}`);
|
|
285
|
+
}
|
|
286
|
+
);
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Benefits
|
|
290
|
+
|
|
291
|
+
- **Fast Feedback**: Know immediately when something is wrong
|
|
292
|
+
- **Clear Context**: Error message explains what failed and why
|
|
293
|
+
- **Easy Debugging**: Stack trace points to the real problem
|
|
294
|
+
|
|
295
|
+
### Checklist
|
|
296
|
+
|
|
297
|
+
- [ ] Do impossible/unexpected states throw descriptive errors?
|
|
298
|
+
- [ ] Are errors silent or do they provide context?
|
|
299
|
+
- [ ] Will debugging be easy if this fails in production?
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## Law 5: Readability — Code Reads Like a Sentence
|
|
304
|
+
|
|
305
|
+
### The Problem
|
|
306
|
+
|
|
307
|
+
Cryptic variable names, magic numbers, and complex logic make code hard to understand without extensive comments.
|
|
308
|
+
|
|
309
|
+
### The Solution
|
|
310
|
+
|
|
311
|
+
Variable names explain intent. Functions do one thing with one responsibility. A reader should understand what the code does **without comments**.
|
|
312
|
+
|
|
313
|
+
### Examples
|
|
314
|
+
|
|
315
|
+
```typescript
|
|
316
|
+
// ❌ BAD — what is 'x'? what is 86400000?
|
|
317
|
+
const x = Date.now() - ts > 86400000;
|
|
318
|
+
if (x) {
|
|
319
|
+
// deactivate user
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// ✅ GOOD — reads like a sentence
|
|
323
|
+
const ONE_DAY_MS = 24 * 60 * 60 * 1000;
|
|
324
|
+
const lastActivityAt = user.lastActivityAt;
|
|
325
|
+
const isExpired = Date.now() - lastActivityAt > ONE_DAY_MS;
|
|
326
|
+
|
|
327
|
+
if (isExpired) {
|
|
328
|
+
deactivateUser(user);
|
|
329
|
+
}
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### Naming Patterns
|
|
333
|
+
|
|
334
|
+
```typescript
|
|
335
|
+
// ❌ BAD — unclear names
|
|
336
|
+
const d = getData();
|
|
337
|
+
const p = process(d);
|
|
338
|
+
const r = save(p);
|
|
339
|
+
|
|
340
|
+
// ✅ GOOD — descriptive names
|
|
341
|
+
const userData = fetchUserData();
|
|
342
|
+
const processedUser = processUserData(userData);
|
|
343
|
+
const savedUser = saveUserToDatabase(processedUser);
|
|
344
|
+
|
|
345
|
+
// ❌ BAD — abbreviated
|
|
346
|
+
const usr = getUser();
|
|
347
|
+
const addr = usr.addr;
|
|
348
|
+
|
|
349
|
+
// ✅ GOOD — full words
|
|
350
|
+
const user = getUser();
|
|
351
|
+
const address = user.address;
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
### Function Naming
|
|
355
|
+
|
|
356
|
+
```typescript
|
|
357
|
+
// ❌ BAD — vague
|
|
358
|
+
function process(data) { ... }
|
|
359
|
+
function handle(event) { ... }
|
|
360
|
+
function doIt() { ... }
|
|
361
|
+
|
|
362
|
+
// ✅ GOOD — specific
|
|
363
|
+
function validateUserCredentials(credentials) { ... }
|
|
364
|
+
function handleUserRegistration(event) { ... }
|
|
365
|
+
function sendWelcomeEmail() { ... }
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### Benefits
|
|
369
|
+
|
|
370
|
+
- **Self-Documenting**: Code explains itself
|
|
371
|
+
- **Easy Review**: Reviewers understand quickly
|
|
372
|
+
- **Maintainable**: Future developers can modify safely
|
|
373
|
+
|
|
374
|
+
### Checklist
|
|
375
|
+
|
|
376
|
+
- [ ] Can a teammate understand each function's purpose from its name?
|
|
377
|
+
- [ ] Are variable names self-documenting?
|
|
378
|
+
- [ ] Does the code flow logically without needing comments?
|
|
379
|
+
|
|
380
|
+
---
|
|
381
|
+
|
|
382
|
+
## Putting It All Together
|
|
383
|
+
|
|
384
|
+
### Example: User Authentication
|
|
385
|
+
|
|
386
|
+
```typescript
|
|
387
|
+
// ❌ BAD — violates all 5 laws
|
|
388
|
+
function login(data) {
|
|
389
|
+
if (data) {
|
|
390
|
+
if (data.email && data.password) {
|
|
391
|
+
const user = users.find(u => u.email === data.email);
|
|
392
|
+
if (user) {
|
|
393
|
+
if (user.password === data.password) {
|
|
394
|
+
currentUser = user;
|
|
395
|
+
return true;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
return false;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// ✅ GOOD — follows all 5 laws
|
|
404
|
+
interface LoginCredentials {
|
|
405
|
+
email: string;
|
|
406
|
+
password: string;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
interface User {
|
|
410
|
+
id: string;
|
|
411
|
+
email: string;
|
|
412
|
+
passwordHash: string;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
function login(credentials: LoginCredentials): User {
|
|
416
|
+
// Law 1: Guard clauses
|
|
417
|
+
if (!credentials.email || !credentials.password) {
|
|
418
|
+
throw new Error('Email and password are required');
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// Law 2: Parsed state (credentials already typed)
|
|
422
|
+
const user = findUserByEmail(credentials.email);
|
|
423
|
+
|
|
424
|
+
// Law 4: Fail loud
|
|
425
|
+
if (!user) {
|
|
426
|
+
throw new Error(`User not found: ${credentials.email}`);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
const isValidPassword = verifyPassword(
|
|
430
|
+
credentials.password,
|
|
431
|
+
user.passwordHash
|
|
432
|
+
);
|
|
433
|
+
|
|
434
|
+
if (!isValidPassword) {
|
|
435
|
+
throw new Error('Invalid password');
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
// Law 3: Purity (returns user, doesn't mutate global)
|
|
439
|
+
return user;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
// Law 5: Readability (clear names, reads like sentence)
|
|
443
|
+
function findUserByEmail(email: string): User | undefined {
|
|
444
|
+
return users.find(user => user.email === email);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
function verifyPassword(password: string, hash: string): boolean {
|
|
448
|
+
return bcrypt.compareSync(password, hash);
|
|
449
|
+
}
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
---
|
|
453
|
+
|
|
454
|
+
## Anti-Patterns Summary
|
|
455
|
+
|
|
456
|
+
| Anti-Pattern | Violates | Solution |
|
|
457
|
+
|-------------|----------|----------|
|
|
458
|
+
| Deeply nested conditionals | Law 1 | Guard clauses at top |
|
|
459
|
+
| Scattered type checks | Law 2 | Parse at boundary |
|
|
460
|
+
| Mutating props/state | Law 3 | Return new values |
|
|
461
|
+
| Silent failures | Law 4 | Throw descriptive errors |
|
|
462
|
+
| Cryptic names/numbers | Law 5 | Self-documenting code |
|
|
463
|
+
|
|
464
|
+
---
|
|
465
|
+
|
|
466
|
+
## Review Checklist
|
|
467
|
+
|
|
468
|
+
When reviewing code, check each law:
|
|
469
|
+
|
|
470
|
+
```markdown
|
|
471
|
+
## Code Philosophy Review
|
|
472
|
+
|
|
473
|
+
### Law 1: Guard Clauses
|
|
474
|
+
- [ ] Edge cases handled at top?
|
|
475
|
+
- [ ] Happy path visible?
|
|
476
|
+
- [ ] No deep nesting?
|
|
477
|
+
|
|
478
|
+
### Law 2: Parsed State
|
|
479
|
+
- [ ] External data parsed at entry?
|
|
480
|
+
- [ ] Types trusted inside?
|
|
481
|
+
- [ ] No scattered checks?
|
|
482
|
+
|
|
483
|
+
### Law 3: Purity
|
|
484
|
+
- [ ] No prop mutations?
|
|
485
|
+
- [ ] No hidden side effects?
|
|
486
|
+
- [ ] Functions predictable?
|
|
487
|
+
|
|
488
|
+
### Law 4: Fail Loud
|
|
489
|
+
- [ ] Invalid states throw?
|
|
490
|
+
- [ ] Errors descriptive?
|
|
491
|
+
- [ ] Debugging easy?
|
|
492
|
+
|
|
493
|
+
### Law 5: Readability
|
|
494
|
+
- [ ] Names self-documenting?
|
|
495
|
+
- [ ] Logic flows clearly?
|
|
496
|
+
- [ ] No magic numbers?
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
---
|
|
500
|
+
|
|
501
|
+
## Remember
|
|
502
|
+
|
|
503
|
+
**These laws are not rules — they are principles.**
|
|
504
|
+
|
|
505
|
+
Use them to guide your thinking:
|
|
506
|
+
- **When writing**: Follow them to write better code
|
|
507
|
+
- **When reviewing**: Use them to identify issues
|
|
508
|
+
- **When refactoring**: Apply them to improve existing code
|
|
509
|
+
|
|
510
|
+
**The goal is code that is clear, correct, and performant.**
|
|
511
|
+
|
|
512
|
+
These laws help you achieve that goal consistently.
|