@rigour-labs/core 2.22.0 → 3.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 (103) hide show
  1. package/README.md +58 -0
  2. package/dist/context.test.js +2 -3
  3. package/dist/environment.test.js +2 -1
  4. package/dist/gates/agent-team.d.ts +2 -1
  5. package/dist/gates/agent-team.js +1 -0
  6. package/dist/gates/base.d.ts +3 -1
  7. package/dist/gates/base.js +3 -0
  8. package/dist/gates/checkpoint.d.ts +2 -1
  9. package/dist/gates/checkpoint.js +3 -2
  10. package/dist/gates/context-window-artifacts.d.ts +2 -1
  11. package/dist/gates/context-window-artifacts.js +6 -3
  12. package/dist/gates/context.d.ts +2 -1
  13. package/dist/gates/context.js +1 -0
  14. package/dist/gates/coverage.js +3 -1
  15. package/dist/gates/dependency.js +5 -5
  16. package/dist/gates/duplication-drift.d.ts +2 -1
  17. package/dist/gates/duplication-drift.js +4 -1
  18. package/dist/gates/environment.js +4 -4
  19. package/dist/gates/hallucinated-imports.d.ts +21 -2
  20. package/dist/gates/hallucinated-imports.js +116 -2
  21. package/dist/gates/inconsistent-error-handling.d.ts +2 -1
  22. package/dist/gates/inconsistent-error-handling.js +21 -7
  23. package/dist/gates/promise-safety.d.ts +68 -0
  24. package/dist/gates/promise-safety.js +509 -0
  25. package/dist/gates/retry-loop-breaker.d.ts +2 -1
  26. package/dist/gates/retry-loop-breaker.js +2 -1
  27. package/dist/gates/runner.js +34 -1
  28. package/dist/gates/safety.d.ts +2 -1
  29. package/dist/gates/safety.js +2 -1
  30. package/dist/gates/security-patterns.d.ts +2 -1
  31. package/dist/gates/security-patterns.js +1 -0
  32. package/dist/gates/structure.js +1 -1
  33. package/dist/index.d.ts +1 -0
  34. package/dist/index.js +1 -0
  35. package/dist/services/fix-packet-service.d.ts +0 -1
  36. package/dist/services/fix-packet-service.js +9 -14
  37. package/dist/services/score-history.d.ts +54 -0
  38. package/dist/services/score-history.js +122 -0
  39. package/dist/templates/index.js +169 -0
  40. package/dist/types/fix-packet.d.ts +5 -5
  41. package/dist/types/fix-packet.js +1 -1
  42. package/dist/types/index.d.ts +153 -0
  43. package/dist/types/index.js +19 -0
  44. package/package.json +21 -1
  45. package/src/context.test.ts +0 -256
  46. package/src/discovery.test.ts +0 -88
  47. package/src/discovery.ts +0 -112
  48. package/src/environment.test.ts +0 -115
  49. package/src/gates/agent-team.test.ts +0 -134
  50. package/src/gates/agent-team.ts +0 -210
  51. package/src/gates/ast-handlers/base.ts +0 -13
  52. package/src/gates/ast-handlers/python.ts +0 -145
  53. package/src/gates/ast-handlers/python_parser.py +0 -181
  54. package/src/gates/ast-handlers/typescript.ts +0 -264
  55. package/src/gates/ast-handlers/universal.ts +0 -184
  56. package/src/gates/ast.ts +0 -54
  57. package/src/gates/base.ts +0 -28
  58. package/src/gates/checkpoint.test.ts +0 -135
  59. package/src/gates/checkpoint.ts +0 -311
  60. package/src/gates/content.ts +0 -51
  61. package/src/gates/context-window-artifacts.ts +0 -277
  62. package/src/gates/context.ts +0 -270
  63. package/src/gates/coverage.ts +0 -74
  64. package/src/gates/dependency.ts +0 -108
  65. package/src/gates/duplication-drift.ts +0 -231
  66. package/src/gates/environment.ts +0 -94
  67. package/src/gates/file.ts +0 -46
  68. package/src/gates/hallucinated-imports.ts +0 -361
  69. package/src/gates/inconsistent-error-handling.ts +0 -254
  70. package/src/gates/retry-loop-breaker.ts +0 -151
  71. package/src/gates/runner.ts +0 -188
  72. package/src/gates/safety.ts +0 -56
  73. package/src/gates/security-patterns.test.ts +0 -162
  74. package/src/gates/security-patterns.ts +0 -306
  75. package/src/gates/structure.ts +0 -36
  76. package/src/index.ts +0 -13
  77. package/src/pattern-index/embeddings.ts +0 -84
  78. package/src/pattern-index/index.ts +0 -59
  79. package/src/pattern-index/indexer.test.ts +0 -276
  80. package/src/pattern-index/indexer.ts +0 -1023
  81. package/src/pattern-index/matcher.test.ts +0 -293
  82. package/src/pattern-index/matcher.ts +0 -493
  83. package/src/pattern-index/overrides.ts +0 -235
  84. package/src/pattern-index/security.ts +0 -151
  85. package/src/pattern-index/staleness.test.ts +0 -313
  86. package/src/pattern-index/staleness.ts +0 -568
  87. package/src/pattern-index/types.ts +0 -339
  88. package/src/safety.test.ts +0 -53
  89. package/src/services/adaptive-thresholds.test.ts +0 -189
  90. package/src/services/adaptive-thresholds.ts +0 -275
  91. package/src/services/context-engine.ts +0 -104
  92. package/src/services/fix-packet-service.ts +0 -42
  93. package/src/services/state-service.ts +0 -138
  94. package/src/smoke.test.ts +0 -18
  95. package/src/templates/index.ts +0 -338
  96. package/src/types/fix-packet.ts +0 -32
  97. package/src/types/index.ts +0 -200
  98. package/src/utils/logger.ts +0 -43
  99. package/src/utils/scanner.test.ts +0 -37
  100. package/src/utils/scanner.ts +0 -43
  101. package/tsconfig.json +0 -10
  102. package/vitest.config.ts +0 -7
  103. package/vitest.setup.ts +0 -30
