@rigour-labs/core 6.6.6 → 6.7.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 (133) hide show
  1. package/README.md +16 -92
  2. package/dist/environment.test.js +0 -4
  3. package/dist/gates/agent-team.d.ts +0 -2
  4. package/dist/gates/agent-team.js +0 -8
  5. package/dist/gates/checkpoint.d.ts +0 -1
  6. package/dist/gates/checkpoint.js +0 -1
  7. package/dist/gates/context.d.ts +0 -4
  8. package/dist/gates/context.js +7 -17
  9. package/dist/gates/deep-analysis.d.ts +0 -1
  10. package/dist/gates/deep-runner.js +0 -1
  11. package/dist/gates/frontend-secret-exposure.test.js +2 -2
  12. package/dist/gates/hallucinated-imports/index.d.ts +0 -2
  13. package/dist/gates/hallucinated-imports/index.js +2 -2
  14. package/dist/gates/hallucinated-imports/js-resolver.js +1 -0
  15. package/dist/gates/hallucinated-imports.test.js +10 -0
  16. package/dist/gates/runner.js +3 -4
  17. package/dist/gates/test-quality-matchers.d.ts +0 -4
  18. package/dist/gates/test-quality-matchers.js +0 -7
  19. package/dist/gates/test-quality.d.ts +0 -2
  20. package/dist/gates/test-quality.js +1 -10
  21. package/dist/hooks/checker.js +1 -1
  22. package/dist/hooks/index.d.ts +1 -2
  23. package/dist/hooks/index.js +0 -1
  24. package/dist/hooks/types.d.ts +0 -14
  25. package/dist/hooks/types.js +1 -15
  26. package/dist/index.d.ts +6 -1
  27. package/dist/index.js +6 -1
  28. package/dist/inference/cloud-provider.d.ts +2 -0
  29. package/dist/inference/cloud-provider.js +16 -6
  30. package/dist/inference/cloud-provider.test.js +21 -0
  31. package/dist/pattern-index/embeddings.d.ts +0 -5
  32. package/dist/pattern-index/embeddings.js +11 -4
  33. package/dist/pattern-index/semantic-runtime.d.ts +10 -0
  34. package/dist/pattern-index/semantic-runtime.js +46 -0
  35. package/dist/pattern-index/semantic-runtime.test.d.ts +1 -0
  36. package/dist/pattern-index/semantic-runtime.test.js +31 -0
  37. package/dist/review/backtest-judges.d.ts +38 -0
  38. package/dist/review/backtest-judges.js +63 -0
  39. package/dist/review/backtest-judges.test.d.ts +1 -0
  40. package/dist/review/backtest-judges.test.js +32 -0
  41. package/dist/review/backtest.d.ts +9 -4
  42. package/dist/review/backtest.js +19 -9
  43. package/dist/review/backtest.test.js +2 -2
  44. package/dist/review/baseline.js +2 -1
  45. package/dist/review/dead-code.test.js +7 -0
  46. package/dist/review/fix-scope.d.ts +21 -0
  47. package/dist/review/fix-scope.js +94 -0
  48. package/dist/review/fix-scope.test.d.ts +1 -0
  49. package/dist/review/fix-scope.test.js +104 -0
  50. package/dist/review/lint-overlay.js +1 -1
  51. package/dist/review/orphan-files.js +3 -2
  52. package/dist/review/partial-wiring.js +5 -3
  53. package/dist/review/query-patterns.js +3 -2
  54. package/dist/review/review.js +2 -1
  55. package/dist/review/reviewer/adapters.d.ts +23 -7
  56. package/dist/review/reviewer/adapters.js +32 -7
  57. package/dist/review/reviewer/adapters.test.d.ts +1 -0
  58. package/dist/review/reviewer/adapters.test.js +23 -0
  59. package/dist/review/reviewer/background.d.ts +8 -1
  60. package/dist/review/reviewer/background.js +34 -9
  61. package/dist/review/reviewer/background.test.js +16 -2
  62. package/dist/review/reviewer/consensus.d.ts +36 -0
  63. package/dist/review/reviewer/consensus.js +144 -0
  64. package/dist/review/reviewer/context.d.ts +75 -0
  65. package/dist/review/reviewer/context.js +140 -0
  66. package/dist/review/reviewer/context.test.d.ts +1 -0
  67. package/dist/review/reviewer/context.test.js +18 -0
  68. package/dist/review/reviewer/exec.js +6 -2
  69. package/dist/review/reviewer/exec.test.d.ts +1 -0
  70. package/dist/review/reviewer/exec.test.js +23 -0
  71. package/dist/review/reviewer/inputs.d.ts +2 -0
  72. package/dist/review/reviewer/inputs.js +5 -1
  73. package/dist/review/reviewer/panel.d.ts +67 -0
  74. package/dist/review/reviewer/panel.js +101 -0
  75. package/dist/review/reviewer/panel.test.d.ts +1 -0
  76. package/dist/review/reviewer/panel.test.js +110 -0
  77. package/dist/review/reviewer/prompt.d.ts +11 -0
  78. package/dist/review/reviewer/prompt.js +26 -4
  79. package/dist/review/reviewer/settings.d.ts +58 -0
  80. package/dist/review/reviewer/settings.js +152 -0
  81. package/dist/review/reviewer/settings.test.d.ts +1 -0
  82. package/dist/review/reviewer/settings.test.js +57 -0
  83. package/dist/review/reviewer/store.d.ts +25 -2
  84. package/dist/review/reviewer/store.js +43 -1
  85. package/dist/review/reviewer/usage.d.ts +2 -0
  86. package/dist/review/reviewer/usage.js +28 -0
  87. package/dist/review/reviewer/usage.test.d.ts +1 -0
  88. package/dist/review/reviewer/usage.test.js +14 -0
  89. package/dist/review/reviewer/verdict.d.ts +15 -1
  90. package/dist/review/reviewer/verdict.js +17 -7
  91. package/dist/review/reviewer.d.ts +45 -2
  92. package/dist/review/reviewer.js +186 -25
  93. package/dist/review/reviewer.test.js +127 -12
  94. package/dist/review/test-files.d.ts +5 -1
  95. package/dist/review/test-files.js +6 -2
  96. package/dist/review/toolchain.js +10 -3
  97. package/dist/review/toolchain.test.js +6 -3
  98. package/dist/review/typed/program.d.ts +0 -1
  99. package/dist/review/typed/program.js +3 -3
  100. package/dist/review/typed/redundancy.js +43 -4
  101. package/dist/review/typed/redundancy.test.js +58 -0
  102. package/dist/review/typed/schema-nullability.d.ts +6 -0
  103. package/dist/review/typed/schema-nullability.js +218 -0
  104. package/dist/review/typed/schema-nullability.test.d.ts +1 -0
  105. package/dist/review/typed/schema-nullability.test.js +63 -0
  106. package/dist/review/unused-exports.js +5 -6
  107. package/dist/semantic/learn/types.d.ts +2 -2
  108. package/dist/services/adaptive-thresholds.d.ts +2 -52
  109. package/dist/services/adaptive-thresholds.js +2 -147
  110. package/dist/services/adaptive-thresholds.test.js +1 -81
  111. package/dist/settings.d.ts +14 -6
  112. package/dist/settings.js +0 -12
  113. package/dist/storage/team-diagnostics.js +1 -1
  114. package/dist/storage/team-schema.d.ts +1 -1
  115. package/dist/storage/team-schema.js +2 -0
  116. package/dist/storage/team-store.js +26 -3
  117. package/dist/storage/team-sync-scope.test.js +35 -2
  118. package/dist/telemetry/telemetry.d.ts +5 -0
  119. package/dist/telemetry/telemetry.js +11 -1
  120. package/dist/templates/paradigms.js +0 -8
  121. package/dist/templates/presets.d.ts +0 -1
  122. package/dist/templates/presets.js +0 -23
  123. package/dist/templates/universal-config.js +8 -45
  124. package/dist/types/index.d.ts +108 -566
  125. package/dist/types/index.js +41 -66
  126. package/dist/types/index.test.d.ts +1 -0
  127. package/dist/types/index.test.js +33 -0
  128. package/dist/utils/command-line.d.ts +8 -0
  129. package/dist/utils/command-line.js +8 -0
  130. package/dist/utils/command-line.test.d.ts +1 -0
  131. package/dist/utils/command-line.test.js +8 -0
  132. package/dist/utils/profile.js +1 -1
  133. package/package.json +6 -7
