agentic-qe 3.8.11 → 3.8.13

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 (98) hide show
  1. package/.claude/skills/qe-code-intelligence/SKILL.md +29 -20
  2. package/.claude/skills/qe-code-intelligence/evals/qe-code-intelligence.yaml +3 -3
  3. package/.claude/skills/qe-quality-assessment/SKILL.md +1 -1
  4. package/.claude/skills/qe-test-generation/SKILL.md +1 -1
  5. package/.claude/skills/skills-manifest.json +1 -1
  6. package/CHANGELOG.md +45 -0
  7. package/README.md +9 -0
  8. package/assets/skills/qe-code-intelligence/SKILL.md +29 -20
  9. package/assets/skills/qe-code-intelligence/evals/qe-code-intelligence.yaml +3 -3
  10. package/assets/skills/qe-quality-assessment/SKILL.md +1 -1
  11. package/assets/skills/qe-test-generation/SKILL.md +1 -1
  12. package/dist/cli/bundle.js +1162 -1046
  13. package/dist/cli/commands/code.js +149 -11
  14. package/dist/cli/commands/init.js +3 -2
  15. package/dist/cli/commands/ruvector-commands.js +17 -0
  16. package/dist/cli/handlers/init-handler.d.ts +1 -0
  17. package/dist/cli/handlers/init-handler.js +15 -10
  18. package/dist/cli/utils/file-discovery.d.ts +1 -0
  19. package/dist/cli/utils/file-discovery.js +1 -1
  20. package/dist/domains/code-intelligence/coordinator-gnn.d.ts +21 -0
  21. package/dist/domains/code-intelligence/coordinator-gnn.js +102 -0
  22. package/dist/domains/contract-testing/coordinator.js +13 -0
  23. package/dist/domains/coverage-analysis/coordinator.js +5 -0
  24. package/dist/domains/defect-intelligence/coordinator.d.ts +1 -0
  25. package/dist/domains/defect-intelligence/coordinator.js +43 -0
  26. package/dist/domains/quality-assessment/coordinator.js +26 -0
  27. package/dist/domains/test-generation/coordinator.js +14 -0
  28. package/dist/init/orchestrator.js +1 -0
  29. package/dist/init/phases/08-mcp.js +4 -4
  30. package/dist/init/phases/phase-interface.d.ts +3 -1
  31. package/dist/integrations/agentic-flow/reasoning-bank/experience-replay.d.ts +11 -0
  32. package/dist/integrations/agentic-flow/reasoning-bank/experience-replay.js +44 -1
  33. package/dist/integrations/rl-suite/algorithms/eprop.d.ts +79 -0
  34. package/dist/integrations/rl-suite/algorithms/eprop.js +284 -0
  35. package/dist/integrations/rl-suite/algorithms/index.d.ts +2 -1
  36. package/dist/integrations/rl-suite/algorithms/index.js +2 -1
  37. package/dist/integrations/rl-suite/index.d.ts +2 -2
  38. package/dist/integrations/rl-suite/index.js +2 -2
  39. package/dist/integrations/rl-suite/interfaces.d.ts +3 -3
  40. package/dist/integrations/rl-suite/interfaces.js +1 -1
  41. package/dist/integrations/rl-suite/orchestrator.d.ts +2 -2
  42. package/dist/integrations/rl-suite/orchestrator.js +3 -2
  43. package/dist/integrations/rl-suite/reward-signals.d.ts +1 -1
  44. package/dist/integrations/rl-suite/reward-signals.js +1 -1
  45. package/dist/integrations/ruvector/coherence-gate-cohomology.d.ts +41 -0
  46. package/dist/integrations/ruvector/coherence-gate-cohomology.js +47 -0
  47. package/dist/integrations/ruvector/coherence-gate-core.d.ts +200 -0
  48. package/dist/integrations/ruvector/coherence-gate-core.js +294 -0
  49. package/dist/integrations/ruvector/coherence-gate-energy.d.ts +136 -0
  50. package/dist/integrations/ruvector/coherence-gate-energy.js +373 -0
  51. package/dist/integrations/ruvector/coherence-gate-vector.d.ts +38 -0
  52. package/dist/integrations/ruvector/coherence-gate-vector.js +76 -0
  53. package/dist/integrations/ruvector/coherence-gate.d.ts +10 -311
  54. package/dist/integrations/ruvector/coherence-gate.js +10 -652
  55. package/dist/integrations/ruvector/cold-tier-trainer.d.ts +103 -0
  56. package/dist/integrations/ruvector/cold-tier-trainer.js +377 -0
  57. package/dist/integrations/ruvector/cusum-detector.d.ts +70 -0
  58. package/dist/integrations/ruvector/cusum-detector.js +142 -0
  59. package/dist/integrations/ruvector/delta-tracker.d.ts +122 -0
  60. package/dist/integrations/ruvector/delta-tracker.js +311 -0
  61. package/dist/integrations/ruvector/domain-transfer.d.ts +79 -1
  62. package/dist/integrations/ruvector/domain-transfer.js +158 -2
  63. package/dist/integrations/ruvector/eprop-learner.d.ts +135 -0
  64. package/dist/integrations/ruvector/eprop-learner.js +351 -0
  65. package/dist/integrations/ruvector/feature-flags.d.ts +177 -0
  66. package/dist/integrations/ruvector/feature-flags.js +145 -0
  67. package/dist/integrations/ruvector/graphmae-encoder.d.ts +88 -0
  68. package/dist/integrations/ruvector/graphmae-encoder.js +360 -0
  69. package/dist/integrations/ruvector/hdc-fingerprint.d.ts +127 -0
  70. package/dist/integrations/ruvector/hdc-fingerprint.js +222 -0
  71. package/dist/integrations/ruvector/hopfield-memory.d.ts +97 -0
  72. package/dist/integrations/ruvector/hopfield-memory.js +238 -0
  73. package/dist/integrations/ruvector/index.d.ts +13 -2
  74. package/dist/integrations/ruvector/index.js +46 -2
  75. package/dist/integrations/ruvector/mincut-wrapper.d.ts +7 -0
  76. package/dist/integrations/ruvector/mincut-wrapper.js +54 -2
  77. package/dist/integrations/ruvector/reservoir-replay.d.ts +172 -0
  78. package/dist/integrations/ruvector/reservoir-replay.js +335 -0
  79. package/dist/integrations/ruvector/solver-adapter.d.ts +93 -0
  80. package/dist/integrations/ruvector/solver-adapter.js +299 -0
  81. package/dist/integrations/ruvector/sona-persistence.d.ts +33 -0
  82. package/dist/integrations/ruvector/sona-persistence.js +47 -0
  83. package/dist/integrations/ruvector/spectral-sparsifier.d.ts +154 -0
  84. package/dist/integrations/ruvector/spectral-sparsifier.js +389 -0
  85. package/dist/integrations/ruvector/temporal-causality.d.ts +63 -0
  86. package/dist/integrations/ruvector/temporal-causality.js +317 -0
  87. package/dist/learning/pattern-promotion.d.ts +63 -0
  88. package/dist/learning/pattern-promotion.js +235 -1
  89. package/dist/learning/pattern-store.d.ts +2 -0
  90. package/dist/learning/pattern-store.js +187 -1
  91. package/dist/learning/sqlite-persistence.d.ts +2 -0
  92. package/dist/learning/sqlite-persistence.js +4 -0
  93. package/dist/mcp/bundle.js +506 -427
  94. package/dist/shared/utils/index.d.ts +1 -0
  95. package/dist/shared/utils/index.js +1 -0
  96. package/dist/shared/utils/xorshift128.d.ts +24 -0
  97. package/dist/shared/utils/xorshift128.js +50 -0
  98. package/package.json +1 -1