@@ -293,6 +293,28 @@ export declare const GatesSchema: z.ZodObject<{
293
293
  degradation_threshold?: number | undefined;
294
294
  signals_required?: number | undefined;
295
295
  }>>>;
296
+ promise_safety: z.ZodDefault<z.ZodOptional<z.ZodObject<{
297
+ enabled: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
298
+ check_unhandled_then: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
299
+ check_unsafe_parse: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
300
+ check_async_without_await: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
301
+ check_unsafe_fetch: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
302
+ ignore_patterns: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>;
303
+ }, "strip", z.ZodTypeAny, {
304
+ enabled: boolean;
305
+ ignore_patterns: string[];
306
+ check_unhandled_then: boolean;
307
+ check_unsafe_parse: boolean;
308
+ check_async_without_await: boolean;
309
+ check_unsafe_fetch: boolean;
310
+ }, {
311
+ enabled?: boolean | undefined;
312
+ ignore_patterns?: string[] | undefined;
313
+ check_unhandled_then?: boolean | undefined;
314
+ check_unsafe_parse?: boolean | undefined;
315
+ check_async_without_await?: boolean | undefined;
316
+ check_unsafe_fetch?: boolean | undefined;
317
+ }>>>;
296
318
  }, "strip", z.ZodTypeAny, {
297
319
  max_file_lines: number;
298
320
  forbid_todos: boolean;
@@ -403,6 +425,14 @@ export declare const GatesSchema: z.ZodObject<{
403
425
  degradation_threshold: number;
404
426
  signals_required: number;
405
427
  };
428
+ promise_safety: {
429
+ enabled: boolean;
430
+ ignore_patterns: string[];
431
+ check_unhandled_then: boolean;
432
+ check_unsafe_parse: boolean;
433
+ check_async_without_await: boolean;
434
+ check_unsafe_fetch: boolean;
435
+ };
406
436
  }, {
407
437
  max_file_lines?: number | undefined;
408
438
  forbid_todos?: boolean | undefined;
@@ -513,6 +543,14 @@ export declare const GatesSchema: z.ZodObject<{
513
543
  degradation_threshold?: number | undefined;
514
544
  signals_required?: number | undefined;
515
545
  } | undefined;
546
+ promise_safety?: {
547
+ enabled?: boolean | undefined;
548
+ ignore_patterns?: string[] | undefined;
549
+ check_unhandled_then?: boolean | undefined;
550
+ check_unsafe_parse?: boolean | undefined;
551
+ check_async_without_await?: boolean | undefined;
552
+ check_unsafe_fetch?: boolean | undefined;
553
+ } | undefined;
516
554
  }>;
