@paths.design/caws-cli 3.5.0 → 4.1.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 (87) hide show
  1. package/dist/budget-derivation.d.ts +41 -2
  2. package/dist/budget-derivation.d.ts.map +1 -1
  3. package/dist/budget-derivation.js +417 -30
  4. package/dist/commands/archive.d.ts +50 -0
  5. package/dist/commands/archive.d.ts.map +1 -0
  6. package/dist/commands/archive.js +353 -0
  7. package/dist/commands/iterate.d.ts.map +1 -1
  8. package/dist/commands/iterate.js +12 -13
  9. package/dist/commands/mode.d.ts +24 -0
  10. package/dist/commands/mode.d.ts.map +1 -0
  11. package/dist/commands/mode.js +259 -0
  12. package/dist/commands/plan.d.ts +49 -0
  13. package/dist/commands/plan.d.ts.map +1 -0
  14. package/dist/commands/plan.js +448 -0
  15. package/dist/commands/quality-gates.d.ts +52 -0
  16. package/dist/commands/quality-gates.d.ts.map +1 -0
  17. package/dist/commands/quality-gates.js +490 -0
  18. package/dist/commands/specs.d.ts +71 -0
  19. package/dist/commands/specs.d.ts.map +1 -0
  20. package/dist/commands/specs.js +735 -0
  21. package/dist/commands/status.d.ts +4 -3
  22. package/dist/commands/status.d.ts.map +1 -1
  23. package/dist/commands/status.js +552 -22
  24. package/dist/commands/tutorial.d.ts +55 -0
  25. package/dist/commands/tutorial.d.ts.map +1 -0
  26. package/dist/commands/tutorial.js +481 -0
  27. package/dist/commands/validate.d.ts +10 -2
  28. package/dist/commands/validate.d.ts.map +1 -1
  29. package/dist/commands/validate.js +199 -39
  30. package/dist/config/modes.d.ts +225 -0
  31. package/dist/config/modes.d.ts.map +1 -0
  32. package/dist/config/modes.js +321 -0
  33. package/dist/constants/spec-types.d.ts +41 -0
  34. package/dist/constants/spec-types.d.ts.map +1 -0
  35. package/dist/constants/spec-types.js +42 -0
  36. package/dist/index-new.d.ts +5 -0
  37. package/dist/index-new.d.ts.map +1 -0
  38. package/dist/index-new.js +317 -0
  39. package/dist/index.js +227 -10
  40. package/dist/index.js.backup +4711 -0
  41. package/dist/policy/PolicyManager.d.ts +104 -0
  42. package/dist/policy/PolicyManager.d.ts.map +1 -0
  43. package/dist/policy/PolicyManager.js +399 -0
  44. package/dist/scaffold/cursor-hooks.d.ts.map +1 -1
  45. package/dist/scaffold/cursor-hooks.js +15 -0
  46. package/dist/scaffold/git-hooks.d.ts.map +1 -1
  47. package/dist/scaffold/git-hooks.js +32 -44
  48. package/dist/scaffold/index.d.ts.map +1 -1
  49. package/dist/scaffold/index.js +19 -0
  50. package/dist/spec/SpecFileManager.d.ts +146 -0
  51. package/dist/spec/SpecFileManager.d.ts.map +1 -0
  52. package/dist/spec/SpecFileManager.js +419 -0
  53. package/dist/utils/quality-gates-errors.js +520 -0
  54. package/dist/utils/quality-gates.d.ts +49 -0
  55. package/dist/utils/quality-gates.d.ts.map +1 -0
  56. package/dist/utils/quality-gates.js +361 -0
  57. package/dist/utils/spec-resolver.d.ts +88 -0
  58. package/dist/utils/spec-resolver.d.ts.map +1 -0
  59. package/dist/utils/spec-resolver.js +602 -0
  60. package/dist/validation/spec-validation.d.ts +14 -0
  61. package/dist/validation/spec-validation.d.ts.map +1 -1
  62. package/dist/validation/spec-validation.js +225 -13
  63. package/package.json +6 -5
  64. package/templates/.cursor/hooks/caws-scope-guard.sh +64 -8
  65. package/templates/.cursor/hooks/validate-spec.sh +22 -12
  66. package/templates/.cursor/rules/00-claims-verification.mdc +144 -0
  67. package/templates/.cursor/rules/01-working-style.mdc +50 -0
  68. package/templates/.cursor/rules/02-quality-gates.mdc +370 -0
  69. package/templates/.cursor/rules/03-naming-and-refactor.mdc +33 -0
  70. package/templates/.cursor/rules/04-logging-language-style.mdc +23 -0
  71. package/templates/.cursor/rules/05-safe-defaults-guards.mdc +23 -0
  72. package/templates/.cursor/rules/06-typescript-conventions.mdc +36 -0
  73. package/templates/.cursor/rules/07-process-ops.mdc +20 -0
  74. package/templates/.cursor/rules/08-solid-and-architecture.mdc +16 -0
  75. package/templates/.cursor/rules/09-docstrings.mdc +89 -0
  76. package/templates/.cursor/rules/10-authorship-and-attribution.mdc +15 -0
  77. package/templates/.cursor/rules/11-documentation-quality-standards.mdc +390 -0
  78. package/templates/.cursor/rules/12-scope-management-waivers.mdc +385 -0
  79. package/templates/.cursor/rules/13-implementation-completeness.mdc +516 -0
  80. package/templates/.cursor/rules/14-language-agnostic-standards.mdc +588 -0
  81. package/templates/.cursor/rules/15-sophisticated-todo-detection.mdc +425 -0
  82. package/templates/.cursor/rules/README.md +150 -0
  83. package/templates/apps/tools/caws/prompt-lint.js.backup +274 -0
  84. package/templates/apps/tools/caws/provenance.js.backup +73 -0
  85. package/templates/scripts/quality-gates/check-god-objects.js +146 -0
  86. package/templates/scripts/quality-gates/run-quality-gates.js +50 -0
  87. package/templates/scripts/v3/analysis/todo_analyzer.py +1950 -0
