sdlc-framework 1.0.0

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.
Files changed (53) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +321 -0
  3. package/bin/install.js +193 -0
  4. package/package.json +39 -0
  5. package/src/commands/close.md +200 -0
  6. package/src/commands/debug.md +124 -0
  7. package/src/commands/fast.md +149 -0
  8. package/src/commands/fix.md +104 -0
  9. package/src/commands/help.md +144 -0
  10. package/src/commands/hotfix.md +99 -0
  11. package/src/commands/impl.md +142 -0
  12. package/src/commands/init.md +93 -0
  13. package/src/commands/milestone.md +136 -0
  14. package/src/commands/pause.md +115 -0
  15. package/src/commands/research.md +136 -0
  16. package/src/commands/resume.md +103 -0
  17. package/src/commands/review.md +195 -0
  18. package/src/commands/spec.md +164 -0
  19. package/src/commands/status.md +118 -0
  20. package/src/commands/verify.md +153 -0
  21. package/src/references/clarification-strategy.md +352 -0
  22. package/src/references/engineering-laws.md +374 -0
  23. package/src/references/loop-phases.md +331 -0
  24. package/src/references/playwright-testing.md +298 -0
  25. package/src/references/prompt-detection.md +264 -0
  26. package/src/references/sub-agent-strategy.md +260 -0
  27. package/src/rules/commands.md +180 -0
  28. package/src/rules/style.md +354 -0
  29. package/src/rules/templates.md +238 -0
  30. package/src/rules/workflows.md +314 -0
  31. package/src/templates/HANDOFF.md +121 -0
  32. package/src/templates/LAWS.md +521 -0
  33. package/src/templates/PROJECT.md +112 -0
  34. package/src/templates/REVIEW.md +145 -0
  35. package/src/templates/ROADMAP.md +101 -0
  36. package/src/templates/SPEC.md +231 -0
  37. package/src/templates/STATE.md +106 -0
  38. package/src/templates/SUMMARY.md +126 -0
  39. package/src/workflows/close-phase.md +189 -0
  40. package/src/workflows/debug-flow.md +302 -0
  41. package/src/workflows/fast-forward.md +340 -0
  42. package/src/workflows/fix-findings.md +235 -0
  43. package/src/workflows/hotfix-flow.md +190 -0
  44. package/src/workflows/impl-phase.md +229 -0
  45. package/src/workflows/init-project.md +249 -0
  46. package/src/workflows/milestone-management.md +169 -0
  47. package/src/workflows/pause-work.md +153 -0
  48. package/src/workflows/research.md +219 -0
  49. package/src/workflows/resume-project.md +159 -0
  50. package/src/workflows/review-phase.md +337 -0
  51. package/src/workflows/spec-phase.md +379 -0
  52. package/src/workflows/transition-phase.md +203 -0
  53. package/src/workflows/verify-phase.md +280 -0