517
555
  export declare const CommandsSchema: z.ZodObject<{
518
556
  format: z.ZodOptional<z.ZodString>;
@@ -844,6 +882,28 @@ export declare const ConfigSchema: z.ZodObject<{
844
882
  degradation_threshold?: number | undefined;
845
883
  signals_required?: number | undefined;
846
884
  }>>>;
885
+ promise_safety: z.ZodDefault<z.ZodOptional<z.ZodObject<{
886
+ enabled: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
887
+ check_unhandled_then: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
888
+ check_unsafe_parse: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
889
+ check_async_without_await: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
890
+ check_unsafe_fetch: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
891
+ ignore_patterns: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>;
892
+ }, "strip", z.ZodTypeAny, {
893
+ enabled: boolean;
894
+ ignore_patterns: string[];
895
+ check_unhandled_then: boolean;
896
+ check_unsafe_parse: boolean;
897
+ check_async_without_await: boolean;
898
+ check_unsafe_fetch: boolean;
899
+ }, {
900
+ enabled?: boolean | undefined;
901
+ ignore_patterns?: string[] | undefined;
902
+ check_unhandled_then?: boolean | undefined;
903
+ check_unsafe_parse?: boolean | undefined;
904
+ check_async_without_await?: boolean | undefined;
905
+ check_unsafe_fetch?: boolean | undefined;
906
+ }>>>;
847
907
  }, "strip", z.ZodTypeAny, {
848
908
  max_file_lines: number;
849
909
  forbid_todos: boolean;
@@ -954,6 +1014,14 @@ export declare const ConfigSchema: z.ZodObject<{
954
1014
  degradation_threshold: number;
955
1015
  signals_required: number;
956
1016
  };
1017
+ promise_safety: {
1018
+ enabled: boolean;
1019
+ ignore_patterns: string[];
1020
+ check_unhandled_then: boolean;
1021
+ check_unsafe_parse: boolean;
1022
+ check_async_without_await: boolean;
1023
+ check_unsafe_fetch: boolean;
1024
+ };
957
1025
  }, {
958
1026
  max_file_lines?: number | undefined;
959
1027
  forbid_todos?: boolean | undefined;
@@ -1064,6 +1132,14 @@ export declare const ConfigSchema: z.ZodObject<{
1064
1132
  degradation_threshold?: number | undefined;
1065
1133
  signals_required?: number | undefined;
1066
1134
  } | undefined;
1135
+ promise_safety?: {
1136
+ enabled?: boolean | undefined;
1137
+ ignore_patterns?: string[] | undefined;
1138
+ check_unhandled_then?: boolean | undefined;
1139
+ check_unsafe_parse?: boolean | undefined;
1140
+ check_async_without_await?: boolean | undefined;
1141
+ check_unsafe_fetch?: boolean | undefined;
1142
+ } | undefined;
1067
1143
  }>>>;
1068
1144
  output: z.ZodDefault<z.ZodOptional<z.ZodObject<{
1069
1145
  report_path: z.ZodDefault<z.ZodString>;
@@ -1193,6 +1269,14 @@ export declare const ConfigSchema: z.ZodObject<{
1193
1269
  degradation_threshold: number;
1194
1270
  signals_required: number;
1195
1271
  };
1272
+ promise_safety: {
1273
+ enabled: boolean;
1274
+ ignore_patterns: string[];
1275
+ check_unhandled_then: boolean;
1276
+ check_unsafe_parse: boolean;
1277
+ check_async_without_await: boolean;
1278
+ check_unsafe_fetch: boolean;
1279
+ };
1196
1280
  };
1197
1281
  output: {
1198
1282
  report_path: string;
@@ -1321,6 +1405,14 @@ export declare const ConfigSchema: z.ZodObject<{
1321
1405
  degradation_threshold?: number | undefined;
1322
1406
  signals_required?: number | undefined;
1323
1407
  } | undefined;
1408
+ promise_safety?: {
1409
+ enabled?: boolean | undefined;
1410
+ ignore_patterns?: string[] | undefined;
1411
+ check_unhandled_then?: boolean | undefined;
1412
+ check_unsafe_parse?: boolean | undefined;
1413
+ check_async_without_await?: boolean | undefined;
1414
+ check_unsafe_fetch?: boolean | undefined;
1415
+ } | undefined;
1324
1416
  } | undefined;