@@ -190,8 +190,9 @@ function validateWorkingSpecWithSuggestions(spec, options = {}) {
190
190
  });
191
191
  }
192
192
 
193
- // Validate risk tier
193
+ // Validate risk tier with enhanced auto-fix
194
194
  if (spec.risk_tier !== undefined && (spec.risk_tier < 1 || spec.risk_tier > 3)) {
195
+ const fixedValue = Math.max(1, Math.min(3, spec.risk_tier || 2));
195
196
  errors.push({
196
197
  instancePath: '/risk_tier',
197
198
  message: 'Risk tier must be 1, 2, or 3',
@@ -199,7 +200,99 @@ function validateWorkingSpecWithSuggestions(spec, options = {}) {
199
200
  'Tier 1: Critical (auth, billing), Tier 2: Standard (features), Tier 3: Low risk (UI)',
200
201
  canAutoFix: true,
201
202
  });
202
- fixes.push({ field: 'risk_tier', value: Math.max(1, Math.min(3, spec.risk_tier || 2)) });
203
+ fixes.push({
204
+ field: 'risk_tier',
205
+ value: fixedValue,
206
+ description: `Clamping risk_tier from ${spec.risk_tier} to valid range [1-3]: ${fixedValue}`,
207
+ reason: 'Risk tier out of bounds',
208
+ });
209
+ }
210
+
211
+ // Auto-fix empty arrays with sensible defaults
212
+ if (!spec.invariants || spec.invariants.length === 0) {
213
+ if (autoFix) {
214
+ fixes.push({
215
+ field: 'invariants',
216
+ value: ['System must remain operational during changes'],
217
+ description: 'Adding default invariant for empty invariants array',
218
+ reason: 'Invariants array was empty',
219
+ });
220
+ }
221
+ }
222
+
223
+ if (!spec.acceptance || spec.acceptance.length === 0) {
224
+ if (autoFix) {
225
+ fixes.push({
226
+ field: 'acceptance',
227
+ value: [
228
+ {
229
+ id: 'A1',
230
+ given: 'the system is in a valid state',
231
+ when: 'the change is applied',
232
+ then: 'the system remains functional',
233
+ },
234
+ ],
235
+ description: 'Adding placeholder acceptance criteria',
236
+ reason: 'Acceptance criteria array was empty',
237
+ });
238
+ }
239
+ }
240
+
241
+ // Auto-fix missing scope.out
242
+ if (spec.scope && !spec.scope.out) {
243
+ fixes.push({
244
+ field: 'scope.out',
245
+ value: ['node_modules/', 'dist/', '.git/'],
246
+ description: 'Adding default exclusions to scope.out',
247
+ reason: 'scope.out was missing',
248
+ });
249
+ }
250
+
251
+ // Auto-fix missing mode
252
+ if (!spec.mode) {
253
+ fixes.push({
254
+ field: 'mode',
255
+ value: 'feature',
256
+ description: 'Setting default mode to "feature"',
257
+ reason: 'mode field was missing',
258
+ });
259
+ }
260
+
261
+ // Auto-fix missing blast_radius
262
+ if (!spec.blast_radius) {
263
+ fixes.push({
264
+ field: 'blast_radius',
265
+ value: {
266
+ modules: [],
267
+ data_migration: false,
268
+ },
269
+ description: 'Adding empty blast_radius structure',
270
+ reason: 'blast_radius was missing',
271
+ });
272
+ }
273
+
274
+ // Auto-fix missing non_functional
275
+ if (!spec.non_functional) {
276
+ fixes.push({
277
+ field: 'non_functional',
278
+ value: {
279
+ a11y: [],
280
+ perf: {},
281
+ security: [],
282
+ },
283
+ description: 'Adding empty non_functional requirements structure',
284
+ reason: 'non_functional was missing',
285
+ });
286
+ }
287
+
288
+ // Auto-fix missing contracts
289
+ if (!spec.contracts) {
290
+ fixes.push({
291
+ field: 'contracts',
292
+ value: [],
293
+ description: 'Adding empty contracts array',
294
+ reason: 'contracts field was missing',
295
+ });
203
296
  }
204
297
 
205
298
  // Validate scope.in is not empty
@@ -241,6 +334,40 @@ function validateWorkingSpecWithSuggestions(spec, options = {}) {
241
334
  }
242
335
  }