@@ -5,17 +5,29 @@
5
5
  */
6
6
  import { Command } from 'commander';
7
7
  import chalk from 'chalk';
8
- import { walkSourceFiles } from '../utils/file-discovery.js';
8
+ import { walkSourceFiles, SOURCE_EXTENSIONS } from '../utils/file-discovery.js';
9
9
  import { writeOutput, toJSON } from '../utils/ci-output.js';
10
10
  export function createCodeCommand(context, cleanupAndExit, ensureInitialized) {
11
11
  const codeCmd = new Command('code')
12
12
  .description('Code intelligence analysis')
13
- .argument('<action>', 'Action (index|search|impact|deps)')
13
+ .argument('<action>', 'Action (index|search|impact|deps|complexity)')
14
14
  .argument('[target]', 'Target path or query')
15
15
  .option('--depth <depth>', 'Analysis depth', '3')
16
16
  .option('--include-tests', 'Include test files')
17
+ .option('--incremental', 'Incremental indexing (index action only)')
18
+ .option('--git-since <ref>', 'Index changes since git ref (index action only)')
17
19
  .option('-F, --format <format>', 'Output format (text|json)', 'text')
18
20
  .option('-o, --output <path>', 'Write output to file')
21
+ .addHelpText('after', `
22
+ Examples:
23
+ aqe code index src/ Index source files into knowledge graph
24
+ aqe code index src/ --incremental Incremental index (only changed files)
25
+ aqe code index . --git-since HEAD~5 Index files changed in last 5 commits
26
+ aqe code search "authentication" Semantic code search
27
+ aqe code impact src/auth/ Analyze change impact
28
+ aqe code deps src/ Map dependencies
29
+ aqe code complexity src/ Analyze code complexity metrics
30
+ `)
19
31
  .action(async (action, target, options) => {
20
32
  if (!await ensureInitialized())
21
33
  return;
@@ -27,17 +39,47 @@ export function createCodeCommand(context, cleanupAndExit, ensureInitialized) {
27
39
  }
28
40
  const path = await import('path');
29
41
  const format = (options.format || 'text');
42
+ const parsedDepth = parseInt(options.depth);
43
+ if (isNaN(parsedDepth) || parsedDepth < 1) {
44
+ console.log(chalk.red(`Invalid --depth value: "${options.depth}" (must be a positive integer)`));
45
+ return;
46
+ }
30
47
  if (action === 'index') {
31
- console.log(chalk.blue(`\n Indexing codebase at ${target || '.'}...\n`));
48
+ const incremental = options.incremental || false;
49
+ const gitSince = options.gitSince;
50
+ const label = incremental ? 'Incrementally indexing' : 'Indexing';
51
+ console.log(chalk.blue(`\n ${label} codebase at ${target || '.'}${gitSince ? ` (since ${gitSince})` : ''}...\n`));
32
52
  const targetPath = path.resolve(target || '.');
33
- // Fix #280: Use shared file discovery supporting all languages
34
- const paths = walkSourceFiles(targetPath, {
35
- includeTests: options.includeTests || false,
36
- });
53
+ let paths;
54
+ if (gitSince) {
55
+ // Use git diff to find changed files since the ref
56
+ // SEC: Use execFileSync with array args to prevent shell injection (CWE-78)
57
+ const { execFileSync } = await import('child_process');
58
+ try {
59
+ const diffOutput = execFileSync('git', ['diff', '--name-only', '--diff-filter=ACMR', gitSince, '--', targetPath], { encoding: 'utf-8', cwd: process.cwd() }).trim();
60
+ paths = diffOutput
61
+ ? diffOutput.split('\n')
62
+ .filter(f => SOURCE_EXTENSIONS.has(path.extname(f)))
63
+ .map(f => path.resolve(f))
64
+ : [];
65
+ }
66
+ catch {
67
+ console.log(chalk.yellow(` Warning: git diff failed for ref "${gitSince}", falling back to full scan`));
68
+ paths = walkSourceFiles(targetPath, {
69
+ includeTests: options.includeTests || false,
70
+ });
71
+ }
72
+ }
73
+ else {
74
+ // Fix #280: Use shared file discovery supporting all languages
75
+ paths = walkSourceFiles(targetPath, {
76
+ includeTests: options.includeTests || false,
77
+ });
78
+ }
37
79
  console.log(chalk.gray(` Found ${paths.length} files to index...\n`));
38
80
  const result = await codeAPI.index({
39
81
  paths,
40
- incremental: false,
82
+ incremental,
41
83
  includeTests: options.includeTests || false,
42
84
  });
43
85
  if (result.success && result.value) {
@@ -101,7 +143,7 @@ export function createCodeCommand(context, cleanupAndExit, ensureInitialized) {
101
143
  const changedFiles = walkSourceFiles(targetPath, { maxDepth: 2 }).slice(0, 10);
102
144
  const result = await codeAPI.analyzeImpact({
103
145
  changedFiles,
104
- depth: parseInt(options.depth),
146
+ depth: parsedDepth,
105
147
  includeTests: options.includeTests || false,
106
148
  });
107
149
  if (result.success && result.value) {
@@ -151,7 +193,7 @@ export function createCodeCommand(context, cleanupAndExit, ensureInitialized) {
151
193
  const result = await codeAPI.mapDependencies({
152
194
  files,
153
195
  direction: 'both',
154
- depth: parseInt(options.depth),
196
+ depth: parsedDepth,
155
197
  });
156
198
  if (result.success && result.value) {
157
199
  const deps = result.value;
@@ -184,9 +226,105 @@ export function createCodeCommand(context, cleanupAndExit, ensureInitialized) {
184
226
  console.log(chalk.red(`Failed: ${result.error?.message || 'Unknown error'}`));
185
227
  }
186
228
  }
229
+ else if (action === 'complexity') {
230
+ console.log(chalk.blue(`\n Analyzing complexity for ${target || '.'}...\n`));
231
+ const targetPath = path.resolve(target || '.');
232
+ const files = walkSourceFiles(targetPath, {
233
+ includeTests: options.includeTests || false,
234
+ maxDepth: 3,
235
+ }).slice(0, 50);
236
+ if (files.length === 0) {
237
+ console.log(chalk.yellow(' No source files found'));
238
+ return await cleanupAndExit(0);
239
+ }
240
+ const fs = await import('fs');
241
+ const analyzer = typeof codeAPI.getSemanticAnalyzer === 'function'
242
+ ? codeAPI.getSemanticAnalyzer()
243
+ : null;
244
+ if (!analyzer) {
245
+ console.log(chalk.red('Semantic analyzer not available — ensure fleet is initialized'));
246
+ return await cleanupAndExit(1);
247
+ }
248
+ // Analyze files in batches of 8 for concurrency
249
+ const BATCH_SIZE = 8;
250
+ const results = [];
251
+ for (let i = 0; i < files.length; i += BATCH_SIZE) {
252
+ const batch = files.slice(i, i + BATCH_SIZE);
253
+ const batchResults = await Promise.all(batch.map(async (file) => {
254
+ try {
255
+ const content = fs.readFileSync(file, 'utf-8');
256
+ const analysisResult = await analyzer.analyze(content);
257
+ if (analysisResult.success && analysisResult.value) {
258
+ const a = analysisResult.value;
259
+ return {
260
+ file,
261
+ cyclomatic: a.complexity.cyclomatic,
262
+ cognitive: a.complexity.cognitive,
263
+ halstead: a.complexity.halstead,
264
+ suggestions: a.suggestions,
265
+ };
266
+ }
267
+ }
268
+ catch {
269
+ // Skip files that can't be read/analyzed
270
+ }
271
+ return null;
272
+ }));
273
+ for (const r of batchResults) {
274
+ if (r)
275
+ results.push(r);
276
+ }
277
+ }
278
+ // Sort by cyclomatic complexity descending
279
+ results.sort((a, b) => b.cyclomatic - a.cyclomatic);
280
+ // Compute aggregates
281
+ const totalCyclomatic = results.reduce((s, r) => s + r.cyclomatic, 0);
282
+ const avgCyclomatic = results.length > 0 ? totalCyclomatic / results.length : 0;
283
+ const maxCyclomatic = results.length > 0 ? results[0].cyclomatic : 0;
284
+ const totalBugs = results.reduce((s, r) => s + r.halstead.bugs, 0);
285
+ const highComplexity = results.filter(r => r.cyclomatic > 10).length;
286
+ if (format === 'json') {
287
+ writeOutput(toJSON({
288
+ filesAnalyzed: results.length,
289
+ aggregate: {
290
+ totalCyclomatic,
291
+ avgCyclomatic: Math.round(avgCyclomatic * 100) / 100,
292
+ maxCyclomatic,
293
+ estimatedBugs: Math.round(totalBugs * 1000) / 1000,
294
+ highComplexityFiles: highComplexity,
295
+ },
296
+ files: results,
297
+ }), options.output);
298
+ }
299
+ else {
300
+ console.log(chalk.cyan(' Aggregate Metrics:'));
301
+ console.log(` Files analyzed: ${chalk.white(results.length)}`);
302
+ console.log(` Avg cyclomatic: ${chalk.yellow(avgCyclomatic.toFixed(2))}`);
303
+ console.log(` Max cyclomatic: ${maxCyclomatic > 20 ? chalk.red(maxCyclomatic) : maxCyclomatic > 10 ? chalk.yellow(maxCyclomatic) : chalk.green(maxCyclomatic)}`);
304
+ console.log(` Estimated bugs: ${chalk.yellow(totalBugs.toFixed(3))}`);
305
+ console.log(` High complexity (>10): ${highComplexity > 0 ? chalk.red(highComplexity) : chalk.green(highComplexity)}`);
306
+ // Show top hotspots
307
+ const hotspots = results.filter(r => r.cyclomatic > 5).slice(0, 10);
308
+ if (hotspots.length > 0) {
309
+ console.log(chalk.cyan('\n Complexity Hotspots:'));
310
+ for (const h of hotspots) {
311
+ const filePath = h.file.replace(process.cwd() + '/', '');
312
+ const cyclColor = h.cyclomatic > 20 ? chalk.red : h.cyclomatic > 10 ? chalk.yellow : chalk.white;
313
+ console.log(` ${chalk.white(filePath)}`);
314
+ console.log(chalk.gray(` Cyclomatic: ${cyclColor(h.cyclomatic)} Cognitive: ${h.cognitive} Halstead bugs: ${h.halstead.bugs}`));
315
+ if (h.suggestions.length > 0) {
316
+ console.log(chalk.gray(` Suggestion: ${h.suggestions[0]}`));
317
+ }
318
+ }
319
+ }
320
+ if (highComplexity === 0) {
321
+ console.log(chalk.green('\n All files within acceptable complexity thresholds'));
322
+ }
323
+ }
324
+ }
187
325
  else {
188
326
  console.log(chalk.red(`\nUnknown action: ${action}`));
189
- console.log(chalk.gray(' Available: index, search, impact, deps\n'));
327
+ console.log(chalk.gray(' Available: index, search, impact, deps, complexity\n'));
190
328
  await cleanupAndExit(1);
191
329
  }
192
330
  console.log('');
@@ -41,7 +41,8 @@ export function createInitCommand() {
41
41
  .option('--with-codex', 'Include OpenAI Codex CLI MCP config and AGENTS.md')
42
42
  .option('--with-windsurf', 'Include Windsurf MCP config and rules')
43
43
  .option('--with-continuedev', 'Include Continue.dev MCP config and rules')
44
- .option('--with-mcp', 'Include MCP server config in .mcp.json (opt-in CLI works without MCP)')
44
+ .option('--no-mcp', 'Skip MCP server config (MCP is enabled by default)')
45
+ .option('--with-mcp', 'Enable MCP server config (default — kept for backward compatibility)')
45
46
  .option('--with-all-platforms', 'Include all coding agent platform configurations')
46
47
  .option('--with-claude-flow', 'Force Claude Flow integration setup')
47
48
  .option('--skip-claude-flow', 'Skip Claude Flow integration')
@@ -114,7 +115,7 @@ async function runInit(options) {
114
115
  withCodex: options.withCodex,
115
116
  withWindsurf: options.withWindsurf,
116
117
  withContinueDev: options.withContinuedev,
117
- withMcp: options.withMcp,
118
+ noMcp: options.noMcp && !options.withMcp,
118
119
  noGovernance: options.noGovernance,
119
120
  });
120
121
  // Run initialization
@@ -50,6 +50,23 @@ const FLAG_DESCRIPTIONS = {
50
50
  useDAGAttention: 'DAG attention for test scheduling (Task 4.2)',
51
51
  useCoherenceActionGate: 'Coherence-gated agent actions (ADR-083, Task 3.2)',
52
52
  useReasoningQEC: 'Reasoning QEC error correction (Task 4.5)',
53
+ // Phase 5 (ADR-087)
54
+ useHDCFingerprinting: 'HDC pattern fingerprinting (R1, ADR-087)',
55
+ useCusumDriftDetection: 'CUSUM drift detection (R2, ADR-087)',
56
+ useDeltaEventSourcing: 'Delta event sourcing (R3, ADR-087)',
57
+ useEwcPlusPlusRegularization: 'EWC++ regularization (ADR-087)',
58
+ // Phase 5 Milestone 2 (ADR-087)
59
+ useGraphMAEEmbeddings: 'GraphMAE self-supervised embeddings (R4, ADR-087)',
60
+ useHopfieldMemory: 'Modern Hopfield memory (R5, ADR-087)',
61
+ useColdTierGNN: 'Cold-tier GNN training (R6, ADR-087)',
62
+ // Phase 5 Milestone 3 (ADR-087)
63
+ useMetaLearningEnhancements: 'Meta-learning enhancements (R7, ADR-087)',
64
+ useSublinearSolver: 'Sublinear PageRank solver (R8, ADR-087)',
65
+ useSpectralSparsification: 'Spectral graph sparsification (R9, ADR-087)',
66
+ useReservoirReplay: 'Reservoir replay with coherence gating (R10, ADR-087)',
67
+ // Phase 5 Milestone 4 (ADR-087)
68
+ useEpropOnlineLearning: 'E-prop online learning, RL algorithm #10 (R11, ADR-087)',
69
+ useGrangerCausality: 'Granger causality for test failure prediction (R12, ADR-087)',
53
70
  };
54
71
  const PROFILES = {
55
72
  performance: {
@@ -40,6 +40,7 @@ interface InitOptions {
40
40
  withWindsurf?: boolean;
41
41
  withContinuedev?: boolean;
42
42
  withAllPlatforms?: boolean;
43
+ noMcp?: boolean;
43
44
  withMcp?: boolean;
44
45
  withClaudeFlow?: boolean;
45
46
  skipClaudeFlow?: boolean;
@@ -49,7 +49,8 @@ export class InitHandler {
49
49
  .option('--with-codex', 'Include OpenAI Codex CLI MCP config and AGENTS.md')
50
50
  .option('--with-windsurf', 'Include Windsurf MCP config and rules')
51
51
  .option('--with-continuedev', 'Include Continue.dev MCP config and rules')
52
- .option('--with-mcp', 'Include MCP server config in .mcp.json (opt-in CLI works without MCP)')
52
+ .option('--no-mcp', 'Skip MCP server config (MCP is enabled by default)')
53
+ .option('--with-mcp', 'Enable MCP server config (default — kept for backward compatibility)')
53
54
  .option('--with-all-platforms', 'Include all coding agent platform configurations')
54
55
  .option('--auto-migrate', 'Automatically migrate from v2 if detected')
55
56
  .option('--with-claude-flow', 'Force Claude Flow integration setup')
@@ -115,7 +116,7 @@ export class InitHandler {
115
116
  withCodex: options.withCodex,
116
117
  withWindsurf: options.withWindsurf,
117
118
  withContinueDev: options.withContinuedev,
118
- withMcp: options.withMcp,
119
+ noMcp: options.noMcp && !options.withMcp,
119
120
  noGovernance: options.noGovernance,
120
121
  });
121
122
  console.log(chalk.white(' Analyzing project...\n'));
@@ -175,10 +176,9 @@ export class InitHandler {
175
176
  console.log(chalk.gray(' 1. Run tests: aqe test <path>'));
176
177
  console.log(chalk.gray(' 2. Check coverage: aqe coverage <path>'));
177
178
  console.log(chalk.gray(' 3. Check status: aqe status'));
178
- if (!result.summary.mcpConfigured) {
179
- console.log(chalk.gray('\n Optional — enable MCP server for richer agent integration:'));
180
- console.log(chalk.gray(' aqe init --with-mcp'));
181
- console.log(chalk.gray(' # or manually: claude mcp add aqe -- aqe-mcp\n'));
179
+ if (result.summary.mcpConfigured) {
180
+ console.log(chalk.gray('\n MCP server configured in .mcp.json'));
181
+ console.log(chalk.gray(' Use --no-mcp to skip MCP setup if using CLI only\n'));
182
182
  }
183
183
  }
184
184
  else {
@@ -230,10 +230,9 @@ export class InitHandler {
230
230
  console.log(chalk.gray(' 1. Run tests: aqe test <path>'));
231
231
  console.log(chalk.gray(' 2. Check coverage: aqe coverage <path>'));
232
232
  console.log(chalk.gray(' 3. Check status: aqe status'));
233
- if (!result.summary.mcpConfigured) {
234
- console.log(chalk.gray('\n Optional — enable MCP server for richer agent integration:'));
235
- console.log(chalk.gray(' aqe init --with-mcp'));
236
- console.log(chalk.gray(' # or manually: claude mcp add aqe -- aqe-mcp\n'));
233
+ if (result.summary.mcpConfigured) {
234
+ console.log(chalk.gray('\n MCP server configured in .mcp.json'));
235
+ console.log(chalk.gray(' Use --no-mcp to skip MCP setup if using CLI only\n'));
237
236
  }
238
237
  }
239
238
  else {
@@ -338,9 +337,15 @@ Options:
338
337
  --auto-migrate Automatically migrate from v2 if detected
339
338
  --with-claude-flow Force Claude Flow integration setup
340
339
  --skip-claude-flow Skip Claude Flow integration
340
+ --no-mcp Skip MCP server config (MCP is enabled by default)
341
341
  --no-governance Skip governance configuration (ADR-058)
342
342
  --modular Use new modular init system
343
343
 
344
+ MCP Server:
345
+ MCP server configuration is ENABLED BY DEFAULT. It writes .mcp.json
346
+ at the project root so Claude Code auto-discovers the AQE MCP server.
347
+ Use --no-mcp to skip if you only want CLI commands.
348
+
344
349
  Governance:
345
350
  Governance is ENABLED BY DEFAULT. It installs .claude/guidance/ with:
346
351
  - constitution.md: 7 unbreakable QE invariants
@@ -6,6 +6,7 @@
6
6
  *
7
7
  * Fixes #280: CLI commands previously only found .ts files.
8
8
  */
9
+ export declare const SOURCE_EXTENSIONS: Set<string>;
9
10
  export interface WalkOptions {
10
11
  /** Maximum directory depth (default: 6) */
11
12
  maxDepth?: number;
@@ -11,7 +11,7 @@ import { join, extname } from 'path';
11
11
  // ============================================================================
12
12
  // Source File Extensions by Language
13
13
  // ============================================================================
14
- const SOURCE_EXTENSIONS = new Set([
14
+ export const SOURCE_EXTENSIONS = new Set([
15
15
  // JavaScript / TypeScript
16
16
  '.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs',
17
17
  // Python
@@ -12,6 +12,13 @@ export declare function initializeGNNIndex(domainKey: string): QEGNNEmbeddingInd
12
12
  * Index code embeddings in GNN for fast similarity search
13
13
  */
14
14
  export declare function indexCodeEmbeddings(gnnIndex: QEGNNEmbeddingIndex, fileReader: FileReader, paths: string[]): Promise<void>;
15
+ /**
16
+ * R4: Generate graph-aware embeddings for a set of files using GraphMAE.
17
+ * Builds a dependency graph from import relationships and uses masked
18
+ * autoencoders to produce structure-aware embeddings.
19
+ * Falls back to feature-hash embeddings when GraphMAE is disabled.
20
+ */
21
+ export declare function generateGraphMAEEmbeddings(fileReader: FileReader, paths: string[]): Promise<Map<string, number[]>>;
15
22
  /**
16
23
  * Generate code embedding using semantic features
17
24
  */
@@ -34,6 +41,20 @@ export declare function mergeSearchResults(semanticResults: SearchResult[], gnnR
34
41
  file: string;
35
42
  similarity: number;
36
43
  }>): SearchResult[];
44
+ /**
45
+ * R6: Train GNN embeddings with memory-bounded cold-tier training.
46
+ * Uses LRU hotset caching when the graph exceeds hotsetSize, falling
47
+ * back to full in-memory training for small graphs.
48
+ */
49
+ export declare function trainWithColdTier(nodeFeatures: Map<number, Float32Array>, adjacency: Map<number, number[]>, options?: {
50
+ hotsetSize?: number;
51
+ epochs?: number;
52
+ hiddenDim?: number;
53
+ }): {
54
+ embeddings: Map<number, Float32Array>;
55
+ loss: number;
56
+ usedColdTier: boolean;
57
+ };
37
58
  /**
38
59
  * Simple hash function for strings
39
60
  */
@@ -6,6 +6,7 @@
6
6
  */
7
7
  import { LoggerFactory } from '../../logging/index.js';
8
8
  import { QEGNNIndexFactory, initGNN, } from '../../integrations/ruvector/wrappers';
9
+ import { isGraphMAEEnabled, isColdTierGNNEnabled, createGraphMAEEncoder, createColdTierTrainer, InMemoryGraph, } from '../../integrations/ruvector/index.js';
9
10
  /**
10
11
  * Initialize GNN for code graph embeddings
11
12
  */
@@ -55,6 +56,73 @@ export async function indexCodeEmbeddings(gnnIndex, fileReader, paths) {
55
56
  logger.error('Failed to index code embeddings:', error instanceof Error ? error : undefined);
56
57
  }
57
58
  }
59
+ // R4: GraphMAE singleton encoder (lazy-initialized)
60
+ let graphMAEEncoder = null;
61
+ /**
62
+ * R4: Generate graph-aware embeddings for a set of files using GraphMAE.
63
+ * Builds a dependency graph from import relationships and uses masked
64
+ * autoencoders to produce structure-aware embeddings.
65
+ * Falls back to feature-hash embeddings when GraphMAE is disabled.
66
+ */
67
+ export async function generateGraphMAEEmbeddings(fileReader, paths) {
68
+ const embeddings = new Map();
69
+ if (!isGraphMAEEnabled() || paths.length < 2) {
70
+ // Fallback: use feature-hash for each file independently
71
+ for (const p of paths) {
72
+ const result = await fileReader.readFile(p);
73
+ if (result.success && result.value) {
74
+ embeddings.set(p, await generateCodeEmbedding(p, result.value));
75
+ }
76
+ }
77
+ return embeddings;
78
+ }
79
+ try {
80
+ // Build QEGraph: nodes are files, edges are import dependencies
81
+ const nodes = new Map();
82
+ const edges = new Map();
83
+ const contentCache = new Map();
84
+ for (const p of paths) {
85
+ const result = await fileReader.readFile(p);
86
+ if (result.success && result.value) {
87
+ contentCache.set(p, result.value);
88
+ const featureVec = await generateCodeEmbedding(p, result.value);
89
+ nodes.set(p, new Float32Array(featureVec.slice(0, 32)));
90
+ // Extract import targets as edges
91
+ const imports = result.value.match(/from\s+['"]([^'"]+)['"]/g) ?? [];
92
+ const targets = imports
93
+ .map(m => m.replace(/from\s+['"]/, '').replace(/['"]$/, ''))
94
+ .filter(t => paths.some(pp => pp.includes(t.replace(/^\.\//, ''))));
95
+ edges.set(p, targets.length > 0 ? targets : []);
96
+ }
97
+ }
98
+ if (nodes.size < 2) {
99
+ // Not enough nodes for meaningful graph learning
100
+ for (const [p, content] of contentCache) {
101
+ embeddings.set(p, await generateCodeEmbedding(p, content));
102
+ }
103
+ return embeddings;
104
+ }
105
+ const graph = { nodes, edges };
106
+ if (!graphMAEEncoder) {
107
+ graphMAEEncoder = createGraphMAEEncoder({ embeddingDim: 128, numHeads: 4 });
108
+ }
109
+ const graphEmbeddings = graphMAEEncoder.embed(graph);
110
+ for (const [nodeId, emb] of graphEmbeddings) {
111
+ embeddings.set(nodeId, Array.from(emb));
112
+ }
113
+ logger.info(`[R4] GraphMAE generated ${graphEmbeddings.size} graph-aware embeddings`);
114
+ }
115
+ catch (error) {
116
+ logger.error('[R4] GraphMAE embedding failed, using feature-hash fallback:', error instanceof Error ? error : undefined);
117
+ for (const p of paths) {
118
+ const result = await fileReader.readFile(p);
119
+ if (result.success && result.value) {
120
+ embeddings.set(p, await generateCodeEmbedding(p, result.value));
121
+ }
122
+ }
123
+ }
124
+ return embeddings;
125
+ }
58
126
  /**
59
127
  * Generate code embedding using semantic features
60
128
  */
@@ -171,6 +239,40 @@ export function mergeSearchResults(semanticResults, gnnResults) {
171
239
  .sort((a, b) => b.score - a.score)
172
240
  .slice(0, 20);
173
241
  }
242
+ // R6: ColdTier trainer singleton (lazy-initialized)
243
+ let coldTierTrainer = null;
244
+ /**
245
+ * R6: Train GNN embeddings with memory-bounded cold-tier training.
246
+ * Uses LRU hotset caching when the graph exceeds hotsetSize, falling
247
+ * back to full in-memory training for small graphs.
248
+ */
249
+ export function trainWithColdTier(nodeFeatures, adjacency, options = {}) {
250
+ if (!isColdTierGNNEnabled()) {
251
+ return { embeddings: new Map(), loss: 0, usedColdTier: false };
252
+ }
253
+ try {
254
+ if (!coldTierTrainer) {
255
+ coldTierTrainer = createColdTierTrainer({
256
+ hotsetSize: options.hotsetSize ?? 10000,
257
+ epochs: options.epochs ?? 10,
258
+ hiddenDim: options.hiddenDim ?? 64,
259
+ });
260
+ }
261
+ const graph = new InMemoryGraph(nodeFeatures, adjacency);
262
+ const result = coldTierTrainer.train(graph);
263
+ logger.info(`[R6] ColdTier training: ${graph.nodeCount} nodes, ` +
264
+ `loss=${result.loss.toFixed(4)}, mode=${result.usedInMemoryMode ? 'in-memory' : 'cold-tier'}`);
265
+ return {
266
+ embeddings: result.embeddings,
267
+ loss: result.loss,
268
+ usedColdTier: !result.usedInMemoryMode,
269
+ };
270
+ }
271
+ catch (error) {
272
+ logger.error('[R6] ColdTier training failed:', error instanceof Error ? error : undefined);
273
+ return { embeddings: new Map(), loss: 0, usedColdTier: false };
274
+ }
275
+ }
174
276
  /**
175
277
  * Simple hash function for strings
176
278
  */
@@ -16,6 +16,8 @@ import { ContractValidatorService } from './services/contract-validator.js';
16
16
  import { ApiCompatibilityService } from './services/api-compatibility.js';
17
17
  import { SARSAAlgorithm } from '../../integrations/rl-suite/algorithms/sarsa.js';
18
18
  import { createPersistentSONAEngine } from '../../integrations/ruvector/sona-persistence.js';
19
+ // Three-loop feature flag for instantAdapt protocol
20
+ import { isSONAThreeLoopEnabled } from '../../integrations/ruvector/feature-flags.js';
19
21
  import { createDomainFinding, } from '../../coordination/consensus/domain-findings.js';
20
22
  // CQ-002: Base domain coordinator
21
23
  import { BaseDomainCoordinator, } from '../base-domain-coordinator.js';
@@ -960,6 +962,17 @@ export class ContractTestingCoordinator extends BaseDomainCoordinator {
960
962
  contract.endpoints.filter((e) => e.responseSchema).length / 100,
961
963
  ],
962
964
  };
965
+ // Three-loop protocol: instantAdapt must precede recordOutcome
966
+ if (isSONAThreeLoopEnabled() && this.qesona.isThreeLoopEnabled()) {
967
+ this.qesona.instantAdapt([
968
+ contract.endpoints.length / 100,
969
+ contract.consumers.length / 50,
970
+ contract.schemas.length / 50,
971
+ quality,
972
+ validationSuccess ? 1 : 0,
973
+ contract.version.major / 10,
974
+ ]);
975
+ }
963
976
  const action = {
964
977
  type: validationSuccess ? 'validate' : 'reject',
965
978
  value: quality,
@@ -69,6 +69,11 @@ export class CoverageAnalysisCoordinator extends BaseDomainCoordinator {
69
69
  async onInitialize() {
70
70
  // Services are stateless, no domain-specific initialization needed
71
71
  // ADR-059: Ghost coverage analyzer is lazy-initialized on first use
72
+ // NOTE: EWC++ three-loop integration not available in this coordinator.
73
+ // Coverage-analysis uses Q-Learning (not SONA), so the three-loop engine
74
+ // is not accessible here. To enable EWC++ for coverage patterns, this
75
+ // coordinator would need a PersistentSONAEngine instance wired the same
76
+ // way as quality-assessment and test-generation coordinators.
72
77
  }
73
78
  async onDispose() {
74
79
  // No domain-specific cleanup needed
@@ -54,6 +54,7 @@ export declare class DefectIntelligenceCoordinator extends BaseDomainCoordinator
54
54
  private readonly predictor;
55
55
  private readonly patternLearner;
56
56
  private readonly rootCauseAnalyzer;
57
+ private readonly testExecutionHistory;
57
58
  constructor(eventBus: EventBus, memory: MemoryBackend, agentCoordinator: AgentCoordinator, config?: Partial<CoordinatorConfig>);
58
59
  protected onInitialize(): Promise<void>;
59
60
  protected onDispose(): Promise<void>;
@@ -17,6 +17,9 @@ import { PatternLearnerService, } from './services/pattern-learner';
17
17
  import { RootCauseAnalyzerService, } from './services/root-cause-analyzer';
18
18
  // CQ-002: Base domain coordinator
19
19
  import { BaseDomainCoordinator, } from '../base-domain-coordinator.js';
20
+ // R12: Granger Causality for temporal failure prediction (ADR-087)
21
+ import { getRuVectorFeatureFlags } from '../../integrations/ruvector/feature-flags.js';
22
+ import { GrangerAnalyzer } from '../../integrations/ruvector/temporal-causality.js';
20
23
  const DEFAULT_CONFIG = {
21
24
  maxConcurrentWorkflows: 5,
22
25
  defaultTimeout: 60000,
@@ -49,6 +52,8 @@ export class DefectIntelligenceCoordinator extends BaseDomainCoordinator {
49
52
  predictor;
50
53
  patternLearner;
51
54
  rootCauseAnalyzer;
55
+ // R12: Accumulated test execution history for Granger causality (ADR-087)
56
+ testExecutionHistory = new Map();
52
57
  constructor(eventBus, memory, agentCoordinator, config = {}) {
53
58
  const fullConfig = { ...DEFAULT_CONFIG, ...config };
54
59
  super(eventBus, 'defect-intelligence', fullConfig, {
@@ -160,6 +165,44 @@ export class DefectIntelligenceCoordinator extends BaseDomainCoordinator {
160
165
  if (this.config.enablePatternLearning) {
161
166
  await this.autoAnalyzeHighRisk(enhancedResult);
162
167
  }
168
+ // R12: Accumulate test history and run Granger causality (ADR-087)
169
+ if (getRuVectorFeatureFlags().useGrangerCausality) {
170
+ try {
171
+ const now = Date.now();
172
+ // Accumulate prediction outcomes into per-test history
173
+ for (const p of enhancedResult.predictions) {
174
+ const history = this.testExecutionHistory.get(p.file) ?? { timestamps: [], outcomes: [] };
175
+ history.timestamps.push(now);
176
+ history.outcomes.push(p.probability > 0.5 ? 0 : 1);
177
+ // Cap history at 500 points per test
178
+ if (history.timestamps.length > 500) {
179
+ history.timestamps.splice(0, history.timestamps.length - 500);
180
+ history.outcomes.splice(0, history.outcomes.length - 500);
181
+ }
182
+ this.testExecutionHistory.set(p.file, history);
183
+ }
184
+ // Run Granger analysis when we have enough accumulated history
185
+ const eligibleSeries = Array.from(this.testExecutionHistory.entries())
186
+ .filter(([, h]) => h.timestamps.length >= 30)
187
+ .map(([testId, h]) => ({ testId, timestamps: h.timestamps, outcomes: h.outcomes }));
188
+ if (eligibleSeries.length >= 3) {
189
+ const analyzer = new GrangerAnalyzer({ maxLag: 5, alpha: 0.05 });
190
+ const causalLinks = analyzer.analyzeCausality(eligibleSeries);
191
+ if (causalLinks.length > 0) {
192
+ logger.info('Granger causality found causal links in defect predictions', {
193
+ linkCount: causalLinks.length,
194
+ historyDepth: eligibleSeries[0].timestamps.length,
195
+ topLink: `${causalLinks[0].sourceTestId} → ${causalLinks[0].targetTestId} (lag=${causalLinks[0].lag}, p=${causalLinks[0].pValue.toFixed(4)})`,
196
+ });
197
+ }
198
+ }
199
+ }
200
+ catch (grangerErr) {
201
+ logger.warn('Granger causality analysis failed (non-fatal)', {
202
+ error: grangerErr instanceof Error ? grangerErr.message : 'unknown',
203
+ });
204
+ }
205
+ }
163
206
  // Stop the agent
164
207
  await this.agentCoordinator.stop(agentResult.value);
165
208
  return ok(enhancedResult);