@@ -0,0 +1,374 @@
1
+ # Engineering Laws Reference
2
+
3
+ This document provides a deep dive into each engineering law enforced by the SDLC framework. It is loaded via `@references/engineering-laws.md` when reviewing code or when a developer needs to understand why a law exists and how it applies to AI-assisted development.
4
+
5
+ ---
6
+
7
+ ## SOLID Principles
8
+
9
+ ### Plain English
10
+
11
+ SOLID is five rules for organizing code so it stays flexible as it grows:
12
+
13
+ 1. **Single Responsibility (S):** Each piece of code does one thing. A user service handles user logic. It does not also send emails.
14
+ 2. **Open/Closed (O):** Add new behavior by writing new code, not by editing existing code. Use interfaces, plugins, or strategy patterns.
15
+ 3. **Liskov Substitution (L):** Any implementation of an interface can replace any other without breaking the system.
16
+ 4. **Interface Segregation (I):** Do not force code to depend on methods it does not use. Keep interfaces small and focused.
17
+ 5. **Dependency Inversion (D):** High-level code depends on abstractions (interfaces), not on low-level details (concrete classes).
18
+
19
+ ### How It Applies to AI-Assisted Development
20
+
21
+ AI code generators tend to produce "complete" solutions in a single file. They pack everything together because they optimize for generating a working answer in one shot. This naturally violates Single Responsibility — the AI does not have an incentive to split code across files.
22
+
23
+ AI also tends to create concrete implementations rather than abstractions. When you ask "build a user service," the AI writes `new PostgresRepository()` directly, violating Dependency Inversion. It does not know your project has an injection system.
24
+
25
+ ### Common AI-Generated Violations
26
+
27
+ **God service pattern:**
28
+ AI generates a service that handles authentication, profile updates, email notifications, and audit logging all in one class. Each method works, but the class has 400 lines and 6 different reasons to change.
29
+
30
+ **Concrete coupling:**
31
+ ```typescript
32
+ // AI writes this because it is "complete" and works immediately
33
+ class OrderService {
34
+ private db = new PostgresClient('postgres://localhost:5432/orders')
35
+ private emailer = new SendGridClient('sg-api-key-here')
36
+ }
37
+ ```
38
+ Two SOLID violations (concrete dependencies) plus a security violation (hardcoded credentials) in two lines.
39
+
40
+ **Fat interfaces:**
41
+ AI creates one interface with every possible method, then forces all implementations to stub out methods they do not need.
42
+
43
+ ### How the Reviewer Detects Violations
44
+
45
+ - Counts methods per class. More than 7-8 methods suggests multiple responsibilities.
46
+ - Searches for `new` keyword inside service classes — concrete instantiation signals dependency inversion violations.
47
+ - Checks that every interface has multiple implementations or is designed for future replacement.
48
+ - Verifies that interface methods are all used by at least one consumer.
49
+
50
+ ### Real-World Consequences
51
+
52
+ A monolithic service cannot be tested in isolation. To test user creation, you need a real database, a real email provider, and a real audit log. Tests become slow, flaky, and expensive. Developers stop writing them. Bugs ship. Eventually, the team says "we need to rewrite" and the cycle restarts — 3 months of work lost.
53
+
54
+ ---
55
+
56
+ ## DRY (Don't Repeat Yourself)
57
+
58
+ ### Plain English
59
+
60
+ Every piece of knowledge should exist in exactly one place. If you need the same logic in two places, extract it into a shared function and call it from both places. Duplication is not just about identical code — it is about identical concepts.
61
+
62
+ ### How It Applies to AI-Assisted Development
63
+
64
+ AI has no memory across prompts (unless explicitly given context). If you ask it to build Feature A and later ask it to build Feature B, it will write fresh implementations of shared logic — validation, formatting, error handling — even if identical code already exists.
65
+
66
+ This is the single most common issue with AI-generated code: it works, but it duplicates existing patterns because the AI did not search the codebase first.
67
+
68
+ ### Common AI-Generated Violations
69
+
70
+ **Duplicate validation logic:**
71
+ The AI writes email validation in the user controller, then writes it again in the contact form handler, then again in the newsletter signup. Three identical regex checks in three files.
72
+
73
+ **Duplicate error response formatting:**
74
+ Every controller method manually constructs `{ status: 'error', message: err.message, code: 400 }` instead of using the existing error response factory.
75
+
76
+ **Duplicate type definitions:**
77
+ The AI defines `interface User { id: string; name: string; email: string }` in three different files because each prompt started fresh.
78
+
79
+ ### How the Reviewer Detects Violations
80
+
81
+ - Searches for identical or near-identical code blocks across files.
82
+ - Checks if new utility functions duplicate existing ones in `src/common/utils/`.
83
+ - Looks for inline implementations of logic that exists in a shared library.
84
+ - Verifies that type definitions are imported from canonical sources, not redefined.
85
+
86
+ ### Real-World Consequences
87
+
88
+ When a validation rule changes (email regex updated for new TLD), the developer fixes one copy and misses the others. Users see inconsistent behavior — "my email works on the signup page but not on the contact form." Debugging takes hours because the developer assumes there is one validation function, not three.
89
+
90
+ ---
91
+
92
+ ## YAGNI (You Ain't Gonna Need It)
93
+
94
+ ### Plain English
95
+
96
+ Do not build things you do not need right now. If the spec says "users can log in with email and password," do not build OAuth, SAML, magic links, and biometric auth "for the future." Build email/password. When the spec says "add OAuth," build OAuth then.
97
+
98
+ ### How It Applies to AI-Assisted Development
99
+
100
+ AI optimizes for impressiveness. Ask it to build a REST endpoint and it will add pagination, filtering, sorting, caching, rate limiting, and webhook support — even if you asked for a simple GET endpoint. The AI is trying to be helpful, but it is building infrastructure you did not ask for.
101
+
102
+ This extra code looks professional but it has real costs: it must be tested, maintained, and documented. It creates surface area for bugs. It confuses developers who wonder "is the caching layer required? Can I remove it?"
103
+
104
+ ### Common AI-Generated Violations
105
+
106
+ **Premature abstraction layers:**
107
+ Spec says "store users in PostgreSQL." AI builds a generic repository pattern with adapters for five databases, a caching layer with Redis, and a query builder abstraction.
108
+
109
+ **Configuration nobody asked for:**
110
+ Spec says "send welcome email." AI adds configurable email templates, A/B testing support, scheduled sending, and retry queues.
111
+
112
+ **Plugin architecture for a single use case:**
113
+ Spec says "validate input." AI builds a pluggable validation framework with custom rule registration, async validators, and i18n error messages.
114
+
115
+ ### How the Reviewer Detects Violations
116
+
117
+ - Maps every file, function, and class back to a task in the spec. Anything that cannot be traced to a spec task is YAGNI.
118
+ - Looks for abstract base classes with only one concrete implementation.
119
+ - Checks for configuration options that are not used or tested.
120
+ - Identifies "framework code" (event buses, plugin registries, middleware chains) when the spec asked for specific behavior.
121
+
122
+ ### Real-World Consequences
123
+
124
+ Extra code is not free. A pagination system nobody uses still needs tests (which nobody writes because nobody uses it). When the real pagination requirement arrives months later, it has different needs than what was pre-built. Now the developer must either force-fit the new requirement into the old abstraction or rip out the old code and write it properly. Either way, the pre-built code wasted time twice — once to write, once to remove.
125
+
126
+ ---
127
+
128
+ ## Clean Code
129
+
130
+ ### Plain English
131
+
132
+ Code should be small, simple, and obvious. Functions should be short (max 40 lines), take few arguments (max 3), and have shallow nesting (max 3 levels). If you need a comment to explain what code does, the code is too complex — simplify it.
133
+
134
+ ### How It Applies to AI-Assisted Development
135
+
136
+ AI generates code in large blocks. It does not naturally refactor long functions into smaller helpers because it writes code in a single pass. A 100-line function with 5 levels of nesting is common in AI output because the AI is solving the problem, not crafting maintainable code.
137
+
138
+ AI also tends to use complex expressions (nested ternaries, long chains of method calls) because they are more token-efficient than explicit if/else blocks.
139
+
140
+ ### Common AI-Generated Violations
141
+
142
+ **Functions that are too long:**
143
+ AI writes a single function that reads a file, parses it, validates it, transforms it, and writes the output. Each step is correct, but the function is 80 lines with no helper extraction.
144
+
145
+ **Deep nesting:**
146
+ ```typescript
147
+ if (user) {
148
+ if (user.isActive) {
149
+ if (user.hasPermission('admin')) {
150
+ if (request.isValid) {
151
+ // actual logic buried 4 levels deep
152
+ }
153
+ }
154
+ }
155
+ }
156
+ ```
157
+
158
+ **Nested ternaries:**
159
+ ```typescript
160
+ const label = status === 'active' ? 'Active' : status === 'pending' ? 'Pending' : status === 'suspended' ? 'Suspended' : 'Unknown'
161
+ ```
162
+
163
+ ### How the Reviewer Detects Violations
164
+
165
+ - Counts lines per function. Any function over 40 lines is flagged.
166
+ - Counts parameters per function. More than 3 triggers a "group into object" suggestion.
167
+ - Measures nesting depth. More than 3 levels triggers a "use guard clauses" suggestion.
168
+ - Searches for nested ternary operators.
169
+ - Looks for comments that explain "what" instead of "why."
170
+
171
+ ### Real-World Consequences
172
+
173
+ A 100-line function cannot be partially tested. You test the whole thing or nothing. When a bug is reported, you re-read all 100 lines to understand the flow. When a requirement changes, you must understand all 100 lines to know where to make the change. Small functions with clear names are grep-able, testable, and replaceable.
174
+
175
+ ---
176
+
177
+ ## Security
178
+
179
+ ### Plain English
180
+
181
+ Never hardcode secrets. Always validate user input. Always use parameterized queries. Always sanitize file paths. Security is not a feature you add — it is a constraint on every feature you build.
182
+
183
+ ### How It Applies to AI-Assisted Development
184
+
185
+ AI generates examples with placeholder credentials that look like real credentials. `const API_KEY = 'sk-1234'` is meant as a placeholder but gets committed as-is. The AI does not know about your `.env` setup or your secrets manager.
186
+
187
+ AI also tends to trust input. When generating an endpoint, it reads `req.body.id` and uses it directly in a query without validation. The AI assumes the input is valid because in the prompt, it was.
188
+
189
+ ### Common AI-Generated Violations
190
+
191
+ **Hardcoded credentials in examples:**
192
+ ```typescript
193
+ const stripe = new Stripe('sk_live_actualkey123')
194
+ const db = new Client({ connectionString: 'postgres://admin:password@prod-db:5432' })
195
+ ```
196
+
197
+ **Unvalidated user input:**
198
+ ```typescript
199
+ app.get('/file/:path', (req, res) => {
200
+ res.sendFile(req.params.path) // directory traversal
201
+ })
202
+ ```
203
+
204
+ **String-concatenated SQL:**
205
+ ```typescript
206
+ const query = `SELECT * FROM users WHERE name = '${req.body.name}'`
207
+ ```
208
+
209
+ ### How the Reviewer Detects Violations
210
+
211
+ - Searches for patterns that look like API keys, tokens, passwords, or connection strings in source files.
212
+ - Checks that every route handler validates its input before processing.
213
+ - Searches for string interpolation or concatenation in SQL queries.
214
+ - Verifies that file path operations use `path.resolve` and check against a safe base directory.
215
+ - Confirms `.env` files are in `.gitignore`.
216
+
217
+ ### Real-World Consequences
218
+
219
+ Hardcoded credentials in git history persist forever — even after deletion, they exist in commit history. Automated scanners find them within hours. SQL injection can read, modify, or delete your entire database. Path traversal can expose any file on your server. These are not theoretical risks; they are the most commonly exploited vulnerabilities in web applications.
220
+
221
+ ---
222
+
223
+ ## Testing
224
+
225
+ ### Plain English
226
+
227
+ If you change how code behaves, you write a test that proves the new behavior works. Every function that could fail should have a test for the success case, the failure case, and the edge cases. Tests are the proof that your code works — without them, you are guessing.
228
+
229
+ ### How It Applies to AI-Assisted Development
230
+
231
+ AI can write excellent tests — but only if you ask. Left to its own devices, AI generates production code without tests or generates tests that assert nothing meaningful (`expect(result).toBeDefined()`). The SDLC framework makes testing a hard requirement, not an afterthought.
232
+
233
+ AI-generated tests also tend to test implementation rather than behavior. They mock internals and assert on internal method calls instead of testing observable outcomes. This makes tests brittle — any refactor breaks them even if behavior is preserved.
234
+
235
+ ### Common AI-Generated Violations
236
+
237
+ **Tests that assert existence, not correctness:**
238
+ ```typescript
239
+ test('creates user', () => {
240
+ const user = createUser({ name: 'Alice' })
241
+ expect(user).toBeDefined() // proves nothing about correctness
242
+ })
243
+ ```
244
+
245
+ **Tests that test implementation:**
246
+ ```typescript
247
+ test('creates user', () => {
248
+ const spy = jest.spyOn(repo, 'save')
249
+ createUser({ name: 'Alice' })
250
+ expect(spy).toHaveBeenCalledTimes(1) // tests HOW, not WHAT
251
+ })
252
+ ```
253
+
254
+ **Missing edge case tests:**
255
+ AI writes one happy-path test and considers testing complete. No tests for null input, empty strings, duplicate entries, or concurrent access.
256
+
257
+ ### How the Reviewer Detects Violations
258
+
259
+ - Checks that every new/modified function has at least one corresponding test.
260
+ - Reads assertions to verify they test specific values, not just existence.
261
+ - Looks for edge case coverage: null, undefined, empty, boundary values.
262
+ - Verifies tests run independently (no shared mutable state).
263
+ - Confirms test names describe scenario and expected outcome.
264
+
265
+ ### Real-World Consequences
266
+
267
+ Without tests, every code change is a roll of the dice. You modify a utility function and silently break three features that depend on it. You discover the breakage when a user reports it, days later. With tests, the CI pipeline catches it in 30 seconds and tells you exactly which behavior broke and where.
268
+
269
+ ---
270
+
271
+ ## Naming
272
+
273
+ ### Plain English
274
+
275
+ Names are the most-read documentation in your codebase. A well-named function does not need a comment. Use full words, not abbreviations. Name functions for what they do (verbs), variables for what they hold (nouns), and booleans as yes/no questions (`isValid`, `hasPermission`).
276
+
277
+ ### How It Applies to AI-Assisted Development
278
+
279
+ AI tends to use short, generic names in generated code: `data`, `result`, `item`, `val`, `cb`. This is because AI training data includes millions of examples with terse naming. The AI optimizes for "plausible code" rather than "code a human will maintain."
280
+
281
+ AI also inconsistently names the same concept — `user` in one file, `account` in another, `profile` in a third — because each generation is independent.
282
+
283
+ ### Common AI-Generated Violations
284
+
285
+ **Generic names:**
286
+ ```typescript
287
+ function process(data: any) {
288
+ const result = data.map((item: any) => transform(item))
289
+ return result.filter((r: any) => r.valid)
290
+ }
291
+ ```
292
+
293
+ **Inconsistent naming:**
294
+ ```typescript
295
+ // File A: UserService with getUser()
296
+ // File B: AccountManager with fetchAccount()
297
+ // File C: ProfileHandler with loadProfile()
298
+ // All three refer to the same domain concept
299
+ ```
300
+
301
+ **Abbreviations:**
302
+ ```typescript
303
+ const usr = getUsr(req.params.usrId)
304
+ const cfg = loadCfg()
305
+ const btn = doc.querySelector('.btn')
306
+ ```
307
+
308
+ ### How the Reviewer Detects Violations
309
+
310
+ - Searches for common generic names: `data`, `result`, `item`, `temp`, `val`, `cb`, `fn`.
311
+ - Searches for common abbreviations: `usr`, `btn`, `msg`, `cfg`, `ctx`, `req`, `res` (outside of framework conventions).
312
+ - Checks that boolean variables start with `is`, `has`, `can`, `should`, or similar question words.
313
+ - Checks that function names start with verbs.
314
+ - Verifies naming consistency across files for the same domain concept.
315
+
316
+ ### Real-World Consequences
317
+
318
+ Bad names force every reader to build a mental translation table. "What does `d` mean here? Let me scroll up... it's the database connection." This takes 2-3 seconds per encounter, multiplied by every developer, every time they read the code. Over a year, a poorly named codebase costs the team hundreds of hours of unnecessary mental overhead.
319
+
320
+ ---
321
+
322
+ ## Error Handling
323
+
324
+ ### Plain English
325
+
326
+ When something goes wrong, your code must either handle it (take corrective action) or report it (log and rethrow). Silently ignoring errors is the worst possible choice — it hides bugs that surface later in harder-to-diagnose ways.
327
+
328
+ ### How It Applies to AI-Assisted Development
329
+
330
+ AI wraps risky code in try/catch but often leaves the catch block empty or with just a `console.log`. This is because AI training data is full of tutorials and examples that use `catch (e) {}` as a shortcut. The AI does not know that your production system needs proper error reporting.
331
+
332
+ AI also tends to throw generic `Error` objects instead of domain-specific exceptions. `throw new Error('failed')` tells you nothing about what failed, where, or why.
333
+
334
+ ### Common AI-Generated Violations
335
+
336
+ **Empty catch blocks:**
337
+ ```typescript
338
+ try {
339
+ await sendEmail(user.email, template)
340
+ } catch (e) {
341
+ // AI left this empty "to prevent crashes"
342
+ }
343
+ ```
344
+ The email silently fails. The user never receives it. Nobody knows.
345
+
346
+ **Generic errors:**
347
+ ```typescript
348
+ if (!user) throw new Error('error')
349
+ if (!order) throw new Error('not found')
350
+ if (!payment) throw new Error('invalid')
351
+ ```
352
+ When this hits the error log, the developer sees "error" with no context.
353
+
354
+ **Swallowed exceptions:**
355
+ ```typescript
356
+ try {
357
+ await processPayment(order)
358
+ } catch (error) {
359
+ console.log('payment failed') // logged and forgotten
360
+ return { success: true } // lies to the caller
361
+ }
362
+ ```
363
+
364
+ ### How the Reviewer Detects Violations
365
+
366
+ - Searches for empty catch blocks: `catch` followed by `{}` or just a comment.
367
+ - Searches for `console.log` inside catch blocks without a rethrow.
368
+ - Checks that custom exception classes exist and are used instead of generic `Error`.
369
+ - Verifies that error messages include context (entity ID, operation name, user context).
370
+ - Confirms that catch blocks either handle the error (retry, fallback) or rethrow it.
371
+
372
+ ### Real-World Consequences
373
+
374
+ A swallowed payment error means a customer is charged but their order is not fulfilled. An empty catch on a database write means data is lost without anyone knowing. A generic error message means the on-call engineer spends 30 minutes figuring out which "not found" error triggered the alert. Proper error handling is the difference between "we fixed it in 5 minutes" and "we lost data and don't know when it started."