243
336
 
337
+ // Tier 1 specific requirements (critical changes)
338
+ if (spec.risk_tier === 1) {
339
+ if (!spec.observability) {
340
+ errors.push({
341
+ instancePath: '/observability',
342
+ message: 'Observability required for Tier 1 changes',
343
+ suggestion: 'Define logging, metrics, and tracing strategy',
344
+ canAutoFix: false,
345
+ });
346
+ }
347
+
348
+ if (!spec.rollback || spec.rollback.length === 0) {
349
+ errors.push({
350
+ instancePath: '/rollback',
351
+ message: 'Rollback procedures required for Tier 1 changes',
352
+ suggestion: 'Document rollback steps and data migration reversal',
353
+ canAutoFix: false,
354
+ });
355
+ }
356
+
357
+ if (
358
+ !spec.non_functional ||
359
+ !spec.non_functional.security ||
360
+ spec.non_functional.security.length === 0
361
+ ) {
362
+ errors.push({
363
+ instancePath: '/non_functional/security',
364
+ message: 'Security requirements required for Tier 1 changes',
365
+ suggestion: 'Define authentication, authorization, and data protection requirements',
366
+ canAutoFix: false,
367
+ });
368
+ }
369
+ }
370
+
244
371
  // Validate waiver_ids format if present
245
372
  if (spec.waiver_ids) {
246
373
  if (!Array.isArray(spec.waiver_ids)) {
@@ -256,7 +383,7 @@ function validateWorkingSpecWithSuggestions(spec, options = {}) {
256
383
  errors.push({
257
384
  instancePath: '/waiver_ids',
258
385
  message: `Invalid waiver ID format: ${waiverId}`,
259
- suggestion: 'Use format: WV-XXXX (e.g., WV-0001)',
386
+ suggestion: 'Use format: WV-XXXX where XXXX is exactly 4 digits (e.g., WV-0001)',
260
387
  canAutoFix: false,
261
388
  });
262
389
  }
@@ -264,6 +391,17 @@ function validateWorkingSpecWithSuggestions(spec, options = {}) {
264
391
  }
265
392
  }
266
393
 
394
+ // Warn if change_budget is present (deprecated/informational only)
395
+ if (spec.change_budget) {
396
+ warnings.push({
397
+ instancePath: '/change_budget',
398
+ message:
399
+ 'change_budget field in working spec is informational only and not used for validation',
400
+ suggestion:
401
+ 'Budget is derived from policy.yaml risk_tier + waivers. This field is auto-calculated.',
402
+ });
403
+ }
404
+
267
405
  // Derive and check budget if requested
268
406
  let budgetCheck = null;
269
407
  if (checkBudget && projectRoot) {
@@ -288,6 +426,16 @@ function validateWorkingSpecWithSuggestions(spec, options = {}) {
288
426
  canAutoFix: false,
289
427
  });
290
428
  }