1325
1417
  output?: {
1326
1418
  report_path?: string | undefined;
@@ -1337,6 +1429,9 @@ export declare const StatusSchema: z.ZodEnum<["PASS", "FAIL", "SKIP", "ERROR"]>;
1337
1429
  export type Status = z.infer<typeof StatusSchema>;
1338
1430
  export declare const SeveritySchema: z.ZodEnum<["critical", "high", "medium", "low", "info"]>;
1339
1431
  export type Severity = z.infer<typeof SeveritySchema>;
1432
+ /** Provenance tags — lets dashboards/agents filter by what matters */
1433
+ export declare const ProvenanceSchema: z.ZodEnum<["ai-drift", "traditional", "security", "governance"]>;
1434
+ export type Provenance = z.infer<typeof ProvenanceSchema>;
1340
1435
  /** Severity weights for score calculation */
1341
1436
  export declare const SEVERITY_WEIGHTS: Record<Severity, number>;
1342
1437
  export declare const FailureSchema: z.ZodObject<{
@@ -1344,6 +1439,7 @@ export declare const FailureSchema: z.ZodObject<{
1344
1439
  title: z.ZodString;
1345
1440
  details: z.ZodString;
1346
1441
  severity: z.ZodOptional<z.ZodEnum<["critical", "high", "medium", "low", "info"]>>;
1442
+ provenance: z.ZodOptional<z.ZodEnum<["ai-drift", "traditional", "security", "governance"]>>;
1347
1443
  files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
1348
1444
  line: z.ZodOptional<z.ZodNumber>;
1349
1445
  endLine: z.ZodOptional<z.ZodNumber>;
@@ -1353,6 +1449,7 @@ export declare const FailureSchema: z.ZodObject<{
1353
1449
  title: string;
1354
1450
  details: string;
1355
1451
  severity?: "critical" | "high" | "medium" | "low" | "info" | undefined;
1452
+ provenance?: "security" | "ai-drift" | "traditional" | "governance" | undefined;
1356
1453
  files?: string[] | undefined;
1357
1454
  line?: number | undefined;
1358
1455
  endLine?: number | undefined;
@@ -1362,6 +1459,7 @@ export declare const FailureSchema: z.ZodObject<{
1362
1459
  title: string;
1363
1460
  details: string;
1364
1461
  severity?: "critical" | "high" | "medium" | "low" | "info" | undefined;
1462
+ provenance?: "security" | "ai-drift" | "traditional" | "governance" | undefined;
1365
1463
  files?: string[] | undefined;
1366
1464
  line?: number | undefined;
1367
1465
  endLine?: number | undefined;
@@ -1376,6 +1474,7 @@ export declare const ReportSchema: z.ZodObject<{
1376
1474
  title: z.ZodString;
1377
1475
  details: z.ZodString;
1378
1476
  severity: z.ZodOptional<z.ZodEnum<["critical", "high", "medium", "low", "info"]>>;
1477
+ provenance: z.ZodOptional<z.ZodEnum<["ai-drift", "traditional", "security", "governance"]>>;
1379
1478
  files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
1380
1479
  line: z.ZodOptional<z.ZodNumber>;
1381
1480
  endLine: z.ZodOptional<z.ZodNumber>;
@@ -1385,6 +1484,7 @@ export declare const ReportSchema: z.ZodObject<{
1385
1484
  title: string;
1386
1485
  details: string;
1387
1486
  severity?: "critical" | "high" | "medium" | "low" | "info" | undefined;
1487
+ provenance?: "security" | "ai-drift" | "traditional" | "governance" | undefined;
1388
1488
  files?: string[] | undefined;
1389
1489
  line?: number | undefined;
1390
1490
  endLine?: number | undefined;
@@ -1394,6 +1494,7 @@ export declare const ReportSchema: z.ZodObject<{
1394
1494
  title: string;
1395
1495
  details: string;
1396
1496
  severity?: "critical" | "high" | "medium" | "low" | "info" | undefined;
1497
+ provenance?: "security" | "ai-drift" | "traditional" | "governance" | undefined;
1397
1498
  files?: string[] | undefined;
1398
1499
  line?: number | undefined;
1399
1500
  endLine?: number | undefined;
@@ -1402,21 +1503,63 @@ export declare const ReportSchema: z.ZodObject<{
1402
1503
  stats: z.ZodObject<{
1403
1504
  duration_ms: z.ZodNumber;
1404
1505
  score: z.ZodOptional<z.ZodNumber>;
1506
+ ai_health_score: z.ZodOptional<z.ZodNumber>;
1507
+ structural_score: z.ZodOptional<z.ZodNumber>;
1405
1508
  severity_breakdown: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
1509
+ provenance_breakdown: z.ZodOptional<z.ZodObject<{
1510
+ 'ai-drift': z.ZodNumber;
1511
+ traditional: z.ZodNumber;
1512
+ security: z.ZodNumber;
1513
+ governance: z.ZodNumber;
1514
+ }, "strip", z.ZodTypeAny, {
1515
+ security: number;
1516
+ 'ai-drift': number;
1517
+ traditional: number;
1518
+ governance: number;
1519
+ }, {
1520
+ security: number;
1521
+ 'ai-drift': number;
1522
+ traditional: number;
1523
+ governance: number;
1524
+ }>>;
1406
1525
  }, "strip", z.ZodTypeAny, {
1407
1526
  duration_ms: number;
1408
1527
  score?: number | undefined;
1528
+ ai_health_score?: number | undefined;
1529
+ structural_score?: number | undefined;
1409
1530
  severity_breakdown?: Record<string, number> | undefined;
1531
+ provenance_breakdown?: {
1532
+ security: number;
1533
+ 'ai-drift': number;
1534
+ traditional: number;
1535
+ governance: number;
1536
+ } | undefined;
1410
1537
  }, {
1411
1538
  duration_ms: number;
1412
1539
  score?: number | undefined;
1540
+ ai_health_score?: number | undefined;
1541
+ structural_score?: number | undefined;
1413
1542
  severity_breakdown?: Record<string, number> | undefined;
1543
+ provenance_breakdown?: {
1544
+ security: number;
1545
+ 'ai-drift': number;
1546
+ traditional: number;
1547
+ governance: number;
1548
+ } | undefined;
1414
1549
  }>;
1415
1550
  }, "strip", z.ZodTypeAny, {
1416
1551
  stats: {
1417
1552
  duration_ms: number;
1418
1553
  score?: number | undefined;
1554
+ ai_health_score?: number | undefined;
1555
+ structural_score?: number | undefined;
1419
1556
  severity_breakdown?: Record<string, number> | undefined;
1557
+ provenance_breakdown?: {
1558
+ security: number;
1559
+ 'ai-drift': number;
1560
+ traditional: number;
1561
+ governance: number;
1562
+ } | undefined;
1420
1563
  };
1421
1564
  status: "PASS" | "FAIL" | "SKIP" | "ERROR";
1422
1565
  summary: Record<string, "PASS" | "FAIL" | "SKIP" | "ERROR">;
@@ -1425,6 +1568,7 @@ export declare const ReportSchema: z.ZodObject<{
1425
1568
  title: string;
1426
1569
  details: string;
1427
1570
  severity?: "critical" | "high" | "medium" | "low" | "info" | undefined;
1571
+ provenance?: "security" | "ai-drift" | "traditional" | "governance" | undefined;
1428
1572
  files?: string[] | undefined;
1429
1573
  line?: number | undefined;
1430
1574
  endLine?: number | undefined;
@@ -1434,7 +1578,15 @@ export declare const ReportSchema: z.ZodObject<{
1434
1578
  stats: {
1435
1579
  duration_ms: number;
1436
1580
  score?: number | undefined;
1581
+ ai_health_score?: number | undefined;
1582
+ structural_score?: number | undefined;
1437
1583
  severity_breakdown?: Record<string, number> | undefined;
1584
+ provenance_breakdown?: {
1585
+ security: number;
1586
+ 'ai-drift': number;
1587
+ traditional: number;
1588
+ governance: number;
1589
+ } | undefined;
1438
1590
  };
1439
1591
  status: "PASS" | "FAIL" | "SKIP" | "ERROR";
1440
1592
  summary: Record<string, "PASS" | "FAIL" | "SKIP" | "ERROR">;
@@ -1443,6 +1595,7 @@ export declare const ReportSchema: z.ZodObject<{
1443
1595
  title: string;
1444
1596
  details: string;
1445
1597
  severity?: "critical" | "high" | "medium" | "low" | "info" | undefined;
1598
+ provenance?: "security" | "ai-drift" | "traditional" | "governance" | undefined;
1446
1599
  files?: string[] | undefined;
1447
1600
  line?: number | undefined;
1448
1601
  endLine?: number | undefined;
@@ -129,6 +129,14 @@ export const GatesSchema = z.object({
129
129
  degradation_threshold: z.number().min(0).max(1).optional().default(0.4),
130
130
  signals_required: z.number().optional().default(2),
131
131
  }).optional().default({}),
132
+ promise_safety: z.object({
133
+ enabled: z.boolean().optional().default(true),
134
+ check_unhandled_then: z.boolean().optional().default(true),
135
+ check_unsafe_parse: z.boolean().optional().default(true),
136
+ check_async_without_await: z.boolean().optional().default(true),
137
+ check_unsafe_fetch: z.boolean().optional().default(true),
138
+ ignore_patterns: z.array(z.string()).optional().default([]),
139
+ }).optional().default({}),
132
140
  });
133
141
  export const CommandsSchema = z.object({
134
142
  format: z.string().optional(),
@@ -150,6 +158,8 @@ export const ConfigSchema = z.object({
150
158
  });
151
159
  export const StatusSchema = z.enum(['PASS', 'FAIL', 'SKIP', 'ERROR']);
152
160
  export const SeveritySchema = z.enum(['critical', 'high', 'medium', 'low', 'info']);
161
+ /** Provenance tags — lets dashboards/agents filter by what matters */
162
+ export const ProvenanceSchema = z.enum(['ai-drift', 'traditional', 'security', 'governance']);
153
163
  /** Severity weights for score calculation */
154
164
  export const SEVERITY_WEIGHTS = {
155
165
  critical: 20,
@@ -163,6 +173,7 @@ export const FailureSchema = z.object({
163
173
  title: z.string(),
164
174
  details: z.string(),
165
175
  severity: SeveritySchema.optional(),
176
+ provenance: ProvenanceSchema.optional(),
166
177
  files: z.array(z.string()).optional(),
167
178
  line: z.number().optional(),
168
179
  endLine: z.number().optional(),
@@ -175,6 +186,14 @@ export const ReportSchema = z.object({
175
186
  stats: z.object({
176
187
  duration_ms: z.number(),
177
188
  score: z.number().optional(),
189
+ ai_health_score: z.number().optional(),
190
+ structural_score: z.number().optional(),
178
191
  severity_breakdown: z.record(z.number()).optional(),
192
+ provenance_breakdown: z.object({
193
+ 'ai-drift': z.number(),
194
+ traditional: z.number(),
195
+ security: z.number(),
196
+ governance: z.number(),
197
+ }).optional(),
179
198
  }),
180
199
  });
package/package.json CHANGED
@@ -1,7 +1,27 @@
1
1
  {
2
2
  "name": "@rigour-labs/core",
3
- "version": "2.22.0",
3
+ "version": "3.0.0",
4
+ "description": "Deterministic quality gate engine for AI-generated code. AST analysis, drift detection, and Fix Packet generation across TypeScript, JavaScript, Python, Go, Ruby, and C#.",
5
+ "license": "MIT",
6
+ "homepage": "https://rigour.run",
7
+ "keywords": [
8
+ "quality-gates",
9
+ "ai-code-quality",
10
+ "static-analysis",
11
+ "ast",
12
+ "drift-detection",
13
+ "code-review",
14
+ "linter",
15
+ "typescript",
16
+ "python",
17
+ "golang",
18
+ "csharp"
19
+ ],
4
20
  "type": "module",
21
+ "files": [
22
+ "dist",
23
+ "README.md"
24
+ ],
5
25
  "main": "dist/index.js",
6
26
  "types": "dist/index.d.ts",
7
27
  "exports": {
@@ -1,256 +0,0 @@
1
- import { describe, it, expect, beforeAll, afterAll } from 'vitest';
2
- import { GateRunner } from '../src/gates/runner.js';
3
- import fs from 'fs-extra';
4
- import path from 'path';
5
- import { fileURLToPath } from 'url';
6
-
7
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
8
- const TEST_CWD = path.join(__dirname, '../temp-test-context');
9
-
10
- describe('Context Awareness Engine', () => {
11
- beforeAll(async () => {
12
- await fs.ensureDir(TEST_CWD);
13
- });
14
-
15
- afterAll(async () => {
16
- await fs.remove(TEST_CWD);
17
- });
18
-
19
- it('should detect context drift for redundant env suffixes (Golden Example)', async () => {
20
- // Setup: Define standard GCP_PROJECT_ID
21
- await fs.writeFile(path.join(TEST_CWD, '.env.example'), 'GCP_PROJECT_ID=my-project\n');
22
-
23
- // Setup: Use drifted GCP_PROJECT_ID_PRODUCTION
24
- await fs.writeFile(path.join(TEST_CWD, 'feature.js'), `
25
- const id = process.env.GCP_PROJECT_ID_PRODUCTION;
26
- console.log(id);
27
- `);
28
-
29
- const config = {
30
- version: 1,
31
- commands: {},
32
- gates: {
33
- context: {
34
- enabled: true,
35
- sensitivity: 0.8,
36
- mining_depth: 10,
37
- ignored_patterns: [],
38
- cross_file_patterns: true,
39
- naming_consistency: true,
40
- import_relationships: true,
41
- max_cross_file_depth: 50,
42
- },
43
- },
44
- output: { report_path: 'rigour-report.json' }
45
- };
46
-
47
- const runner = new GateRunner(config as any);
48
- const report = await runner.run(TEST_CWD);
49
-
50
- const driftFailures = report.failures.filter(f => f.id === 'context-drift');
51
- expect(driftFailures.length).toBeGreaterThan(0);
52
- expect(driftFailures[0].details).toContain('GCP_PROJECT_ID_PRODUCTION');
53
- expect(driftFailures[0].hint).toContain('GCP_PROJECT_ID');
54
- });
55
-
56
- it('should not flag valid environment variables', async () => {
57
- await fs.writeFile(path.join(TEST_CWD, 'valid.js'), `
58
- const id = process.env.GCP_PROJECT_ID;
59
- `);
60
-
61
- const config = {
62
- version: 1,
63
- commands: {},
64
- gates: {
65
- context: {
66
- enabled: true,
67
- sensitivity: 0.8,
68
- mining_depth: 100,
69
- ignored_patterns: [],
70
- cross_file_patterns: true,
71
- naming_consistency: true,
72
- import_relationships: true,
73
- max_cross_file_depth: 50,
74
- },
75
- },
76
- output: { report_path: 'rigour-report.json' }
77
- };
78
-
79
- const runner = new GateRunner(config as any);
80
- const report = await runner.run(TEST_CWD);
81
-
82
- const driftFailures = report.failures.filter(f => f.id === 'context-drift');
83
- // Filter out failures from other files if they still exist in TEST_CWD
84
- const specificFailures = driftFailures.filter(f => f.files?.includes('valid.js'));
85
- expect(specificFailures.length).toBe(0);
86
- });
87
- it('should classify arrow function exports as camelCase, not unknown', async () => {
88
- // Create files with arrow function patterns that previously returned 'unknown'
89
- await fs.writeFile(path.join(TEST_CWD, 'api.ts'), `
90
- export const fetchData = async () => { return []; };
91
- export const getUserProfile = async (id: string) => { return {}; };
92
- export const use = () => {};
93
- export const get = async () => {};
94
- const handleClick = (e: Event) => {};
95
- let processItem = async (item: any) => {};
96
- `);
97
-
98
- // Create a second file with consistent arrow function naming
99
- await fs.writeFile(path.join(TEST_CWD, 'service.ts'), `
100
- export const createUser = async (data: any) => {};
101
- export const deleteUser = async (id: string) => {};
102
- export const updateUser = async (id: string, data: any) => {};
103
- `);
104
-
105
- const config = {
106
- version: 1,
107
- commands: {},
108
- gates: {
109
- context: {
110
- enabled: true,
111
- sensitivity: 0.8,
112
- mining_depth: 10,
113
- ignored_patterns: [],
114
- cross_file_patterns: true,
115
- naming_consistency: true,
116
- import_relationships: true,
117
- max_cross_file_depth: 50,
118
- },
119
- },
120
- output: { report_path: 'rigour-report.json' }
121
- };
122
-
123
- const runner = new GateRunner(config as any);
124
- const report = await runner.run(TEST_CWD);
125
-
126
- // Should NOT have any "unknown" naming convention failures
127
- const namingFailures = report.failures.filter(f =>
128
- f.id === 'context-drift' && f.details?.includes('unknown')
129
- );
130
- expect(namingFailures.length).toBe(0);
131
- });
132
-
133
- it('should not classify plain variable declarations as function patterns', async () => {
134
- // Create file with non-function const declarations
135
- await fs.writeFile(path.join(TEST_CWD, 'constants.ts'), `
136
- export const API_URL = 'https://api.example.com';
137
- export const MAX_RETRIES = 3;
138
- const config = { timeout: 5000 };
139
- let count = 0;
140
- `);
141
-
142
- // Create file with actual functions for a dominant pattern
143
- await fs.writeFile(path.join(TEST_CWD, 'utils.ts'), `
144
- function getData() { return []; }
145
- function setData(d: any) { return d; }
146
- function processRequest(req: any) { return req; }
147
- `);
148
-
149
- const config = {
150
- version: 1,
151
- commands: {},
152
- gates: {
153
- context: {
154
- enabled: true,
155
- sensitivity: 0.8,
156
- mining_depth: 10,
157
- ignored_patterns: [],
158
- cross_file_patterns: true,
159
- naming_consistency: true,
160
- import_relationships: true,
161
- max_cross_file_depth: 50,
162
- },
163
- },
164
- output: { report_path: 'rigour-report.json' }
165
- };
166
-
167
- const runner = new GateRunner(config as any);
168
- const report = await runner.run(TEST_CWD);
169
-
170
- // SCREAMING_SNAKE constants should NOT create naming drift failures
171
- // because they should not be in the 'function' pattern bucket at all
172
- const namingFailures = report.failures.filter(f =>
173
- f.id === 'context-drift' && f.details?.includes('SCREAMING_SNAKE')
174
- );
175
- expect(namingFailures.length).toBe(0);
176
- });
177
- });
178
-
179
- /**
180
- * Direct unit tests for detectCasing logic
181
- */
182
- describe('detectCasing classification', () => {
183
- // We test the regex rules directly since detectCasing is private
184
- function detectCasing(name: string): string {
185
- if (/^[A-Z][a-z]/.test(name) && /[a-z][A-Z]/.test(name)) return 'PascalCase';
186
- if (/^[a-z]/.test(name) && /[a-z][A-Z]/.test(name)) return 'camelCase';
187
- if (/^[a-z][a-zA-Z0-9]*$/.test(name)) return 'camelCase'; // single-word lowercase
188
- if (/^[a-z]+(_[a-z]+)+$/.test(name)) return 'snake_case';
189
- if (/^[A-Z]+(_[A-Z]+)*$/.test(name)) return 'SCREAMING_SNAKE';
190
- if (/^[A-Z][a-zA-Z]*$/.test(name)) return 'PascalCase';
191
- return 'unknown';
192
- }
193
-
194
- // Multi-word camelCase
195
- it('classifies multi-word camelCase', () => {
196
- expect(detectCasing('fetchData')).toBe('camelCase');
197
- expect(detectCasing('getUserProfile')).toBe('camelCase');
198
- expect(detectCasing('handleClick')).toBe('camelCase');
199
- expect(detectCasing('processItem')).toBe('camelCase');
200
- expect(detectCasing('createNewUser')).toBe('camelCase');
201
- });
202
-
203
- // Single-word lowercase (the bug fix)
204
- it('classifies single-word lowercase as camelCase', () => {
205
- expect(detectCasing('fetch')).toBe('camelCase');
206
- expect(detectCasing('use')).toBe('camelCase');
207
- expect(detectCasing('get')).toBe('camelCase');
208
- expect(detectCasing('set')).toBe('camelCase');
209
- expect(detectCasing('run')).toBe('camelCase');
210
- expect(detectCasing('a')).toBe('camelCase');
211
- expect(detectCasing('x')).toBe('camelCase');
212
- expect(detectCasing('id')).toBe('camelCase');
213
- });
214
-
215
- // Single-word lowercase with digits
216
- it('classifies lowercase with digits as camelCase', () => {
217
- expect(detectCasing('handler2')).toBe('camelCase');
218
- expect(detectCasing('config3')).toBe('camelCase');
219
- expect(detectCasing('v2')).toBe('camelCase');
220
- });
221
-
222
- // PascalCase
223
- it('classifies PascalCase', () => {
224
- expect(detectCasing('MyComponent')).toBe('PascalCase');
225
- expect(detectCasing('UserService')).toBe('PascalCase');
226
- expect(detectCasing('App')).toBe('PascalCase');
227
- expect(detectCasing('A')).toBe('SCREAMING_SNAKE'); // single uppercase letter
228
- });
229
-
230
- // snake_case
231
- it('classifies snake_case', () => {
232
- expect(detectCasing('my_func')).toBe('snake_case');
233
- expect(detectCasing('get_data')).toBe('snake_case');
234
- expect(detectCasing('process_all_items')).toBe('snake_case');
235
- });
236
-
237
- // SCREAMING_SNAKE
238
- it('classifies SCREAMING_SNAKE_CASE', () => {
239
- expect(detectCasing('API_URL')).toBe('SCREAMING_SNAKE');
240
- expect(detectCasing('MAX_RETRIES')).toBe('SCREAMING_SNAKE');
241
- expect(detectCasing('A')).toBe('SCREAMING_SNAKE');
242
- expect(detectCasing('DB')).toBe('SCREAMING_SNAKE');
243
- });
244
-
245
- // Edge cases that should NOT be unknown
246
- it('does not return unknown for valid identifiers', () => {
247
- const validIdentifiers = [
248
- 'fetch', 'getData', 'MyClass', 'my_func', 'API_KEY',
249
- 'use', 'run', 'a', 'x', 'id', 'App', 'handler2',
250
- 'processItem', 'UserProfile', 'get_all_data', 'MAX_SIZE',
251
- ];
252
- for (const name of validIdentifiers) {
253
- expect(detectCasing(name)).not.toBe('unknown');
254
- }
255
- });
256
- });