agentic-qe 3.6.6 → 3.6.7

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 (131) hide show
  1. package/.claude/skills/skills-manifest.json +1 -1
  2. package/package.json +1 -1
  3. package/v3/CHANGELOG.md +28 -0
  4. package/v3/dist/cli/bundle.js +747 -147
  5. package/v3/dist/cli/commands/hooks.d.ts.map +1 -1
  6. package/v3/dist/cli/commands/hooks.js +172 -31
  7. package/v3/dist/cli/commands/hooks.js.map +1 -1
  8. package/v3/dist/coordination/dynamic-scaling/dynamic-scaler.d.ts +21 -0
  9. package/v3/dist/coordination/dynamic-scaling/dynamic-scaler.d.ts.map +1 -1
  10. package/v3/dist/coordination/dynamic-scaling/dynamic-scaler.js +76 -0
  11. package/v3/dist/coordination/dynamic-scaling/dynamic-scaler.js.map +1 -1
  12. package/v3/dist/coordination/mincut/mincut-persistence.d.ts +4 -0
  13. package/v3/dist/coordination/mincut/mincut-persistence.d.ts.map +1 -1
  14. package/v3/dist/coordination/mincut/mincut-persistence.js +30 -0
  15. package/v3/dist/coordination/mincut/mincut-persistence.js.map +1 -1
  16. package/v3/dist/coordination/mincut/time-crystal.d.ts +22 -0
  17. package/v3/dist/coordination/mincut/time-crystal.d.ts.map +1 -1
  18. package/v3/dist/coordination/mincut/time-crystal.js +95 -0
  19. package/v3/dist/coordination/mincut/time-crystal.js.map +1 -1
  20. package/v3/dist/domains/code-intelligence/coordinator.d.ts.map +1 -1
  21. package/v3/dist/domains/code-intelligence/coordinator.js +6 -3
  22. package/v3/dist/domains/code-intelligence/coordinator.js.map +1 -1
  23. package/v3/dist/domains/code-intelligence/services/knowledge-graph.d.ts.map +1 -1
  24. package/v3/dist/domains/code-intelligence/services/knowledge-graph.js +19 -34
  25. package/v3/dist/domains/code-intelligence/services/knowledge-graph.js.map +1 -1
  26. package/v3/dist/domains/coverage-analysis/services/hnsw-index.d.ts.map +1 -1
  27. package/v3/dist/domains/coverage-analysis/services/hnsw-index.js +5 -3
  28. package/v3/dist/domains/coverage-analysis/services/hnsw-index.js.map +1 -1
  29. package/v3/dist/domains/security-compliance/services/scanners/sast-scanner.d.ts.map +1 -1
  30. package/v3/dist/domains/security-compliance/services/scanners/sast-scanner.js +7 -3
  31. package/v3/dist/domains/security-compliance/services/scanners/sast-scanner.js.map +1 -1
  32. package/v3/dist/early-exit/early-exit-controller.d.ts +20 -0
  33. package/v3/dist/early-exit/early-exit-controller.d.ts.map +1 -1
  34. package/v3/dist/early-exit/early-exit-controller.js +72 -0
  35. package/v3/dist/early-exit/early-exit-controller.js.map +1 -1
  36. package/v3/dist/feedback/coverage-learner.d.ts +19 -0
  37. package/v3/dist/feedback/coverage-learner.d.ts.map +1 -1
  38. package/v3/dist/feedback/coverage-learner.js +134 -0
  39. package/v3/dist/feedback/coverage-learner.js.map +1 -1
  40. package/v3/dist/feedback/feedback-loop.d.ts +10 -1
  41. package/v3/dist/feedback/feedback-loop.d.ts.map +1 -1
  42. package/v3/dist/feedback/feedback-loop.js +20 -1
  43. package/v3/dist/feedback/feedback-loop.js.map +1 -1
  44. package/v3/dist/feedback/index.d.ts +1 -1
  45. package/v3/dist/feedback/index.d.ts.map +1 -1
  46. package/v3/dist/feedback/index.js +1 -1
  47. package/v3/dist/feedback/index.js.map +1 -1
  48. package/v3/dist/feedback/test-outcome-tracker.d.ts +19 -0
  49. package/v3/dist/feedback/test-outcome-tracker.d.ts.map +1 -1
  50. package/v3/dist/feedback/test-outcome-tracker.js +114 -0
  51. package/v3/dist/feedback/test-outcome-tracker.js.map +1 -1
  52. package/v3/dist/governance/compliance-reporter.d.ts +13 -0
  53. package/v3/dist/governance/compliance-reporter.d.ts.map +1 -1
  54. package/v3/dist/governance/compliance-reporter.js +63 -0
  55. package/v3/dist/governance/compliance-reporter.js.map +1 -1
  56. package/v3/dist/governance/continue-gate-integration.d.ts +8 -0
  57. package/v3/dist/governance/continue-gate-integration.d.ts.map +1 -1
  58. package/v3/dist/governance/continue-gate-integration.js +50 -2
  59. package/v3/dist/governance/continue-gate-integration.js.map +1 -1
  60. package/v3/dist/governance/evolution-pipeline-integration.d.ts +13 -0
  61. package/v3/dist/governance/evolution-pipeline-integration.d.ts.map +1 -1
  62. package/v3/dist/governance/evolution-pipeline-integration.js +53 -0
  63. package/v3/dist/governance/evolution-pipeline-integration.js.map +1 -1
  64. package/v3/dist/index.d.ts +1 -1
  65. package/v3/dist/index.d.ts.map +1 -1
  66. package/v3/dist/index.js +1 -1
  67. package/v3/dist/index.js.map +1 -1
  68. package/v3/dist/init/phases/07-hooks.d.ts.map +1 -1
  69. package/v3/dist/init/phases/07-hooks.js +26 -5
  70. package/v3/dist/init/phases/07-hooks.js.map +1 -1
  71. package/v3/dist/integrations/ruvector/ast-complexity.d.ts +8 -0
  72. package/v3/dist/integrations/ruvector/ast-complexity.d.ts.map +1 -1
  73. package/v3/dist/integrations/ruvector/ast-complexity.js +45 -0
  74. package/v3/dist/integrations/ruvector/ast-complexity.js.map +1 -1
  75. package/v3/dist/integrations/ruvector/attention-wrapper.d.ts +18 -1
  76. package/v3/dist/integrations/ruvector/attention-wrapper.d.ts.map +1 -1
  77. package/v3/dist/integrations/ruvector/attention-wrapper.js +60 -2
  78. package/v3/dist/integrations/ruvector/attention-wrapper.js.map +1 -1
  79. package/v3/dist/integrations/ruvector/coverage-router.d.ts +8 -0
  80. package/v3/dist/integrations/ruvector/coverage-router.d.ts.map +1 -1
  81. package/v3/dist/integrations/ruvector/coverage-router.js +45 -0
  82. package/v3/dist/integrations/ruvector/coverage-router.js.map +1 -1
  83. package/v3/dist/integrations/ruvector/diff-risk-classifier.d.ts +8 -0
  84. package/v3/dist/integrations/ruvector/diff-risk-classifier.d.ts.map +1 -1
  85. package/v3/dist/integrations/ruvector/diff-risk-classifier.js +45 -0
  86. package/v3/dist/integrations/ruvector/diff-risk-classifier.js.map +1 -1
  87. package/v3/dist/integrations/ruvector/graph-boundaries.d.ts +8 -0
  88. package/v3/dist/integrations/ruvector/graph-boundaries.d.ts.map +1 -1
  89. package/v3/dist/integrations/ruvector/graph-boundaries.js +45 -0
  90. package/v3/dist/integrations/ruvector/graph-boundaries.js.map +1 -1
  91. package/v3/dist/integrations/ruvector/index.d.ts.map +1 -1
  92. package/v3/dist/integrations/ruvector/index.js +5 -20
  93. package/v3/dist/integrations/ruvector/index.js.map +1 -1
  94. package/v3/dist/integrations/ruvector/persistent-q-router.d.ts +7 -3
  95. package/v3/dist/integrations/ruvector/persistent-q-router.d.ts.map +1 -1
  96. package/v3/dist/integrations/ruvector/persistent-q-router.js +7 -3
  97. package/v3/dist/integrations/ruvector/persistent-q-router.js.map +1 -1
  98. package/v3/dist/integrations/ruvector/q-learning-router.d.ts +13 -0
  99. package/v3/dist/integrations/ruvector/q-learning-router.d.ts.map +1 -1
  100. package/v3/dist/integrations/ruvector/q-learning-router.js +67 -0
  101. package/v3/dist/integrations/ruvector/q-learning-router.js.map +1 -1
  102. package/v3/dist/kernel/hybrid-backend.d.ts +1 -0
  103. package/v3/dist/kernel/hybrid-backend.d.ts.map +1 -1
  104. package/v3/dist/kernel/hybrid-backend.js +39 -0
  105. package/v3/dist/kernel/hybrid-backend.js.map +1 -1
  106. package/v3/dist/kernel/unified-memory.d.ts +1 -0
  107. package/v3/dist/kernel/unified-memory.d.ts.map +1 -1
  108. package/v3/dist/kernel/unified-memory.js +116 -4
  109. package/v3/dist/kernel/unified-memory.js.map +1 -1
  110. package/v3/dist/learning/experience-capture-middleware.d.ts.map +1 -1
  111. package/v3/dist/learning/experience-capture-middleware.js +45 -18
  112. package/v3/dist/learning/experience-capture-middleware.js.map +1 -1
  113. package/v3/dist/learning/pattern-store.d.ts.map +1 -1
  114. package/v3/dist/learning/pattern-store.js +12 -61
  115. package/v3/dist/learning/pattern-store.js.map +1 -1
  116. package/v3/dist/learning/qe-reasoning-bank.d.ts.map +1 -1
  117. package/v3/dist/learning/qe-reasoning-bank.js +15 -2
  118. package/v3/dist/learning/qe-reasoning-bank.js.map +1 -1
  119. package/v3/dist/learning/token-tracker.d.ts +23 -0
  120. package/v3/dist/learning/token-tracker.d.ts.map +1 -1
  121. package/v3/dist/learning/token-tracker.js +91 -0
  122. package/v3/dist/learning/token-tracker.js.map +1 -1
  123. package/v3/dist/mcp/bundle.js +635 -128
  124. package/v3/dist/routing/routing-feedback.d.ts +21 -0
  125. package/v3/dist/routing/routing-feedback.d.ts.map +1 -1
  126. package/v3/dist/routing/routing-feedback.js +95 -0
  127. package/v3/dist/routing/routing-feedback.js.map +1 -1
  128. package/v3/dist/shared/sql-safety.d.ts.map +1 -1
  129. package/v3/dist/shared/sql-safety.js +2 -0
  130. package/v3/dist/shared/sql-safety.js.map +1 -1
  131. package/v3/package.json +1 -1