429
+
430
+ // Suggest adding waiver_ids if budget exceeded and none referenced
431
+ if (!spec.waiver_ids || spec.waiver_ids.length === 0) {
432
+ warnings.push({
433
+ instancePath: '/waiver_ids',
434
+ message: 'Budget exceeded but no waivers referenced',
435
+ suggestion:
436
+ 'Add waiver_ids: ["WV-0001"] to working spec, then create waiver file with: caws waiver create',
437
+ });
438
+ }
291
439
  }
292
440
  } catch (error) {
293
441
  warnings.push({
@@ -298,27 +446,55 @@ function validateWorkingSpecWithSuggestions(spec, options = {}) {
298
446
  }
299
447
  }
300
448
 
301
- // Apply auto-fixes if requested
449
+ // Apply auto-fixes if requested and not in dry-run mode
450
+ const { dryRun = false } = options;
451
+ let appliedFixes = [];
452
+
302
453
  if (autoFix && fixes.length > 0) {
303
- console.log('🔧 Applying auto-fixes...');
304
- for (const fix of fixes) {
305
- const pathParts = fix.field.split('.');
306
- let current = spec;
307
- for (let i = 0; i < pathParts.length - 1; i++) {
308
- if (!current[pathParts[i]]) current[pathParts[i]] = {};
309
- current = current[pathParts[i]];
454
+ if (dryRun) {
455
+ console.log('🔍 Auto-fix preview (dry-run mode):');
456
+ for (const fix of fixes) {
457
+ console.log(` [WOULD FIX] ${fix.field}`);
458
+ console.log(` Description: ${fix.description}`);
459
+ console.log(` Reason: ${fix.reason}`);
460
+ console.log(
461
+ ` Value: ${typeof fix.value === 'object' ? JSON.stringify(fix.value) : fix.value}`
462
+ );
463
+ console.log('');
464
+ }
465
+ } else {
466
+ console.log('🔧 Applying auto-fixes...');
467
+ for (const fix of fixes) {
468
+ try {
469
+ const pathParts = fix.field.split('.');
470
+ let current = spec;
471
+ for (let i = 0; i < pathParts.length - 1; i++) {
472
+ if (!current[pathParts[i]]) current[pathParts[i]] = {};
473
+ current = current[pathParts[i]];
474
+ }
475
+ current[pathParts[pathParts.length - 1]] = fix.value;
476
+ appliedFixes.push(fix);
477
+ console.log(` ✅ Fixed ${fix.field}`);
478
+ console.log(` ${fix.description}`);
479
+ } catch (error) {
480
+ console.warn(` ⚠️ Failed to apply fix for ${fix.field}: ${error.message}`);
481
+ }
310
482
  }
311
- current[pathParts[pathParts.length - 1]] = fix.value;
312
- console.log(` Fixed ${fix.field}: ${fix.value}`);
313
483
  }
314
484
  }
315
485
 
486
+ // Calculate compliance score (0-1 scale)
487
+ const complianceScore = calculateComplianceScore(errors, warnings);
488
+
316
489
  return {
317
490
  valid: errors.length === 0,
318
491
  errors,
319
492
  warnings,
320
493
  fixes: fixes.length > 0 ? fixes : undefined,
494
+ appliedFixes: appliedFixes.length > 0 ? appliedFixes : undefined,
495
+ dryRun,
321
496
  budget_check: budgetCheck,
497
+ complianceScore,
322
498
  };
323
499
  } catch (error) {
324
500
  return {
@@ -333,6 +509,40 @@ function validateWorkingSpecWithSuggestions(spec, options = {}) {
333
509
  }
334
510
  }
335
511
 
512
+ /**
513
+ * Calculate compliance score based on errors and warnings
514
+ * Score ranges from 0 (many issues) to 1 (perfect)
515
+ * @param {Array} errors - Validation errors
516
+ * @param {Array} warnings - Validation warnings
517
+ * @returns {number} Compliance score (0-1)
518
+ */
519
+ function calculateComplianceScore(errors, warnings) {
520
+ // Start at perfect score
521
+ let score = 1.0;
522
+
523
+ // Each error reduces score by 0.2
524
+ score -= errors.length * 0.2;
525
+
526
+ // Each warning reduces score by 0.1
527
+ score -= warnings.length * 0.1;
528
+
529
+ // Floor at 0
530
+ return Math.max(0, score);
531
+ }
532
+
533
+ /**
534
+ * Get compliance grade from score
535
+ * @param {number} score - Compliance score (0-1)
536
+ * @returns {string} Grade (A, B, C, D, F)
537
+ */
538
+ function getComplianceGrade(score) {
539
+ if (score >= 0.9) return 'A';
540
+ if (score >= 0.8) return 'B';
541
+ if (score >= 0.7) return 'C';
542
+ if (score >= 0.6) return 'D';
543
+ return 'F';
544
+ }
545
+
336
546
  /**
337
547
  * Get suggestion for a missing field
338
548
  * @param {string} field - Field name
@@ -373,4 +583,6 @@ module.exports = {
373
583
  validateWorkingSpecWithSuggestions,
374
584
  getFieldSuggestion,
375
585
  canAutoFixField,
586
+ calculateComplianceScore,
587
+ getComplianceGrade,
376
588
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paths.design/caws-cli",
3
- "version": "3.5.0",
3
+ "version": "4.1.0",
4
4
  "description": "CAWS CLI - Coding Agent Workflow System command line tools",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -13,7 +13,7 @@
13
13
  "templates"
14
14
  ],
15
15
  "scripts": {
16
- "build": "mkdir -p dist && cp -r src/* dist/ && npm run typecheck",
16
+ "build": "mkdir -p dist && cp -r src/* dist/",
17
17
  "dev": "mkdir -p dist && cp -r src/* dist/ && node dist/index.js",
18
18
  "typecheck": "tsc --emitDeclarationOnly --outDir dist",
19
19
  "start": "node dist/index.js",
@@ -51,12 +51,10 @@
51
51
  "directory": "packages/caws-cli"
52
52
  },
53
53
  "dependencies": {
54
- "ajv": "^8.12.0",
55
54
  "chalk": "4.1.2",
56
55
  "commander": "^11.0.0",
57
56
  "fs-extra": "^11.0.0",
58
- "inquirer": "8.2.7",
59
- "js-yaml": "4.1.0"
57
+ "inquirer": "8.2.7"
60
58
  },
61
59
  "devDependencies": {
62
60
  "@eslint/js": "^9.0.0",
@@ -68,10 +66,13 @@
68
66
  "@types/inquirer": "^8.2.6",
69
67
  "@types/js-yaml": "^4.0.0",
70
68
  "@types/node": "^20.0.0",
69
+ "ajv": "8.17.1",
71
70
  "esbuild": "0.25.10",
72
71
  "eslint": "^9.0.0",
73
72
  "jest": "30.1.3",
73
+ "js-yaml": "4.1.0",
74
74
  "lint-staged": "15.5.2",
75
+ "micromatch": "4.0.8",
75
76
  "prettier": "^3.0.0",
76
77
  "semantic-release": "25.0.0-beta.6",
77
78
  "typescript": "^5.0.0"
@@ -13,6 +13,57 @@ FILE_PATH=$(echo "$INPUT" | jq -r '.file_path // ""')
13
13
  # Check if CAWS is available and we have a working spec
14
14
  if command -v caws &> /dev/null && [[ -f ".caws/working-spec.yaml" ]]; then
15
15
 
16
+ # AGENT GUARDRAILS - Prevent policy bypass attempts
17
+ if [[ "$ACTION" == "edit_file" ]] || [[ "$ACTION" == "create_file" ]]; then
18
+ if [[ "$FILE_PATH" == ".caws/policy.yaml" ]]; then
19
+ echo '{
20
+ "userMessage": "🚫 Policy file editing blocked by agent guardrails",
21
+ "agentMessage": "Agents cannot edit .caws/policy.yaml - requires human dual control",
22
+ "block": true,
23
+ "suggestions": [
24
+ "Policy changes must be approved by humans with Gatekeeper role",
25
+ "Create a separate PR for policy changes",
26
+ "For budget exceptions: caws waivers create --title=\"Budget exception\" --reason=architectural_refactor --gates=budget_limit",
27
+ "Contact @gatekeepers for policy modifications"
28
+ ]
29
+ }'
30
+ exit 1
31
+ fi
32
+
33
+ if [[ "$FILE_PATH" == "CODEOWNERS" ]]; then
34
+ echo '{
35
+ "userMessage": "🚫 CODEOWNERS editing blocked by agent guardrails",
36
+ "agentMessage": "Agents cannot modify CODEOWNERS - governance changes require approval",
37
+ "block": true,
38
+ "suggestions": [
39
+ "CODEOWNERS changes require governance review",
40
+ "Contact repository maintainers for ownership changes",
41
+ "For approval workflows: caws waivers create --reason=governance_change"
42
+ ]
43
+ }'
44
+ exit 1
45
+ fi
46
+
47
+ if [[ "$FILE_PATH" == ".caws/working-spec.yaml" ]]; then
48
+ # Check if trying to add change_budget
49
+ FILE_CONTENT=$(echo "$INPUT" | jq -r '.content // ""')
50
+ if echo "$FILE_CONTENT" | grep -q "change_budget"; then
51
+ echo '{
52
+ "userMessage": "🚫 Budget editing blocked by agent guardrails",
53
+ "agentMessage": "Agents cannot introduce change_budget fields - budgets are derived automatically",
54
+ "block": true,
55
+ "suggestions": [
56
+ "Check current budget status: caws burnup",
57
+ "For budget exceptions: caws waivers create --title=\"Scope expansion\" --reason=architectural_refactor --gates=budget_limit --expires-at=\"2025-12-31T23:59:59Z\"",
58
+ "Add waiver_ids to working spec instead: [\"WV-XXXX\"]",
59
+ "Validate waiver: caws validate .caws/working-spec.yaml"
60
+ ]
61
+ }'
62
+ exit 1
63
+ fi
64
+ fi
65
+ fi
66
+
16
67
  # For file access actions, check scope
17
68
  if [[ "$ACTION" == "read_file" ]] || [[ "$ACTION" == "edit_file" ]] || [[ -n "$FILE_PATH" ]]; then
18
69
 
@@ -25,9 +76,10 @@ if command -v caws &> /dev/null && [[ -f ".caws/working-spec.yaml" ]]; then
25
76
  "agentMessage": "Cannot access '"$FILE_PATH"' - outside CAWS defined scope",
26
77
  "block": true,
27
78
  "suggestions": [
28
- "Check CAWS working spec scope definition",
29
- "Update scope in .caws/working-spec.yaml if needed",
30
- "Create waiver for scope violation: caws waivers create --reason=scope_violation"
79
+ "Check current scope: caws validate .caws/working-spec.yaml",
80
+ "Update scope in working spec: edit .caws/working-spec.yaml scope.in array",
81
+ "For scope exceptions: caws waivers create --title=\"Scope expansion\" --reason=architectural_refactor --gates=scope_boundary --description=\"Need access to '"$FILE_PATH"' for implementation\"",
82
+ "Validate changes: caws validate .caws/working-spec.yaml"
31
83
  ]
32
84
  }'
33
85
  exit 1
@@ -36,8 +88,10 @@ if command -v caws &> /dev/null && [[ -f ".caws/working-spec.yaml" ]]; then
36
88
  "userMessage": "⚠️ File access outside primary scope",
37
89
  "agentMessage": "File '"$FILE_PATH"' is outside primary scope but allowed",
38
90
  "suggestions": [
39
- "Consider if this file should be in primary scope",
40
- "Update .caws/working-spec.yaml scope if needed"
91
+ "Check if needed in primary scope: edit .caws/working-spec.yaml scope.in",
92
+ "Consider scope implications: caws agent evaluate",
93
+ "Document scope decision in working spec invariants",
94
+ "Validate scope changes: caws validate .caws/working-spec.yaml"
41
95
  ]
42
96
  }'
43
97
  fi
@@ -63,9 +117,11 @@ if command -v caws &> /dev/null && [[ -f ".caws/working-spec.yaml" ]]; then
63
117
  "userMessage": "⚠️ Prompt references files outside CAWS scope",
64
118
  "agentMessage": "Prompt mentions out-of-scope files: '"$OUT_OF_SCOPE"'",
65
119
  "suggestions": [
66
- "Focus on files within CAWS defined scope",
67
- "Update working spec scope if additional files needed",
68
- "Remove out-of-scope file references from prompt"
120
+ "Check current scope definition: caws validate .caws/working-spec.yaml",
121
+ "Update working spec scope: edit .caws/working-spec.yaml scope.in array",
122
+ "For scope exceptions: caws waivers create --title=\"Scope expansion\" --reason=architectural_refactor --gates=scope_boundary",
123
+ "Refocus prompt on in-scope files or request scope update approval",
124
+ "Validate scope changes: caws validate .caws/working-spec.yaml"
69
125
  ]
70
126
  }'
71
127
  fi
@@ -16,20 +16,30 @@ FILE_PATH=$(echo "$INPUT" | jq -r '.file_path // ""')
16
16
 
17
17
  # Only validate if working-spec.yaml was edited
18
18
  if [[ "$FILE_PATH" == *"working-spec.yaml"* ]] || [[ "$FILE_PATH" == *"working-spec.yml"* ]]; then
19
- # Run CAWS validation
20
- if [ -f "apps/tools/caws/validate.js" ]; then
21
- if ! node apps/tools/caws/validate.js --quiet 2>/dev/null; then
22
- echo '{"userMessage":"⚠️ CAWS spec validation failed. Run: caws validate --suggestions","agentMessage":"The working-spec.yaml file has validation errors. Please review and fix before continuing."}' 2>/dev/null
23
- exit 0
19
+ echo "🔍 Validating CAWS working spec..." >&2
20
+
21
+ # Check if CAWS CLI is available
22
+ if command -v caws &> /dev/null; then
23
+ # Run CAWS validation with suggestions
24
+ if VALIDATION=$(caws validate "$FILE_PATH" --quiet 2>&1); then
25
+ echo '{"userMessage":"✅ CAWS spec validation passed","agentMessage":"Working specification is valid and complete."}' 2>/dev/null
26
+ else
27
+ # Get suggestions for fixing the spec
28
+ SUGGESTIONS=$(caws validate "$FILE_PATH" --suggestions 2>/dev/null | head -5 | tr '\n' '; ' | sed 's/; $//' || echo "Run caws validate --suggestions for details")
29
+
30
+ echo '{
31
+ "userMessage": "⚠️ CAWS spec validation failed. Run: caws validate --suggestions",
32
+ "agentMessage": "The working-spec.yaml file has validation errors. Please review and fix before continuing.",
33
+ "suggestions": [
34
+ "Run caws validate --suggestions for detailed error messages",
35
+ "Check required fields: id, title, risk_tier, mode",
36
+ "Ensure acceptance criteria are properly defined",
37
+ "Verify scope boundaries are appropriate"
38
+ ]
39
+ }' 2>/dev/null
24
40
  fi
25
41
  else
26
- # Fallback: try caws CLI
27
- if command -v caws &> /dev/null; then
28
- if ! caws validate --quiet 2>/dev/null; then
29
- echo '{"userMessage":"⚠️ CAWS spec validation failed. Run: caws validate --suggestions","agentMessage":"The working-spec.yaml file has validation errors."}' 2>/dev/null
30
- exit 0
31
- fi
32
- fi
42
+ echo '{"userMessage":"⚠️ CAWS CLI not available for validation","agentMessage":"Install CAWS CLI for automatic spec validation: npm install -g @caws/cli"}' 2>/dev/null
33
43
  fi
34
44
  fi
35
45
 
@@ -0,0 +1,144 @@
1
+ ---
2
+ description: Production readiness claims require rigorous verification - agents must prove, not assert
3
+ globs:
4
+ alwaysApply: true
5
+ ---
6
+
7
+ # Production Readiness Verification & Accountability
8
+
9
+ ## Core Principle
10
+
11
+ **Never claim "production-ready", "production-grade", or similar unless ALL criteria below are met.** If any criterion is not satisfied, use these statuses instead:
12
+
13
+ - ❌ **"In development"** - Active development with known issues
14
+ - ❌ **"Partially implemented"** - Some features working, major gaps remain
15
+ - ❌ **"Proof of concept"** - Core concept demonstrated, not production-viable
16
+
17
+ ## Mandatory Production Readiness Criteria
18
+
19
+ Before claiming production readiness, **agents must verify ALL of these**:
20
+
21
+ ### ✅ Code Quality Gates
22
+
23
+ - **Zero linting errors or warnings** (ESLint, TypeScript, etc.)
24
+ - **Zero TypeScript compilation errors**
25
+ - **All TODOs, PLACEHOLDERs, and MOCK DATA cleared from production code**
26
+ - **No dead code or unused imports**
27
+ - **Consistent code formatting** (Prettier/ESLint rules)
28
+
29
+ ### ✅ Testing & Quality Assurance
30
+
31
+ - **Complete unit test coverage** (80%+ line coverage, 90%+ branch coverage)
32
+ - **All unit tests passing** (no skipped tests in production code)
33
+ - **Integration tests passing** (database, external APIs, end-to-end flows)
34
+ - **Mutation testing** (70%+ score for critical components)
35
+ - **Performance tests** meeting documented SLAs
36
+
37
+ ### ✅ Infrastructure & Persistence
38
+
39
+ - **Actual database persistence implemented** (not just in-memory mocks)
40
+ - **Database integration tests passing** with real database
41
+ - **Migration scripts tested and working**
42
+ - **Data consistency and rollback capabilities**
43
+ - **Connection pooling and error handling**
44
+
45
+ ### ✅ Security & Reliability
46
+
47
+ - **Security controls tested and validated** (authentication, authorization, input validation)
48
+ - **No security scan violations** (SAST, dependency scanning)
49
+ - **Circuit breakers and retry logic** for external dependencies
50
+ - **Graceful degradation** under failure conditions
51
+ - **Logging and monitoring** implemented
52
+
53
+ ### ✅ Documentation & Reality Alignment
54
+
55
+ - **Documentation matches implementation reality** (no claims of features that don't exist)
56
+ - **API documentation** current and accurate
57
+ - **Deployment and operational docs** exist
58
+ - **Architecture diagrams** reflect actual implementation
59
+ - **README and changelogs** accurate
60
+
61
+ ## Accountability Measures for Coding Agents
62
+
63
+ ### Pre-Claim Verification Process
64
+
65
+ 1. **Run full test suite** - All tests pass locally
66
+ 2. **Run linters** - Zero errors/warnings
67
+ 3. **Run security scans** - No vulnerabilities
68
+ 4. **Check coverage reports** - Meet or exceed thresholds
69
+ 5. **Verify database operations** - Real persistence working
70
+ 6. **Test deployment pipeline** - CI/CD passes
71
+ 7. **Document verification evidence** - Include in PR/commit
72
+
73
+ ### Prohibited Claims
74
+
75
+ **NEVER claim these without verification:**
76
+
77
+ - "Production-ready" without all criteria met
78
+ - "Enterprise-grade" without enterprise testing
79
+ - "Battle-tested" without comprehensive testing
80
+ - "Stable" with failing tests or linting errors
81
+ - "Complete" with TODOs, placeholders, or mock data
82
+ - "Secure" without security testing and scans
83
+
84
+ ### Evidence Requirements
85
+
86
+ For any production readiness claim, provide:
87
+
88
+ - Test execution results (screenshots/logs)
89
+ - Coverage reports
90
+ - Lint results
91
+ - Security scan reports
92
+ - Performance benchmarks
93
+ - Database connectivity proofs
94
+ - Deployment verification
95
+
96
+ ## Common Failure Patterns to Avoid
97
+
98
+ ### Implementation Gaps
99
+
100
+ - Empty directories claiming "full implementation"
101
+ - Mock functions in production code
102
+ - TODO comments in core business logic
103
+ - Placeholder implementations
104
+ - Missing error handling
105
+
106
+ ### Testing Shortcuts
107
+
108
+ - Skipping integration tests
109
+ - Mocking database operations
110
+ - Ignoring linting errors
111
+ - Not testing error conditions
112
+ - Fake test data instead of real fixtures
113
+
114
+ ### Documentation Lies
115
+
116
+ - Claiming 100% coverage with 75% actual
117
+ - Features documented but not implemented
118
+ - APIs documented with wrong signatures
119
+ - Missing breaking changes in changelogs
120
+
121
+ ### Infrastructure Pretending
122
+
123
+ - In-memory storage claiming "persistence"
124
+ - No-op security claiming "secure"
125
+ - Console.log claiming "monitoring"
126
+ - No circuit breakers claiming "resilient"
127
+
128
+ ## Verification Checklist
129
+
130
+ Use this before any production claim:
131
+
132
+ - [ ] `npm test` passes all tests
133
+ - [ ] `npm run lint` shows zero errors
134
+ - [ ] `npm run typecheck` passes
135
+ - [ ] Database tests use real PostgreSQL/MySQL/etc.
136
+ - [ ] Security tests validate actual controls
137
+ - [ ] Performance tests meet SLAs
138
+ - [ ] No TODO/PLACEHOLDER/MOCK_DATA in src/
139
+ - [ ] Coverage reports show adequate thresholds
140
+ - [ ] CI/CD pipeline passes
141
+ - [ ] Deployment docs exist and are tested
142
+ - [ ] Documentation matches code reality
143
+
144
+ **If ANY box is unchecked, do not claim production readiness.**