package/README.md CHANGED
@@ -1,104 +1,28 @@
1
1
  # @rigour-labs/core
2
2
 
3
- [![npm version](https://img.shields.io/npm/v/@rigour-labs/core?color=cyan)](https://www.npmjs.com/package/@rigour-labs/core)
4
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
3
+ [![npm version](https://img.shields.io/npm/v/@rigour-labs/core?color=4f46e5)](https://www.npmjs.com/package/@rigour-labs/core)
4
+ [![License: MIT](https://img.shields.io/badge/license-MIT-facc15.svg)](https://opensource.org/licenses/MIT)
5
5
 
6
- **AI Agent Governance Engine — deterministic quality gates, drift detection, and LLM-powered deep analysis.**
6
+ The engine behind [Rigour](https://github.com/rigour-labs/rigour): the checks, the review of a change, the
7
+ reviewer that runs coding agents' own CLIs as judges, model review, local learning and the team database.
7
8
 
8
- The core library powering [Rigour](https://rigour.run) — 27+ quality gates, five-signal deep analysis pipeline, temporal drift engine, and AI agent DLP across TypeScript, JavaScript, Python, Go, Ruby, and C#/.NET.
9
+ Most people want the command, [@rigour-labs/cli](https://www.npmjs.com/package/@rigour-labs/cli), or the MCP
10
+ server, [@rigour-labs/mcp](https://www.npmjs.com/package/@rigour-labs/mcp). This package is for building on
11
+ the engine.
9
12
 
10
- > This package is the engine. For the CLI, use [`@rigour-labs/cli`](https://www.npmjs.com/package/@rigour-labs/cli). For MCP integration, use [`@rigour-labs/mcp`](https://www.npmjs.com/package/@rigour-labs/mcp).
11
-
12
- ## What's Inside
13
-
14
- ### 27+ Deterministic Quality Gates
15
-
16
- **Structural:** File size, cyclomatic complexity, method count, parameter count, nesting depth, required docs, content hygiene.
17
-
18
- **Security:** Hardcoded secrets, SQL injection, XSS, command injection, path traversal, frontend secret exposure.
19
-
20
- **AI Drift Detection:**
21
- - **Three-pass duplication drift** — MD5 exact → AST Jaccard (tree-sitter) → semantic embedding (all-MiniLM-L6-v2, 384D cosine). Catches `.find()` vs `.filter()[0]` — same intent, different implementation.
22
- - **Hallucinated imports** — language-aware resolution for relative + package imports.
23
- - **Phantom APIs** — non-existent stdlib/framework methods the LLM invented.
24
- - **Style drift** — fingerprints naming, error handling, import style, quote preferences against project baseline.
25
- - **Logic drift** — tracks comparison operators (>= → >), branch counts, return statements per function across scans.
26
- - **Dependency bloat** — unused deps, heavy alternatives (moment→dayjs), duplicate purpose packages.
27
- - **Context-window artifacts**, inconsistent error handling, promise safety, deprecated APIs.
28
-
29
- **Semantic Bugs (type-aware, on by default):** a TypeScript program with the checker and cross-file value tracing proves a defect before reporting it: credentials forwarded on redirect, paged reads aggregated in memory, cached responses that can carry a failure fallback. Rules learned from fixes (`rigour learn`) run alongside them from `.rigour/rules/`.
30
-
31
- **Agent Governance:** Multi-agent scope isolation, EWMA-based checkpoint supervision, context drift, retry loop breaker, memory & skills governance with DLP scanning.
32
-
33
- ### Real-Time Hook Engine
34
-
35
- Sub-200ms per-file-write checker with 5 fast gates (governance, hallucinated imports, promise safety, security patterns, file size). Generates native hook configs for Claude Code, Cursor, Cline, and Windsurf.
36
-
37
- ### AI Agent DLP (Data Loss Prevention)
38
-
39
- 29 credential patterns with anti-evasion hardening (unicode normalization, zero-width char removal, bidi control stripping, Shannon entropy detection >4.5 bits). Compliance-mapped to SOC2-CC6.1, HIPAA-164.312, PCI-DSS-3.4/3.5/6.5, OWASP-A2, CWE-798.
40
-
41
- ### Five-Signal Deep Analysis Pipeline
42
-
43
- Rigour's deep analysis is not a wrapper around a generic LLM. The model operates within a cage of deterministic facts:
44
-
45
- 1. **Extract** — five independent signal streams (AST facts, semantic embeddings, style fingerprints, logic baselines, dependency graphs) computed deterministically before the LLM sees anything.
46
- 2. **Interpret** — the model receives structured facts (not raw source), focuses on SOLID, design patterns, language idioms, architecture. Constrained input prevents hallucination.
47
- 3. **Verify** — every LLM finding is cross-referenced against all five signal streams. Wrong line numbers, phantom patterns, non-existent functions → discarded. Only verified findings with confidence scores reach the report.
48
-
49
- Deep review is built for frontier models: your own key, or the coding agent's own model. The small local models (lite and deep tiers fine-tuned via the [DriftBench RLAIF pipeline](https://github.com/rigour-labs/driftbench); max is the stock Qwen2.5-Coder-7B) remain available offline but are no longer developed.
50
-
51
- ### Temporal Drift Engine (v5.1)
52
-
53
- Cross-session trend analysis powered by EWMA and Z-score anomaly detection. Tracks three independent provenance streams (AI drift, structural, security) with separate trend directions. Reads from the SQLite brain for month-over-month analysis.
54
-
55
- Key capabilities: per-provenance EWMA streams (alpha=0.3), Z-score anomaly detection (|Z| > 2.0), monthly/weekly rollups, semantic duplicate tracking, style + logic baseline evolution, human-readable narrative generation.
56
-
57
- ### Multi-Language Support
58
-
59
- Hallucinated import detection supports 8 languages with stdlib whitelists and dependency manifest parsing: TypeScript, JavaScript, Python, Go, Ruby, C#/.NET, Rust, Java, and Kotlin. Core structural gates support all languages via AST analysis.
60
-
61
- ### Two-Score System
62
-
63
- Every failure carries a **provenance tag** (`ai-drift`, `traditional`, `security`, `governance`) and contributes to two sub-scores:
64
-
65
- - **AI Health Score** (0–100) — AI-specific failures
66
- - **Structural Score** (0–100) — Traditional code quality
67
-
68
- ### Fix Packets (v2)
69
-
70
- Machine-readable JSON diagnostics with severity, provenance, file, line number, and step-by-step remediation instructions that AI agents can consume directly.
71
-
72
- ## Usage
73
-
74
- ```typescript
75
- import { GateRunner } from '@rigour-labs/core';
76
-
77
- const runner = new GateRunner(config);
78
- const report = await runner.run(projectRoot);
79
-
80
- console.log(report.status); // 'PASS' or 'FAIL'
81
- console.log(report.stats.score); // 0-100
82
- console.log(report.failures); // Failure[]
13
+ ```bash
14
+ npm install @rigour-labs/core
83
15
  ```
84
16
 
85
- ### With Deep Analysis
86
-
87
- ```typescript
88
- import { GateRunner } from '@rigour-labs/core';
17
+ ```ts
18
+ import { ConfigSchema, reviewChange } from '@rigour-labs/core';
89
19
 
90
- const runner = new GateRunner(config);
91
- const report = await runner.run(projectRoot, undefined, {
92
- enabled: true,
93
- pro: false, // true for full-power model
94
- provider: 'local', // or 'claude', 'openai', etc.
95
- });
20
+ const config = ConfigSchema.parse({}); // or the parsed rigour.yml
21
+ const result = await reviewChange({ cwd: process.cwd(), config, source: { mode: 'working' } });
22
+ console.log(result.status, result.findings);
96
23
  ```
97
24
 
98
- ## Documentation
99
-
100
- **[Full docs at docs.rigour.run](https://docs.rigour.run)**
101
-
102
- ## License
25
+ What each check finds and whether it blocks: [What Rigour checks](https://github.com/rigour-labs/rigour/blob/main/docs/CHECKS.md). Every setting:
26
+ [Configuration reference](https://github.com/rigour-labs/rigour/blob/main/docs/CONFIG_REFERENCE.md). Node 22 or later.
103
27
 
104
28
  MIT © [Rigour Labs](https://github.com/rigour-labs)
@@ -14,7 +14,6 @@ describe('Environment Alignment Gate', () => {
14
14
  });
15
15
  it('should detect tool version mismatch (Explicit)', async () => {
16
16
  const rawConfig = {
17
- version: 1,
18
17
  gates: {
19
18
  environment: {
20
19
  enabled: true,
@@ -36,7 +35,6 @@ describe('Environment Alignment Gate', () => {
36
35
  });
37
36
  it('should detect missing environment variables', async () => {
38
37
  const rawConfig = {
39
- version: 1,
40
38
  gates: {
41
39
  environment: {
42
40
  enabled: true,
@@ -57,7 +55,6 @@ describe('Environment Alignment Gate', () => {
57
55
  ruff = ">=99.14.0"
58
56
  `);
59
57
  const rawConfig = {
60
- version: 1,
61
58
  gates: {
62
59
  environment: {
63
60
  enabled: true,
@@ -77,7 +74,6 @@ ruff = ">=99.14.0"
77
74
  });
78
75
  it('should prioritize environment gate and run it first', async () => {
79
76
  const rawConfig = {
80
- version: 1,
81
77
  gates: {
82
78
  max_file_lines: 1,
83
79
  environment: {
@@ -26,8 +26,6 @@ export interface AgentTeamSession {
26
26
  export interface AgentTeamConfig {
27
27
  enabled?: boolean;
28
28
  max_concurrent_agents?: number;
29
- cross_agent_pattern_check?: boolean;
30
- handoff_verification?: boolean;
31
29
  task_ownership?: 'strict' | 'collaborative';
32
30
  }
33
31
  /**
@@ -114,8 +114,6 @@ export class AgentTeamGate extends Gate {
114
114
  this.config = {
115
115
  enabled: config.enabled ?? false,
116
116
  max_concurrent_agents: config.max_concurrent_agents ?? 3,
117
- cross_agent_pattern_check: config.cross_agent_pattern_check ?? true,
118
- handoff_verification: config.handoff_verification ?? true,
119
117
  task_ownership: config.task_ownership ?? 'strict',
120
118
  };
121
119
  }
@@ -148,12 +146,6 @@ export class AgentTeamGate extends Gate {
148
146
  }
149
147
  }
150
148
  }
151
- // Check 3: Cross-agent pattern detection (if enabled)
152
- if (this.config.cross_agent_pattern_check && context.record) {
153
- // This would integrate with the Pattern Index to detect conflicting patterns
154
- // For now, we log that we would do this check
155
- Logger.debug('Cross-agent pattern check: would analyze patterns across agent scopes');
156
- }
157
149
  return failures;
158
150
  }
159
151
  }
@@ -44,7 +44,6 @@ export interface CheckpointConfig {
44
44
  interval_minutes?: number;
45
45
  quality_threshold?: number;
46
46
  drift_detection?: boolean;
47
- auto_save_on_failure?: boolean;
48
47
  /** EWMA smoothing factor. Higher = more weight on recent data. Default 0.3 */
49
48
  ewma_alpha?: number;
50
49
  /** Drop from EWMA that triggers drift warning. Default 15 */
@@ -256,7 +256,6 @@ export class CheckpointGate extends Gate {
256
256
  interval_minutes: config.interval_minutes ?? 15,
257
257
  quality_threshold: config.quality_threshold ?? 80,
258
258
  drift_detection: config.drift_detection ?? true,
259
- auto_save_on_failure: config.auto_save_on_failure ?? true,
260
259
  ewma_alpha: config.ewma_alpha ?? 0.3,
261
260
  drift_drop_threshold: config.drift_drop_threshold ?? 15,
262
261
  };
@@ -8,10 +8,6 @@ export interface ExtendedContextConfig {
8
8
  enabled?: boolean;
9
9
  sensitivity?: number;
10
10
  mining_depth?: number;
11
- cross_file_patterns?: boolean;
12
- naming_consistency?: boolean;
13
- import_relationships?: boolean;
14
- max_cross_file_depth?: number;
15
11
  }
16
12
  export declare class ContextGate extends Gate {
17
13
  private config;
@@ -13,10 +13,6 @@ export class ContextGate extends Gate {
13
13
  enabled: config.context?.enabled ?? false,
14
14
  sensitivity: config.context?.sensitivity ?? 0.8,
15
15
  mining_depth: config.context?.mining_depth ?? 100,
16
- cross_file_patterns: true, // Default ON for frontier model support
17
- naming_consistency: true,
18
- import_relationships: true,
19
- max_cross_file_depth: 50,
20
16
  };
21
17
  }
22
18
  get provenance() { return 'ai-drift'; }
@@ -42,22 +38,16 @@ export class ContextGate extends Gate {
42
38
  const codeContent = this.stripComments(content);
43
39
  // 1. Original: Detect Redundant Suffixes (The Golden Example)
44
40
  this.checkEnvDrift(codeContent, file, envAnchors, failures);
45
- // 2. NEW: Cross-file pattern collection
46
- if (this.extendedConfig.cross_file_patterns) {
47
- this.collectNamingPatterns(codeContent, file, namingPatterns);
48
- this.collectImportPatterns(codeContent, file, importPatterns);
49
- }
41
+ // 2. Cross-file pattern collection
42
+ this.collectNamingPatterns(codeContent, file, namingPatterns);
43
+ this.collectImportPatterns(codeContent, file, importPatterns);
50
44
  }
51
45
  catch (e) { }
52
46
  }
53
- // 3. NEW: Analyze naming consistency across files
54
- if (this.extendedConfig.naming_consistency) {
55
- this.analyzeNamingConsistency(namingPatterns, failures);
56
- }
57
- // 4. NEW: Analyze import relationship patterns
58
- if (this.extendedConfig.import_relationships) {
59
- this.analyzeImportPatterns(importPatterns, failures);
60
- }
47
+ // 3. Naming consistency across files
48
+ this.analyzeNamingConsistency(namingPatterns, failures);
49
+ // 4. Import relationship patterns
50
+ this.analyzeImportPatterns(importPatterns, failures);
61
51
  // Cross-file patterns need the whole repo, but a scoped run reports
62
52
  // only findings that cite a file in scope.
63
53
  if (isScoped(context.patterns)) {
@@ -20,7 +20,6 @@ import { type LessonMode } from '../review-learning/team-lessons.js';
20
20
  export interface DeepGateConfig {
21
21
  options: DeepOptions;
22
22
  checks?: Record<string, boolean>;
23
- threads?: number;
24
23
  maxTokens?: number;
25
24
  temperature?: number;
26
25
  timeoutMs?: number;
@@ -16,7 +16,6 @@ export async function runDeepAnalysis(config, context, deepOptions) {
16
16
  const deepGate = new DeepAnalysisGate({
17
17
  options: deepOptions,
18
18
  checks: config.gates.deep?.checks,
19
- threads: config.gates.deep?.threads,
20
19
  maxTokens: config.gates.deep?.max_tokens,
21
20
  temperature: config.gates.deep?.temperature,
22
21
  timeoutMs: config.gates.deep?.timeout_ms,
@@ -97,9 +97,9 @@ describe('FrontendSecretExposureGate', () => {
97
97
  expect(await gate.run({ cwd: testDir })).toHaveLength(0);
98
98
  });
99
99
  it('ignores shell files even when a broad project scan passes them in', async () => {
100
- const shellPath = path.join(testDir, 'scripts/rigour-nmc.sh');
100
+ const shellPath = path.join(testDir, 'scripts/rigour-team.sh');
101
101
  fs.mkdirSync(path.dirname(shellPath), { recursive: true });
102
- fs.writeFileSync(shellPath, 'node -e "process.env.RIGOUR_NMC_DATABASE_URL"');
102
+ fs.writeFileSync(shellPath, 'node -e "process.env.APP_DATABASE_URL"');
103
103
  const gate = new FrontendSecretExposureGate();
104
104
  expect(await gate.run({ cwd: testDir, patterns: ['**/*'] })).toHaveLength(0);
105
105
  });
@@ -27,8 +27,6 @@ export interface HallucinatedImport {
27
27
  }
28
28
  export interface HallucinatedImportsConfig {
29
29
  enabled?: boolean;
30
- check_relative?: boolean;
31
- check_packages?: boolean;
32
30
  ignore_patterns?: string[];
33
31
  }
34
32
  export declare class HallucinatedImportsGate extends Gate {
@@ -33,8 +33,6 @@ export class HallucinatedImportsGate extends Gate {
33
33
  super('hallucinated-imports', 'Hallucinated Import Detection');
34
34
  this.config = {
35
35
  enabled: config.enabled ?? true,
36
- check_relative: config.check_relative ?? true,
37
- check_packages: config.check_packages ?? true,
38
36
  ignore_patterns: config.ignore_patterns ?? [
39
37
  '\\.css$', '\\.scss$', '\\.less$', '\\.svg$', '\\.png$', '\\.jpg$',
40
38
  '\\.json$', '\\.wasm$', '\\.graphql$', '\\.gql$',
@@ -70,6 +68,8 @@ export class HallucinatedImportsGate extends Gate {
70
68
  const allProjectFiles = projectFiles;
71
69
  const packageJson = await loadPackageJson(context.cwd);
72
70
  const rootDeps = new Set([
71
+ // A package importing itself by its own name (type tests, examples) is Node's self-reference.
72
+ ...(typeof packageJson?.name === 'string' ? [packageJson.name] : []),
73
73
  ...Object.keys(packageJson?.dependencies || {}),
74
74
  ...Object.keys(packageJson?.devDependencies || {}),
75
75
  ...Object.keys(packageJson?.peerDependencies || {}),
@@ -180,6 +180,7 @@ export async function resolveJSDepsForFile(file, cwd, rootDeps, depCacheByDir) {
180
180
  const packageJson = await fs.readJson(packageJsonPath);
181
181
  const deps = new Set([
182
182
  ...rootDeps,
183
+ ...(typeof packageJson?.name === 'string' ? [packageJson.name] : []),
183
184
  ...Object.keys(packageJson?.dependencies || {}),
184
185
  ...Object.keys(packageJson?.devDependencies || {}),
185
186
  ...Object.keys(packageJson?.peerDependencies || {}),
@@ -423,6 +423,16 @@ import { cfg } from '~shared/config';
423
423
  expect(details.includes("Path alias '@/utils/missing' does not resolve to a project file")
424
424
  || details.includes("Package '@/utils' not in package.json dependencies")).toBe(true);
425
425
  });
426
+ it('should NOT flag a package importing itself by its own name (type tests, examples), and still flag an undeclared one', async () => {
427
+ FileScanner.findFiles.mockResolvedValue(['test-d/types.ts']);
428
+ mockReadFile.mockResolvedValue(`import ky from 'ky';\nimport left from 'left-pad';\n`);
429
+ mockPathExists.mockImplementation(async (p) => normalizePath(p) === `${testCwdNormalized}/package.json`);
430
+ mockReadJson.mockResolvedValue({ name: 'ky', dependencies: {}, devDependencies: {} });
431
+ const failures = await gate.run(context);
432
+ const details = failures.map(f => f.details).join('\n');
433
+ expect(details).not.toContain("Package 'ky'");
434
+ expect(details).toContain("Package 'left-pad' not in package.json dependencies");
435
+ });
426
436
  it('should resolve configured aliases to hidden generated files', async () => {
427
437
  const jsContent = `import { docs } from '@/.source';`;
428
438
  const tsconfigContent = `{
@@ -1,6 +1,7 @@
1
1
  import { SEVERITY_WEIGHTS } from '../types/index.js';
2
2
  import { runDeepAnalysis } from './deep-runner.js';
3
3
  import { persistAndReinforce } from '../storage/local-memory.js';
4
+ import { splitCommand } from '../utils/command-line.js';
4
5
  import { recordGateRun } from '../services/adaptive-thresholds.js';
5
6
  import { FileGate } from './file.js';
6
7
  import { ContentGate } from './content.js';
@@ -71,7 +72,7 @@ export class GateRunner {
71
72
  if (this.config.gates.checkpoint?.enabled) {
72
73
  this.gates.push(new CheckpointGate(this.config.gates.checkpoint));
73
74
  }
74
- // Semantic Bugs Gate (type-aware, proven findings) — opt-in until field-validated
75
+ // Semantic Bugs Gate (type-aware, proven findings); on by default, `enabled: false` turns it off
75
76
  if (this.config.gates.semantic_bugs?.enabled) {
76
77
  this.gates.push(new SemanticBugsGate(this.config.gates.semantic_bugs));
77
78
  }
@@ -192,9 +193,7 @@ export class GateRunner {
192
193
  }
193
194
  try {
194
195
  Logger.info(`Running command gate: ${key} (${cmd})`);
195
- const parts = cmd.match(/(?:[^\s"']+|"[^"]*"|'[^']*')+/g) || [cmd];
196
- const bin = parts[0];
197
- const args = parts.slice(1).map(a => a.replace(/^["']|["']$/g, ''));
196
+ const { bin, args } = splitCommand(cmd);
198
197
  await execa(bin, args, { cwd });
199
198
  summary[key] = 'PASS';
200
199
  }
@@ -35,10 +35,6 @@ export declare const JS_TAUTOLOGICAL_PATTERNS: RegExp[];
35
35
  * Variable tautology pattern for JavaScript
36
36
  */
37
37
  export declare const JS_VAR_TAUTOLOGY_PATTERN: RegExp;
38
- /**
39
- * Snapshot test patterns
40
- */
41
- export declare const SNAPSHOT_PATTERNS: RegExp[];
42
38
  /**
43
39
  * Python tautological patterns
44
40
  */
@@ -64,13 +64,6 @@ export const JS_TAUTOLOGICAL_PATTERNS = [
64
64
  * Variable tautology pattern for JavaScript
65
65
  */
66
66
  export const JS_VAR_TAUTOLOGY_PATTERN = /expect\s*\(\s*(\w+)\s*\)\s*\.(?:toBe|toEqual|toStrictEqual)\s*\(\s*(\w+)\s*\)/;
67
- /**
68
- * Snapshot test patterns
69
- */
70
- export const SNAPSHOT_PATTERNS = [
71
- /\.toMatchSnapshot\s*\(/,
72
- /\.toMatchInlineSnapshot\s*\(/,
73
- ];
74
67
  /**
75
68
  * Python tautological patterns
76
69
  */
@@ -33,10 +33,8 @@ export interface TestQualityConfig {
33
33
  check_empty_tests?: boolean;
34
34
  check_tautological?: boolean;
35
35
  check_mock_heavy?: boolean;
36
- check_snapshot_abuse?: boolean;
37
36
  check_assertion_free_async?: boolean;
38
37
  max_mocks_per_test?: number;
39
- ignore_patterns?: string[];
40
38
  }
41
39
  export declare class TestQualityGate extends Gate {
42
40
  private config;
@@ -25,7 +25,7 @@ import { FileScanner } from '../utils/scanner.js';
25
25
  import { Logger } from '../utils/logger.js';
26
26
  import { languageAdapters } from './language-adapters/index.js';
27
27
  import { checkGoTestQuality, checkJavaKotlinTestQuality } from './test-quality-lang.js';
28
- import { JS_TEST_START_PATTERN, JS_ASSERTION_PATTERNS, JS_MOCK_PATTERNS, JS_TAUTOLOGICAL_PATTERNS, JS_VAR_TAUTOLOGY_PATTERN, SNAPSHOT_PATTERNS, PYTHON_TEST_FUNC_PATTERN, PYTHON_ASSERTION_PATTERNS, PYTHON_MOCK_PATTERNS, PYTHON_TAUTOLOGICAL_PATTERNS, PYTHON_FIXTURE_PATTERN, PYTHON_CONFTEST_NAME, } from './test-quality-matchers.js';
28
+ import { JS_TEST_START_PATTERN, JS_ASSERTION_PATTERNS, JS_MOCK_PATTERNS, JS_TAUTOLOGICAL_PATTERNS, JS_VAR_TAUTOLOGY_PATTERN, PYTHON_TEST_FUNC_PATTERN, PYTHON_ASSERTION_PATTERNS, PYTHON_MOCK_PATTERNS, PYTHON_TAUTOLOGICAL_PATTERNS, PYTHON_FIXTURE_PATTERN, PYTHON_CONFTEST_NAME, } from './test-quality-matchers.js';
29
29
  import fs from 'fs-extra';
30
30
  import path from 'path';
31
31
  export class TestQualityGate extends Gate {
@@ -37,10 +37,8 @@ export class TestQualityGate extends Gate {
37
37
  check_empty_tests: config.check_empty_tests ?? true,
38
38
  check_tautological: config.check_tautological ?? true,
39
39
  check_mock_heavy: config.check_mock_heavy ?? true,
40
- check_snapshot_abuse: config.check_snapshot_abuse ?? true,
41
40
  check_assertion_free_async: config.check_assertion_free_async ?? true,
42
41
  max_mocks_per_test: config.max_mocks_per_test ?? 5,
43
- ignore_patterns: config.ignore_patterns ?? [],
44
42
  };
45
43
  }
46
44
  get provenance() { return 'ai-drift'; }
@@ -200,13 +198,6 @@ export class TestQualityGate extends Gate {
200
198
  });
201
199
  }
202
200
  }
203
- // Check for snapshot-only tests
204
- if (this.config.check_snapshot_abuse) {
205
- if (SNAPSHOT_PATTERNS.some(p => p.test(line))) {
206
- // This is fine IF there are also semantic assertions
207
- // We'll check when the block ends
208
- }
209
- }
210
201
  // End of test block
211
202
  if (braceDepth === 0) {
212
203
  this.analyzeJSTestBlock(testBlockContent, file, testStartLine, mockCount, hasAssertion, hasAwait, isAsync, issues);
@@ -40,7 +40,7 @@ async function loadConfig(cwd) {
40
40
  const raw = yaml.parse(await fs.readFile(configPath, 'utf-8'));
41
41
  return ConfigSchema.parse(raw);
42
42
  }
43
- return ConfigSchema.parse({ version: 1 });
43
+ return ConfigSchema.parse({});
44
44
  }
45
45
  /**
46
46
  * Resolve a file path to absolute, read its content, and return metadata.
@@ -6,8 +6,7 @@ export { runHookChecker } from './checker.js';
6
6
  export type { CheckerOptions } from './checker.js';
7
7
  export { generateHookFiles, pushGateShell } from './templates.js';
8
8
  export type { GeneratedHookFile } from './templates.js';
9
- export type { HookTool, HookConfig, HookCheckerResult } from './types.js';
10
- export { DEFAULT_HOOK_CONFIG, FAST_GATE_IDS } from './types.js';
9
+ export type { HookTool, HookCheckerResult } from './types.js';
11
10
  export { scanInputForCredentials, formatDLPAlert, createDLPAuditEntry } from './input-validator.js';
12
11
  export type { CredentialDetection, InputValidationResult, InputValidationConfig } from './input-validator.js';
13
12
  export { recordDLPFeedback, allowLastDLPBlock, writeDLPBlockManifest, getLearnedAllowCount, loadDLPFeedbackStore, loadDLPFeedbackStoreSync, fingerprintDetection, } from './dlp-feedback.js';
@@ -4,7 +4,6 @@
4
4
  */
5
5
  export { runHookChecker } from './checker.js';
6
6
  export { generateHookFiles, pushGateShell } from './templates.js';
7
- export { DEFAULT_HOOK_CONFIG, FAST_GATE_IDS } from './types.js';
8
7
  // DLP (Data Loss Prevention) — v4.2.0
9
8
  export { scanInputForCredentials, formatDLPAlert, createDLPAuditEntry } from './input-validator.js';
10
9
  export { recordDLPFeedback, allowLastDLPBlock, writeDLPBlockManifest, getLearnedAllowCount, loadDLPFeedbackStore, loadDLPFeedbackStoreSync, fingerprintDetection, } from './dlp-feedback.js';
@@ -6,20 +6,6 @@
6
6
  *
7
7
  */
8
8
  export type HookTool = 'claude' | 'cursor' | 'cline' | 'windsurf';
9
- export interface HookConfig {
10
- /** Which tools to generate hooks for */
11
- tools: HookTool[];
12
- /** Gates to run in the hook checker (fast subset) */
13
- fast_gates: string[];
14
- /** Max execution time in ms before the checker aborts */
15
- timeout_ms: number;
16
- /** Whether to block the tool on failure (exit 2) or just warn */
17
- block_on_failure: boolean;
18
- }
19
- /** The fast gates that can run per-file in <200ms */
20
- export declare const FAST_GATE_IDS: readonly ["file-guard", "governance", "hallucinated-imports", "promise-safety", "security-patterns", "file-size"];
21
- export declare const DEFAULT_HOOK_CONFIG: HookConfig;
22
- export type FastGateId = typeof FAST_GATE_IDS[number];
23
9
  export interface HookCheckerResult {
24
10
  status: 'pass' | 'fail' | 'error';
25
11
  failures: Array<{
@@ -5,18 +5,4 @@
5
5
  * has its own hook format. These types unify the config generation.
6
6
  *
7
7
  */
8
- /** The fast gates that can run per-file in <200ms */
9
- export const FAST_GATE_IDS = [
10
- 'file-guard',
11
- 'governance',
12
- 'hallucinated-imports',
13
- 'promise-safety',
14
- 'security-patterns',
15
- 'file-size',
16
- ];
17
- export const DEFAULT_HOOK_CONFIG = {
18
- tools: ['claude'],
19
- fast_gates: [...FAST_GATE_IDS],
20
- timeout_ms: 5000,
21
- block_on_failure: false,
22
- };
8
+ export {};
package/dist/index.d.ts CHANGED
@@ -12,20 +12,25 @@ export * from './utils/logger.js';
12
12
  export { normalizeScopePatterns, isScoped } from './utils/scope.js';
13
13
  export { deepAnalysisError } from './utils/deep-status.js';
14
14
  export { rigourUserDir, repoStateDir } from './utils/user-state.js';
15
+ export { locateTransformers, semanticRuntimeDir, semanticRuntimeInstalled, TRANSFORMERS_SPEC } from './pattern-index/semantic-runtime.js';
15
16
  export { reviewChange, toReviewFinding, type ReviewInput, type ReviewResult, type ReviewFinding } from './review/review.js';
16
17
  export { splitByChangedLines, type ChangedLineSplit } from './review/changed-lines.js';
17
18
  export { isControlFile, mergeBaseOf, readStateFile } from './review/trusted-state.js';
18
19
  export { dismissFinding, dismissedKeys, findingKey, isProven, mustFix, quietSplit, DISMISSED_FILE } from './review/quiet.js';
19
20
  export { loadLedger, ledgerProblems, runBacktest, backtestPassed, formatBacktest, LEDGER_PATH, type Ledger, type RoundResult } from './review/backtest.js';
20
21
  export { scaffoldLedger } from './review/backtest-init.js';
22
+ export { fixScope, type FixScope } from './review/fix-scope.js';
21
23
  export { isGeneratedFile } from './review/generated-files.js';
22
- export { countUsage, durationBucket, flushDailyUsage, isTelemetryEnabled, readTelemetryState, setTelemetryEnabled, shouldAskTelemetry, telemetryToken, trackUsage } from './telemetry/telemetry.js';
24
+ export { costBucket, countUsage, doNotTrack, durationBucket, flushDailyUsage, isTelemetryEnabled, readTelemetryState, setTelemetryEnabled, shouldAskTelemetry, telemetryToken, trackUsage } from './telemetry/telemetry.js';
23
25
  export { buildReviewTask, type ReviewTask, type ReviewTaskItem } from './review/review-task.js';
24
26
  export { buildQualityReceipt, receiptReport, type QualityReceipt, type ReceiptGap, type ReceiptOptions } from './review/receipt.js';
25
27
  export { runToolchain, type ToolResult, type ToolStatus } from './review/toolchain.js';
26
28
  export { branchFailures, mergeConflicts, staleReferences } from './review/branch-checks.js';
27
29
  export { runReviewer, reviewerBlocks, itemLine, type ReviewerOptions, type ReviewerResult, type ReviewerOutcome, type OpenItem } from './review/reviewer.js';
28
30
  export { startBackgroundReview, backgroundReview, reviewStatus, type ReviewStatus } from './review/reviewer/background.js';
31
+ export { dismissReviewerFinding, REVIEW_DISMISSALS, reviewerInputs } from './review/reviewer/context.js';
32
+ export { resolveReviewer, saveUserReviewer, type ResolvedReviewer, type RunChoice, type UserReviewerPatch } from './review/reviewer/settings.js';
33
+ export { reviewerAvailability } from './review/reviewer/adapters.js';
29
34
  export { branchBase, type BranchBase } from './gates/logic-drift-git-base.js';
30
35
  export { acknowledgeReview, type ReviewAck, type AckResult } from './review/review-ack.js';
31
36
  export { exportReviewed, readLedger, reviewedKeys, isReviewed, recordReview, REVIEWED_FILE, type LedgerEntry, type ReviewedKey, type ReviewVerdict } from './review/ledger.js';
package/dist/index.js CHANGED
@@ -12,20 +12,25 @@ export * from './utils/logger.js';
12
12
  export { normalizeScopePatterns, isScoped } from './utils/scope.js';
13
13
  export { deepAnalysisError } from './utils/deep-status.js';
14
14
  export { rigourUserDir, repoStateDir } from './utils/user-state.js';
15
+ export { locateTransformers, semanticRuntimeDir, semanticRuntimeInstalled, TRANSFORMERS_SPEC } from './pattern-index/semantic-runtime.js';
15
16
  export { reviewChange, toReviewFinding } from './review/review.js';
16
17
  export { splitByChangedLines } from './review/changed-lines.js';
17
18
  export { isControlFile, mergeBaseOf, readStateFile } from './review/trusted-state.js';
18
19
  export { dismissFinding, dismissedKeys, findingKey, isProven, mustFix, quietSplit, DISMISSED_FILE } from './review/quiet.js';
19
20
  export { loadLedger, ledgerProblems, runBacktest, backtestPassed, formatBacktest, LEDGER_PATH } from './review/backtest.js';
20
21
  export { scaffoldLedger } from './review/backtest-init.js';
22
+ export { fixScope } from './review/fix-scope.js';
21
23
  export { isGeneratedFile } from './review/generated-files.js';
22
- export { countUsage, durationBucket, flushDailyUsage, isTelemetryEnabled, readTelemetryState, setTelemetryEnabled, shouldAskTelemetry, telemetryToken, trackUsage } from './telemetry/telemetry.js';
24
+ export { costBucket, countUsage, doNotTrack, durationBucket, flushDailyUsage, isTelemetryEnabled, readTelemetryState, setTelemetryEnabled, shouldAskTelemetry, telemetryToken, trackUsage } from './telemetry/telemetry.js';
23
25
  export { buildReviewTask } from './review/review-task.js';
24
26
  export { buildQualityReceipt, receiptReport } from './review/receipt.js';
25
27
  export { runToolchain } from './review/toolchain.js';
26
28
  export { branchFailures, mergeConflicts, staleReferences } from './review/branch-checks.js';
27
29
  export { runReviewer, reviewerBlocks, itemLine } from './review/reviewer.js';
28
30
  export { startBackgroundReview, backgroundReview, reviewStatus } from './review/reviewer/background.js';
31
+ export { dismissReviewerFinding, REVIEW_DISMISSALS, reviewerInputs } from './review/reviewer/context.js';
32
+ export { resolveReviewer, saveUserReviewer } from './review/reviewer/settings.js';
33
+ export { reviewerAvailability } from './review/reviewer/adapters.js';
29
34
  export { branchBase } from './gates/logic-drift-git-base.js';
30
35
  export { acknowledgeReview } from './review/review-ack.js';
31
36
  export { exportReviewed, readLedger, reviewedKeys, isReviewed, recordReview, REVIEWED_FILE } from './review/ledger.js';
@@ -41,5 +41,7 @@ export declare class CloudProvider implements InferenceProvider {
41
41
  /** OpenRouter forwards Anthropic's cache_control to Claude models. */
42
42
  private cachesPrompts;
43
43
  private isOpenRouter;
44
+ /** The API base URL: the one given, else the provider's own. */
45
+ private endpoint;
44
46
  dispose(): void;
45
47
  }