@@ -4179,6 +4179,10 @@ var init_sql_safety = __esm({
4179
4179
  "mincut_observations",
4180
4180
  // SONA tables
4181
4181
  "sona_patterns",
4182
+ // Feedback loop tables
4183
+ "test_outcomes",
4184
+ "routing_outcomes",
4185
+ "coverage_sessions",
4182
4186
  // Sync tables
4183
4187
  "patterns",
4184
4188
  // Hypergraph tables
@@ -5123,12 +5127,16 @@ function findProjectRoot(startDir = process.cwd()) {
5123
5127
  let dir = startDir;
5124
5128
  const root = path.parse(dir).root;
5125
5129
  let checkDir = dir;
5130
+ let topmostAqeDir = null;
5126
5131
  while (checkDir !== root) {
5127
5132
  if (fs.existsSync(path.join(checkDir, ".agentic-qe"))) {
5128
- return checkDir;
5133
+ topmostAqeDir = checkDir;
5129
5134
  }
5130
5135
  checkDir = path.dirname(checkDir);
5131
5136
  }
5137
+ if (topmostAqeDir) {
5138
+ return topmostAqeDir;
5139
+ }
5132
5140
  checkDir = dir;
5133
5141
  while (checkDir !== root) {
5134
5142
  if (fs.existsSync(path.join(checkDir, ".git"))) {
@@ -5193,7 +5201,7 @@ function registerExitHandlers() {
5193
5201
  process.exit(0);
5194
5202
  });
5195
5203
  }
5196
- var DEFAULT_UNIFIED_MEMORY_CONFIG, SCHEMA_VERSION, SCHEMA_VERSION_TABLE, KV_STORE_SCHEMA, VECTORS_SCHEMA, RL_QVALUES_SCHEMA, GOAP_SCHEMA, DREAM_SCHEMA, QE_PATTERNS_SCHEMA, MINCUT_SCHEMA, SONA_PATTERNS_SCHEMA, BinaryHeap, InMemoryHNSWIndex, UnifiedMemoryManager, exitHandlersRegistered;
5204
+ var DEFAULT_UNIFIED_MEMORY_CONFIG, SCHEMA_VERSION, SCHEMA_VERSION_TABLE, KV_STORE_SCHEMA, VECTORS_SCHEMA, RL_QVALUES_SCHEMA, GOAP_SCHEMA, DREAM_SCHEMA, QE_PATTERNS_SCHEMA, MINCUT_SCHEMA, SONA_PATTERNS_SCHEMA, FEEDBACK_SCHEMA, BinaryHeap, InMemoryHNSWIndex, UnifiedMemoryManager, exitHandlersRegistered;
5197
5205
  var init_unified_memory = __esm({
5198
5206
  "src/kernel/unified-memory.ts"() {
5199
5207
  "use strict";
@@ -5213,7 +5221,7 @@ var init_unified_memory = __esm({
5213
5221
  busyTimeout: MEMORY_CONSTANTS.BUSY_TIMEOUT_MS,
5214
5222
  vectorDimensions: MEMORY_CONSTANTS.DEFAULT_VECTOR_DIMENSIONS
5215
5223
  };
5216
- SCHEMA_VERSION = 7;
5224
+ SCHEMA_VERSION = 8;
5217
5225
  SCHEMA_VERSION_TABLE = `
5218
5226
  CREATE TABLE IF NOT EXISTS schema_version (
5219
5227
  id INTEGER PRIMARY KEY CHECK (id = 1),
@@ -5684,6 +5692,81 @@ var init_unified_memory = __esm({
5684
5692
  CREATE INDEX IF NOT EXISTS idx_sona_patterns_domain ON sona_patterns(domain);
5685
5693
  CREATE INDEX IF NOT EXISTS idx_sona_patterns_confidence ON sona_patterns(confidence DESC);
5686
5694
  CREATE INDEX IF NOT EXISTS idx_sona_patterns_updated ON sona_patterns(updated_at DESC);
5695
+ `;
5696
+ FEEDBACK_SCHEMA = `
5697
+ -- Test outcomes (ADR-023: Quality Feedback Loop)
5698
+ CREATE TABLE IF NOT EXISTS test_outcomes (
5699
+ id TEXT PRIMARY KEY,
5700
+ test_id TEXT NOT NULL,
5701
+ test_name TEXT NOT NULL,
5702
+ generated_by TEXT NOT NULL,
5703
+ pattern_id TEXT,
5704
+ framework TEXT NOT NULL,
5705
+ language TEXT NOT NULL,
5706
+ domain TEXT NOT NULL,
5707
+ passed INTEGER NOT NULL,
5708
+ error_message TEXT,
5709
+ coverage_lines REAL DEFAULT 0,
5710
+ coverage_branches REAL DEFAULT 0,
5711
+ coverage_functions REAL DEFAULT 0,
5712
+ mutation_score REAL,
5713
+ execution_time_ms REAL NOT NULL,
5714
+ flaky INTEGER DEFAULT 0,
5715
+ flakiness_score REAL,
5716
+ maintainability_score REAL NOT NULL,
5717
+ complexity REAL,
5718
+ lines_of_code INTEGER,
5719
+ assertion_count INTEGER,
5720
+ file_path TEXT,
5721
+ source_file_path TEXT,
5722
+ metadata_json TEXT,
5723
+ created_at TEXT DEFAULT (datetime('now'))
5724
+ );
5725
+ CREATE INDEX IF NOT EXISTS idx_test_outcomes_pattern ON test_outcomes(pattern_id);
5726
+ CREATE INDEX IF NOT EXISTS idx_test_outcomes_agent ON test_outcomes(generated_by);
5727
+ CREATE INDEX IF NOT EXISTS idx_test_outcomes_domain ON test_outcomes(domain);
5728
+ CREATE INDEX IF NOT EXISTS idx_test_outcomes_created ON test_outcomes(created_at);
5729
+
5730
+ -- Routing outcomes (ADR-022: Adaptive QE Agent Routing)
5731
+ CREATE TABLE IF NOT EXISTS routing_outcomes (
5732
+ id TEXT PRIMARY KEY,
5733
+ task_json TEXT NOT NULL,
5734
+ decision_json TEXT NOT NULL,
5735
+ used_agent TEXT NOT NULL,
5736
+ followed_recommendation INTEGER NOT NULL,
5737
+ success INTEGER NOT NULL,
5738
+ quality_score REAL NOT NULL,
5739
+ duration_ms REAL NOT NULL,
5740
+ error TEXT,
5741
+ created_at TEXT DEFAULT (datetime('now'))
5742
+ );
5743
+ CREATE INDEX IF NOT EXISTS idx_routing_outcomes_agent ON routing_outcomes(used_agent);
5744
+ CREATE INDEX IF NOT EXISTS idx_routing_outcomes_created ON routing_outcomes(created_at);
5745
+
5746
+ -- Coverage sessions (ADR-023: Coverage Learning)
5747
+ CREATE TABLE IF NOT EXISTS coverage_sessions (
5748
+ id TEXT PRIMARY KEY,
5749
+ target_path TEXT NOT NULL,
5750
+ agent_id TEXT NOT NULL,
5751
+ technique TEXT NOT NULL,
5752
+ before_lines REAL DEFAULT 0,
5753
+ before_branches REAL DEFAULT 0,
5754
+ before_functions REAL DEFAULT 0,
5755
+ after_lines REAL DEFAULT 0,
5756
+ after_branches REAL DEFAULT 0,
5757
+ after_functions REAL DEFAULT 0,
5758
+ tests_generated INTEGER DEFAULT 0,
5759
+ tests_passed INTEGER DEFAULT 0,
5760
+ gaps_json TEXT,
5761
+ duration_ms REAL NOT NULL,
5762
+ started_at TEXT NOT NULL,
5763
+ completed_at TEXT NOT NULL,
5764
+ context_json TEXT,
5765
+ created_at TEXT DEFAULT (datetime('now'))
5766
+ );
5767
+ CREATE INDEX IF NOT EXISTS idx_coverage_sessions_technique ON coverage_sessions(technique);
5768
+ CREATE INDEX IF NOT EXISTS idx_coverage_sessions_agent ON coverage_sessions(agent_id);
5769
+ CREATE INDEX IF NOT EXISTS idx_coverage_sessions_created ON coverage_sessions(created_at);
5687
5770
  `;
5688
5771
  BinaryHeap = class {
5689
5772
  data = [];
@@ -6023,6 +6106,7 @@ var init_unified_memory = __esm({
6023
6106
  db = null;
6024
6107
  config;
6025
6108
  initialized = false;
6109
+ vectorsLoaded = false;
6026
6110
  initPromise = null;
6027
6111
  preparedStatements = /* @__PURE__ */ new Map();
6028
6112
  vectorIndex = new InMemoryHNSWIndex();
@@ -6100,7 +6184,7 @@ var init_unified_memory = __esm({
6100
6184
  this.db.pragma(`busy_timeout = ${this.config.busyTimeout}`);
6101
6185
  this.db.pragma("foreign_keys = ON");
6102
6186
  await this.runMigrations();
6103
- await this.loadVectorIndex();
6187
+ this.vectorsLoaded = false;
6104
6188
  this.initialized = true;
6105
6189
  console.log(`[UnifiedMemory] Initialized: ${this.config.dbPath}`);
6106
6190
  this.warnIfDuplicateDatabases();
@@ -6221,6 +6305,9 @@ var init_unified_memory = __esm({
6221
6305
  if (currentVersion < 7) {
6222
6306
  this.db.exec(SONA_PATTERNS_SCHEMA);
6223
6307
  }
6308
+ if (currentVersion < 8) {
6309
+ this.db.exec(FEEDBACK_SCHEMA);
6310
+ }
6224
6311
  this.db.prepare(`
6225
6312
  INSERT OR REPLACE INTO schema_version (id, version, migrated_at)
6226
6313
  VALUES (1, ?, datetime('now'))
@@ -6234,6 +6321,7 @@ var init_unified_memory = __esm({
6234
6321
  * Load all vectors from SQLite into HNSW index
6235
6322
  */
6236
6323
  async loadVectorIndex() {
6324
+ if (this.vectorsLoaded) return;
6237
6325
  if (!this.db) throw new Error("Database not initialized");
6238
6326
  this.vectorIndex.clear();
6239
6327
  const rows = this.db.prepare(
@@ -6243,6 +6331,7 @@ var init_unified_memory = __esm({
6243
6331
  const embedding = this.bufferToFloatArray(row2.embedding, row2.dimensions);
6244
6332
  this.vectorIndex.add(row2.id, embedding);
6245
6333
  }
6334
+ this.vectorsLoaded = true;
6246
6335
  console.log(`[UnifiedMemory] Loaded ${rows.length} vectors into HNSW index`);
6247
6336
  }
6248
6337
  // ============================================================================
@@ -6366,6 +6455,9 @@ var init_unified_memory = __esm({
6366
6455
  */
6367
6456
  async vectorSearch(query, k68 = 10, namespace) {
6368
6457
  this.ensureInitialized();
6458
+ if (!this.vectorsLoaded) {
6459
+ await this.loadVectorIndex();
6460
+ }
6369
6461
  const results = this.vectorIndex.search(query, k68 * 2);
6370
6462
  if (results.length === 0) return [];
6371
6463
  const ids = results.map((r54) => r54.id);
@@ -9720,6 +9812,7 @@ var init_attention_wrapper = __esm({
9720
9812
  "src/integrations/ruvector/attention-wrapper.ts"() {
9721
9813
  "use strict";
9722
9814
  init_attention();
9815
+ init_unified_memory();
9723
9816
  QE_FLASH_ATTENTION_CONFIG = {
9724
9817
  "test-similarity": {
9725
9818
  dim: 384,
@@ -9833,11 +9926,19 @@ var init_attention_wrapper = __esm({
9833
9926
  }
9834
9927
  }
9835
9928
  };
9836
- QEFlashAttention = class {
9929
+ QEFlashAttention = class _QEFlashAttention {
9837
9930
  attention;
9838
9931
  config;
9839
9932
  workload;
9840
9933
  metrics = [];
9934
+ // kv_store persistence
9935
+ db = null;
9936
+ persistCount = 0;
9937
+ static KV_NAMESPACE = "attention-metrics";
9938
+ static KV_TTL = 3600;
9939
+ // 1 hour
9940
+ static PERSIST_INTERVAL = 10;
9941
+ // every 10 operations
9841
9942
  constructor(workload, customConfig) {
9842
9943
  this.workload = workload;
9843
9944
  const baseConfig = QE_FLASH_ATTENTION_CONFIG[workload];
@@ -9848,10 +9949,18 @@ var init_attention_wrapper = __esm({
9848
9949
  this.attention = AttentionFactory.create(this.config);
9849
9950
  }
9850
9951
  /**
9851
- * Initialize Flash Attention
9952
+ * Initialize Flash Attention and kv_store persistence
9852
9953
  * Note: @ruvector/attention doesn't require async initialization
9853
9954
  */
9854
9955
  async initialize() {
9956
+ try {
9957
+ this.db = getUnifiedMemory();
9958
+ if (!this.db.isInitialized()) await this.db.initialize();
9959
+ await this.loadFromKv();
9960
+ } catch (error) {
9961
+ console.warn("[QEFlashAttention] DB init failed, using memory-only:", error instanceof Error ? error.message : String(error));
9962
+ this.db = null;
9963
+ }
9855
9964
  }
9856
9965
  /**
9857
9966
  * Compute Flash Attention using @ruvector/attention
@@ -9896,6 +10005,7 @@ var init_attention_wrapper = __esm({
9896
10005
  throughput: seqLen * seqLen / ((endTime - startTime) / 1e3),
9897
10006
  peakMemoryMB: endMemory
9898
10007
  });
10008
+ this.maybePersistToKv();
9899
10009
  return output;
9900
10010
  }
9901
10011
  /**
@@ -10062,6 +10172,49 @@ var init_attention_wrapper = __esm({
10062
10172
  this.metrics = [];
10063
10173
  }
10064
10174
  // ========================================================================
10175
+ // kv_store Persistence
10176
+ // ========================================================================
10177
+ /**
10178
+ * Persist metrics snapshot to kv_store
10179
+ */
10180
+ async persistToKv() {
10181
+ if (!this.db) return;
10182
+ const kvKey = `attention-metrics-${this.workload}`;
10183
+ const snapshot = {
10184
+ workload: this.workload,
10185
+ metrics: this.metrics.slice(-50),
10186
+ savedAt: Date.now()
10187
+ };
10188
+ await this.db.kvSet(
10189
+ kvKey,
10190
+ snapshot,
10191
+ _QEFlashAttention.KV_NAMESPACE,
10192
+ _QEFlashAttention.KV_TTL
10193
+ );
10194
+ }
10195
+ /**
10196
+ * Load metrics snapshot from kv_store
10197
+ */
10198
+ async loadFromKv() {
10199
+ if (!this.db) return;
10200
+ const kvKey = `attention-metrics-${this.workload}`;
10201
+ const snapshot = await this.db.kvGet(kvKey, _QEFlashAttention.KV_NAMESPACE);
10202
+ if (snapshot?.metrics?.length) {
10203
+ this.metrics = snapshot.metrics;
10204
+ }
10205
+ }
10206
+ /**
10207
+ * Track operations and persist periodically
10208
+ */
10209
+ maybePersistToKv() {
10210
+ this.persistCount++;
10211
+ if (this.persistCount >= _QEFlashAttention.PERSIST_INTERVAL) {
10212
+ this.persistCount = 0;
10213
+ this.persistToKv().catch(() => {
10214
+ });
10215
+ }
10216
+ }
10217
+ // ========================================================================
10065
10218
  // Private Helper Methods
10066
10219
  // ========================================================================
10067
10220
  /**
@@ -10860,8 +11013,6 @@ var init_hnsw_index = __esm({
10860
11013
  const embedding = this.vectorToEmbedding(vector, key, metadata);
10861
11014
  this.ruvectorIndex.addEmbedding(embedding, label);
10862
11015
  this.vectorStore.set(key, vector);
10863
- const fullKey = this.buildKey(key);
10864
- await this.memory.storeVector(fullKey, vector, metadata);
10865
11016
  this.stats.insertOperations++;
10866
11017
  this.stats.vectorCount++;
10867
11018
  }
@@ -18305,31 +18456,6 @@ var init_pattern_store = __esm({
18305
18456
  * Load existing patterns from memory with timeout protection
18306
18457
  */
18307
18458
  async loadPatterns() {
18308
- try {
18309
- const timeoutMs = 5e3;
18310
- const searchPromise = this.memory.search(`${this.config.namespace}:pattern:*`, 1e4);
18311
- const timeoutPromise = new Promise(
18312
- (_56, reject) => setTimeout(() => reject(new Error("Pattern load timeout")), timeoutMs)
18313
- );
18314
- const keys = await Promise.race([searchPromise, timeoutPromise]);
18315
- const BATCH_SIZE = 50;
18316
- for (let i58 = 0; i58 < keys.length; i58 += BATCH_SIZE) {
18317
- const batch = keys.slice(i58, i58 + BATCH_SIZE);
18318
- const patterns = await Promise.all(
18319
- batch.map((key) => this.memory.get(key).catch(() => null))
18320
- );
18321
- for (const pattern of patterns) {
18322
- if (pattern) {
18323
- this.indexPattern(pattern);
18324
- }
18325
- }
18326
- }
18327
- if (this.patternCache.size > 0) {
18328
- console.log(`[PatternStore] Loaded ${this.patternCache.size} patterns`);
18329
- }
18330
- } catch (error) {
18331
- console.log(`[PatternStore] Starting fresh (no existing patterns loaded): ${error instanceof Error ? error.message : "unknown error"}`);
18332
- }
18333
18459
  }
18334
18460
  /**
18335
18461
  * Index a pattern in local caches
@@ -18377,10 +18503,6 @@ var init_pattern_store = __esm({
18377
18503
  if (domainCount >= this.config.maxPatternsPerDomain) {
18378
18504
  await this.cleanupDomain(pattern.qeDomain);
18379
18505
  }
18380
- const key = `${this.config.namespace}:pattern:${pattern.id}`;
18381
- await this.memory.set(key, pattern, {
18382
- persist: true
18383
- });
18384
18506
  this.indexPattern(pattern);
18385
18507
  if (pattern.embedding) {
18386
18508
  const hnsw = await this.ensureHNSW();
@@ -18477,15 +18599,7 @@ var init_pattern_store = __esm({
18477
18599
  if (!this.initialized) {
18478
18600
  await this.initialize();
18479
18601
  }
18480
- const cached = this.patternCache.get(id);
18481
- if (cached) return cached;
18482
- const key = `${this.config.namespace}:pattern:${id}`;
18483
- const pattern = await this.memory.get(key);
18484
- if (pattern) {
18485
- this.indexPattern(pattern);
18486
- return pattern;
18487
- }
18488
- return null;
18602
+ return this.patternCache.get(id) ?? null;
18489
18603
  }
18490
18604
  /**
18491
18605
  * Search for patterns
@@ -18682,10 +18796,6 @@ var init_pattern_store = __esm({
18682
18796
  if (shouldPromote && updated.tier === "short-term") {
18683
18797
  await this.promote(id);
18684
18798
  } else {
18685
- const key = `${this.config.namespace}:pattern:${id}`;
18686
- await this.memory.set(key, updated, {
18687
- persist: true
18688
- });
18689
18799
  this.patternCache.set(id, updated);
18690
18800
  }
18691
18801
  return ok(void 0);
@@ -18709,10 +18819,6 @@ var init_pattern_store = __esm({
18709
18819
  };
18710
18820
  this.tierIndex.get("short-term")?.delete(id);
18711
18821
  this.tierIndex.get("long-term")?.add(id);
18712
- const key = `${this.config.namespace}:pattern:${id}`;
18713
- await this.memory.set(key, promoted, {
18714
- persist: true
18715
- });
18716
18822
  this.patternCache.set(id, promoted);
18717
18823
  console.log(
18718
18824
  `[PatternStore] Promoted pattern ${id} (${pattern.name}) to long-term storage`
@@ -18728,8 +18834,6 @@ var init_pattern_store = __esm({
18728
18834
  return err(new Error(`Pattern not found: ${id}`));
18729
18835
  }
18730
18836
  this.unindexPattern(pattern);
18731
- const key = `${this.config.namespace}:pattern:${id}`;
18732
- await this.memory.delete(key);
18733
18837
  if (this.hnswIndex !== null) {
18734
18838
  try {
18735
18839
  await this.hnswIndex.delete(id);
@@ -18996,7 +19100,15 @@ var init_qe_reasoning_bank = __esm({
18996
19100
  await this.loadPretrainedPatterns();
18997
19101
  this.initialized = true;
18998
19102
  try {
18999
- await this.seedCrossDomainPatterns();
19103
+ const SEED_FLAG_KEY = "reasoning-bank:cross-domain-seeded";
19104
+ const alreadySeeded = await this.memory.get(SEED_FLAG_KEY);
19105
+ if (!alreadySeeded) {
19106
+ await this.memory.set(SEED_FLAG_KEY, true);
19107
+ await this.seedCrossDomainPatterns();
19108
+ } else {
19109
+ const stats = await this.patternStore.getStats();
19110
+ console.log(`[QEReasoningBank] Cross-domain transfer already complete (${stats.totalPatterns} patterns)`);
19111
+ }
19000
19112
  } catch (error) {
19001
19113
  console.warn("[QEReasoningBank] Cross-domain seeding failed (non-fatal):", error);
19002
19114
  }
@@ -30866,6 +30978,7 @@ var HybridMemoryBackend = class {
30866
30978
  unifiedMemory = null;
30867
30979
  config;
30868
30980
  cleanupInterval;
30981
+ cleanupCount = 0;
30869
30982
  initialized = false;
30870
30983
  constructor(config) {
30871
30984
  this.config = {
@@ -31082,6 +31195,31 @@ var HybridMemoryBackend = class {
31082
31195
  if (this.unifiedMemory?.isInitialized()) {
31083
31196
  try {
31084
31197
  await this.unifiedMemory.kvCleanupExpired();
31198
+ const db = this.unifiedMemory.getDatabase();
31199
+ try {
31200
+ const expired = db.prepare("DELETE FROM kv_store WHERE expires_at IS NOT NULL AND expires_at < ?").run(Date.now());
31201
+ if (expired.changes > 0) {
31202
+ console.log(`[HybridBackend] Expired ${expired.changes} kv_store entries`);
31203
+ }
31204
+ } catch (e20) {
31205
+ }
31206
+ this.cleanupCount++;
31207
+ if (this.cleanupCount % 10 === 0) {
31208
+ try {
31209
+ const kvCount = db.prepare("SELECT COUNT(*) as cnt FROM kv_store").get();
31210
+ if (kvCount.cnt > 5e3) {
31211
+ const deleted = db.prepare(`
31212
+ DELETE FROM kv_store WHERE rowid NOT IN (
31213
+ SELECT rowid FROM kv_store ORDER BY rowid DESC LIMIT 5000
31214
+ )
31215
+ `).run();
31216
+ if (deleted.changes > 0) {
31217
+ console.log(`[HybridBackend] kv_store retention: pruned ${deleted.changes} rows (kept 5000)`);
31218
+ }
31219
+ }
31220
+ } catch (e20) {
31221
+ }
31222
+ }
31085
31223
  } catch (error) {
31086
31224
  console.warn("[HybridBackend] Cleanup failed:", error);
31087
31225
  }
@@ -43320,11 +43458,19 @@ var isConstitutionalEnforcerEnabled = () => governanceFlags.isGateEnabled("const
43320
43458
  var isStrictMode = () => governanceFlags.getFlags().global.strictMode;
43321
43459
 
43322
43460
  // src/governance/continue-gate-integration.ts
43323
- var ContinueGateIntegration = class {
43461
+ init_unified_memory();
43462
+ var ContinueGateIntegration = class _ContinueGateIntegration {
43324
43463
  actionHistory = /* @__PURE__ */ new Map();
43325
43464
  throttledAgents = /* @__PURE__ */ new Map();
43326
43465
  guidanceContinueGate = null;
43327
43466
  initialized = false;
43467
+ db = null;
43468
+ persistCount = 0;
43469
+ static KV_NAMESPACE = "continue-gate-actions";
43470
+ static KV_KEY = "snapshot";
43471
+ static PERSIST_INTERVAL = 20;
43472
+ static KV_TTL = 3600;
43473
+ // 1 hour
43328
43474
  /**
43329
43475
  * Initialize the ContinueGate integration
43330
43476
  *
@@ -43335,8 +43481,48 @@ var ContinueGateIntegration = class {
43335
43481
  */
43336
43482
  async initialize() {
43337
43483
  if (this.initialized) return;
43484
+ try {
43485
+ this.db = getUnifiedMemory();
43486
+ if (!this.db.isInitialized()) await this.db.initialize();
43487
+ await this.loadFromKv();
43488
+ } catch (error) {
43489
+ console.warn("[ContinueGateIntegration] DB init failed, using memory-only:", error instanceof Error ? error.message : String(error));
43490
+ this.db = null;
43491
+ }
43338
43492
  this.initialized = true;
43339
43493
  }
43494
+ async loadFromKv() {
43495
+ if (!this.db) return;
43496
+ const data = await this.db.kvGet(_ContinueGateIntegration.KV_KEY, _ContinueGateIntegration.KV_NAMESPACE);
43497
+ if (data) {
43498
+ for (const [agentId, actions] of data.actionHistory) {
43499
+ this.actionHistory.set(agentId, actions);
43500
+ }
43501
+ const now = Date.now();
43502
+ for (const [agentId, until] of data.throttledAgents) {
43503
+ if (until > now) this.throttledAgents.set(agentId, until);
43504
+ }
43505
+ console.log("[ContinueGateIntegration] Loaded state from DB");
43506
+ }
43507
+ }
43508
+ async persistSnapshot() {
43509
+ if (!this.db) return;
43510
+ try {
43511
+ await this.db.kvSet(
43512
+ _ContinueGateIntegration.KV_KEY,
43513
+ {
43514
+ actionHistory: Array.from(this.actionHistory.entries()).map(
43515
+ ([agentId, actions]) => [agentId, actions.slice(-50)]
43516
+ ),
43517
+ throttledAgents: Array.from(this.throttledAgents.entries())
43518
+ },
43519
+ _ContinueGateIntegration.KV_NAMESPACE,
43520
+ _ContinueGateIntegration.KV_TTL
43521
+ );
43522
+ } catch (error) {
43523
+ console.warn("[ContinueGateIntegration] Persist failed:", error instanceof Error ? error.message : String(error));
43524
+ }
43525
+ }
43340
43526
  /**
43341
43527
  * Record an agent action for loop detection
43342
43528
  */
@@ -43348,6 +43534,11 @@ var ContinueGateIntegration = class {
43348
43534
  history.shift();
43349
43535
  }
43350
43536
  this.actionHistory.set(action.agentId, history);
43537
+ this.persistCount++;
43538
+ if (this.persistCount % _ContinueGateIntegration.PERSIST_INTERVAL === 0) {
43539
+ this.persistSnapshot().catch(() => {
43540
+ });
43541
+ }
43351
43542
  }
43352
43543
  /**
43353
43544
  * Evaluate whether an agent should continue
@@ -44626,6 +44817,7 @@ var DeterministicGatewayIntegration = class {
44626
44817
  var deterministicGatewayIntegration = new DeterministicGatewayIntegration();
44627
44818
 
44628
44819
  // src/governance/evolution-pipeline-integration.ts
44820
+ init_unified_memory();
44629
44821
  function isEvolutionPipelineEnabled() {
44630
44822
  const flags = governanceFlags.getFlags();
44631
44823
  if (!flags.global.enableAllGates) return false;
@@ -44641,11 +44833,18 @@ function getEvolutionFlags() {
44641
44833
  learningRate: 0.1
44642
44834
  };
44643
44835
  }
44644
- var EvolutionPipelineIntegration = class {
44836
+ var EvolutionPipelineIntegration = class _EvolutionPipelineIntegration {
44645
44837
  rules = /* @__PURE__ */ new Map();
44646
44838
  variantTests = /* @__PURE__ */ new Map();
44647
44839
  taskOutcomes = /* @__PURE__ */ new Map();
44648
44840
  initialized = false;
44841
+ // KV persistence
44842
+ db = null;
44843
+ persistCount = 0;
44844
+ static NAMESPACE = "rule-evolution";
44845
+ static TTL_SECONDS = 604800;
44846
+ // 7 days
44847
+ static PERSIST_INTERVAL = 10;
44649
44848
  // Statistics
44650
44849
  stats = {
44651
44850
  autoPromotions: 0,
@@ -44663,6 +44862,14 @@ var EvolutionPipelineIntegration = class {
44663
44862
  */
44664
44863
  async initialize() {
44665
44864
  if (this.initialized) return;
44865
+ try {
44866
+ this.db = getUnifiedMemory();
44867
+ if (!this.db.isInitialized()) await this.db.initialize();
44868
+ await this.loadFromKv();
44869
+ } catch (error) {
44870
+ console.warn("[EvolutionPipeline] DB init failed, using memory-only:", error instanceof Error ? error.message : String(error));
44871
+ this.db = null;
44872
+ }
44666
44873
  this.initialized = true;
44667
44874
  this.logEvent("initialize", "Evolution Pipeline initialized");
44668
44875
  }
@@ -44684,6 +44891,7 @@ var EvolutionPipelineIntegration = class {
44684
44891
  record.applications.push(application);
44685
44892
  this.pruneApplicationHistory(record);
44686
44893
  this.checkAutoPromotionDemotion(ruleId);
44894
+ this.persistSnapshot();
44687
44895
  this.logEvent("rule_application", `Rule ${ruleId} applied: ${success ? "success" : "failure"}`);
44688
44896
  }
44689
44897
  /**
@@ -45108,6 +45316,36 @@ var EvolutionPipelineIntegration = class {
45108
45316
  this.rules.delete(ruleId);
45109
45317
  }
45110
45318
  // ============================================================================
45319
+ // KV Persistence
45320
+ // ============================================================================
45321
+ /**
45322
+ * Load rules snapshot from KV store
45323
+ */
45324
+ async loadFromKv() {
45325
+ if (!this.db) return;
45326
+ const data = await this.db.kvGet("snapshot", _EvolutionPipelineIntegration.NAMESPACE);
45327
+ if (data) {
45328
+ for (const [key, record] of Object.entries(data)) {
45329
+ this.rules.set(key, record);
45330
+ }
45331
+ }
45332
+ }
45333
+ /**
45334
+ * Persist rules snapshot to KV store on interval
45335
+ */
45336
+ persistSnapshot() {
45337
+ if (!this.db) return;
45338
+ this.persistCount++;
45339
+ if (this.persistCount % _EvolutionPipelineIntegration.PERSIST_INTERVAL !== 0) return;
45340
+ try {
45341
+ const snapshot = Object.fromEntries(this.rules);
45342
+ this.db.kvSet("snapshot", snapshot, _EvolutionPipelineIntegration.NAMESPACE, _EvolutionPipelineIntegration.TTL_SECONDS).catch(() => {
45343
+ });
45344
+ } catch (error) {
45345
+ console.warn("[EvolutionPipeline] Persist failed:", error instanceof Error ? error.message : String(error));
45346
+ }
45347
+ }
45348
+ // ============================================================================
45111
45349
  // Private Helpers
45112
45350
  // ============================================================================
45113
45351
  /**
@@ -47452,6 +47690,7 @@ var ProofEnvelopeIntegration = class {
47452
47690
  var proofEnvelopeIntegration = new ProofEnvelopeIntegration();
47453
47691
 
47454
47692
  // src/governance/compliance-reporter.ts
47693
+ init_unified_memory();
47455
47694
  var DEFAULT_COMPLIANCE_REPORTER_FLAGS = {
47456
47695
  enabled: true,
47457
47696
  autoRecordViolations: true,
@@ -47468,7 +47707,7 @@ var SEVERITY_WEIGHTS = {
47468
47707
  var DEFAULT_SCORE = 100;
47469
47708
  var SCORE_DECAY_RATE = 0.5;
47470
47709
  var TREND_THRESHOLD = 5;
47471
- var ComplianceReporter = class {
47710
+ var ComplianceReporter = class _ComplianceReporter {
47472
47711
  violations = /* @__PURE__ */ new Map();
47473
47712
  alertThresholds = /* @__PURE__ */ new Map();
47474
47713
  proofIntegration;
@@ -47476,6 +47715,13 @@ var ComplianceReporter = class {
47476
47715
  initialized = false;
47477
47716
  scoreHistory = [];
47478
47717
  alertListeners = /* @__PURE__ */ new Set();
47718
+ // KV persistence
47719
+ db = null;
47720
+ persistCount = 0;
47721
+ static NAMESPACE = "compliance-audit";
47722
+ static TTL_SECONDS = 2592e3;
47723
+ // 30 days
47724
+ static PERSIST_INTERVAL = 10;
47479
47725
  /**
47480
47726
  * Create a new ComplianceReporter instance
47481
47727
  *
@@ -47491,6 +47737,14 @@ var ComplianceReporter = class {
47491
47737
  */
47492
47738
  async initialize() {
47493
47739
  if (this.initialized) return;
47740
+ try {
47741
+ this.db = getUnifiedMemory();
47742
+ if (!this.db.isInitialized()) await this.db.initialize();
47743
+ await this.loadFromKv();
47744
+ } catch (error) {
47745
+ console.warn("[ComplianceReporter] DB init failed, using memory-only:", error instanceof Error ? error.message : String(error));
47746
+ this.db = null;
47747
+ }
47494
47748
  if (!this.proofIntegration.isInitialized()) {
47495
47749
  await this.proofIntegration.initialize();
47496
47750
  }
@@ -47559,6 +47813,7 @@ var ComplianceReporter = class {
47559
47813
  if (this.flags.alertOnCritical && violation.severity === "critical") {
47560
47814
  this.triggerAlert(violation.gate, "Critical violation detected", "critical");
47561
47815
  }
47816
+ this.persistSnapshot();
47562
47817
  this.cleanupOldViolations();
47563
47818
  return id;
47564
47819
  }
@@ -47988,6 +48243,45 @@ var ComplianceReporter = class {
47988
48243
  this.initialized = false;
47989
48244
  }
47990
48245
  // ============================================================================
48246
+ // KV Persistence
48247
+ // ============================================================================
48248
+ /**
48249
+ * Load violations and score history from KV store
48250
+ */
48251
+ async loadFromKv() {
48252
+ if (!this.db) return;
48253
+ const data = await this.db.kvGet("snapshot", _ComplianceReporter.NAMESPACE);
48254
+ if (data) {
48255
+ if (data.violations) {
48256
+ for (const [key, violation] of Object.entries(data.violations)) {
48257
+ this.violations.set(key, violation);
48258
+ }
48259
+ }
48260
+ if (data.scoreHistory) {
48261
+ this.scoreHistory = data.scoreHistory;
48262
+ }
48263
+ }
48264
+ }
48265
+ /**
48266
+ * Persist violations and score history to KV store on interval
48267
+ */
48268
+ persistSnapshot() {
48269
+ if (!this.db) return;
48270
+ this.persistCount++;
48271
+ if (this.persistCount % _ComplianceReporter.PERSIST_INTERVAL !== 0) return;
48272
+ try {
48273
+ const violationEntries = Array.from(this.violations.entries()).slice(-500);
48274
+ const snapshot = {
48275
+ violations: Object.fromEntries(violationEntries),
48276
+ scoreHistory: this.scoreHistory.slice(-100)
48277
+ };
48278
+ this.db.kvSet("snapshot", snapshot, _ComplianceReporter.NAMESPACE, _ComplianceReporter.TTL_SECONDS).catch(() => {
48279
+ });
48280
+ } catch (error) {
48281
+ console.warn("[ComplianceReporter] Persist failed:", error instanceof Error ? error.message : String(error));
48282
+ }
48283
+ }
48284
+ // ============================================================================
47991
48285
  // Private Methods
47992
48286
  // ============================================================================
47993
48287
  /**
@@ -82890,13 +83184,6 @@ var KnowledgeGraphService = class {
82890
83184
  async clear() {
82891
83185
  this.nodeCache.clear();
82892
83186
  this.edgeIndex.clear();
82893
- const nodePattern = `${this.config.namespace}:node:*`;
82894
- const edgePattern = `${this.config.namespace}:edge:*`;
82895
- const nodeKeys = await this.memory.search(nodePattern, this.config.maxNodes);
82896
- const edgeKeys = await this.memory.search(edgePattern, this.config.maxNodes * 10);
82897
- for (const key of [...nodeKeys, ...edgeKeys]) {
82898
- await this.memory.delete(key);
82899
- }
82900
83187
  }
82901
83188
  // ============================================================================
82902
83189
  // ADR-051: LLM Enhancement Methods
@@ -83131,26 +83418,18 @@ ${JSON.stringify(results.map((n61) => ({ id: n61.id, label: n61.label, propertie
83131
83418
  await this.createEdge(sourceId, targetId, rel.type);
83132
83419
  edgesCreated++;
83133
83420
  }
83134
- if (relationships.designPatterns.length > 0) {
83135
- await this.memory.set(
83136
- `${this.config.namespace}:patterns:${fileNodeId}`,
83137
- relationships.designPatterns,
83138
- { namespace: this.config.namespace }
83139
- );
83140
- }
83141
- if (relationships.architecturalBoundaries.length > 0) {
83142
- await this.memory.set(
83143
- `${this.config.namespace}:boundaries:${fileNodeId}`,
83144
- relationships.architecturalBoundaries,
83145
- { namespace: this.config.namespace }
83146
- );
83147
- }
83148
- if (relationships.dependencyImpacts.length > 0) {
83149
- await this.memory.set(
83150
- `${this.config.namespace}:impacts:${fileNodeId}`,
83151
- relationships.dependencyImpacts,
83152
- { namespace: this.config.namespace }
83153
- );
83421
+ const node = this.nodeCache.get(fileNodeId);
83422
+ if (node) {
83423
+ if (relationships.designPatterns.length > 0) {
83424
+ node.properties.designPatterns = relationships.designPatterns;
83425
+ }
83426
+ if (relationships.architecturalBoundaries.length > 0) {
83427
+ node.properties.architecturalBoundaries = relationships.architecturalBoundaries;
83428
+ }
83429
+ if (relationships.dependencyImpacts.length > 0) {
83430
+ node.properties.dependencyImpacts = relationships.dependencyImpacts;
83431
+ }
83432
+ this.nodeCache.set(fileNodeId, node);
83154
83433
  }
83155
83434
  return edgesCreated;
83156
83435
  }
@@ -83200,9 +83479,6 @@ ${JSON.stringify(results.map((n61) => ({ id: n61.id, label: n61.label, propertie
83200
83479
  target: targetId,
83201
83480
  type
83202
83481
  };
83203
- await this.memory.set(`${this.config.namespace}:edge:${edgeId}`, edge, {
83204
- namespace: this.config.namespace
83205
- });
83206
83482
  const sourceEdges = this.edgeIndex.get(sourceId) || [];
83207
83483
  sourceEdges.push(edge);
83208
83484
  this.edgeIndex.set(sourceId, sourceEdges);
@@ -83214,12 +83490,8 @@ ${JSON.stringify(results.map((n61) => ({ id: n61.id, label: n61.label, propertie
83214
83490
  if (firstKey) {
83215
83491
  this.nodeCache.delete(firstKey);
83216
83492
  this.edgeIndex.delete(firstKey);
83217
- await this.memory.delete(`${this.config.namespace}:node:${firstKey}`);
83218
83493
  }
83219
83494
  }
83220
- await this.memory.set(`${this.config.namespace}:node:${node.id}`, node, {
83221
- namespace: this.config.namespace
83222
- });
83223
83495
  this.nodeCache.set(node.id, node);
83224
83496
  }
83225
83497
  async extractEntities(filePath) {
@@ -83610,11 +83882,7 @@ ${JSON.stringify(results.map((n61) => ({ id: n61.id, label: n61.label, propertie
83610
83882
  return true;
83611
83883
  });
83612
83884
  }
83613
- async storeIndexMetadata(metadata) {
83614
- await this.memory.set(`${this.config.namespace}:metadata:index`, metadata, {
83615
- namespace: this.config.namespace,
83616
- persist: true
83617
- });
83885
+ async storeIndexMetadata(_metadata) {
83618
83886
  }
83619
83887
  async generateEmbedding(entity) {
83620
83888
  const text2 = `${entity.type} ${entity.name} ${entity.visibility}${entity.isAsync ? " async" : ""}`;
@@ -86713,9 +86981,11 @@ var CodeIntelligenceCoordinator = class {
86713
86981
  async initializeHypergraph() {
86714
86982
  try {
86715
86983
  const Database = (await Promise.resolve().then(() => (init_better_sqlite3(), better_sqlite3_exports))).default;
86716
- const dbPath = this.config.hypergraphDbPath || ".agentic-qe/hypergraph.db";
86717
86984
  const fs19 = await import("fs");
86718
86985
  const path21 = await import("path");
86986
+ const { findProjectRoot: findProjectRoot2 } = await Promise.resolve().then(() => (init_unified_memory(), unified_memory_exports));
86987
+ const projectRoot = findProjectRoot2();
86988
+ const dbPath = this.config.hypergraphDbPath || path21.join(projectRoot, ".agentic-qe", "hypergraph.db");
86719
86989
  const dir = path21.dirname(dbPath);
86720
86990
  if (!fs19.existsSync(dir)) {
86721
86991
  fs19.mkdirSync(dir, { recursive: true });
@@ -89345,17 +89615,22 @@ var SASTScanner = class {
89345
89615
  * Store scan results in memory
89346
89616
  */
89347
89617
  async storeScanResults(scanId, scanType, vulnerabilities, summary) {
89618
+ const scanSummary = {
89619
+ scanId,
89620
+ scanType,
89621
+ summary,
89622
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
89623
+ vulnerabilityCount: vulnerabilities.length,
89624
+ // Keep only critical/high vulnerabilities in stored result
89625
+ criticalVulnerabilities: vulnerabilities.filter(
89626
+ (v62) => v62.severity === "critical" || v62.severity === "high"
89627
+ )
89628
+ };
89348
89629
  await this.memory.set(
89349
89630
  `security:scan:${scanId}`,
89350
- {
89351
- scanId,
89352
- scanType,
89353
- vulnerabilities,
89354
- summary,
89355
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
89356
- },
89357
- { namespace: "security-compliance", ttl: 86400 * 7 }
89358
- // 7 days
89631
+ scanSummary,
89632
+ { namespace: "security-compliance", ttl: 86400 * 2 }
89633
+ // 2 days (reduced from 7)
89359
89634
  );
89360
89635
  }
89361
89636
  // ==========================================================================
@@ -119135,8 +119410,34 @@ var MinCutPersistence = class {
119135
119410
  JSON.stringify(snapshot.vertices),
119136
119411
  JSON.stringify(snapshot.edges)
119137
119412
  );
119413
+ await this.enforceRetention();
119138
119414
  return id;
119139
119415
  }
119416
+ /**
119417
+ * Enforce retention limits on snapshots and history to prevent DB bloat (Issue #258)
119418
+ */
119419
+ async enforceRetention(maxSnapshots = 200) {
119420
+ const db = this.memory.getDatabase();
119421
+ if (!db) return 0;
119422
+ const countRow = db.prepare("SELECT COUNT(*) as count FROM mincut_snapshots").get();
119423
+ if (!countRow || countRow.count <= maxSnapshots) return 0;
119424
+ const deleteCount = countRow.count - maxSnapshots;
119425
+ db.prepare(`
119426
+ DELETE FROM mincut_snapshots WHERE id IN (
119427
+ SELECT id FROM mincut_snapshots ORDER BY created_at ASC LIMIT ?
119428
+ )
119429
+ `).run(deleteCount);
119430
+ const historyCount = db.prepare("SELECT COUNT(*) as count FROM mincut_history").get();
119431
+ if (historyCount.count > 500) {
119432
+ const historyDelete = historyCount.count - 500;
119433
+ db.prepare(`
119434
+ DELETE FROM mincut_history WHERE id IN (
119435
+ SELECT id FROM mincut_history ORDER BY created_at ASC LIMIT ?
119436
+ )
119437
+ `).run(historyDelete);
119438
+ }
119439
+ return deleteCount;
119440
+ }
119140
119441
  /**
119141
119442
  * Get a snapshot by ID
119142
119443
  */
@@ -125120,7 +125421,8 @@ var DEFAULT_DYNAMIC_SCALING_CONFIG = {
125120
125421
 
125121
125422
  // src/coordination/dynamic-scaling/dynamic-scaler.ts
125122
125423
  import { randomUUID as randomUUID5 } from "node:crypto";
125123
- var DynamicScaler = class {
125424
+ init_unified_memory();
125425
+ var DynamicScaler = class _DynamicScaler {
125124
125426
  config;
125125
125427
  policy;
125126
125428
  metricsHistory = [];
@@ -125131,6 +125433,13 @@ var DynamicScaler = class {
125131
125433
  totalDecisions = 0;
125132
125434
  currentAgents;
125133
125435
  lastDecision;
125436
+ // KV store persistence (Tier 2)
125437
+ db = null;
125438
+ persistCount = 0;
125439
+ static KV_NAMESPACE = "scaling-metrics";
125440
+ static KV_KEY = "dynamic-scaler-snapshot";
125441
+ static PERSIST_INTERVAL = 10;
125442
+ static KV_TTL = 7200;
125134
125443
  /**
125135
125444
  * Create a new DynamicScaler.
125136
125445
  *
@@ -125156,6 +125465,11 @@ var DynamicScaler = class {
125156
125465
  if (this.metricsHistory.length > this.config.metricsHistorySize) {
125157
125466
  this.metricsHistory.shift();
125158
125467
  }
125468
+ this.persistCount++;
125469
+ if (this.persistCount % _DynamicScaler.PERSIST_INTERVAL === 0) {
125470
+ this.persistSnapshot().catch(() => {
125471
+ });
125472
+ }
125159
125473
  }
125160
125474
  // --------------------------------------------------------------------------
125161
125475
  // Evaluation
@@ -125353,6 +125667,23 @@ var DynamicScaler = class {
125353
125667
  // --------------------------------------------------------------------------
125354
125668
  // Lifecycle
125355
125669
  // --------------------------------------------------------------------------
125670
+ /**
125671
+ * Initialize persistence layer and load last snapshot from KV store.
125672
+ * Safe to call multiple times; will not throw on DB failure.
125673
+ */
125674
+ async initialize() {
125675
+ try {
125676
+ this.db = getUnifiedMemory();
125677
+ if (!this.db.isInitialized()) await this.db.initialize();
125678
+ await this.loadFromKv();
125679
+ } catch (error) {
125680
+ console.warn(
125681
+ "[DynamicScaler] DB init failed, using memory-only:",
125682
+ error instanceof Error ? error.message : String(error)
125683
+ );
125684
+ this.db = null;
125685
+ }
125686
+ }
125356
125687
  /**
125357
125688
  * Release internal buffers. The scaler should not be used after disposal.
125358
125689
  */
@@ -125393,12 +125724,68 @@ var DynamicScaler = class {
125393
125724
  }
125394
125725
  /**
125395
125726
  * Record a scaling event, evicting the oldest when the history cap is hit.
125727
+ * Triggers periodic persistence to KV store.
125396
125728
  */
125397
125729
  recordEvent(event) {
125398
125730
  this.events.push(event);
125399
125731
  if (this.events.length > this.config.decisionHistorySize) {
125400
125732
  this.events.shift();
125401
125733
  }
125734
+ this.persistCount++;
125735
+ if (this.persistCount % _DynamicScaler.PERSIST_INTERVAL === 0) {
125736
+ this.persistSnapshot().catch(() => {
125737
+ });
125738
+ }
125739
+ }
125740
+ /**
125741
+ * Load last persisted snapshot from KV store into in-memory state.
125742
+ */
125743
+ async loadFromKv() {
125744
+ if (!this.db) return;
125745
+ try {
125746
+ const snapshot = await this.db.kvGet(_DynamicScaler.KV_KEY, _DynamicScaler.KV_NAMESPACE);
125747
+ if (snapshot) {
125748
+ if (Array.isArray(snapshot.metricsHistory)) {
125749
+ for (const m74 of snapshot.metricsHistory) {
125750
+ this.metricsHistory.push(m74);
125751
+ }
125752
+ }
125753
+ if (Array.isArray(snapshot.events)) {
125754
+ for (const e20 of snapshot.events) {
125755
+ this.events.push(e20);
125756
+ }
125757
+ }
125758
+ }
125759
+ } catch (error) {
125760
+ console.warn(
125761
+ "[DynamicScaler] Failed to load KV snapshot:",
125762
+ error instanceof Error ? error.message : String(error)
125763
+ );
125764
+ }
125765
+ }
125766
+ /**
125767
+ * Persist a trimmed snapshot of metricsHistory and events to KV store.
125768
+ * Keeps only the last 50 entries of each to limit storage size.
125769
+ */
125770
+ async persistSnapshot() {
125771
+ if (!this.db) return;
125772
+ try {
125773
+ const snapshot = {
125774
+ metricsHistory: this.metricsHistory.slice(-50),
125775
+ events: this.events.slice(-50)
125776
+ };
125777
+ await this.db.kvSet(
125778
+ _DynamicScaler.KV_KEY,
125779
+ snapshot,
125780
+ _DynamicScaler.KV_NAMESPACE,
125781
+ _DynamicScaler.KV_TTL
125782
+ );
125783
+ } catch (error) {
125784
+ console.warn(
125785
+ "[DynamicScaler] Failed to persist KV snapshot:",
125786
+ error instanceof Error ? error.message : String(error)
125787
+ );
125788
+ }
125402
125789
  }
125403
125790
  };
125404
125791
  function createDynamicScaler(initialAgents, config) {
@@ -135671,6 +136058,7 @@ var EarlyExitTokenOptimizer = class {
135671
136058
  init_pattern_store();
135672
136059
 
135673
136060
  // src/learning/token-tracker.ts
136061
+ init_unified_memory();
135674
136062
  import { randomUUID as randomUUID7 } from "crypto";
135675
136063
  var DEFAULT_COST_CONFIG = {
135676
136064
  costPerInputToken: 3e-3 / 1e3,
@@ -135684,7 +136072,7 @@ var DEFAULT_PERSISTENCE_CONFIG2 = {
135684
136072
  // Auto-save every minute
135685
136073
  maxMetricsInMemory: 1e4
135686
136074
  };
135687
- var TokenMetricsCollectorImpl = class {
136075
+ var TokenMetricsCollectorImpl = class _TokenMetricsCollectorImpl {
135688
136076
  taskMetrics = [];
135689
136077
  agentMetrics = /* @__PURE__ */ new Map();
135690
136078
  domainMetrics = /* @__PURE__ */ new Map();
@@ -135700,6 +136088,15 @@ var TokenMetricsCollectorImpl = class {
135700
136088
  persistenceConfig = DEFAULT_PERSISTENCE_CONFIG2;
135701
136089
  autoSaveTimer = null;
135702
136090
  isDirty = false;
136091
+ // kv_store persistence
136092
+ db = null;
136093
+ kvPersistCount = 0;
136094
+ static KV_NAMESPACE = "token-usage-metrics";
136095
+ static KV_KEY = "token-tracker-snapshot";
136096
+ static KV_TTL = 604800;
136097
+ // 7 days
136098
+ static KV_PERSIST_INTERVAL = 10;
136099
+ // every 10 operations
135703
136100
  constructor() {
135704
136101
  this.sessionId = `session-${Date.now()}-${randomUUID7().substring(0, 8)}`;
135705
136102
  this.sessionStartTime = Date.now();
@@ -136114,6 +136511,88 @@ var TokenMetricsCollectorImpl = class {
136114
136511
  return this.isDirty;
136115
136512
  }
136116
136513
  // ============================================================================
136514
+ // kv_store Persistence
136515
+ // ============================================================================
136516
+ /**
136517
+ * Initialize kv_store persistence and restore snapshot if available.
136518
+ * This supplements the existing file-based persistence.
136519
+ */
136520
+ async initializeDb() {
136521
+ try {
136522
+ this.db = getUnifiedMemory();
136523
+ if (!this.db.isInitialized()) await this.db.initialize();
136524
+ await this.loadFromKv();
136525
+ } catch (error) {
136526
+ console.warn("[TokenMetricsCollector] DB init failed, using memory-only:", error instanceof Error ? error.message : String(error));
136527
+ this.db = null;
136528
+ }
136529
+ }
136530
+ /**
136531
+ * Persist current state snapshot to kv_store
136532
+ */
136533
+ async persistToKv() {
136534
+ if (!this.db) return;
136535
+ const snapshot = {
136536
+ version: "1.0.0",
136537
+ sessionId: this.sessionId,
136538
+ sessionStartTime: this.sessionStartTime,
136539
+ taskMetrics: this.taskMetrics.slice(-this.persistenceConfig.maxMetricsInMemory),
136540
+ optimizationStats: {
136541
+ cacheHits: this.cacheHits,
136542
+ earlyExits: this.earlyExits,
136543
+ totalTokensSaved: this.totalTokensSaved,
136544
+ totalPatternsReused: this.totalPatternsReused
136545
+ },
136546
+ lastSavedAt: Date.now()
136547
+ };
136548
+ await this.db.kvSet(
136549
+ _TokenMetricsCollectorImpl.KV_KEY,
136550
+ snapshot,
136551
+ _TokenMetricsCollectorImpl.KV_NAMESPACE,
136552
+ _TokenMetricsCollectorImpl.KV_TTL
136553
+ );
136554
+ }
136555
+ /**
136556
+ * Load state snapshot from kv_store
136557
+ */
136558
+ async loadFromKv() {
136559
+ if (!this.db) return false;
136560
+ const snapshot = await this.db.kvGet(
136561
+ _TokenMetricsCollectorImpl.KV_KEY,
136562
+ _TokenMetricsCollectorImpl.KV_NAMESPACE
136563
+ );
136564
+ if (!snapshot) return false;
136565
+ if (!snapshot.version || !snapshot.version.startsWith("1.")) {
136566
+ console.warn("[TokenMetricsCollector] Incompatible kv_store data version, skipping load");
136567
+ return false;
136568
+ }
136569
+ const historicalMetrics = snapshot.taskMetrics || [];
136570
+ this.taskMetrics = [...historicalMetrics, ...this.taskMetrics];
136571
+ this.cacheHits += snapshot.optimizationStats?.cacheHits || 0;
136572
+ this.earlyExits += snapshot.optimizationStats?.earlyExits || 0;
136573
+ this.totalTokensSaved += snapshot.optimizationStats?.totalTokensSaved || 0;
136574
+ this.totalPatternsReused += snapshot.optimizationStats?.totalPatternsReused || 0;
136575
+ for (const metric of historicalMetrics) {
136576
+ this.updateAgentMetrics(metric.agentId, metric.usage, metric.patternReused, metric.tokensSaved || 0);
136577
+ this.updateDomainMetrics(metric.domain, metric.usage);
136578
+ }
136579
+ if (this.taskMetrics.length > this.persistenceConfig.maxMetricsInMemory) {
136580
+ this.taskMetrics = this.taskMetrics.slice(-this.persistenceConfig.maxMetricsInMemory);
136581
+ }
136582
+ return true;
136583
+ }
136584
+ /**
136585
+ * Track state changes and persist to kv_store periodically
136586
+ */
136587
+ maybePersistToKv() {
136588
+ this.kvPersistCount++;
136589
+ if (this.kvPersistCount >= _TokenMetricsCollectorImpl.KV_PERSIST_INTERVAL) {
136590
+ this.kvPersistCount = 0;
136591
+ this.persistToKv().catch(() => {
136592
+ });
136593
+ }
136594
+ }
136595
+ // ============================================================================
136117
136596
  // Private Helper Methods
136118
136597
  // ============================================================================
136119
136598
  ensureInitialized() {
@@ -145484,6 +145963,9 @@ var GOAPStatusTool = class extends MCPToolBase {
145484
145963
  }
145485
145964
  };
145486
145965
 
145966
+ // src/coordination/mincut/time-crystal.ts
145967
+ init_unified_memory();
145968
+
145487
145969
  // src/mcp/tools/mincut/index.ts
145488
145970
  var MINCUT_TOOL_NAMES = {
145489
145971
  HEALTH: "qe/mincut/health",
@@ -151844,24 +152326,49 @@ async function doInitialize() {
151844
152326
  await memoryManager.initialize();
151845
152327
  const db = memoryManager.getDatabase();
151846
152328
  if (db) {
152329
+ let needsCreate = false;
152330
+ const tableExists = db.prepare(
152331
+ "SELECT COUNT(*) as cnt FROM sqlite_master WHERE type='table' AND name='captured_experiences'"
152332
+ ).get().cnt > 0;
152333
+ if (tableExists) {
152334
+ const columns = db.prepare("PRAGMA table_info(captured_experiences)").all();
152335
+ const colNames = new Set(columns.map((c70) => c70.name));
152336
+ if (!colNames.has("success") || !colNames.has("task")) {
152337
+ db.exec("ALTER TABLE captured_experiences RENAME TO captured_experiences_v2_backup");
152338
+ needsCreate = true;
152339
+ } else {
152340
+ if (!colNames.has("domain")) {
152341
+ db.exec("ALTER TABLE captured_experiences ADD COLUMN domain TEXT NOT NULL DEFAULT ''");
152342
+ }
152343
+ if (!colNames.has("source")) {
152344
+ db.exec("ALTER TABLE captured_experiences ADD COLUMN source TEXT DEFAULT 'middleware'");
152345
+ }
152346
+ }
152347
+ } else {
152348
+ needsCreate = true;
152349
+ }
152350
+ if (needsCreate) {
152351
+ db.exec(`
152352
+ CREATE TABLE IF NOT EXISTS captured_experiences (
152353
+ id TEXT PRIMARY KEY,
152354
+ task TEXT NOT NULL,
152355
+ agent TEXT NOT NULL,
152356
+ domain TEXT NOT NULL DEFAULT '',
152357
+ success INTEGER NOT NULL DEFAULT 0,
152358
+ quality REAL NOT NULL DEFAULT 0.5,
152359
+ duration_ms INTEGER NOT NULL DEFAULT 0,
152360
+ model_tier INTEGER,
152361
+ routing_json TEXT,
152362
+ steps_json TEXT,
152363
+ result_json TEXT,
152364
+ error TEXT,
152365
+ started_at TEXT NOT NULL DEFAULT (datetime('now')),
152366
+ completed_at TEXT NOT NULL DEFAULT (datetime('now')),
152367
+ source TEXT DEFAULT 'middleware'
152368
+ );
152369
+ `);
152370
+ }
151847
152371
  db.exec(`
151848
- CREATE TABLE IF NOT EXISTS captured_experiences (
151849
- id TEXT PRIMARY KEY,
151850
- task TEXT NOT NULL,
151851
- agent TEXT NOT NULL,
151852
- domain TEXT NOT NULL,
151853
- success INTEGER NOT NULL DEFAULT 0,
151854
- quality REAL NOT NULL DEFAULT 0.5,
151855
- duration_ms INTEGER NOT NULL DEFAULT 0,
151856
- model_tier INTEGER,
151857
- routing_json TEXT,
151858
- steps_json TEXT,
151859
- result_json TEXT,
151860
- error TEXT,
151861
- started_at TEXT NOT NULL,
151862
- completed_at TEXT NOT NULL DEFAULT (datetime('now')),
151863
- source TEXT DEFAULT 'middleware'
151864
- );
151865
152372
  CREATE INDEX IF NOT EXISTS idx_captured_exp_domain ON captured_experiences(domain);
151866
152373
  CREATE INDEX IF NOT EXISTS idx_captured_exp_success ON captured_experiences(success);
151867
152374
  CREATE INDEX IF NOT EXISTS idx_captured_exp_agent ON captured_experiences(agent);