@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.
- package/README.md +58 -0
- package/dist/context.test.js +2 -3
- package/dist/environment.test.js +2 -1
- package/dist/gates/agent-team.d.ts +2 -1
- package/dist/gates/agent-team.js +1 -0
- package/dist/gates/base.d.ts +3 -1
- package/dist/gates/base.js +3 -0
- package/dist/gates/checkpoint.d.ts +2 -1
- package/dist/gates/checkpoint.js +3 -2
- package/dist/gates/context-window-artifacts.d.ts +2 -1
- package/dist/gates/context-window-artifacts.js +6 -3
- package/dist/gates/context.d.ts +2 -1
- package/dist/gates/context.js +1 -0
- package/dist/gates/coverage.js +3 -1
- package/dist/gates/dependency.js +5 -5
- package/dist/gates/duplication-drift.d.ts +2 -1
- package/dist/gates/duplication-drift.js +4 -1
- package/dist/gates/environment.js +4 -4
- package/dist/gates/hallucinated-imports.d.ts +21 -2
- package/dist/gates/hallucinated-imports.js +116 -2
- package/dist/gates/inconsistent-error-handling.d.ts +2 -1
- package/dist/gates/inconsistent-error-handling.js +21 -7
- package/dist/gates/promise-safety.d.ts +68 -0
- package/dist/gates/promise-safety.js +509 -0
- package/dist/gates/retry-loop-breaker.d.ts +2 -1
- package/dist/gates/retry-loop-breaker.js +2 -1
- package/dist/gates/runner.js +34 -1
- package/dist/gates/safety.d.ts +2 -1
- package/dist/gates/safety.js +2 -1
- package/dist/gates/security-patterns.d.ts +2 -1
- package/dist/gates/security-patterns.js +1 -0
- package/dist/gates/structure.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/services/fix-packet-service.d.ts +0 -1
- package/dist/services/fix-packet-service.js +9 -14
- package/dist/services/score-history.d.ts +54 -0
- package/dist/services/score-history.js +122 -0
- package/dist/templates/index.js +169 -0
- package/dist/types/fix-packet.d.ts +5 -5
- package/dist/types/fix-packet.js +1 -1
- package/dist/types/index.d.ts +153 -0
- package/dist/types/index.js +19 -0
- package/package.json +21 -1
- package/src/context.test.ts +0 -256
- package/src/discovery.test.ts +0 -88
- package/src/discovery.ts +0 -112
- package/src/environment.test.ts +0 -115
- package/src/gates/agent-team.test.ts +0 -134
- package/src/gates/agent-team.ts +0 -210
- package/src/gates/ast-handlers/base.ts +0 -13
- package/src/gates/ast-handlers/python.ts +0 -145
- package/src/gates/ast-handlers/python_parser.py +0 -181
- package/src/gates/ast-handlers/typescript.ts +0 -264
- package/src/gates/ast-handlers/universal.ts +0 -184
- package/src/gates/ast.ts +0 -54
- package/src/gates/base.ts +0 -28
- package/src/gates/checkpoint.test.ts +0 -135
- package/src/gates/checkpoint.ts +0 -311
- package/src/gates/content.ts +0 -51
- package/src/gates/context-window-artifacts.ts +0 -277
- package/src/gates/context.ts +0 -270
- package/src/gates/coverage.ts +0 -74
- package/src/gates/dependency.ts +0 -108
- package/src/gates/duplication-drift.ts +0 -231
- package/src/gates/environment.ts +0 -94
- package/src/gates/file.ts +0 -46
- package/src/gates/hallucinated-imports.ts +0 -361
- package/src/gates/inconsistent-error-handling.ts +0 -254
- package/src/gates/retry-loop-breaker.ts +0 -151
- package/src/gates/runner.ts +0 -188
- package/src/gates/safety.ts +0 -56
- package/src/gates/security-patterns.test.ts +0 -162
- package/src/gates/security-patterns.ts +0 -306
- package/src/gates/structure.ts +0 -36
- package/src/index.ts +0 -13
- package/src/pattern-index/embeddings.ts +0 -84
- package/src/pattern-index/index.ts +0 -59
- package/src/pattern-index/indexer.test.ts +0 -276
- package/src/pattern-index/indexer.ts +0 -1023
- package/src/pattern-index/matcher.test.ts +0 -293
- package/src/pattern-index/matcher.ts +0 -493
- package/src/pattern-index/overrides.ts +0 -235
- package/src/pattern-index/security.ts +0 -151
- package/src/pattern-index/staleness.test.ts +0 -313
- package/src/pattern-index/staleness.ts +0 -568
- package/src/pattern-index/types.ts +0 -339
- package/src/safety.test.ts +0 -53
- package/src/services/adaptive-thresholds.test.ts +0 -189
- package/src/services/adaptive-thresholds.ts +0 -275
- package/src/services/context-engine.ts +0 -104
- package/src/services/fix-packet-service.ts +0 -42
- package/src/services/state-service.ts +0 -138
- package/src/smoke.test.ts +0 -18
- package/src/templates/index.ts +0 -338
- package/src/types/fix-packet.ts +0 -32
- package/src/types/index.ts +0 -200
- package/src/utils/logger.ts +0 -43
- package/src/utils/scanner.test.ts +0 -37
- package/src/utils/scanner.ts +0 -43
- package/tsconfig.json +0 -10
- package/vitest.config.ts +0 -7
- package/vitest.setup.ts +0 -30
package/dist/types/index.d.ts
CHANGED
|
@@ -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;
|
package/dist/types/index.js
CHANGED
|
@@ -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": "
|
|
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": {
|
package/src/context.test.ts
DELETED
|
@@ -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
|
-
});
|