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,521 @@
1
+ # Engineering Laws Template
2
+
3
+ This template defines the engineering laws configuration stored at `.sdlc/LAWS.md`. Laws are enforced during `/sdlc:review`. Violations at the configured severity level block loop closure. This is the backbone of quality enforcement — every line of code passes through these laws before it ships.
4
+
5
+ ---
6
+
7
+ ```markdown
8
+ # Engineering Laws
9
+
10
+ These laws are enforced at /sdlc:review. Violations at configured severity block loop closure.
11
+
12
+ ## Configuration
13
+
14
+ | Law | Severity | Description |
15
+ |-----|----------|-------------|
16
+ | SOLID | error | Single Responsibility, Open/Closed, Liskov, Interface Segregation, Dependency Inversion |
17
+ | DRY | error | Don't Repeat Yourself — search before create, no duplicate logic |
18
+ | YAGNI | error | You Ain't Gonna Need It — only build what's in the spec |
19
+ | CLEAN_CODE | error | Max 40 lines/function, max 3 params, max 3 nesting levels |
20
+ | SECURITY | error | No hardcoded secrets, input validation, parameterized queries |
21
+ | TESTING | error | Every behavior change needs tests, meaningful assertions |
22
+ | NAMING | warning | Descriptive names, no abbreviations, self-documenting |
23
+ | ERROR_HANDLING | error | No empty catch, domain-specific exceptions, no swallowed errors |
24
+
25
+ Severity levels: error (blocks /sdlc:close) | warning (reported, doesn't block) | info (noted only)
26
+
27
+ ---
28
+
29
+ ## SOLID — Structural Integrity
30
+
31
+ ### What It Means
32
+
33
+ SOLID is five principles that keep code flexible and maintainable. Each class, module, or function should have one reason to change (S), be extendable without editing existing code (O), be replaceable by subtypes without breaking anything (L), not force consumers to depend on methods they do not use (I), and depend on abstractions rather than concrete implementations (D).
34
+
35
+ ### What the Reviewer Checks
36
+
37
+ - **S — Single Responsibility:** Does each class/module/function do exactly one thing? Does it have exactly one reason to change?
38
+ - **O — Open/Closed:** Can new behavior be added by extending (new class, new handler) rather than modifying existing code?
39
+ - **L — Liskov Substitution:** Can any subclass/implementation replace its parent/interface without the caller knowing?
40
+ - **I — Interface Segregation:** Are interfaces small and focused? Does any consumer import methods it never calls?
41
+ - **D — Dependency Inversion:** Do high-level modules depend on abstractions? Are concrete implementations injected, not instantiated?
42
+
43
+ ### Violations and Fixes
44
+
45
+ **Violation — God class:**
46
+ ```typescript
47
+ // BAD: UserService handles auth, profile, notifications, billing
48
+ class UserService {
49
+ login() { /* ... */ }
50
+ updateProfile() { /* ... */ }
51
+ sendNotification() { /* ... */ }
52
+ processPayment() { /* ... */ }
53
+ }
54
+ ```
55
+
56
+ **Fix — Split by responsibility:**
57
+ ```typescript
58
+ // GOOD: Each service owns one domain
59
+ class AuthService { login() { /* ... */ } }
60
+ class ProfileService { updateProfile() { /* ... */ } }
61
+ class NotificationService { sendNotification() { /* ... */ } }
62
+ class BillingService { processPayment() { /* ... */ } }
63
+ ```
64
+
65
+ **Violation — Concrete dependency:**
66
+ ```typescript
67
+ // BAD: Controller creates its own service
68
+ class UserController {
69
+ private service = new UserService(new PostgresRepo())
70
+ }
71
+ ```
72
+
73
+ **Fix — Inject abstraction:**
74
+ ```typescript
75
+ // GOOD: Depend on interface, inject via constructor
76
+ class UserController {
77
+ constructor(private readonly userService: UserServiceInterface) {}
78
+ }
79
+ ```
80
+
81
+ ### Why It Matters
82
+
83
+ Code that violates SOLID becomes rigid. One change breaks unrelated features. Testing requires mocking the entire world. New developers are afraid to touch anything. Eventually the team rewrites instead of extending, wasting weeks or months.
84
+
85
+ ---
86
+
87
+ ## DRY — No Duplicate Logic
88
+
89
+ ### What It Means
90
+
91
+ Every piece of knowledge should have a single, authoritative representation in the codebase. Before writing any new code, search for existing implementations. If you find one, use it. If you need a variation, extend the existing code rather than duplicating it.
92
+
93
+ ### What the Reviewer Checks
94
+
95
+ - Are there two or more functions/methods with the same logic (even if variable names differ)?
96
+ - Is the same validation logic written in multiple places?
97
+ - Are there multiple constants with the same value but different names?
98
+ - Did the developer search for existing helpers/utilities before writing new ones?
99
+ - Are there inline implementations of logic that already exists in a shared utility?
100
+
101
+ ### Violations and Fixes
102
+
103
+ **Violation — Duplicated validation:**
104
+ ```typescript
105
+ // In user.controller.ts
106
+ function validateEmail(email: string): boolean {
107
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)
108
+ }
109
+
110
+ // In contact.controller.ts (same logic, different file)
111
+ function isValidEmail(input: string): boolean {
112
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(input)
113
+ }
114
+ ```
115
+
116
+ **Fix — Single shared utility:**
117
+ ```typescript
118
+ // In src/common/utils/validation.ts
119
+ export function isValidEmail(email: string): boolean {
120
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)
121
+ }
122
+
123
+ // Both controllers import from the same source
124
+ import { isValidEmail } from '@/common/utils/validation'
125
+ ```
126
+
127
+ **Violation — Repeated error response shape:**
128
+ ```typescript
129
+ // Inline in every controller method
130
+ return { status: 'error', message: err.message, code: 400 }
131
+ ```
132
+
133
+ **Fix — Shared error factory:**
134
+ ```typescript
135
+ // In src/common/errors/error-response.ts
136
+ export function createErrorResponse(message: string, code: number): ErrorResponse {
137
+ return { status: 'error', message, code }
138
+ }
139
+ ```
140
+
141
+ ### Why It Matters
142
+
143
+ Duplicated logic means duplicated bugs. Fix a bug in one place, the copy still has it. Over time, copies diverge — slightly different behavior in different places. Users see inconsistent results. Developers spend hours hunting down "which version is right."
144
+
145
+ ---
146
+
147
+ ## YAGNI — Only Build What Is Specified
148
+
149
+ ### What It Means
150
+
151
+ Do not build features, abstractions, or infrastructure that are not explicitly required by the current spec. "We might need this later" is not a justification. Build for today's requirements. If tomorrow needs something different, build it tomorrow.
152
+
153
+ ### What the Reviewer Checks
154
+
155
+ - Does every file, function, and class trace back to a task in the spec?
156
+ - Are there abstract base classes with only one implementation?
157
+ - Are there configuration options nobody asked for?
158
+ - Are there API endpoints not in the spec?
159
+ - Are there database columns not required by any acceptance criterion?
160
+ - Is there "framework code" (plugin systems, event buses, middleware chains) when the spec asked for a simple function?
161
+
162
+ ### Violations and Fixes
163
+
164
+ **Violation — Premature abstraction:**
165
+ ```typescript
166
+ // Spec says "store users in PostgreSQL"
167
+ // Developer builds a generic repository pattern with adapters for
168
+ // PostgreSQL, MongoDB, Redis, and SQLite "just in case"
169
+ interface StorageAdapter<T> { /* ... */ }
170
+ class PostgresAdapter<T> implements StorageAdapter<T> { /* ... */ }
171
+ class MongoAdapter<T> implements StorageAdapter<T> { /* ... */ }
172
+ class RedisAdapter<T> implements StorageAdapter<T> { /* ... */ }
173
+ class SQLiteAdapter<T> implements StorageAdapter<T> { /* ... */ }
174
+ ```
175
+
176
+ **Fix — Build what is needed:**
177
+ ```typescript
178
+ // Just the PostgreSQL repository the spec requires
179
+ class UserRepository {
180
+ async findById(id: string): Promise<User | null> { /* ... */ }
181
+ async save(user: User): Promise<void> { /* ... */ }
182
+ }
183
+ ```
184
+
185
+ **Violation — Unused configuration:**
186
+ ```typescript
187
+ // Spec says nothing about rate limiting
188
+ export const config = {
189
+ rateLimitEnabled: true,
190
+ rateLimitWindow: 60000,
191
+ rateLimitMax: 100,
192
+ }
193
+ ```
194
+
195
+ **Fix — Remove it:**
196
+ ```typescript
197
+ // If it is not in the spec, it does not exist
198
+ ```
199
+
200
+ ### Why It Matters
201
+
202
+ Unused code is not free. It must be read, understood, tested, and maintained. It creates false signals ("is this used? I better not delete it"). It adds complexity that slows down the team. The most maintainable code is code that does not exist.
203
+
204
+ ---
205
+
206
+ ## CLEAN_CODE — Readable and Maintainable
207
+
208
+ ### What It Means
209
+
210
+ Code is read far more often than it is written. Clean code is small functions (max 40 lines), few parameters (max 3), shallow nesting (max 3 levels), and clear flow (guard clauses, early returns). If you need a comment to explain what code does, the code is not clean enough.
211
+
212
+ ### What the Reviewer Checks
213
+
214
+ - **Function length:** Is any function longer than 40 lines? Count them.
215
+ - **Parameter count:** Does any function take more than 3 parameters? Group into an object.
216
+ - **Nesting depth:** Are there more than 3 levels of indentation? Use guard clauses.
217
+ - **Ternary chains:** Are there nested ternaries? Use if/else.
218
+ - **Comments explaining "what":** Is there a comment that describes what code does (not why)? Rename or restructure instead.
219
+ - **Dead code:** Are there commented-out blocks, unreachable branches, or unused variables?
220
+
221
+ ### Violations and Fixes
222
+
223
+ **Violation — Deep nesting:**
224
+ ```typescript
225
+ function processOrder(order: Order) {
226
+ if (order) {
227
+ if (order.items.length > 0) {
228
+ if (order.payment) {
229
+ if (order.payment.verified) {
230
+ // actual logic buried 4 levels deep
231
+ }
232
+ }
233
+ }
234
+ }
235
+ }
236
+ ```
237
+
238
+ **Fix — Guard clauses:**
239
+ ```typescript
240
+ function processOrder(order: Order) {
241
+ if (!order) return
242
+ if (order.items.length === 0) return
243
+ if (!order.payment) return
244
+ if (!order.payment.verified) return
245
+
246
+ // actual logic at top level
247
+ }
248
+ ```
249
+
250
+ **Violation — Too many parameters:**
251
+ ```typescript
252
+ function createUser(
253
+ name: string,
254
+ email: string,
255
+ age: number,
256
+ role: string,
257
+ department: string,
258
+ managerId: string,
259
+ ) { /* ... */ }
260
+ ```
261
+
262
+ **Fix — Parameter object:**
263
+ ```typescript
264
+ interface CreateUserParams {
265
+ name: string
266
+ email: string
267
+ age: number
268
+ role: string
269
+ department: string
270
+ managerId: string
271
+ }
272
+
273
+ function createUser(params: CreateUserParams) { /* ... */ }
274
+ ```
275
+
276
+ ### Why It Matters
277
+
278
+ Complex code is where bugs hide. Deep nesting makes it impossible to trace execution paths. Long functions do too many things and break in unexpected ways. Too many parameters mean the function has too many responsibilities. Clean code is debuggable code.
279
+
280
+ ---
281
+
282
+ ## SECURITY — No Vulnerabilities
283
+
284
+ ### What It Means
285
+
286
+ Security is not a feature — it is a constraint on all features. Never hardcode secrets. Always validate input from users, APIs, and files. Use parameterized queries for all database access. Sanitize file paths. Use established security middleware.
287
+
288
+ ### What the Reviewer Checks
289
+
290
+ - **Hardcoded secrets:** Are there API keys, passwords, tokens, or connection strings in source files?
291
+ - **Input validation:** Is every user-facing input validated at the system boundary (controller, API handler, CLI parser)?
292
+ - **SQL injection:** Are all database queries parameterized? Is any query built with string concatenation?
293
+ - **Path traversal:** Are file paths sanitized? Can a user input `../../etc/passwd`?
294
+ - **Authentication/Authorization:** Are protected routes actually checking credentials? Is there a gap where unauthenticated access is possible?
295
+ - **.env files:** Are `.env` files in `.gitignore`? Are there example `.env.example` files instead?
296
+ - **Dependencies:** Are there known vulnerable dependencies?
297
+
298
+ ### Violations and Fixes
299
+
300
+ **Violation — Hardcoded secret:**
301
+ ```typescript
302
+ const API_KEY = 'sk-1234567890abcdef'
303
+ const dbUrl = 'postgres://admin:password@localhost:5432/mydb'
304
+ ```
305
+
306
+ **Fix — Environment variables:**
307
+ ```typescript
308
+ const API_KEY = process.env.API_KEY
309
+ const dbUrl = process.env.DATABASE_URL
310
+ ```
311
+
312
+ **Violation — SQL injection:**
313
+ ```typescript
314
+ const query = `SELECT * FROM users WHERE email = '${userInput}'`
315
+ ```
316
+
317
+ **Fix — Parameterized query:**
318
+ ```typescript
319
+ const query = 'SELECT * FROM users WHERE email = $1'
320
+ const result = await db.query(query, [userInput])
321
+ ```
322
+
323
+ **Violation — No input validation:**
324
+ ```typescript
325
+ app.post('/upload', (req, res) => {
326
+ const filePath = req.body.path
327
+ fs.readFile(filePath, (err, data) => { /* ... */ })
328
+ })
329
+ ```
330
+
331
+ **Fix — Path sanitization:**
332
+ ```typescript
333
+ app.post('/upload', (req, res) => {
334
+ const safePath = path.resolve(UPLOAD_DIR, path.basename(req.body.path))
335
+ if (!safePath.startsWith(UPLOAD_DIR)) {
336
+ throw new ForbiddenException('Invalid file path')
337
+ }
338
+ fs.readFile(safePath, (err, data) => { /* ... */ })
339
+ })
340
+ ```
341
+
342
+ ### Why It Matters
343
+
344
+ Security vulnerabilities are not theoretical. They get exploited. Hardcoded secrets end up in git history and leak. SQL injection lets attackers read your entire database. Path traversal lets attackers read your server's filesystem. One vulnerability can destroy user trust permanently.
345
+
346
+ ---
347
+
348
+ ## TESTING — Every Behavior Has a Test
349
+
350
+ ### What It Means
351
+
352
+ If you change how code behaves, you write a test that proves the new behavior works. Tests are not optional. They are not "nice to have." They are the proof that your code does what the spec says. Without tests, the verification phase has nothing to verify.
353
+
354
+ ### What the Reviewer Checks
355
+
356
+ - **Coverage:** Does every new/modified function have at least one test?
357
+ - **Meaningful assertions:** Do tests assert specific outcomes, not just "it didn't crash"?
358
+ - **Edge cases:** Are null, undefined, empty arrays, empty strings, and boundary values tested?
359
+ - **Test isolation:** Does each test run independently? No shared mutable state between tests?
360
+ - **Test naming:** Does each test name describe the scenario and expected outcome?
361
+ - **No implementation testing:** Do tests verify behavior (what), not implementation (how)?
362
+
363
+ ### Violations and Fixes
364
+
365
+ **Violation — Test that asserts nothing meaningful:**
366
+ ```typescript
367
+ test('createUser works', () => {
368
+ const result = createUser({ name: 'Alice', email: 'a@b.com' })
369
+ expect(result).toBeDefined()
370
+ })
371
+ ```
372
+
373
+ **Fix — Meaningful assertions:**
374
+ ```typescript
375
+ test('createUser returns user with generated ID and provided name', () => {
376
+ const result = createUser({ name: 'Alice', email: 'a@b.com' })
377
+ expect(result.id).toMatch(/^[0-9a-f-]{36}$/)
378
+ expect(result.name).toBe('Alice')
379
+ expect(result.email).toBe('a@b.com')
380
+ expect(result.createdAt).toBeInstanceOf(Date)
381
+ })
382
+ ```
383
+
384
+ **Violation — Missing edge case test:**
385
+ ```typescript
386
+ // Only tests the happy path
387
+ test('findUser returns user', () => {
388
+ const user = findUser('existing-id')
389
+ expect(user.name).toBe('Alice')
390
+ })
391
+ ```
392
+
393
+ **Fix — Test the edges:**
394
+ ```typescript
395
+ test('findUser returns user when ID exists', () => {
396
+ const user = findUser('existing-id')
397
+ expect(user.name).toBe('Alice')
398
+ })
399
+
400
+ test('findUser returns null when ID does not exist', () => {
401
+ const user = findUser('nonexistent-id')
402
+ expect(user).toBeNull()
403
+ })
404
+
405
+ test('findUser throws when ID is empty string', () => {
406
+ expect(() => findUser('')).toThrow(InvalidIdError)
407
+ })
408
+ ```
409
+
410
+ ### Why It Matters
411
+
412
+ Code without tests is code you cannot refactor. You cannot add features confidently because you do not know what you will break. Every change is a gamble. Tests are not about catching bugs today — they are about preventing regressions tomorrow and next month and next year.
413
+
414
+ ---
415
+
416
+ ## NAMING — Self-Documenting Code
417
+
418
+ ### What It Means
419
+
420
+ Names are the primary documentation of code. A good name tells you what something does without reading the implementation. Use full words, not abbreviations. Name functions for their action, variables for their content, and types for their shape.
421
+
422
+ ### What the Reviewer Checks
423
+
424
+ - **Abbreviations:** Are there names like `usr`, `btn`, `msg`, `cfg`, `ctx`? Use `user`, `button`, `message`, `config`, `context`.
425
+ - **Vague names:** Are there names like `data`, `result`, `info`, `item`, `temp`, `val`? Use specific names.
426
+ - **Boolean naming:** Do boolean variables read as questions? `isValid`, `hasPermission`, `canEdit` — not `valid`, `permission`, `edit`.
427
+ - **Function naming:** Do functions start with verbs? `calculateTotal`, `validateInput`, `fetchUser` — not `total`, `input`, `user`.
428
+ - **Consistency:** Is the same concept named the same way everywhere? Not `user` in one file and `account` in another for the same entity.
429
+
430
+ ### Violations and Fixes
431
+
432
+ **Violation — Abbreviations and vague names:**
433
+ ```typescript
434
+ function proc(d: any) {
435
+ const r = d.map((i: any) => i.v * i.q)
436
+ return r.reduce((a: number, b: number) => a + b, 0)
437
+ }
438
+ ```
439
+
440
+ **Fix — Descriptive names:**
441
+ ```typescript
442
+ function calculateOrderTotal(lineItems: LineItem[]): number {
443
+ const itemTotals = lineItems.map(item => item.price * item.quantity)
444
+ return itemTotals.reduce((sum, itemTotal) => sum + itemTotal, 0)
445
+ }
446
+ ```
447
+
448
+ ### Why It Matters
449
+
450
+ You read code 10x more than you write it. Every abbreviation costs 2 seconds of mental translation, multiplied by every developer who reads it, multiplied by every time they read it. Over a project's lifetime, bad names cost hundreds of hours.
451
+
452
+ ---
453
+
454
+ ## ERROR_HANDLING — No Silent Failures
455
+
456
+ ### What It Means
457
+
458
+ When something goes wrong, the code must either handle it properly or tell someone about it. Empty catch blocks are banned — they hide bugs that surface weeks later in production. Use domain-specific exceptions that carry context. Never throw raw `Error` with a generic message.
459
+
460
+ ### What the Reviewer Checks
461
+
462
+ - **Empty catch blocks:** Is there any `catch (e) {}` or `catch { }` in the codebase? This is unconditionally banned.
463
+ - **Swallowed exceptions:** Is there a catch block that logs but does not rethrow or return an error response?
464
+ - **Generic errors:** Are there `throw new Error('something went wrong')` instead of domain-specific exceptions?
465
+ - **Missing error handling:** Are there async operations without try/catch or .catch()?
466
+ - **Error messages:** Do error messages include enough context to diagnose the problem?
467
+
468
+ ### Violations and Fixes
469
+
470
+ **Violation — Empty catch block:**
471
+ ```typescript
472
+ try {
473
+ await saveUser(user)
474
+ } catch (e) {
475
+ // swallowed — user thinks save succeeded
476
+ }
477
+ ```
478
+
479
+ **Fix — Handle or rethrow:**
480
+ ```typescript
481
+ try {
482
+ await saveUser(user)
483
+ } catch (error) {
484
+ logger.error('Failed to save user', { userId: user.id, error })
485
+ throw new UserPersistenceError(`Failed to save user ${user.id}`, { cause: error })
486
+ }
487
+ ```
488
+
489
+ **Violation — Generic error:**
490
+ ```typescript
491
+ if (!user) {
492
+ throw new Error('Not found')
493
+ }
494
+ ```
495
+
496
+ **Fix — Domain-specific exception:**
497
+ ```typescript
498
+ if (!user) {
499
+ throw new UserNotFoundError(`User with ID ${userId} does not exist`)
500
+ }
501
+ ```
502
+
503
+ ### Why It Matters
504
+
505
+ Swallowed errors are time bombs. The operation failed, but nothing reported it. Data is silently corrupted. Users see stale information. By the time someone notices, the root cause is buried under layers of subsequent operations. An error that screams immediately saves hours of debugging later.
506
+ ```
507
+
508
+ ---
509
+
510
+ ## Field Documentation
511
+
512
+ ### Severity Configuration
513
+ Each law has one of three severity levels:
514
+ - **error** — Violations of this law block `/sdlc:close`. The loop cannot complete until violations are fixed.
515
+ - **warning** — Violations are reported in the review but do not block loop closure. They should be addressed but are not critical.
516
+ - **info** — Violations are noted for awareness. No action required.
517
+
518
+ Severity can be changed per project to match team standards. For example, a prototype project might set TESTING to `warning` while a production API keeps it at `error`.
519
+
520
+ ### Adding Custom Laws
521
+ Teams can add project-specific laws following the same format: name, severity, description, checks, examples, and rationale. Custom laws participate in the review process identically to built-in laws.
@@ -0,0 +1,112 @@
1
+ # Project Context Template
2
+
3
+ This template defines the project context document stored at `.sdlc/PROJECT.md`. It is created during `/sdlc:init` and referenced throughout the lifecycle. Every field must be populated — incomplete project context leads to ambiguous specs.
4
+
5
+ ---
6
+
7
+ ```markdown
8
+ # Project: {{PROJECT_NAME}}
9
+
10
+ ## Description
11
+
12
+ {{PROJECT_DESCRIPTION}}
13
+
14
+ A 2-3 sentence summary of what this project does, who it serves, and what problem it solves.
15
+
16
+ ## Tech Stack
17
+
18
+ | Layer | Technology | Version |
19
+ |-------|------------|---------|
20
+ | Language | {{LANGUAGE}} | {{VERSION}} |
21
+ | Framework | {{FRAMEWORK}} | {{VERSION}} |
22
+ | Database | {{DATABASE}} | {{VERSION}} |
23
+ | Package Manager | {{PACKAGE_MANAGER}} | {{VERSION}} |
24
+ | Test Runner | {{TEST_RUNNER}} | {{VERSION}} |
25
+ | Linter/Formatter | {{LINTER}} | {{VERSION}} |
26
+ | Build Tool | {{BUILD_TOOL}} | {{VERSION}} |
27
+
28
+ ## Architecture Overview
29
+
30
+ {{ARCHITECTURE_DESCRIPTION}}
31
+
32
+ Describe the high-level architecture: monolith, microservices, serverless, etc.
33
+ Include key patterns: MVC, DDD, event-driven, CQRS, etc.
34
+
35
+ ### Directory Structure
36
+
37
+ ```
38
+ {{PROJECT_ROOT}}/
39
+ src/
40
+ {{DIRECTORY_LAYOUT}}
41
+ tests/
42
+ {{TEST_LAYOUT}}
43
+ ```
44
+
45
+ ### Key Boundaries
46
+
47
+ - **Entry points:** {{ENTRY_POINTS}}
48
+ - **API layer:** {{API_LAYER}}
49
+ - **Business logic:** {{BUSINESS_LOGIC_LAYER}}
50
+ - **Data access:** {{DATA_ACCESS_LAYER}}
51
+ - **External integrations:** {{EXTERNAL_INTEGRATIONS}}
52
+
53
+ ## Requirements
54
+
55
+ | ID | Requirement | Priority | Status |
56
+ |----|-------------|----------|--------|
57
+ | REQ-001 | {{REQUIREMENT_DESCRIPTION}} | {{high/medium/low}} | {{active/validated/invalidated}} |
58
+ | REQ-002 | {{REQUIREMENT_DESCRIPTION}} | {{high/medium/low}} | {{active/validated/invalidated}} |
59
+
60
+ ### Status Definitions
61
+
62
+ - **active** — Requirement is current and guides development
63
+ - **validated** — Requirement has been implemented and verified
64
+ - **invalidated** — Requirement was dropped or replaced (include reason)
65
+
66
+ ## Current State
67
+
68
+ - **Phase:** {{init/active/maintenance}}
69
+ - **Last milestone completed:** {{MILESTONE_NAME or "None"}}
70
+ - **Active milestone:** {{MILESTONE_NAME or "None"}}
71
+ - **Known issues:** {{COUNT or "None"}}
72
+ - **Test coverage:** {{PERCENTAGE or "Unknown"}}
73
+
74
+ ## Constraints
75
+
76
+ | Constraint | Description | Impact |
77
+ |------------|-------------|--------|
78
+ | {{CONSTRAINT_NAME}} | {{WHAT_AND_WHY}} | {{HOW_IT_AFFECTS_DEVELOPMENT}} |
79
+
80
+ ### Common Constraint Categories
81
+
82
+ - **Performance:** Response time limits, throughput requirements
83
+ - **Security:** Compliance requirements, data handling rules
84
+ - **Compatibility:** Browser support, API versioning, backward compatibility
85
+ - **Infrastructure:** Hosting limits, budget, CI/CD pipeline constraints
86
+ - **Team:** Skill level, availability, timezone considerations
87
+ ```
88
+
89
+ ---
90
+
91
+ ## Field Documentation
92
+
93
+ ### PROJECT_NAME
94
+ The canonical name of the project. Use the name from `package.json`, `Cargo.toml`, or equivalent manifest. If no manifest exists, use the root directory name.
95
+
96
+ ### PROJECT_DESCRIPTION
97
+ Plain English summary. Avoid jargon. A new team member should understand what this project does after reading this field.
98
+
99
+ ### Tech Stack Table
100
+ Every technology the project depends on for development and deployment. Include versions — version mismatches cause subtle bugs that waste hours.
101
+
102
+ ### Architecture Overview
103
+ Not a design doc. A quick orientation so that anyone reading a spec knows where code lives and how layers interact.
104
+
105
+ ### Requirements
106
+ Living document. Requirements move from `active` to `validated` when implemented and verified. They move to `invalidated` when scope changes — never delete them, mark them so there is an audit trail.
107
+
108
+ ### Current State
109
+ Updated at the end of each loop closure. Provides instant orientation for session resume.
110
+
111
+ ### Constraints
112
+ Hard limits that specs must respect. If a spec violates a constraint, the reviewer catches it. Constraints are not negotiable without explicit stakeholder approval.