@champpaba/claude-agent-kit 2.1.6 → 2.2.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.
- package/.claude/agents/_shared/pre-work-checklist.md +83 -1
- package/.claude/commands/csetup.md +464 -0
- package/.claude/contexts/patterns/validation-framework.md +51 -1
- package/.claude/lib/agent-executor.md +149 -0
- package/.claude/lib/feature-best-practices.md +386 -0
- package/README.md +14 -0
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Pre-Work Checklist (Shared by All Agents)
|
|
2
2
|
|
|
3
|
-
> **Version:** 2.
|
|
3
|
+
> **Version:** 2.2.0 (Library Feasibility Validation)
|
|
4
4
|
> **Purpose:** Single source of truth for pre-work validation
|
|
5
5
|
|
|
6
6
|
---
|
|
@@ -49,6 +49,88 @@ WHY not defaults? Design spec has project-specific security requirements.
|
|
|
49
49
|
|
|
50
50
|
---
|
|
51
51
|
|
|
52
|
+
### Step 0.5: Library Feasibility Validation (v2.2.0)
|
|
53
|
+
|
|
54
|
+
**Before implementing, verify the chosen library supports ALL spec requirements:**
|
|
55
|
+
|
|
56
|
+
WHY: Implementing without verifying library capabilities leads to spec drift. Better to discover gaps early than during implementation.
|
|
57
|
+
|
|
58
|
+
1. **List spec requirements from design.md:**
|
|
59
|
+
|
|
60
|
+
Extract specific technical requirements, for example:
|
|
61
|
+
- "JWT access token 15min expiry"
|
|
62
|
+
- "Redis refresh token 30d"
|
|
63
|
+
- "Refresh token rotation on each use"
|
|
64
|
+
- "Token revocation capability"
|
|
65
|
+
|
|
66
|
+
2. **For each requirement, verify library support:**
|
|
67
|
+
|
|
68
|
+
- Check library documentation
|
|
69
|
+
- Query Context7 if available: "How to implement {requirement} with {library}?"
|
|
70
|
+
- Search for feature in library's plugin/extension list
|
|
71
|
+
- Check if feature is: built-in, plugin-available, or unsupported
|
|
72
|
+
|
|
73
|
+
3. **Report feasibility in your validation:**
|
|
74
|
+
|
|
75
|
+
```markdown
|
|
76
|
+
Library Feasibility Check:
|
|
77
|
+
- [ ] {requirement 1} → {library} supports: YES/PARTIAL/NO
|
|
78
|
+
- [ ] {requirement 2} → {library} supports: YES/PARTIAL/NO
|
|
79
|
+
- [ ] {requirement 3} → {library} supports: YES/PARTIAL/NO
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
4. **If ANY requirement is NOT FULLY supported:**
|
|
83
|
+
|
|
84
|
+
**STOP - Do not proceed with implementation**
|
|
85
|
+
|
|
86
|
+
Report to Main Claude using the Spec Deviation Protocol:
|
|
87
|
+
|
|
88
|
+
```markdown
|
|
89
|
+
⚠️ Library Capability Gap Detected
|
|
90
|
+
|
|
91
|
+
**Library:** {name}
|
|
92
|
+
**Requirement (from design.md):** {exact requirement text}
|
|
93
|
+
**Support Status:** NO / PARTIAL
|
|
94
|
+
|
|
95
|
+
**What library supports:** {alternative approach library offers}
|
|
96
|
+
**What spec requires:** {original requirement}
|
|
97
|
+
|
|
98
|
+
**Gap Analysis:**
|
|
99
|
+
{explain what cannot be implemented as specified}
|
|
100
|
+
|
|
101
|
+
**Options:**
|
|
102
|
+
A) Change library → {suggest alternative library that supports this}
|
|
103
|
+
B) Change spec → Update design.md to use what library supports
|
|
104
|
+
C) Custom implementation → Build missing feature on top of library
|
|
105
|
+
|
|
106
|
+
**My Recommendation:** {A/B/C} because {reasoning}
|
|
107
|
+
|
|
108
|
+
Awaiting decision before proceeding.
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
5. **Wait for explicit decision before implementing**
|
|
112
|
+
|
|
113
|
+
- Do NOT implement alternative approach silently
|
|
114
|
+
- Do NOT assume user would prefer simpler option
|
|
115
|
+
- Do NOT continue with "close enough" solution
|
|
116
|
+
|
|
117
|
+
WHY: Silent spec drift creates technical debt and user confusion. Explicit decisions create documented trade-offs.
|
|
118
|
+
|
|
119
|
+
**Example Gap Detection:**
|
|
120
|
+
```markdown
|
|
121
|
+
Library Feasibility Check:
|
|
122
|
+
- [x] JWT access token 15min → better-auth jwt plugin: YES ✅
|
|
123
|
+
- [x] Refresh token → better-auth: PARTIAL ⚠️ (session-based, not separate token)
|
|
124
|
+
- [ ] Refresh token rotation → better-auth: NO ❌
|
|
125
|
+
- [ ] Redis session storage → better-auth: NO ❌
|
|
126
|
+
|
|
127
|
+
⚠️ STOP - Gaps found in requirements 3 and 4
|
|
128
|
+
|
|
129
|
+
Reporting to Main Claude...
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
52
134
|
### Step 1-4: Standard Checks
|
|
53
135
|
|
|
54
136
|
1. **Context Discovery** - Load project context via agent-discovery.md
|
|
@@ -249,6 +249,233 @@ Continue anyway? (yes/no)
|
|
|
249
249
|
|
|
250
250
|
---
|
|
251
251
|
|
|
252
|
+
### Step 2.6: Feature Best Practice Analysis (v2.2.0)
|
|
253
|
+
|
|
254
|
+
> **NEW:** Validate spec against industry standards BEFORE checking stack best practices
|
|
255
|
+
> **Reference:** `.claude/lib/feature-best-practices.md`
|
|
256
|
+
|
|
257
|
+
WHY: Stack best practices tell you "how to use React well", but Feature best practices tell you "what a good auth system needs". The feature layer is higher-level and informs whether your spec is complete.
|
|
258
|
+
|
|
259
|
+
```typescript
|
|
260
|
+
output(`\n🔍 Analyzing Feature Best Practices...`)
|
|
261
|
+
|
|
262
|
+
// 1. Detect features from proposal/tasks/design
|
|
263
|
+
const combined = (proposalContent + ' ' + tasksContent + ' ' + designContent).toLowerCase()
|
|
264
|
+
|
|
265
|
+
const featureDetection = {
|
|
266
|
+
authentication: {
|
|
267
|
+
keywords: ['login', 'auth', 'register', 'password', 'session', 'jwt', 'token', 'oauth'],
|
|
268
|
+
tier: 1, // Blocking
|
|
269
|
+
standards: [
|
|
270
|
+
{ name: 'Short-lived access token', keywords: ['jwt', 'access', '15', '30', 'min'], priority: 'required' },
|
|
271
|
+
{ name: 'Refresh token rotation', keywords: ['refresh', 'rotation', 'rotate'], priority: 'required' },
|
|
272
|
+
{ name: 'Secure token storage', keywords: ['httponly', 'cookie', 'secure'], priority: 'required' },
|
|
273
|
+
{ name: 'Token revocation', keywords: ['revoke', 'invalidate', 'logout'], priority: 'required' },
|
|
274
|
+
{ name: 'Rate limiting', keywords: ['rate', 'limit', 'throttle', 'attempt'], priority: 'required' },
|
|
275
|
+
{ name: 'Account lockout', keywords: ['lockout', 'lock', 'failed attempt'], priority: 'recommended' }
|
|
276
|
+
]
|
|
277
|
+
},
|
|
278
|
+
payment: {
|
|
279
|
+
keywords: ['payment', 'stripe', 'checkout', 'billing', 'subscription'],
|
|
280
|
+
tier: 1,
|
|
281
|
+
standards: [
|
|
282
|
+
{ name: 'No card data on server', keywords: ['elements', 'checkout', 'client-side'], priority: 'required' },
|
|
283
|
+
{ name: 'Webhook signature verification', keywords: ['webhook', 'signature', 'verify'], priority: 'required' },
|
|
284
|
+
{ name: 'Idempotency keys', keywords: ['idempotency', 'idempotent'], priority: 'required' }
|
|
285
|
+
]
|
|
286
|
+
},
|
|
287
|
+
fileUpload: {
|
|
288
|
+
keywords: ['upload', 'file', 'image', 's3', 'storage'],
|
|
289
|
+
tier: 1,
|
|
290
|
+
standards: [
|
|
291
|
+
{ name: 'File type validation', keywords: ['mime', 'type', 'validation', 'allowed'], priority: 'required' },
|
|
292
|
+
{ name: 'File size limits', keywords: ['size', 'limit', 'max'], priority: 'required' },
|
|
293
|
+
{ name: 'Filename sanitization', keywords: ['sanitize', 'filename', 'path'], priority: 'required' }
|
|
294
|
+
]
|
|
295
|
+
},
|
|
296
|
+
apiDesign: {
|
|
297
|
+
keywords: ['api', 'endpoint', 'rest', 'graphql'],
|
|
298
|
+
tier: 2, // Warning
|
|
299
|
+
standards: [
|
|
300
|
+
{ name: 'Rate limiting', keywords: ['rate', 'limit'], priority: 'required' },
|
|
301
|
+
{ name: 'Input validation', keywords: ['validate', 'validation', 'zod', 'schema'], priority: 'required' },
|
|
302
|
+
{ name: 'Pagination', keywords: ['pagination', 'page', 'limit', 'offset'], priority: 'recommended' }
|
|
303
|
+
]
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// 2. Find detected features
|
|
308
|
+
const detectedFeatures = []
|
|
309
|
+
for (const [featureName, config] of Object.entries(featureDetection)) {
|
|
310
|
+
if (config.keywords.some(kw => combined.includes(kw))) {
|
|
311
|
+
detectedFeatures.push({ name: featureName, ...config })
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
if (detectedFeatures.length > 0) {
|
|
316
|
+
output(`\n📋 Features Detected:`)
|
|
317
|
+
detectedFeatures.forEach(f => {
|
|
318
|
+
output(` - ${f.name} (Tier ${f.tier}: ${f.tier === 1 ? 'Blocking' : 'Warning'})`)
|
|
319
|
+
})
|
|
320
|
+
|
|
321
|
+
// 3. For each Tier 1/2 feature, check spec against standards
|
|
322
|
+
const allGaps = []
|
|
323
|
+
|
|
324
|
+
for (const feature of detectedFeatures) {
|
|
325
|
+
output(`\n🔍 Checking ${feature.name} against industry standards...`)
|
|
326
|
+
|
|
327
|
+
const gaps = []
|
|
328
|
+
const matches = []
|
|
329
|
+
|
|
330
|
+
for (const standard of feature.standards) {
|
|
331
|
+
const isMentioned = standard.keywords.some(kw =>
|
|
332
|
+
designContent.toLowerCase().includes(kw)
|
|
333
|
+
)
|
|
334
|
+
|
|
335
|
+
if (isMentioned) {
|
|
336
|
+
matches.push(standard.name)
|
|
337
|
+
} else if (standard.priority === 'required') {
|
|
338
|
+
gaps.push({
|
|
339
|
+
feature: feature.name,
|
|
340
|
+
requirement: standard.name,
|
|
341
|
+
priority: standard.priority,
|
|
342
|
+
tier: feature.tier
|
|
343
|
+
})
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
if (matches.length > 0) {
|
|
348
|
+
output(` ✅ Matches: ${matches.join(', ')}`)
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
if (gaps.length > 0) {
|
|
352
|
+
output(` ❌ Gaps: ${gaps.map(g => g.requirement).join(', ')}`)
|
|
353
|
+
allGaps.push(...gaps)
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// 4. Handle gaps based on tier
|
|
358
|
+
const tier1Gaps = allGaps.filter(g => g.tier === 1)
|
|
359
|
+
const tier2Gaps = allGaps.filter(g => g.tier === 2)
|
|
360
|
+
|
|
361
|
+
if (tier1Gaps.length > 0) {
|
|
362
|
+
output(`\n⚠️ Security-Critical Gaps Found (Tier 1)`)
|
|
363
|
+
output(``)
|
|
364
|
+
output(`Your spec is missing these industry-standard requirements:`)
|
|
365
|
+
output(``)
|
|
366
|
+
|
|
367
|
+
// Group by feature
|
|
368
|
+
const byFeature = {}
|
|
369
|
+
tier1Gaps.forEach(g => {
|
|
370
|
+
if (!byFeature[g.feature]) byFeature[g.feature] = []
|
|
371
|
+
byFeature[g.feature].push(g.requirement)
|
|
372
|
+
})
|
|
373
|
+
|
|
374
|
+
for (const [feature, reqs] of Object.entries(byFeature)) {
|
|
375
|
+
output(` ${feature}:`)
|
|
376
|
+
reqs.forEach(r => output(` - ${r}`))
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
output(``)
|
|
380
|
+
output(`Options:`)
|
|
381
|
+
output(` A) Update spec - Add missing requirements to design.md`)
|
|
382
|
+
output(` B) Document skip - Record why these aren't needed (requires justification)`)
|
|
383
|
+
output(` C) Continue anyway - Proceed with security gap (not recommended)`)
|
|
384
|
+
output(``)
|
|
385
|
+
|
|
386
|
+
const decision = await askUserQuestion({
|
|
387
|
+
questions: [{
|
|
388
|
+
question: 'How would you like to handle the security gaps?',
|
|
389
|
+
header: 'Spec Gaps',
|
|
390
|
+
options: [
|
|
391
|
+
{ label: 'A) Update spec', description: 'Add missing requirements to design.md (recommended)' },
|
|
392
|
+
{ label: 'B) Document skip', description: 'Record justification for skipping' },
|
|
393
|
+
{ label: 'C) Continue anyway', description: 'Proceed with gap (security risk)' }
|
|
394
|
+
],
|
|
395
|
+
multiSelect: false
|
|
396
|
+
}]
|
|
397
|
+
})
|
|
398
|
+
|
|
399
|
+
if (decision.includes('A')) {
|
|
400
|
+
// Generate suggested additions
|
|
401
|
+
output(`\n📝 Add this to design.md:\n`)
|
|
402
|
+
output(`\`\`\`markdown`)
|
|
403
|
+
output(`### D{n}: Security Requirements (Industry Standard Alignment)`)
|
|
404
|
+
output(``)
|
|
405
|
+
output(`**Added based on industry best practices:**`)
|
|
406
|
+
output(``)
|
|
407
|
+
for (const [feature, reqs] of Object.entries(byFeature)) {
|
|
408
|
+
output(`#### ${feature}`)
|
|
409
|
+
reqs.forEach(r => output(`- ${r}`))
|
|
410
|
+
}
|
|
411
|
+
output(``)
|
|
412
|
+
output(`**Source:** Feature Best Practice Validation`)
|
|
413
|
+
output(`**Added:** ${new Date().toISOString().split('T')[0]}`)
|
|
414
|
+
output(`\`\`\``)
|
|
415
|
+
output(``)
|
|
416
|
+
output(`Please update design.md and re-run /csetup.`)
|
|
417
|
+
return
|
|
418
|
+
} else if (decision.includes('B')) {
|
|
419
|
+
// Document conscious skip
|
|
420
|
+
output(`\n📝 Add this to design.md to document the skip:\n`)
|
|
421
|
+
output(`\`\`\`markdown`)
|
|
422
|
+
output(`### D{n}: Conscious Security Trade-offs`)
|
|
423
|
+
output(``)
|
|
424
|
+
output(`**Skipped requirements (with justification):**`)
|
|
425
|
+
output(``)
|
|
426
|
+
output(`| Requirement | Why Skipped | Risk Level | Mitigation |`)
|
|
427
|
+
output(`|-------------|-------------|------------|------------|`)
|
|
428
|
+
for (const gap of tier1Gaps) {
|
|
429
|
+
output(`| ${gap.requirement} | [YOUR REASON] | [LOW/MED/HIGH] | [YOUR MITIGATION] |`)
|
|
430
|
+
}
|
|
431
|
+
output(``)
|
|
432
|
+
output(`**Acknowledged by:** User decision in /csetup`)
|
|
433
|
+
output(`**Date:** ${new Date().toISOString().split('T')[0]}`)
|
|
434
|
+
output(`\`\`\``)
|
|
435
|
+
output(``)
|
|
436
|
+
|
|
437
|
+
const confirm = await askUserQuestion({
|
|
438
|
+
questions: [{
|
|
439
|
+
question: 'Confirm you will document this in design.md?',
|
|
440
|
+
header: 'Confirm',
|
|
441
|
+
options: [
|
|
442
|
+
{ label: 'Yes, continue', description: 'I will add documentation' },
|
|
443
|
+
{ label: 'Cancel', description: 'Go back and update spec' }
|
|
444
|
+
],
|
|
445
|
+
multiSelect: false
|
|
446
|
+
}]
|
|
447
|
+
})
|
|
448
|
+
|
|
449
|
+
if (confirm.includes('Cancel')) {
|
|
450
|
+
output(`\n❌ Setup cancelled. Please update design.md first.`)
|
|
451
|
+
return
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
// If C, just continue with warning logged
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
if (tier2Gaps.length > 0) {
|
|
458
|
+
output(`\n⚠️ Recommendations (Tier 2 - Non-blocking):`)
|
|
459
|
+
tier2Gaps.forEach(g => {
|
|
460
|
+
output(` - ${g.feature}: ${g.requirement}`)
|
|
461
|
+
})
|
|
462
|
+
output(` Continuing with setup...`)
|
|
463
|
+
}
|
|
464
|
+
} else {
|
|
465
|
+
output(`\n✅ No security-critical features detected`)
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
// Store feature analysis for later use
|
|
469
|
+
const featureAnalysis = {
|
|
470
|
+
detected: detectedFeatures.map(f => f.name),
|
|
471
|
+
tier1Gaps: tier1Gaps || [],
|
|
472
|
+
tier2Gaps: tier2Gaps || [],
|
|
473
|
+
validated: true
|
|
474
|
+
}
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
---
|
|
478
|
+
|
|
252
479
|
### Step 2.7: Auto-Setup Best Practices (v1.8.0)
|
|
253
480
|
|
|
254
481
|
> **NEW:** Auto-detect tech stack and generate best-practices (replaces /psetup and /agentsetup)
|
|
@@ -419,6 +646,243 @@ const stackForContext = {
|
|
|
419
646
|
}
|
|
420
647
|
```
|
|
421
648
|
|
|
649
|
+
---
|
|
650
|
+
|
|
651
|
+
### Step 2.8: Library Capability Validation (v2.2.0)
|
|
652
|
+
|
|
653
|
+
> **NEW:** Verify chosen libraries support ALL spec requirements before proceeding
|
|
654
|
+
> **WHY:** Prevents spec drift - discovering during implementation that library doesn't support requirements
|
|
655
|
+
|
|
656
|
+
```typescript
|
|
657
|
+
output(`\n🔍 Validating Library Capabilities...`)
|
|
658
|
+
|
|
659
|
+
// 1. Extract spec requirements from design.md
|
|
660
|
+
const designPath = `openspec/changes/${changeId}/design.md`
|
|
661
|
+
if (!fileExists(designPath)) {
|
|
662
|
+
output(` ⚠️ No design.md found - skipping library validation`)
|
|
663
|
+
} else {
|
|
664
|
+
const designContent = Read(designPath)
|
|
665
|
+
|
|
666
|
+
// 2. Find library mentions in spec
|
|
667
|
+
const libraryPatterns = {
|
|
668
|
+
'better-auth': {
|
|
669
|
+
patterns: ['better-auth', 'betterauth'],
|
|
670
|
+
context7Id: null, // No Context7 mapping yet
|
|
671
|
+
knownLimitations: [
|
|
672
|
+
{ feature: 'refresh token rotation', supported: false },
|
|
673
|
+
{ feature: 'redis session storage', supported: false },
|
|
674
|
+
{ feature: 'jwt plugin', supported: true },
|
|
675
|
+
{ feature: 'bearer plugin', supported: true },
|
|
676
|
+
{ feature: 'session-based auth', supported: true }
|
|
677
|
+
]
|
|
678
|
+
},
|
|
679
|
+
'nextauth': {
|
|
680
|
+
patterns: ['next-auth', 'nextauth', 'authjs'],
|
|
681
|
+
context7Id: '/nextauthjs/next-auth',
|
|
682
|
+
knownLimitations: []
|
|
683
|
+
},
|
|
684
|
+
'lucia': {
|
|
685
|
+
patterns: ['lucia', 'lucia-auth'],
|
|
686
|
+
context7Id: '/lucia-auth/lucia',
|
|
687
|
+
knownLimitations: []
|
|
688
|
+
},
|
|
689
|
+
'prisma': {
|
|
690
|
+
patterns: ['prisma'],
|
|
691
|
+
context7Id: '/prisma/prisma',
|
|
692
|
+
knownLimitations: []
|
|
693
|
+
},
|
|
694
|
+
'drizzle': {
|
|
695
|
+
patterns: ['drizzle'],
|
|
696
|
+
context7Id: '/drizzle-team/drizzle-orm',
|
|
697
|
+
knownLimitations: []
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
// 3. Detect which libraries are mentioned
|
|
702
|
+
const detectedLibraries = []
|
|
703
|
+
for (const [libName, config] of Object.entries(libraryPatterns)) {
|
|
704
|
+
if (config.patterns.some(p => designContent.toLowerCase().includes(p))) {
|
|
705
|
+
detectedLibraries.push({ name: libName, ...config })
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
if (detectedLibraries.length > 0) {
|
|
710
|
+
output(`\n📚 Libraries in Spec:`)
|
|
711
|
+
detectedLibraries.forEach(lib => output(` - ${lib.name}`))
|
|
712
|
+
|
|
713
|
+
// 4. Extract requirements from design.md
|
|
714
|
+
// Look for patterns like: "JWT 15min", "refresh token", "rotation"
|
|
715
|
+
const requirementPatterns = [
|
|
716
|
+
{ name: 'JWT access token', pattern: /jwt.*(?:access|token).*(\d+\s*min)/i },
|
|
717
|
+
{ name: 'Refresh token', pattern: /refresh\s*token/i },
|
|
718
|
+
{ name: 'Token rotation', pattern: /(?:token\s*)?rotation|rotate/i },
|
|
719
|
+
{ name: 'Redis session', pattern: /redis.*session|session.*redis/i },
|
|
720
|
+
{ name: 'Bearer token', pattern: /bearer\s*(?:token|auth)/i },
|
|
721
|
+
{ name: 'OAuth providers', pattern: /oauth|google|github|social\s*login/i },
|
|
722
|
+
{ name: 'Rate limiting', pattern: /rate\s*limit/i },
|
|
723
|
+
{ name: 'Account lockout', pattern: /lockout|lock\s*account/i }
|
|
724
|
+
]
|
|
725
|
+
|
|
726
|
+
const specRequirements = []
|
|
727
|
+
for (const rp of requirementPatterns) {
|
|
728
|
+
if (rp.pattern.test(designContent)) {
|
|
729
|
+
specRequirements.push(rp.name)
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
if (specRequirements.length > 0) {
|
|
734
|
+
output(`\n📋 Spec Requirements Found:`)
|
|
735
|
+
specRequirements.forEach(r => output(` - ${r}`))
|
|
736
|
+
|
|
737
|
+
// 5. Check each library's capability
|
|
738
|
+
const capabilityGaps = []
|
|
739
|
+
|
|
740
|
+
for (const lib of detectedLibraries) {
|
|
741
|
+
output(`\n🔍 Checking ${lib.name} capabilities...`)
|
|
742
|
+
|
|
743
|
+
for (const req of specRequirements) {
|
|
744
|
+
// Check known limitations first
|
|
745
|
+
const known = lib.knownLimitations.find(l =>
|
|
746
|
+
req.toLowerCase().includes(l.feature.toLowerCase()) ||
|
|
747
|
+
l.feature.toLowerCase().includes(req.toLowerCase())
|
|
748
|
+
)
|
|
749
|
+
|
|
750
|
+
if (known && !known.supported) {
|
|
751
|
+
output(` ❌ ${req} - NOT SUPPORTED`)
|
|
752
|
+
capabilityGaps.push({
|
|
753
|
+
library: lib.name,
|
|
754
|
+
requirement: req,
|
|
755
|
+
supported: false,
|
|
756
|
+
note: `${lib.name} does not have built-in support for ${req}`
|
|
757
|
+
})
|
|
758
|
+
} else if (known && known.supported) {
|
|
759
|
+
output(` ✅ ${req} - Supported`)
|
|
760
|
+
} else {
|
|
761
|
+
// Unknown - query Context7 if available
|
|
762
|
+
if (lib.context7Id) {
|
|
763
|
+
output(` 🔍 ${req} - Checking Context7...`)
|
|
764
|
+
// Note: In actual implementation, this would call Context7
|
|
765
|
+
// For now, mark as unknown
|
|
766
|
+
output(` ⚠️ ${req} - Verify manually`)
|
|
767
|
+
} else {
|
|
768
|
+
output(` ⚠️ ${req} - Verify manually (no Context7 mapping)`)
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
// 6. Report gaps if any
|
|
775
|
+
if (capabilityGaps.length > 0) {
|
|
776
|
+
output(`\n⚠️ Library Capability Gaps Detected!`)
|
|
777
|
+
output(``)
|
|
778
|
+
output(`The following spec requirements are NOT supported by chosen libraries:`)
|
|
779
|
+
output(``)
|
|
780
|
+
|
|
781
|
+
// Group by library
|
|
782
|
+
const byLibrary = {}
|
|
783
|
+
capabilityGaps.forEach(g => {
|
|
784
|
+
if (!byLibrary[g.library]) byLibrary[g.library] = []
|
|
785
|
+
byLibrary[g.library].push(g.requirement)
|
|
786
|
+
})
|
|
787
|
+
|
|
788
|
+
for (const [library, reqs] of Object.entries(byLibrary)) {
|
|
789
|
+
output(` ${library}:`)
|
|
790
|
+
reqs.forEach(r => output(` - ${r}`))
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
output(``)
|
|
794
|
+
output(`This will cause spec drift during implementation!`)
|
|
795
|
+
output(``)
|
|
796
|
+
output(`Options:`)
|
|
797
|
+
output(` A) Change library - Use a library that supports these features`)
|
|
798
|
+
output(` B) Downgrade spec - Remove unsupported requirements (must document trade-off)`)
|
|
799
|
+
output(` C) Custom implementation - Build missing features on top of library`)
|
|
800
|
+
output(` D) Continue anyway - Proceed and let agent handle at implementation time`)
|
|
801
|
+
output(``)
|
|
802
|
+
|
|
803
|
+
const decision = await askUserQuestion({
|
|
804
|
+
questions: [{
|
|
805
|
+
question: 'How would you like to handle the capability gaps?',
|
|
806
|
+
header: 'Lib Gaps',
|
|
807
|
+
options: [
|
|
808
|
+
{ label: 'A) Change library', description: 'Switch to a library that supports requirements' },
|
|
809
|
+
{ label: 'B) Downgrade spec', description: 'Update design.md to use what library supports' },
|
|
810
|
+
{ label: 'C) Custom implementation', description: 'Build on top of library (more work)' },
|
|
811
|
+
{ label: 'D) Continue anyway', description: 'Let agent handle during implementation' }
|
|
812
|
+
],
|
|
813
|
+
multiSelect: false
|
|
814
|
+
}]
|
|
815
|
+
})
|
|
816
|
+
|
|
817
|
+
if (decision.includes('A')) {
|
|
818
|
+
output(`\n📝 Suggested alternative libraries:`)
|
|
819
|
+
for (const [library, reqs] of Object.entries(byLibrary)) {
|
|
820
|
+
if (library === 'better-auth') {
|
|
821
|
+
output(` Instead of ${library}, consider:`)
|
|
822
|
+
output(` - lucia-auth (supports custom session storage)`)
|
|
823
|
+
output(` - NextAuth.js (supports refresh token rotation with JWT strategy)`)
|
|
824
|
+
output(` - Custom implementation with jose + Redis`)
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
output(``)
|
|
828
|
+
output(`Please update design.md with new library choice and re-run /csetup.`)
|
|
829
|
+
return
|
|
830
|
+
} else if (decision.includes('B')) {
|
|
831
|
+
output(`\n📝 Update design.md to remove unsupported requirements:`)
|
|
832
|
+
output(``)
|
|
833
|
+
output(`\`\`\`markdown`)
|
|
834
|
+
output(`### D{n}: Library Capability Alignment`)
|
|
835
|
+
output(``)
|
|
836
|
+
output(`**Changed requirements to match ${Object.keys(byLibrary).join(', ')} capabilities:**`)
|
|
837
|
+
output(``)
|
|
838
|
+
for (const gap of capabilityGaps) {
|
|
839
|
+
output(`- ~~${gap.requirement}~~ → Use ${gap.library}'s default approach instead`)
|
|
840
|
+
}
|
|
841
|
+
output(``)
|
|
842
|
+
output(`**Reason:** Library limitation`)
|
|
843
|
+
output(`**Trade-off:** ${capabilityGaps.map(g => g.requirement).join(', ')} not available`)
|
|
844
|
+
output(`**Date:** ${new Date().toISOString().split('T')[0]}`)
|
|
845
|
+
output(`\`\`\``)
|
|
846
|
+
output(``)
|
|
847
|
+
output(`Please update design.md and re-run /csetup.`)
|
|
848
|
+
return
|
|
849
|
+
} else if (decision.includes('C')) {
|
|
850
|
+
output(`\n📝 Custom implementation notes for agents:`)
|
|
851
|
+
output(``)
|
|
852
|
+
output(`Add to context.md:`)
|
|
853
|
+
output(`\`\`\`markdown`)
|
|
854
|
+
output(`## Custom Implementation Required`)
|
|
855
|
+
output(``)
|
|
856
|
+
output(`The following features need custom implementation:`)
|
|
857
|
+
for (const gap of capabilityGaps) {
|
|
858
|
+
output(`- ${gap.requirement} (not supported by ${gap.library})`)
|
|
859
|
+
}
|
|
860
|
+
output(``)
|
|
861
|
+
output(`Agents should implement these on top of the base library.`)
|
|
862
|
+
output(`\`\`\``)
|
|
863
|
+
|
|
864
|
+
// Store for context.md generation
|
|
865
|
+
customImplementationRequired = capabilityGaps
|
|
866
|
+
}
|
|
867
|
+
// If D, continue with gaps logged for agent awareness
|
|
868
|
+
} else {
|
|
869
|
+
output(`\n✅ All spec requirements supported by chosen libraries`)
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
} else {
|
|
873
|
+
output(` ℹ️ No specific libraries detected in spec`)
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
// Store capability analysis
|
|
878
|
+
const capabilityAnalysis = {
|
|
879
|
+
libraries: detectedLibraries || [],
|
|
880
|
+
requirements: specRequirements || [],
|
|
881
|
+
gaps: capabilityGaps || [],
|
|
882
|
+
customRequired: customImplementationRequired || []
|
|
883
|
+
}
|
|
884
|
+
```
|
|
885
|
+
|
|
422
886
|
**Helper: generateBestPracticesFile()**
|
|
423
887
|
```typescript
|
|
424
888
|
function generateBestPracticesFile(tech: string, context7Docs: string): string {
|
|
@@ -228,12 +228,56 @@ logger.warning("login_failed", extra={"email": email, "reason": "invalid_credent
|
|
|
228
228
|
logger.error("login_error", extra={"error": str(e)})
|
|
229
229
|
```
|
|
230
230
|
|
|
231
|
-
### F.
|
|
231
|
+
### F. Library Feasibility Check ✓ (v2.2.0)
|
|
232
|
+
**From:** design.md + library documentation
|
|
233
|
+
|
|
234
|
+
**Spec Requirements:**
|
|
235
|
+
- JWT access token 15min expiry
|
|
236
|
+
- Refresh token with rotation
|
|
237
|
+
- Redis session storage
|
|
238
|
+
- Token revocation capability
|
|
239
|
+
|
|
240
|
+
**Library Capability Verification:**
|
|
241
|
+
- [x] JWT 15min → better-auth jwt plugin: YES ✅
|
|
242
|
+
- [x] Refresh token → better-auth: PARTIAL ⚠️ (session-based, not separate token)
|
|
243
|
+
- [ ] Token rotation → better-auth: NO ❌
|
|
244
|
+
- [ ] Redis storage → better-auth: NO ❌
|
|
245
|
+
|
|
246
|
+
**IF ALL SUPPORTED:**
|
|
247
|
+
```
|
|
248
|
+
✅ Library Feasibility Validated
|
|
249
|
+
All spec requirements are supported by chosen library.
|
|
250
|
+
Proceeding with implementation...
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
**IF GAPS FOUND:**
|
|
254
|
+
```
|
|
255
|
+
⚠️ Library Capability Gap Detected
|
|
256
|
+
|
|
257
|
+
Library: better-auth
|
|
258
|
+
Requirement: Refresh token rotation
|
|
259
|
+
Support Status: NO
|
|
260
|
+
|
|
261
|
+
What library supports: Session-based auth with auto-refresh
|
|
262
|
+
What spec requires: Explicit refresh token rotation on each use
|
|
263
|
+
|
|
264
|
+
Options:
|
|
265
|
+
A) Change library → lucia-auth (supports custom session storage)
|
|
266
|
+
B) Change spec → Use session-based approach instead
|
|
267
|
+
C) Custom implementation → Build rotation on top of better-auth
|
|
268
|
+
|
|
269
|
+
My Recommendation: B (simplest, meets core security needs)
|
|
270
|
+
|
|
271
|
+
Awaiting decision before proceeding.
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### G. Ready to Implement ✓
|
|
232
275
|
✅ Patterns loaded
|
|
233
276
|
✅ Existing endpoints searched
|
|
234
277
|
✅ TDD workflow planned
|
|
235
278
|
✅ Error handling pattern identified
|
|
236
279
|
✅ Logging pattern identified
|
|
280
|
+
✅ Library feasibility validated
|
|
237
281
|
|
|
238
282
|
**Proceeding with TDD (RED phase first)...**
|
|
239
283
|
```
|
|
@@ -244,8 +288,14 @@ logger.error("login_error", extra={"error": str(e)})
|
|
|
244
288
|
- IF TDD: Contains "TDD Workflow" + "RED-GREEN-REFACTOR"
|
|
245
289
|
- Contains: "Error Handling Pattern ✓"
|
|
246
290
|
- Contains: "Logging Pattern ✓"
|
|
291
|
+
- Contains: "Library Feasibility" (either "Validated" or "Gap Detected")
|
|
247
292
|
- Contains: "Ready to Implement ✓"
|
|
248
293
|
|
|
294
|
+
**Spec Deviation Markers (triggers workflow pause):**
|
|
295
|
+
- "⚠️ Library Capability Gap"
|
|
296
|
+
- "Awaiting decision"
|
|
297
|
+
- "Support Status: NO"
|
|
298
|
+
|
|
249
299
|
---
|
|
250
300
|
|
|
251
301
|
### 3️⃣ **frontend Agent**
|
|
@@ -318,6 +318,155 @@ Please provide complete output including:
|
|
|
318
318
|
|
|
319
319
|
---
|
|
320
320
|
|
|
321
|
+
## 🔄 Spec Deviation Protocol (v2.2.0)
|
|
322
|
+
|
|
323
|
+
When an agent discovers that implementation cannot match spec exactly, this protocol ensures proper handling.
|
|
324
|
+
|
|
325
|
+
WHY: Silent spec drift creates technical debt and user confusion. Explicit decisions create documented trade-offs.
|
|
326
|
+
|
|
327
|
+
### Detection Triggers
|
|
328
|
+
|
|
329
|
+
Agent discovers:
|
|
330
|
+
- Library doesn't support a spec feature
|
|
331
|
+
- Technical constraint prevents exact implementation
|
|
332
|
+
- Better alternative exists than what spec describes
|
|
333
|
+
- Dependency conflict with existing code
|
|
334
|
+
|
|
335
|
+
### Required Actions
|
|
336
|
+
|
|
337
|
+
**Agent should NOT:**
|
|
338
|
+
- Implement alternative approach silently
|
|
339
|
+
- Change the approach without user knowledge
|
|
340
|
+
- Continue with "close enough" solution
|
|
341
|
+
- Assume user would prefer the simpler option
|
|
342
|
+
|
|
343
|
+
**Agent MUST:**
|
|
344
|
+
1. Document the gap clearly
|
|
345
|
+
2. Stop implementation immediately
|
|
346
|
+
3. Report to Main Claude with options
|
|
347
|
+
4. Wait for explicit decision
|
|
348
|
+
|
|
349
|
+
### Spec Deviation Report Format
|
|
350
|
+
|
|
351
|
+
```markdown
|
|
352
|
+
⚠️ Spec Deviation Required
|
|
353
|
+
|
|
354
|
+
**Phase:** {current phase}
|
|
355
|
+
**Agent:** {agent type}
|
|
356
|
+
|
|
357
|
+
---
|
|
358
|
+
|
|
359
|
+
**Spec Requirement:** (exact text from design.md)
|
|
360
|
+
{paste the exact requirement from design.md}
|
|
361
|
+
|
|
362
|
+
**Library/Technical Constraint:**
|
|
363
|
+
{what the library/system actually supports}
|
|
364
|
+
|
|
365
|
+
**Gap Analysis:**
|
|
366
|
+
{explain what cannot be implemented as specified}
|
|
367
|
+
|
|
368
|
+
---
|
|
369
|
+
|
|
370
|
+
**Options:**
|
|
371
|
+
|
|
372
|
+
A) **Change Approach** - Use what library supports
|
|
373
|
+
- Implementation: {alternative approach}
|
|
374
|
+
- Benefit: {what you gain}
|
|
375
|
+
- Trade-off: {what you lose vs spec}
|
|
376
|
+
|
|
377
|
+
B) **Change Library** - Switch to alternative
|
|
378
|
+
- Alternative: {library name}
|
|
379
|
+
- Benefit: Matches spec exactly
|
|
380
|
+
- Trade-off: {migration effort, learning curve}
|
|
381
|
+
|
|
382
|
+
C) **Custom Implementation** - Build on top of library
|
|
383
|
+
- Implementation: {what needs to be built}
|
|
384
|
+
- Benefit: Matches spec, uses existing library
|
|
385
|
+
- Trade-off: {maintenance burden, complexity}
|
|
386
|
+
|
|
387
|
+
---
|
|
388
|
+
|
|
389
|
+
**My Recommendation:** {A/B/C}
|
|
390
|
+
**Reasoning:** {why this option is best}
|
|
391
|
+
|
|
392
|
+
Awaiting decision before proceeding.
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
### Main Claude Response Protocol
|
|
396
|
+
|
|
397
|
+
When receiving a spec deviation report:
|
|
398
|
+
|
|
399
|
+
1. **Pause workflow** - Do not auto-proceed to next phase
|
|
400
|
+
2. **Show report to user** - Present options clearly
|
|
401
|
+
3. **Get explicit decision** - User must choose A, B, or C
|
|
402
|
+
4. **Document decision** in design.md:
|
|
403
|
+
|
|
404
|
+
```markdown
|
|
405
|
+
### D{n}: {Decision Title}
|
|
406
|
+
|
|
407
|
+
**Context:** Agent found {library} doesn't support {feature}
|
|
408
|
+
**Decision:** Option {A/B/C} - {brief description}
|
|
409
|
+
**Reason:** {user's reasoning}
|
|
410
|
+
**Trade-off Accepted:** {what we're giving up}
|
|
411
|
+
**Date:** {date}
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
5. **Update spec if needed:**
|
|
415
|
+
- If Option A: Add "Library Capability Alignment" section to design.md
|
|
416
|
+
- If Option B: Update library references in design.md and tasks.md
|
|
417
|
+
- If Option C: Add "Custom Implementation Required" section
|
|
418
|
+
|
|
419
|
+
6. **Resume workflow** with clear, documented direction
|
|
420
|
+
|
|
421
|
+
### Spec Deviation Validation
|
|
422
|
+
|
|
423
|
+
**Check agent output for spec deviation markers:**
|
|
424
|
+
|
|
425
|
+
| Marker | Meaning |
|
|
426
|
+
|--------|---------|
|
|
427
|
+
| "⚠️ Spec Deviation" | Agent found gap, needs decision |
|
|
428
|
+
| "Library Capability Gap" | Library doesn't support requirement |
|
|
429
|
+
| "Awaiting decision" | Agent stopped, waiting for response |
|
|
430
|
+
|
|
431
|
+
**Main Claude should:**
|
|
432
|
+
- Pause workflow when seeing these markers
|
|
433
|
+
- Present options to user
|
|
434
|
+
- Record decision before resuming
|
|
435
|
+
|
|
436
|
+
### Example Flow
|
|
437
|
+
|
|
438
|
+
```
|
|
439
|
+
Agent: Backend implementing auth
|
|
440
|
+
↓
|
|
441
|
+
Agent: Reads design.md "JWT + Redis refresh + rotation"
|
|
442
|
+
↓
|
|
443
|
+
Agent: Checks better-auth capabilities
|
|
444
|
+
↓
|
|
445
|
+
Agent: Finds "rotation" not supported
|
|
446
|
+
↓
|
|
447
|
+
Agent: ⚠️ STOPS - Sends Spec Deviation Report
|
|
448
|
+
↓
|
|
449
|
+
Main Claude: Pauses workflow, shows user options
|
|
450
|
+
↓
|
|
451
|
+
User: Chooses Option B (change library to lucia-auth)
|
|
452
|
+
↓
|
|
453
|
+
Main Claude: Updates design.md with decision
|
|
454
|
+
↓
|
|
455
|
+
Main Claude: Resumes workflow with new library
|
|
456
|
+
↓
|
|
457
|
+
Agent: Implements with lucia-auth (supports rotation)
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
### Benefits of Spec Deviation Protocol
|
|
461
|
+
|
|
462
|
+
- **Prevents silent drift** - User knows about every deviation
|
|
463
|
+
- **Documented trade-offs** - All decisions recorded in design.md
|
|
464
|
+
- **Early detection** - Gaps found at pre-work, not during implementation
|
|
465
|
+
- **Clear options** - User can make informed choice
|
|
466
|
+
- **Audit trail** - Design decisions are traceable
|
|
467
|
+
|
|
468
|
+
---
|
|
469
|
+
|
|
321
470
|
## 🎯 Benefits
|
|
322
471
|
|
|
323
472
|
✅ **Auto-recovery** - Transient errors handled automatically
|
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
# Feature Best Practices Detection & Validation
|
|
2
|
+
|
|
3
|
+
> **Version:** 1.0.0
|
|
4
|
+
> **Purpose:** Detect features from spec and validate against industry standards
|
|
5
|
+
> **Used by:** `/csetup` Step 2.6
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
Before querying stack-level best practices (React, Next.js, etc.), we first need to:
|
|
12
|
+
1. Detect what features the change involves (Auth, Payment, etc.)
|
|
13
|
+
2. Query industry best practices for each feature
|
|
14
|
+
3. Compare spec against industry standards
|
|
15
|
+
4. Report gaps and get user decision
|
|
16
|
+
|
|
17
|
+
WHY: Stack best practices tell you "how to use React well", but Feature best practices tell you "what a good auth system needs". The feature layer is higher-level and informs whether your spec is complete.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Feature Detection
|
|
22
|
+
|
|
23
|
+
### Keyword Mapping
|
|
24
|
+
|
|
25
|
+
| Keywords in proposal/tasks/design | Feature Type | Security Tier |
|
|
26
|
+
|-----------------------------------|--------------|---------------|
|
|
27
|
+
| login, auth, register, password, session, jwt, token, oauth | Authentication | Tier 1 (Blocking) |
|
|
28
|
+
| payment, stripe, checkout, billing, subscription, invoice | Payment | Tier 1 (Blocking) |
|
|
29
|
+
| upload, file, image, s3, storage, attachment | File Upload | Tier 1 (Blocking) |
|
|
30
|
+
| admin, role, permission, rbac, acl, access control | Authorization | Tier 1 (Blocking) |
|
|
31
|
+
| api, endpoint, rest, graphql, webhook | API Design | Tier 2 (Warning) |
|
|
32
|
+
| realtime, websocket, notification, push, sse | Real-time | Tier 2 (Warning) |
|
|
33
|
+
| email, smtp, sendgrid, notification, mailer | Email/Notification | Tier 2 (Warning) |
|
|
34
|
+
| search, elasticsearch, algolia, filter, query | Search | Tier 2 (Warning) |
|
|
35
|
+
| cache, redis, memcached, cdn | Caching | Tier 2 (Warning) |
|
|
36
|
+
| crud, list, table, form, dashboard | CRUD/UI | Tier 3 (Info) |
|
|
37
|
+
| landing, hero, marketing, seo | Marketing Page | Tier 3 (Info) |
|
|
38
|
+
|
|
39
|
+
### Security Tiers
|
|
40
|
+
|
|
41
|
+
**Tier 1 (Blocking):** Security-critical features
|
|
42
|
+
- Validation against industry standard is required
|
|
43
|
+
- User must explicitly approve if skipping requirements
|
|
44
|
+
- Gaps are documented in design.md
|
|
45
|
+
|
|
46
|
+
**Tier 2 (Warning):** Important but not security-critical
|
|
47
|
+
- Show warning if gaps found
|
|
48
|
+
- Allow continue without blocking
|
|
49
|
+
- Log decision
|
|
50
|
+
|
|
51
|
+
**Tier 3 (Info):** Nice-to-have
|
|
52
|
+
- Suggest best practices
|
|
53
|
+
- No blocking or warning
|
|
54
|
+
- Optional to follow
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Industry Standard Queries
|
|
59
|
+
|
|
60
|
+
### Authentication
|
|
61
|
+
|
|
62
|
+
**Query Topics:**
|
|
63
|
+
```
|
|
64
|
+
- "JWT authentication best practices 2024"
|
|
65
|
+
- "refresh token rotation security"
|
|
66
|
+
- "session management security best practices"
|
|
67
|
+
- "OAuth 2.0 implementation best practices"
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**Expected Standards:**
|
|
71
|
+
|
|
72
|
+
| Requirement | Description | Priority |
|
|
73
|
+
|-------------|-------------|----------|
|
|
74
|
+
| Short-lived access token | JWT 15-60 minutes max | Required |
|
|
75
|
+
| Refresh token rotation | New refresh token on each use | Required |
|
|
76
|
+
| Secure token storage | httpOnly cookies, not localStorage | Required |
|
|
77
|
+
| Token revocation | Ability to invalidate tokens immediately | Required |
|
|
78
|
+
| Rate limiting | 5-10 attempts per minute on auth endpoints | Required |
|
|
79
|
+
| Account lockout | Lock after N failed attempts | Recommended |
|
|
80
|
+
| Password requirements | Min length, complexity | Required |
|
|
81
|
+
| Secure password storage | bcrypt/argon2, never plain text | Required |
|
|
82
|
+
| HTTPS only | All auth endpoints over TLS | Required |
|
|
83
|
+
| CSRF protection | For cookie-based auth | Required |
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
### Payment
|
|
88
|
+
|
|
89
|
+
**Query Topics:**
|
|
90
|
+
```
|
|
91
|
+
- "payment integration security best practices"
|
|
92
|
+
- "PCI DSS compliance requirements"
|
|
93
|
+
- "Stripe integration best practices"
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Expected Standards:**
|
|
97
|
+
|
|
98
|
+
| Requirement | Description | Priority |
|
|
99
|
+
|-------------|-------------|----------|
|
|
100
|
+
| No card data on server | Use Stripe Elements/Checkout | Required |
|
|
101
|
+
| Webhook signature verification | Validate Stripe webhook signatures | Required |
|
|
102
|
+
| Idempotency keys | Prevent duplicate charges | Required |
|
|
103
|
+
| Amount validation | Server-side price validation | Required |
|
|
104
|
+
| Audit logging | Log all payment events | Required |
|
|
105
|
+
| Error handling | Graceful failure, no sensitive data in errors | Required |
|
|
106
|
+
| Test mode separation | Clear separation of test/live keys | Required |
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
### File Upload
|
|
111
|
+
|
|
112
|
+
**Query Topics:**
|
|
113
|
+
```
|
|
114
|
+
- "file upload security best practices"
|
|
115
|
+
- "image upload validation security"
|
|
116
|
+
- "S3 presigned URL best practices"
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**Expected Standards:**
|
|
120
|
+
|
|
121
|
+
| Requirement | Description | Priority |
|
|
122
|
+
|-------------|-------------|----------|
|
|
123
|
+
| File type validation | Server-side MIME type check | Required |
|
|
124
|
+
| File size limits | Configurable max size | Required |
|
|
125
|
+
| Filename sanitization | Remove path traversal, special chars | Required |
|
|
126
|
+
| Virus scanning | For user-uploaded files | Recommended |
|
|
127
|
+
| Presigned URLs | For direct-to-S3 uploads | Recommended |
|
|
128
|
+
| Access control | Private by default, signed URLs for access | Required |
|
|
129
|
+
| Content-Disposition | Force download, prevent XSS | Required |
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
### Authorization (RBAC)
|
|
134
|
+
|
|
135
|
+
**Query Topics:**
|
|
136
|
+
```
|
|
137
|
+
- "role based access control best practices"
|
|
138
|
+
- "RBAC implementation patterns"
|
|
139
|
+
- "authorization security best practices"
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
**Expected Standards:**
|
|
143
|
+
|
|
144
|
+
| Requirement | Description | Priority |
|
|
145
|
+
|-------------|-------------|----------|
|
|
146
|
+
| Deny by default | No access unless explicitly granted | Required |
|
|
147
|
+
| Server-side checks | Never trust client-side only | Required |
|
|
148
|
+
| Principle of least privilege | Minimal permissions needed | Required |
|
|
149
|
+
| Role hierarchy | Clear inheritance if needed | Recommended |
|
|
150
|
+
| Audit logging | Log access decisions | Required |
|
|
151
|
+
| Separation of duties | Critical actions need multiple roles | Recommended |
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
### API Design
|
|
156
|
+
|
|
157
|
+
**Query Topics:**
|
|
158
|
+
```
|
|
159
|
+
- "REST API design best practices 2024"
|
|
160
|
+
- "API security best practices"
|
|
161
|
+
- "API rate limiting best practices"
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**Expected Standards:**
|
|
165
|
+
|
|
166
|
+
| Requirement | Description | Priority |
|
|
167
|
+
|-------------|-------------|----------|
|
|
168
|
+
| Consistent naming | Resource-based URLs, proper HTTP methods | Required |
|
|
169
|
+
| Versioning | URL or header-based versioning | Recommended |
|
|
170
|
+
| Rate limiting | Per-user/IP rate limits | Required |
|
|
171
|
+
| Input validation | Validate all inputs server-side | Required |
|
|
172
|
+
| Error format | Consistent error response structure | Required |
|
|
173
|
+
| Pagination | For list endpoints | Required |
|
|
174
|
+
| CORS configuration | Proper origin restrictions | Required |
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Spec Comparison Logic
|
|
179
|
+
|
|
180
|
+
### Extracting Spec Requirements
|
|
181
|
+
|
|
182
|
+
From `design.md`, look for:
|
|
183
|
+
1. **Decision sections** (### D1, ### D2, etc.)
|
|
184
|
+
2. **Technical specs** (tables, bullet points)
|
|
185
|
+
3. **Architecture descriptions**
|
|
186
|
+
|
|
187
|
+
### Comparison Algorithm
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
interface SpecComparison {
|
|
191
|
+
feature: string
|
|
192
|
+
industryRequirements: Requirement[]
|
|
193
|
+
specRequirements: string[]
|
|
194
|
+
gaps: Gap[]
|
|
195
|
+
matches: Match[]
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
interface Gap {
|
|
199
|
+
requirement: string
|
|
200
|
+
priority: 'required' | 'recommended'
|
|
201
|
+
securityImpact: 'high' | 'medium' | 'low'
|
|
202
|
+
suggestion: string
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function compareSpecToIndustry(
|
|
206
|
+
featureType: string,
|
|
207
|
+
specContent: string,
|
|
208
|
+
industryStandards: Requirement[]
|
|
209
|
+
): SpecComparison {
|
|
210
|
+
const gaps = []
|
|
211
|
+
const matches = []
|
|
212
|
+
|
|
213
|
+
for (const standard of industryStandards) {
|
|
214
|
+
// Check if spec mentions this requirement
|
|
215
|
+
const mentioned = checkIfMentioned(specContent, standard.keywords)
|
|
216
|
+
|
|
217
|
+
if (mentioned) {
|
|
218
|
+
matches.push({ requirement: standard.name, specText: mentioned })
|
|
219
|
+
} else if (standard.priority === 'required') {
|
|
220
|
+
gaps.push({
|
|
221
|
+
requirement: standard.name,
|
|
222
|
+
priority: standard.priority,
|
|
223
|
+
securityImpact: standard.securityImpact,
|
|
224
|
+
suggestion: standard.suggestion
|
|
225
|
+
})
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return { feature: featureType, industryRequirements, specRequirements, gaps, matches }
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## Gap Report Format
|
|
236
|
+
|
|
237
|
+
### For Tier 1 (Blocking) Features
|
|
238
|
+
|
|
239
|
+
```markdown
|
|
240
|
+
## Feature Best Practice Validation
|
|
241
|
+
|
|
242
|
+
### Feature: Authentication
|
|
243
|
+
**Security Tier:** 1 (Blocking)
|
|
244
|
+
|
|
245
|
+
### Spec vs Industry Standard
|
|
246
|
+
|
|
247
|
+
| Requirement | Industry Standard | Your Spec | Status |
|
|
248
|
+
|-------------|------------------|-----------|--------|
|
|
249
|
+
| Access token expiry | 15-60 min | 15 min | ✅ Match |
|
|
250
|
+
| Refresh token rotation | Required | Not specified | ❌ Gap |
|
|
251
|
+
| Token revocation | Required | Redis-based | ✅ Match |
|
|
252
|
+
| Rate limiting | 5-10/min | Not specified | ❌ Gap |
|
|
253
|
+
| Account lockout | Recommended | Not specified | ⚠️ Missing |
|
|
254
|
+
|
|
255
|
+
### Gaps Found: 2 Required, 1 Recommended
|
|
256
|
+
|
|
257
|
+
**Security Impact:** HIGH
|
|
258
|
+
|
|
259
|
+
⚠️ Your spec is missing security-critical requirements.
|
|
260
|
+
|
|
261
|
+
### Options:
|
|
262
|
+
|
|
263
|
+
**A) Update spec (Recommended)**
|
|
264
|
+
Add missing requirements to design.md:
|
|
265
|
+
- Refresh token rotation on each use
|
|
266
|
+
- Rate limiting: 5 attempts per minute
|
|
267
|
+
|
|
268
|
+
**B) Document conscious skip**
|
|
269
|
+
Record why these aren't needed for your use case.
|
|
270
|
+
(Requires justification for security review)
|
|
271
|
+
|
|
272
|
+
**C) Continue anyway**
|
|
273
|
+
Proceed without these requirements.
|
|
274
|
+
⚠️ Security risk - not recommended for production
|
|
275
|
+
|
|
276
|
+
Which option? [A/B/C]
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### For Tier 2 (Warning) Features
|
|
280
|
+
|
|
281
|
+
```markdown
|
|
282
|
+
## Feature Best Practice Validation
|
|
283
|
+
|
|
284
|
+
### Feature: API Design
|
|
285
|
+
**Security Tier:** 2 (Warning)
|
|
286
|
+
|
|
287
|
+
### Recommendations
|
|
288
|
+
|
|
289
|
+
Your spec could be improved with:
|
|
290
|
+
- [ ] API versioning strategy
|
|
291
|
+
- [ ] Pagination for list endpoints
|
|
292
|
+
- [ ] Consistent error format
|
|
293
|
+
|
|
294
|
+
These are recommended but not blocking.
|
|
295
|
+
Continuing with implementation...
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## Suggested Spec Updates
|
|
301
|
+
|
|
302
|
+
When user chooses Option A (Update spec), generate:
|
|
303
|
+
|
|
304
|
+
```markdown
|
|
305
|
+
### D{n}: Security Requirements (Industry Standard Alignment)
|
|
306
|
+
|
|
307
|
+
**Added based on industry best practices:**
|
|
308
|
+
|
|
309
|
+
#### Authentication Security
|
|
310
|
+
- Refresh token rotation: Generate new refresh token on each use
|
|
311
|
+
- Rate limiting: Max 5 login attempts per minute per IP
|
|
312
|
+
- Account lockout: Lock account for 15 minutes after 5 failed attempts
|
|
313
|
+
|
|
314
|
+
#### Rationale
|
|
315
|
+
These requirements align with OWASP Authentication Guidelines and
|
|
316
|
+
industry standard security practices for production applications.
|
|
317
|
+
|
|
318
|
+
**Source:** Feature Best Practice Validation in /csetup
|
|
319
|
+
**Added:** {date}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
## Conscious Skip Documentation
|
|
325
|
+
|
|
326
|
+
When user chooses Option B (Document skip):
|
|
327
|
+
|
|
328
|
+
```markdown
|
|
329
|
+
### D{n}: Conscious Security Trade-offs
|
|
330
|
+
|
|
331
|
+
**Skipped requirements (with justification):**
|
|
332
|
+
|
|
333
|
+
| Requirement | Why Skipped | Risk Level | Mitigation |
|
|
334
|
+
|-------------|-------------|------------|------------|
|
|
335
|
+
| Refresh token rotation | Internal tool, 3 users only | Low | Short session timeout (1 hour) |
|
|
336
|
+
| Rate limiting | Behind VPN, no public access | Low | VPN already rate-limits |
|
|
337
|
+
|
|
338
|
+
**Acknowledged by:** User decision in /csetup
|
|
339
|
+
**Date:** {date}
|
|
340
|
+
**Review reminder:** Re-evaluate if app becomes public-facing
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
## Integration with /csetup
|
|
346
|
+
|
|
347
|
+
This file is used in Step 2.6 of `/csetup`:
|
|
348
|
+
|
|
349
|
+
```typescript
|
|
350
|
+
// In csetup.md Step 2.6
|
|
351
|
+
|
|
352
|
+
// 1. Detect features
|
|
353
|
+
const features = detectFeatures(proposalContent, tasksContent, designContent)
|
|
354
|
+
|
|
355
|
+
// 2. For each Tier 1/2 feature, validate
|
|
356
|
+
for (const feature of features) {
|
|
357
|
+
const industryStandards = loadIndustryStandards(feature.type)
|
|
358
|
+
const comparison = compareSpecToIndustry(feature.type, designContent, industryStandards)
|
|
359
|
+
|
|
360
|
+
if (comparison.gaps.length > 0 && feature.tier <= 2) {
|
|
361
|
+
// Show gap report and get user decision
|
|
362
|
+
const decision = await showGapReport(comparison)
|
|
363
|
+
|
|
364
|
+
if (decision === 'A') {
|
|
365
|
+
// Generate spec update suggestions
|
|
366
|
+
await updateSpec(changeId, comparison.gaps)
|
|
367
|
+
} else if (decision === 'B') {
|
|
368
|
+
// Document conscious skip
|
|
369
|
+
await documentSkip(changeId, comparison.gaps)
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
---
|
|
376
|
+
|
|
377
|
+
## Best Practice Sources
|
|
378
|
+
|
|
379
|
+
When querying, use these sources in order:
|
|
380
|
+
1. **Context7** - For library-specific best practices
|
|
381
|
+
2. **OWASP** - For security best practices
|
|
382
|
+
3. **Industry standards** - PCI DSS, OAuth 2.0 RFC, etc.
|
|
383
|
+
|
|
384
|
+
---
|
|
385
|
+
|
|
386
|
+
This feature-first validation ensures specs are complete before we check if libraries support them.
|
package/README.md
CHANGED
|
@@ -29,10 +29,24 @@ cak init
|
|
|
29
29
|
|
|
30
30
|
## Features
|
|
31
31
|
|
|
32
|
+
- **4-Layer Validation (v2.2.0)** - Feature BP → Spec Alignment → Library Capability → Stack BP
|
|
33
|
+
- **Spec Drift Prevention** - Validates library supports spec before implementation
|
|
32
34
|
- **Instruction-based Library Detection** - Agents scan `tasks.md`/`design.md` for required libraries
|
|
33
35
|
- **Cross-session Context** - `PROJECT_STATUS.yml` maintains state across sessions
|
|
34
36
|
- **Design System v2.0** - Interactive setup with theme selection
|
|
35
37
|
|
|
38
|
+
## Validation Flow (v2.2.0)
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
/csetup
|
|
42
|
+
├── Step 2.6: Feature Best Practice (Auth, Payment, etc. vs industry standard)
|
|
43
|
+
├── Step 2.7: Stack Best Practice (React, Next.js, etc.)
|
|
44
|
+
└── Step 2.8: Library Capability (verify library supports spec)
|
|
45
|
+
|
|
46
|
+
/cdev
|
|
47
|
+
└── Agent Step 0.5: Double-check feasibility before implement
|
|
48
|
+
```
|
|
49
|
+
|
|
36
50
|
## Commands
|
|
37
51
|
|
|
38
52
|
**CLI:** `cak init` | `cak update`
|