agentic-qe 3.6.6 → 3.6.8

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 (147) hide show
  1. package/.claude/skills/skills-manifest.json +1 -1
  2. package/package.json +3 -1
  3. package/scripts/benchmark-aqe-baseline.ts +614 -0
  4. package/v3/CHANGELOG.md +41 -0
  5. package/v3/dist/cli/bundle.js +970 -350
  6. package/v3/dist/cli/commands/hooks.d.ts.map +1 -1
  7. package/v3/dist/cli/commands/hooks.js +172 -31
  8. package/v3/dist/cli/commands/hooks.js.map +1 -1
  9. package/v3/dist/coordination/dynamic-scaling/dynamic-scaler.d.ts +21 -0
  10. package/v3/dist/coordination/dynamic-scaling/dynamic-scaler.d.ts.map +1 -1
  11. package/v3/dist/coordination/dynamic-scaling/dynamic-scaler.js +76 -0
  12. package/v3/dist/coordination/dynamic-scaling/dynamic-scaler.js.map +1 -1
  13. package/v3/dist/coordination/mincut/mincut-persistence.d.ts +4 -0
  14. package/v3/dist/coordination/mincut/mincut-persistence.d.ts.map +1 -1
  15. package/v3/dist/coordination/mincut/mincut-persistence.js +30 -0
  16. package/v3/dist/coordination/mincut/mincut-persistence.js.map +1 -1
  17. package/v3/dist/coordination/mincut/queen-integration.d.ts.map +1 -1
  18. package/v3/dist/coordination/mincut/queen-integration.js +7 -2
  19. package/v3/dist/coordination/mincut/queen-integration.js.map +1 -1
  20. package/v3/dist/coordination/mincut/time-crystal.d.ts +22 -0
  21. package/v3/dist/coordination/mincut/time-crystal.d.ts.map +1 -1
  22. package/v3/dist/coordination/mincut/time-crystal.js +95 -0
  23. package/v3/dist/coordination/mincut/time-crystal.js.map +1 -1
  24. package/v3/dist/domains/code-intelligence/coordinator.d.ts.map +1 -1
  25. package/v3/dist/domains/code-intelligence/coordinator.js +6 -3
  26. package/v3/dist/domains/code-intelligence/coordinator.js.map +1 -1
  27. package/v3/dist/domains/code-intelligence/services/knowledge-graph.d.ts.map +1 -1
  28. package/v3/dist/domains/code-intelligence/services/knowledge-graph.js +19 -34
  29. package/v3/dist/domains/code-intelligence/services/knowledge-graph.js.map +1 -1
  30. package/v3/dist/domains/coverage-analysis/services/hnsw-index.d.ts.map +1 -1
  31. package/v3/dist/domains/coverage-analysis/services/hnsw-index.js +5 -3
  32. package/v3/dist/domains/coverage-analysis/services/hnsw-index.js.map +1 -1
  33. package/v3/dist/domains/security-compliance/services/scanners/sast-scanner.d.ts.map +1 -1
  34. package/v3/dist/domains/security-compliance/services/scanners/sast-scanner.js +7 -3
  35. package/v3/dist/domains/security-compliance/services/scanners/sast-scanner.js.map +1 -1
  36. package/v3/dist/early-exit/early-exit-controller.d.ts +20 -0
  37. package/v3/dist/early-exit/early-exit-controller.d.ts.map +1 -1
  38. package/v3/dist/early-exit/early-exit-controller.js +72 -0
  39. package/v3/dist/early-exit/early-exit-controller.js.map +1 -1
  40. package/v3/dist/feedback/coverage-learner.d.ts +19 -0
  41. package/v3/dist/feedback/coverage-learner.d.ts.map +1 -1
  42. package/v3/dist/feedback/coverage-learner.js +134 -0
  43. package/v3/dist/feedback/coverage-learner.js.map +1 -1
  44. package/v3/dist/feedback/feedback-loop.d.ts +10 -1
  45. package/v3/dist/feedback/feedback-loop.d.ts.map +1 -1
  46. package/v3/dist/feedback/feedback-loop.js +20 -1
  47. package/v3/dist/feedback/feedback-loop.js.map +1 -1
  48. package/v3/dist/feedback/index.d.ts +1 -1
  49. package/v3/dist/feedback/index.d.ts.map +1 -1
  50. package/v3/dist/feedback/index.js +1 -1
  51. package/v3/dist/feedback/index.js.map +1 -1
  52. package/v3/dist/feedback/test-outcome-tracker.d.ts +19 -0
  53. package/v3/dist/feedback/test-outcome-tracker.d.ts.map +1 -1
  54. package/v3/dist/feedback/test-outcome-tracker.js +114 -0
  55. package/v3/dist/feedback/test-outcome-tracker.js.map +1 -1
  56. package/v3/dist/governance/compliance-reporter.d.ts +13 -0
  57. package/v3/dist/governance/compliance-reporter.d.ts.map +1 -1
  58. package/v3/dist/governance/compliance-reporter.js +63 -0
  59. package/v3/dist/governance/compliance-reporter.js.map +1 -1
  60. package/v3/dist/governance/continue-gate-integration.d.ts +8 -0
  61. package/v3/dist/governance/continue-gate-integration.d.ts.map +1 -1
  62. package/v3/dist/governance/continue-gate-integration.js +50 -2
  63. package/v3/dist/governance/continue-gate-integration.js.map +1 -1
  64. package/v3/dist/governance/evolution-pipeline-integration.d.ts +13 -0
  65. package/v3/dist/governance/evolution-pipeline-integration.d.ts.map +1 -1
  66. package/v3/dist/governance/evolution-pipeline-integration.js +53 -0
  67. package/v3/dist/governance/evolution-pipeline-integration.js.map +1 -1
  68. package/v3/dist/index.d.ts +1 -1
  69. package/v3/dist/index.d.ts.map +1 -1
  70. package/v3/dist/index.js +1 -1
  71. package/v3/dist/index.js.map +1 -1
  72. package/v3/dist/init/migration/data-migrator.d.ts.map +1 -1
  73. package/v3/dist/init/migration/data-migrator.js +5 -6
  74. package/v3/dist/init/migration/data-migrator.js.map +1 -1
  75. package/v3/dist/init/phases/07-hooks.d.ts.map +1 -1
  76. package/v3/dist/init/phases/07-hooks.js +26 -5
  77. package/v3/dist/init/phases/07-hooks.js.map +1 -1
  78. package/v3/dist/integrations/agentic-flow/reasoning-bank/experience-replay.d.ts +4 -2
  79. package/v3/dist/integrations/agentic-flow/reasoning-bank/experience-replay.d.ts.map +1 -1
  80. package/v3/dist/integrations/agentic-flow/reasoning-bank/experience-replay.js +68 -42
  81. package/v3/dist/integrations/agentic-flow/reasoning-bank/experience-replay.js.map +1 -1
  82. package/v3/dist/integrations/ruvector/ast-complexity.d.ts +8 -0
  83. package/v3/dist/integrations/ruvector/ast-complexity.d.ts.map +1 -1
  84. package/v3/dist/integrations/ruvector/ast-complexity.js +45 -0
  85. package/v3/dist/integrations/ruvector/ast-complexity.js.map +1 -1
  86. package/v3/dist/integrations/ruvector/attention-wrapper.d.ts +18 -1
  87. package/v3/dist/integrations/ruvector/attention-wrapper.d.ts.map +1 -1
  88. package/v3/dist/integrations/ruvector/attention-wrapper.js +60 -2
  89. package/v3/dist/integrations/ruvector/attention-wrapper.js.map +1 -1
  90. package/v3/dist/integrations/ruvector/coverage-router.d.ts +8 -0
  91. package/v3/dist/integrations/ruvector/coverage-router.d.ts.map +1 -1
  92. package/v3/dist/integrations/ruvector/coverage-router.js +45 -0
  93. package/v3/dist/integrations/ruvector/coverage-router.js.map +1 -1
  94. package/v3/dist/integrations/ruvector/diff-risk-classifier.d.ts +8 -0
  95. package/v3/dist/integrations/ruvector/diff-risk-classifier.d.ts.map +1 -1
  96. package/v3/dist/integrations/ruvector/diff-risk-classifier.js +45 -0
  97. package/v3/dist/integrations/ruvector/diff-risk-classifier.js.map +1 -1
  98. package/v3/dist/integrations/ruvector/graph-boundaries.d.ts +8 -0
  99. package/v3/dist/integrations/ruvector/graph-boundaries.d.ts.map +1 -1
  100. package/v3/dist/integrations/ruvector/graph-boundaries.js +45 -0
  101. package/v3/dist/integrations/ruvector/graph-boundaries.js.map +1 -1
  102. package/v3/dist/integrations/ruvector/index.d.ts.map +1 -1
  103. package/v3/dist/integrations/ruvector/index.js +5 -20
  104. package/v3/dist/integrations/ruvector/index.js.map +1 -1
  105. package/v3/dist/integrations/ruvector/persistent-q-router.d.ts +7 -3
  106. package/v3/dist/integrations/ruvector/persistent-q-router.d.ts.map +1 -1
  107. package/v3/dist/integrations/ruvector/persistent-q-router.js +7 -3
  108. package/v3/dist/integrations/ruvector/persistent-q-router.js.map +1 -1
  109. package/v3/dist/integrations/ruvector/q-learning-router.d.ts +13 -0
  110. package/v3/dist/integrations/ruvector/q-learning-router.d.ts.map +1 -1
  111. package/v3/dist/integrations/ruvector/q-learning-router.js +67 -0
  112. package/v3/dist/integrations/ruvector/q-learning-router.js.map +1 -1
  113. package/v3/dist/kernel/hybrid-backend.d.ts +1 -0
  114. package/v3/dist/kernel/hybrid-backend.d.ts.map +1 -1
  115. package/v3/dist/kernel/hybrid-backend.js +39 -0
  116. package/v3/dist/kernel/hybrid-backend.js.map +1 -1
  117. package/v3/dist/kernel/kernel.d.ts.map +1 -1
  118. package/v3/dist/kernel/kernel.js +8 -0
  119. package/v3/dist/kernel/kernel.js.map +1 -1
  120. package/v3/dist/kernel/unified-memory.d.ts +1 -0
  121. package/v3/dist/kernel/unified-memory.d.ts.map +1 -1
  122. package/v3/dist/kernel/unified-memory.js +123 -4
  123. package/v3/dist/kernel/unified-memory.js.map +1 -1
  124. package/v3/dist/learning/experience-capture-middleware.d.ts.map +1 -1
  125. package/v3/dist/learning/experience-capture-middleware.js +45 -18
  126. package/v3/dist/learning/experience-capture-middleware.js.map +1 -1
  127. package/v3/dist/learning/pattern-store.d.ts.map +1 -1
  128. package/v3/dist/learning/pattern-store.js +12 -61
  129. package/v3/dist/learning/pattern-store.js.map +1 -1
  130. package/v3/dist/learning/qe-reasoning-bank.d.ts.map +1 -1
  131. package/v3/dist/learning/qe-reasoning-bank.js +15 -2
  132. package/v3/dist/learning/qe-reasoning-bank.js.map +1 -1
  133. package/v3/dist/learning/token-tracker.d.ts +23 -0
  134. package/v3/dist/learning/token-tracker.d.ts.map +1 -1
  135. package/v3/dist/learning/token-tracker.js +91 -0
  136. package/v3/dist/learning/token-tracker.js.map +1 -1
  137. package/v3/dist/mcp/bundle.js +945 -375
  138. package/v3/dist/mcp/entry.js +21 -1
  139. package/v3/dist/mcp/entry.js.map +1 -1
  140. package/v3/dist/routing/routing-feedback.d.ts +21 -0
  141. package/v3/dist/routing/routing-feedback.d.ts.map +1 -1
  142. package/v3/dist/routing/routing-feedback.js +95 -0
  143. package/v3/dist/routing/routing-feedback.js.map +1 -1
  144. package/v3/dist/shared/sql-safety.d.ts.map +1 -1
  145. package/v3/dist/shared/sql-safety.js +2 -0
  146. package/v3/dist/shared/sql-safety.js.map +1 -1
  147. package/v3/package.json +1 -1
@@ -595,6 +595,10 @@ var init_sql_safety = __esm({
595
595
  "mincut_observations",
596
596
  // SONA tables
597
597
  "sona_patterns",
598
+ // Feedback loop tables
599
+ "test_outcomes",
600
+ "routing_outcomes",
601
+ "coverage_sessions",
598
602
  // Sync tables
599
603
  "patterns",
600
604
  // Hypergraph tables
@@ -1539,12 +1543,16 @@ function findProjectRoot(startDir = process.cwd()) {
1539
1543
  let dir = startDir;
1540
1544
  const root = path.parse(dir).root;
1541
1545
  let checkDir = dir;
1546
+ let topmostAqeDir = null;
1542
1547
  while (checkDir !== root) {
1543
1548
  if (fs.existsSync(path.join(checkDir, ".agentic-qe"))) {
1544
- return checkDir;
1549
+ topmostAqeDir = checkDir;
1545
1550
  }
1546
1551
  checkDir = path.dirname(checkDir);
1547
1552
  }
1553
+ if (topmostAqeDir) {
1554
+ return topmostAqeDir;
1555
+ }
1548
1556
  checkDir = dir;
1549
1557
  while (checkDir !== root) {
1550
1558
  if (fs.existsSync(path.join(checkDir, ".git"))) {
@@ -1609,7 +1617,7 @@ function registerExitHandlers() {
1609
1617
  process.exit(0);
1610
1618
  });
1611
1619
  }
1612
- 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;
1620
+ 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;
1613
1621
  var init_unified_memory = __esm({
1614
1622
  "src/kernel/unified-memory.ts"() {
1615
1623
  "use strict";
@@ -1629,7 +1637,7 @@ var init_unified_memory = __esm({
1629
1637
  busyTimeout: MEMORY_CONSTANTS.BUSY_TIMEOUT_MS,
1630
1638
  vectorDimensions: MEMORY_CONSTANTS.DEFAULT_VECTOR_DIMENSIONS
1631
1639
  };
1632
- SCHEMA_VERSION = 7;
1640
+ SCHEMA_VERSION = 8;
1633
1641
  SCHEMA_VERSION_TABLE = `
1634
1642
  CREATE TABLE IF NOT EXISTS schema_version (
1635
1643
  id INTEGER PRIMARY KEY CHECK (id = 1),
@@ -2100,6 +2108,81 @@ var init_unified_memory = __esm({
2100
2108
  CREATE INDEX IF NOT EXISTS idx_sona_patterns_domain ON sona_patterns(domain);
2101
2109
  CREATE INDEX IF NOT EXISTS idx_sona_patterns_confidence ON sona_patterns(confidence DESC);
2102
2110
  CREATE INDEX IF NOT EXISTS idx_sona_patterns_updated ON sona_patterns(updated_at DESC);
2111
+ `;
2112
+ FEEDBACK_SCHEMA = `
2113
+ -- Test outcomes (ADR-023: Quality Feedback Loop)
2114
+ CREATE TABLE IF NOT EXISTS test_outcomes (
2115
+ id TEXT PRIMARY KEY,
2116
+ test_id TEXT NOT NULL,
2117
+ test_name TEXT NOT NULL,
2118
+ generated_by TEXT NOT NULL,
2119
+ pattern_id TEXT,
2120
+ framework TEXT NOT NULL,
2121
+ language TEXT NOT NULL,
2122
+ domain TEXT NOT NULL,
2123
+ passed INTEGER NOT NULL,
2124
+ error_message TEXT,
2125
+ coverage_lines REAL DEFAULT 0,
2126
+ coverage_branches REAL DEFAULT 0,
2127
+ coverage_functions REAL DEFAULT 0,
2128
+ mutation_score REAL,
2129
+ execution_time_ms REAL NOT NULL,
2130
+ flaky INTEGER DEFAULT 0,
2131
+ flakiness_score REAL,
2132
+ maintainability_score REAL NOT NULL,
2133
+ complexity REAL,
2134
+ lines_of_code INTEGER,
2135
+ assertion_count INTEGER,
2136
+ file_path TEXT,
2137
+ source_file_path TEXT,
2138
+ metadata_json TEXT,
2139
+ created_at TEXT DEFAULT (datetime('now'))
2140
+ );
2141
+ CREATE INDEX IF NOT EXISTS idx_test_outcomes_pattern ON test_outcomes(pattern_id);
2142
+ CREATE INDEX IF NOT EXISTS idx_test_outcomes_agent ON test_outcomes(generated_by);
2143
+ CREATE INDEX IF NOT EXISTS idx_test_outcomes_domain ON test_outcomes(domain);
2144
+ CREATE INDEX IF NOT EXISTS idx_test_outcomes_created ON test_outcomes(created_at);
2145
+
2146
+ -- Routing outcomes (ADR-022: Adaptive QE Agent Routing)
2147
+ CREATE TABLE IF NOT EXISTS routing_outcomes (
2148
+ id TEXT PRIMARY KEY,
2149
+ task_json TEXT NOT NULL,
2150
+ decision_json TEXT NOT NULL,
2151
+ used_agent TEXT NOT NULL,
2152
+ followed_recommendation INTEGER NOT NULL,
2153
+ success INTEGER NOT NULL,
2154
+ quality_score REAL NOT NULL,
2155
+ duration_ms REAL NOT NULL,
2156
+ error TEXT,
2157
+ created_at TEXT DEFAULT (datetime('now'))
2158
+ );
2159
+ CREATE INDEX IF NOT EXISTS idx_routing_outcomes_agent ON routing_outcomes(used_agent);
2160
+ CREATE INDEX IF NOT EXISTS idx_routing_outcomes_created ON routing_outcomes(created_at);
2161
+
2162
+ -- Coverage sessions (ADR-023: Coverage Learning)
2163
+ CREATE TABLE IF NOT EXISTS coverage_sessions (
2164
+ id TEXT PRIMARY KEY,
2165
+ target_path TEXT NOT NULL,
2166
+ agent_id TEXT NOT NULL,
2167
+ technique TEXT NOT NULL,
2168
+ before_lines REAL DEFAULT 0,
2169
+ before_branches REAL DEFAULT 0,
2170
+ before_functions REAL DEFAULT 0,
2171
+ after_lines REAL DEFAULT 0,
2172
+ after_branches REAL DEFAULT 0,
2173
+ after_functions REAL DEFAULT 0,
2174
+ tests_generated INTEGER DEFAULT 0,
2175
+ tests_passed INTEGER DEFAULT 0,
2176
+ gaps_json TEXT,
2177
+ duration_ms REAL NOT NULL,
2178
+ started_at TEXT NOT NULL,
2179
+ completed_at TEXT NOT NULL,
2180
+ context_json TEXT,
2181
+ created_at TEXT DEFAULT (datetime('now'))
2182
+ );
2183
+ CREATE INDEX IF NOT EXISTS idx_coverage_sessions_technique ON coverage_sessions(technique);
2184
+ CREATE INDEX IF NOT EXISTS idx_coverage_sessions_agent ON coverage_sessions(agent_id);
2185
+ CREATE INDEX IF NOT EXISTS idx_coverage_sessions_created ON coverage_sessions(created_at);
2103
2186
  `;
2104
2187
  BinaryHeap = class {
2105
2188
  data = [];
@@ -2439,6 +2522,7 @@ var init_unified_memory = __esm({
2439
2522
  db = null;
2440
2523
  config;
2441
2524
  initialized = false;
2525
+ vectorsLoaded = false;
2442
2526
  initPromise = null;
2443
2527
  preparedStatements = /* @__PURE__ */ new Map();
2444
2528
  vectorIndex = new InMemoryHNSWIndex();
@@ -2447,6 +2531,10 @@ var init_unified_memory = __esm({
2447
2531
  constructor(config) {
2448
2532
  const resolvedDefaults = getResolvedDefaultConfig();
2449
2533
  this.config = { ...resolvedDefaults, ...config };
2534
+ if (!path.isAbsolute(this.config.dbPath)) {
2535
+ const projectRoot = findProjectRoot();
2536
+ this.config.dbPath = path.join(projectRoot, this.config.dbPath);
2537
+ }
2450
2538
  }
2451
2539
  /**
2452
2540
  * Get or create the singleton instance (synchronous).
@@ -2516,7 +2604,7 @@ var init_unified_memory = __esm({
2516
2604
  this.db.pragma(`busy_timeout = ${this.config.busyTimeout}`);
2517
2605
  this.db.pragma("foreign_keys = ON");
2518
2606
  await this.runMigrations();
2519
- await this.loadVectorIndex();
2607
+ this.vectorsLoaded = false;
2520
2608
  this.initialized = true;
2521
2609
  console.log(`[UnifiedMemory] Initialized: ${this.config.dbPath}`);
2522
2610
  this.warnIfDuplicateDatabases();
@@ -2637,6 +2725,9 @@ var init_unified_memory = __esm({
2637
2725
  if (currentVersion < 7) {
2638
2726
  this.db.exec(SONA_PATTERNS_SCHEMA);
2639
2727
  }
2728
+ if (currentVersion < 8) {
2729
+ this.db.exec(FEEDBACK_SCHEMA);
2730
+ }
2640
2731
  this.db.prepare(`
2641
2732
  INSERT OR REPLACE INTO schema_version (id, version, migrated_at)
2642
2733
  VALUES (1, ?, datetime('now'))
@@ -2650,6 +2741,7 @@ var init_unified_memory = __esm({
2650
2741
  * Load all vectors from SQLite into HNSW index
2651
2742
  */
2652
2743
  async loadVectorIndex() {
2744
+ if (this.vectorsLoaded) return;
2653
2745
  if (!this.db) throw new Error("Database not initialized");
2654
2746
  this.vectorIndex.clear();
2655
2747
  const rows = this.db.prepare(
@@ -2659,6 +2751,7 @@ var init_unified_memory = __esm({
2659
2751
  const embedding = this.bufferToFloatArray(row.embedding, row.dimensions);
2660
2752
  this.vectorIndex.add(row.id, embedding);
2661
2753
  }
2754
+ this.vectorsLoaded = true;
2662
2755
  console.log(`[UnifiedMemory] Loaded ${rows.length} vectors into HNSW index`);
2663
2756
  }
2664
2757
  // ============================================================================
@@ -2782,6 +2875,9 @@ var init_unified_memory = __esm({
2782
2875
  */
2783
2876
  async vectorSearch(query, k68 = 10, namespace) {
2784
2877
  this.ensureInitialized();
2878
+ if (!this.vectorsLoaded) {
2879
+ await this.loadVectorIndex();
2880
+ }
2785
2881
  const results = this.vectorIndex.search(query, k68 * 2);
2786
2882
  if (results.length === 0) return [];
2787
2883
  const ids = results.map((r54) => r54.id);
@@ -3416,6 +3512,211 @@ var init_real_embeddings = __esm({
3416
3512
  }
3417
3513
  });
3418
3514
 
3515
+ // src/kernel/unified-persistence.ts
3516
+ function getUnifiedPersistence(config) {
3517
+ return UnifiedPersistenceManager.getInstance(config);
3518
+ }
3519
+ async function initializeUnifiedPersistence(config) {
3520
+ const manager = getUnifiedPersistence(config);
3521
+ await manager.initialize();
3522
+ return manager;
3523
+ }
3524
+ function registerExitHandlers2() {
3525
+ if (exitHandlersRegistered2) return;
3526
+ exitHandlersRegistered2 = true;
3527
+ const cleanup = () => {
3528
+ try {
3529
+ const instance3 = UnifiedPersistenceManager["instance"];
3530
+ if (instance3) {
3531
+ instance3.close();
3532
+ }
3533
+ } catch (error) {
3534
+ console.debug("[UnifiedPersistence] Cleanup error:", error instanceof Error ? error.message : error);
3535
+ }
3536
+ };
3537
+ process.on("beforeExit", cleanup);
3538
+ process.on("SIGINT", () => {
3539
+ cleanup();
3540
+ process.exit(0);
3541
+ });
3542
+ process.on("SIGTERM", () => {
3543
+ cleanup();
3544
+ process.exit(0);
3545
+ });
3546
+ }
3547
+ var DEFAULT_UNIFIED_CONFIG, UnifiedPersistenceManager, exitHandlersRegistered2;
3548
+ var init_unified_persistence = __esm({
3549
+ "src/kernel/unified-persistence.ts"() {
3550
+ "use strict";
3551
+ init_unified_memory();
3552
+ DEFAULT_UNIFIED_CONFIG = {
3553
+ dbPath: DEFAULT_UNIFIED_MEMORY_CONFIG.dbPath,
3554
+ // '.agentic-qe/memory.db'
3555
+ walMode: true,
3556
+ mmapSize: 64 * 1024 * 1024,
3557
+ // 64MB
3558
+ cacheSize: -32e3,
3559
+ // 32MB
3560
+ busyTimeout: 5e3
3561
+ };
3562
+ UnifiedPersistenceManager = class _UnifiedPersistenceManager {
3563
+ static instance = null;
3564
+ static instancePromise = null;
3565
+ unifiedMemory = null;
3566
+ config;
3567
+ initialized = false;
3568
+ initPromise = null;
3569
+ constructor(config) {
3570
+ this.config = { ...DEFAULT_UNIFIED_CONFIG, ...config };
3571
+ }
3572
+ /**
3573
+ * Get or create the singleton instance (synchronous).
3574
+ * Thread-safe: JS is single-threaded for synchronous code.
3575
+ */
3576
+ static getInstance(config) {
3577
+ if (_UnifiedPersistenceManager.instance) {
3578
+ return _UnifiedPersistenceManager.instance;
3579
+ }
3580
+ _UnifiedPersistenceManager.instance = new _UnifiedPersistenceManager(config);
3581
+ return _UnifiedPersistenceManager.instance;
3582
+ }
3583
+ /**
3584
+ * Get or create the singleton instance with async initialization.
3585
+ * Thread-safe: Uses Promise lock to prevent concurrent initialization races.
3586
+ */
3587
+ static async getInstanceAsync(config) {
3588
+ if (_UnifiedPersistenceManager.instance?.initialized) {
3589
+ return _UnifiedPersistenceManager.instance;
3590
+ }
3591
+ if (!_UnifiedPersistenceManager.instancePromise) {
3592
+ _UnifiedPersistenceManager.instancePromise = (async () => {
3593
+ const instance3 = _UnifiedPersistenceManager.getInstance(config);
3594
+ await instance3.initialize();
3595
+ return instance3;
3596
+ })();
3597
+ }
3598
+ return _UnifiedPersistenceManager.instancePromise;
3599
+ }
3600
+ /**
3601
+ * Reset the singleton (for testing)
3602
+ */
3603
+ static resetInstance() {
3604
+ if (_UnifiedPersistenceManager.instance) {
3605
+ _UnifiedPersistenceManager.instance.close();
3606
+ _UnifiedPersistenceManager.instance = null;
3607
+ }
3608
+ _UnifiedPersistenceManager.instancePromise = null;
3609
+ resetUnifiedMemory();
3610
+ }
3611
+ /**
3612
+ * Initialize the database and create all schemas.
3613
+ * Thread-safe: Uses Promise lock to prevent concurrent initialization races.
3614
+ */
3615
+ async initialize() {
3616
+ if (this.initialized) return;
3617
+ if (!this.initPromise) {
3618
+ this.initPromise = this._doInitialize();
3619
+ }
3620
+ return this.initPromise;
3621
+ }
3622
+ /**
3623
+ * Internal initialization implementation
3624
+ */
3625
+ async _doInitialize() {
3626
+ if (this.initialized) return;
3627
+ try {
3628
+ const memoryConfig = {
3629
+ dbPath: this.config.dbPath,
3630
+ walMode: this.config.walMode,
3631
+ busyTimeout: this.config.busyTimeout,
3632
+ mmapSize: this.config.mmapSize,
3633
+ cacheSize: this.config.cacheSize
3634
+ };
3635
+ this.unifiedMemory = getUnifiedMemory(memoryConfig);
3636
+ await this.unifiedMemory.initialize();
3637
+ this.initialized = true;
3638
+ console.log(`[UnifiedPersistence] Initialized via UnifiedMemoryManager: ${this.config.dbPath}`);
3639
+ } catch (error) {
3640
+ this.initPromise = null;
3641
+ throw new Error(
3642
+ `Failed to initialize UnifiedPersistenceManager: ${error instanceof Error ? error.message : String(error)}`
3643
+ );
3644
+ }
3645
+ }
3646
+ /**
3647
+ * Get the raw database connection for advanced operations
3648
+ */
3649
+ getDatabase() {
3650
+ if (!this.unifiedMemory || !this.initialized) {
3651
+ throw new Error("UnifiedPersistenceManager not initialized");
3652
+ }
3653
+ return this.unifiedMemory.getDatabase();
3654
+ }
3655
+ /**
3656
+ * Check if initialized
3657
+ */
3658
+ isInitialized() {
3659
+ return this.initialized;
3660
+ }
3661
+ /**
3662
+ * Get the database path
3663
+ */
3664
+ getDbPath() {
3665
+ return this.config.dbPath;
3666
+ }
3667
+ /**
3668
+ * Prepare and cache a statement
3669
+ */
3670
+ prepare(name, sql) {
3671
+ if (!this.unifiedMemory) throw new Error("Database not initialized");
3672
+ return this.unifiedMemory.prepare(name, sql);
3673
+ }
3674
+ /**
3675
+ * Execute a transaction
3676
+ */
3677
+ transaction(fn) {
3678
+ if (!this.unifiedMemory) throw new Error("Database not initialized");
3679
+ return this.unifiedMemory.transaction(fn);
3680
+ }
3681
+ /**
3682
+ * Get database statistics
3683
+ */
3684
+ getStats() {
3685
+ if (!this.unifiedMemory) throw new Error("Database not initialized");
3686
+ const memStats = this.unifiedMemory.getStats();
3687
+ return {
3688
+ tables: memStats.tables,
3689
+ fileSize: memStats.fileSize,
3690
+ walSize: memStats.walSize
3691
+ };
3692
+ }
3693
+ /**
3694
+ * Vacuum the database to reclaim space
3695
+ */
3696
+ vacuum() {
3697
+ const db = this.getDatabase();
3698
+ db.exec("VACUUM");
3699
+ }
3700
+ /**
3701
+ * Checkpoint WAL to main database
3702
+ */
3703
+ checkpoint() {
3704
+ const db = this.getDatabase();
3705
+ db.pragma("wal_checkpoint(TRUNCATE)");
3706
+ }
3707
+ /**
3708
+ * Close the database connection
3709
+ */
3710
+ close() {
3711
+ this.initialized = false;
3712
+ console.log("[UnifiedPersistence] Facade closed");
3713
+ }
3714
+ };
3715
+ exitHandlersRegistered2 = false;
3716
+ registerExitHandlers2();
3717
+ }
3718
+ });
3719
+
3419
3720
  // src/shared/embeddings/types.ts
3420
3721
  var EMBEDDING_CONFIG;
3421
3722
  var init_types2 = __esm({
@@ -6624,206 +6925,6 @@ var init_sona_wrapper = __esm({
6624
6925
  }
6625
6926
  });
6626
6927
 
6627
- // src/kernel/unified-persistence.ts
6628
- function getUnifiedPersistence(config) {
6629
- return UnifiedPersistenceManager.getInstance(config);
6630
- }
6631
- function registerExitHandlers2() {
6632
- if (exitHandlersRegistered2) return;
6633
- exitHandlersRegistered2 = true;
6634
- const cleanup = () => {
6635
- try {
6636
- const instance3 = UnifiedPersistenceManager["instance"];
6637
- if (instance3) {
6638
- instance3.close();
6639
- }
6640
- } catch (error) {
6641
- console.debug("[UnifiedPersistence] Cleanup error:", error instanceof Error ? error.message : error);
6642
- }
6643
- };
6644
- process.on("beforeExit", cleanup);
6645
- process.on("SIGINT", () => {
6646
- cleanup();
6647
- process.exit(0);
6648
- });
6649
- process.on("SIGTERM", () => {
6650
- cleanup();
6651
- process.exit(0);
6652
- });
6653
- }
6654
- var DEFAULT_UNIFIED_CONFIG, UnifiedPersistenceManager, exitHandlersRegistered2;
6655
- var init_unified_persistence = __esm({
6656
- "src/kernel/unified-persistence.ts"() {
6657
- "use strict";
6658
- init_unified_memory();
6659
- DEFAULT_UNIFIED_CONFIG = {
6660
- dbPath: DEFAULT_UNIFIED_MEMORY_CONFIG.dbPath,
6661
- // '.agentic-qe/memory.db'
6662
- walMode: true,
6663
- mmapSize: 64 * 1024 * 1024,
6664
- // 64MB
6665
- cacheSize: -32e3,
6666
- // 32MB
6667
- busyTimeout: 5e3
6668
- };
6669
- UnifiedPersistenceManager = class _UnifiedPersistenceManager {
6670
- static instance = null;
6671
- static instancePromise = null;
6672
- unifiedMemory = null;
6673
- config;
6674
- initialized = false;
6675
- initPromise = null;
6676
- constructor(config) {
6677
- this.config = { ...DEFAULT_UNIFIED_CONFIG, ...config };
6678
- }
6679
- /**
6680
- * Get or create the singleton instance (synchronous).
6681
- * Thread-safe: JS is single-threaded for synchronous code.
6682
- */
6683
- static getInstance(config) {
6684
- if (_UnifiedPersistenceManager.instance) {
6685
- return _UnifiedPersistenceManager.instance;
6686
- }
6687
- _UnifiedPersistenceManager.instance = new _UnifiedPersistenceManager(config);
6688
- return _UnifiedPersistenceManager.instance;
6689
- }
6690
- /**
6691
- * Get or create the singleton instance with async initialization.
6692
- * Thread-safe: Uses Promise lock to prevent concurrent initialization races.
6693
- */
6694
- static async getInstanceAsync(config) {
6695
- if (_UnifiedPersistenceManager.instance?.initialized) {
6696
- return _UnifiedPersistenceManager.instance;
6697
- }
6698
- if (!_UnifiedPersistenceManager.instancePromise) {
6699
- _UnifiedPersistenceManager.instancePromise = (async () => {
6700
- const instance3 = _UnifiedPersistenceManager.getInstance(config);
6701
- await instance3.initialize();
6702
- return instance3;
6703
- })();
6704
- }
6705
- return _UnifiedPersistenceManager.instancePromise;
6706
- }
6707
- /**
6708
- * Reset the singleton (for testing)
6709
- */
6710
- static resetInstance() {
6711
- if (_UnifiedPersistenceManager.instance) {
6712
- _UnifiedPersistenceManager.instance.close();
6713
- _UnifiedPersistenceManager.instance = null;
6714
- }
6715
- _UnifiedPersistenceManager.instancePromise = null;
6716
- resetUnifiedMemory();
6717
- }
6718
- /**
6719
- * Initialize the database and create all schemas.
6720
- * Thread-safe: Uses Promise lock to prevent concurrent initialization races.
6721
- */
6722
- async initialize() {
6723
- if (this.initialized) return;
6724
- if (!this.initPromise) {
6725
- this.initPromise = this._doInitialize();
6726
- }
6727
- return this.initPromise;
6728
- }
6729
- /**
6730
- * Internal initialization implementation
6731
- */
6732
- async _doInitialize() {
6733
- if (this.initialized) return;
6734
- try {
6735
- const memoryConfig = {
6736
- dbPath: this.config.dbPath,
6737
- walMode: this.config.walMode,
6738
- busyTimeout: this.config.busyTimeout,
6739
- mmapSize: this.config.mmapSize,
6740
- cacheSize: this.config.cacheSize
6741
- };
6742
- this.unifiedMemory = getUnifiedMemory(memoryConfig);
6743
- await this.unifiedMemory.initialize();
6744
- this.initialized = true;
6745
- console.log(`[UnifiedPersistence] Initialized via UnifiedMemoryManager: ${this.config.dbPath}`);
6746
- } catch (error) {
6747
- this.initPromise = null;
6748
- throw new Error(
6749
- `Failed to initialize UnifiedPersistenceManager: ${error instanceof Error ? error.message : String(error)}`
6750
- );
6751
- }
6752
- }
6753
- /**
6754
- * Get the raw database connection for advanced operations
6755
- */
6756
- getDatabase() {
6757
- if (!this.unifiedMemory || !this.initialized) {
6758
- throw new Error("UnifiedPersistenceManager not initialized");
6759
- }
6760
- return this.unifiedMemory.getDatabase();
6761
- }
6762
- /**
6763
- * Check if initialized
6764
- */
6765
- isInitialized() {
6766
- return this.initialized;
6767
- }
6768
- /**
6769
- * Get the database path
6770
- */
6771
- getDbPath() {
6772
- return this.config.dbPath;
6773
- }
6774
- /**
6775
- * Prepare and cache a statement
6776
- */
6777
- prepare(name, sql) {
6778
- if (!this.unifiedMemory) throw new Error("Database not initialized");
6779
- return this.unifiedMemory.prepare(name, sql);
6780
- }
6781
- /**
6782
- * Execute a transaction
6783
- */
6784
- transaction(fn) {
6785
- if (!this.unifiedMemory) throw new Error("Database not initialized");
6786
- return this.unifiedMemory.transaction(fn);
6787
- }
6788
- /**
6789
- * Get database statistics
6790
- */
6791
- getStats() {
6792
- if (!this.unifiedMemory) throw new Error("Database not initialized");
6793
- const memStats = this.unifiedMemory.getStats();
6794
- return {
6795
- tables: memStats.tables,
6796
- fileSize: memStats.fileSize,
6797
- walSize: memStats.walSize
6798
- };
6799
- }
6800
- /**
6801
- * Vacuum the database to reclaim space
6802
- */
6803
- vacuum() {
6804
- const db = this.getDatabase();
6805
- db.exec("VACUUM");
6806
- }
6807
- /**
6808
- * Checkpoint WAL to main database
6809
- */
6810
- checkpoint() {
6811
- const db = this.getDatabase();
6812
- db.pragma("wal_checkpoint(TRUNCATE)");
6813
- }
6814
- /**
6815
- * Close the database connection
6816
- */
6817
- close() {
6818
- this.initialized = false;
6819
- console.log("[UnifiedPersistence] Facade closed");
6820
- }
6821
- };
6822
- exitHandlersRegistered2 = false;
6823
- registerExitHandlers2();
6824
- }
6825
- });
6826
-
6827
6928
  // native-require:@ruvector/attention
6828
6929
  var attention_exports = {};
6829
6930
  __export(attention_exports, {
@@ -6940,6 +7041,7 @@ var init_attention_wrapper = __esm({
6940
7041
  "src/integrations/ruvector/attention-wrapper.ts"() {
6941
7042
  "use strict";
6942
7043
  init_attention();
7044
+ init_unified_memory();
6943
7045
  QE_FLASH_ATTENTION_CONFIG = {
6944
7046
  "test-similarity": {
6945
7047
  dim: 384,
@@ -7053,11 +7155,19 @@ var init_attention_wrapper = __esm({
7053
7155
  }
7054
7156
  }
7055
7157
  };
7056
- QEFlashAttention = class {
7158
+ QEFlashAttention = class _QEFlashAttention {
7057
7159
  attention;
7058
7160
  config;
7059
7161
  workload;
7060
7162
  metrics = [];
7163
+ // kv_store persistence
7164
+ db = null;
7165
+ persistCount = 0;
7166
+ static KV_NAMESPACE = "attention-metrics";
7167
+ static KV_TTL = 3600;
7168
+ // 1 hour
7169
+ static PERSIST_INTERVAL = 10;
7170
+ // every 10 operations
7061
7171
  constructor(workload, customConfig) {
7062
7172
  this.workload = workload;
7063
7173
  const baseConfig = QE_FLASH_ATTENTION_CONFIG[workload];
@@ -7068,10 +7178,18 @@ var init_attention_wrapper = __esm({
7068
7178
  this.attention = AttentionFactory.create(this.config);
7069
7179
  }
7070
7180
  /**
7071
- * Initialize Flash Attention
7181
+ * Initialize Flash Attention and kv_store persistence
7072
7182
  * Note: @ruvector/attention doesn't require async initialization
7073
7183
  */
7074
7184
  async initialize() {
7185
+ try {
7186
+ this.db = getUnifiedMemory();
7187
+ if (!this.db.isInitialized()) await this.db.initialize();
7188
+ await this.loadFromKv();
7189
+ } catch (error) {
7190
+ console.warn("[QEFlashAttention] DB init failed, using memory-only:", error instanceof Error ? error.message : String(error));
7191
+ this.db = null;
7192
+ }
7075
7193
  }
7076
7194
  /**
7077
7195
  * Compute Flash Attention using @ruvector/attention
@@ -7116,6 +7234,7 @@ var init_attention_wrapper = __esm({
7116
7234
  throughput: seqLen * seqLen / ((endTime - startTime) / 1e3),
7117
7235
  peakMemoryMB: endMemory
7118
7236
  });
7237
+ this.maybePersistToKv();
7119
7238
  return output;
7120
7239
  }
7121
7240
  /**
@@ -7282,6 +7401,49 @@ var init_attention_wrapper = __esm({
7282
7401
  this.metrics = [];
7283
7402
  }
7284
7403
  // ========================================================================
7404
+ // kv_store Persistence
7405
+ // ========================================================================
7406
+ /**
7407
+ * Persist metrics snapshot to kv_store
7408
+ */
7409
+ async persistToKv() {
7410
+ if (!this.db) return;
7411
+ const kvKey = `attention-metrics-${this.workload}`;
7412
+ const snapshot = {
7413
+ workload: this.workload,
7414
+ metrics: this.metrics.slice(-50),
7415
+ savedAt: Date.now()
7416
+ };
7417
+ await this.db.kvSet(
7418
+ kvKey,
7419
+ snapshot,
7420
+ _QEFlashAttention.KV_NAMESPACE,
7421
+ _QEFlashAttention.KV_TTL
7422
+ );
7423
+ }
7424
+ /**
7425
+ * Load metrics snapshot from kv_store
7426
+ */
7427
+ async loadFromKv() {
7428
+ if (!this.db) return;
7429
+ const kvKey = `attention-metrics-${this.workload}`;
7430
+ const snapshot = await this.db.kvGet(kvKey, _QEFlashAttention.KV_NAMESPACE);
7431
+ if (snapshot?.metrics?.length) {
7432
+ this.metrics = snapshot.metrics;
7433
+ }
7434
+ }
7435
+ /**
7436
+ * Track operations and persist periodically
7437
+ */
7438
+ maybePersistToKv() {
7439
+ this.persistCount++;
7440
+ if (this.persistCount >= _QEFlashAttention.PERSIST_INTERVAL) {
7441
+ this.persistCount = 0;
7442
+ this.persistToKv().catch(() => {
7443
+ });
7444
+ }
7445
+ }
7446
+ // ========================================================================
7285
7447
  // Private Helper Methods
7286
7448
  // ========================================================================
7287
7449
  /**
@@ -8092,8 +8254,6 @@ var init_hnsw_index = __esm({
8092
8254
  const embedding = this.vectorToEmbedding(vector, key, metadata);
8093
8255
  this.ruvectorIndex.addEmbedding(embedding, label);
8094
8256
  this.vectorStore.set(key, vector);
8095
- const fullKey = this.buildKey(key);
8096
- await this.memory.storeVector(fullKey, vector, metadata);
8097
8257
  this.stats.insertOperations++;
8098
8258
  this.stats.vectorCount++;
8099
8259
  }
@@ -9018,13 +9178,13 @@ var init_path_traversal_validator = __esm({
9018
9178
  */
9019
9179
  joinPathsAbsolute(...paths) {
9020
9180
  if (paths.length === 0) return "";
9021
- const isAbsolute5 = paths[0].startsWith("/");
9181
+ const isAbsolute6 = paths[0].startsWith("/");
9022
9182
  const result = paths.map((p74) => {
9023
9183
  while (p74.startsWith("/")) p74 = p74.slice(1);
9024
9184
  while (p74.endsWith("/")) p74 = p74.slice(0, -1);
9025
9185
  return p74;
9026
9186
  }).filter(Boolean).join("/");
9027
- return isAbsolute5 ? `/${result}` : result;
9187
+ return isAbsolute6 ? `/${result}` : result;
9028
9188
  }
9029
9189
  /**
9030
9190
  * Get file extension from path
@@ -10009,13 +10169,6 @@ var init_knowledge_graph = __esm({
10009
10169
  async clear() {
10010
10170
  this.nodeCache.clear();
10011
10171
  this.edgeIndex.clear();
10012
- const nodePattern = `${this.config.namespace}:node:*`;
10013
- const edgePattern = `${this.config.namespace}:edge:*`;
10014
- const nodeKeys = await this.memory.search(nodePattern, this.config.maxNodes);
10015
- const edgeKeys = await this.memory.search(edgePattern, this.config.maxNodes * 10);
10016
- for (const key of [...nodeKeys, ...edgeKeys]) {
10017
- await this.memory.delete(key);
10018
- }
10019
10172
  }
10020
10173
  // ============================================================================
10021
10174
  // ADR-051: LLM Enhancement Methods
@@ -10250,26 +10403,18 @@ ${JSON.stringify(results.map((n61) => ({ id: n61.id, label: n61.label, propertie
10250
10403
  await this.createEdge(sourceId, targetId, rel.type);
10251
10404
  edgesCreated++;
10252
10405
  }
10253
- if (relationships.designPatterns.length > 0) {
10254
- await this.memory.set(
10255
- `${this.config.namespace}:patterns:${fileNodeId}`,
10256
- relationships.designPatterns,
10257
- { namespace: this.config.namespace }
10258
- );
10259
- }
10260
- if (relationships.architecturalBoundaries.length > 0) {
10261
- await this.memory.set(
10262
- `${this.config.namespace}:boundaries:${fileNodeId}`,
10263
- relationships.architecturalBoundaries,
10264
- { namespace: this.config.namespace }
10265
- );
10266
- }
10267
- if (relationships.dependencyImpacts.length > 0) {
10268
- await this.memory.set(
10269
- `${this.config.namespace}:impacts:${fileNodeId}`,
10270
- relationships.dependencyImpacts,
10271
- { namespace: this.config.namespace }
10272
- );
10406
+ const node = this.nodeCache.get(fileNodeId);
10407
+ if (node) {
10408
+ if (relationships.designPatterns.length > 0) {
10409
+ node.properties.designPatterns = relationships.designPatterns;
10410
+ }
10411
+ if (relationships.architecturalBoundaries.length > 0) {
10412
+ node.properties.architecturalBoundaries = relationships.architecturalBoundaries;
10413
+ }
10414
+ if (relationships.dependencyImpacts.length > 0) {
10415
+ node.properties.dependencyImpacts = relationships.dependencyImpacts;
10416
+ }
10417
+ this.nodeCache.set(fileNodeId, node);
10273
10418
  }
10274
10419
  return edgesCreated;
10275
10420
  }
@@ -10319,9 +10464,6 @@ ${JSON.stringify(results.map((n61) => ({ id: n61.id, label: n61.label, propertie
10319
10464
  target: targetId,
10320
10465
  type
10321
10466
  };
10322
- await this.memory.set(`${this.config.namespace}:edge:${edgeId}`, edge, {
10323
- namespace: this.config.namespace
10324
- });
10325
10467
  const sourceEdges = this.edgeIndex.get(sourceId) || [];
10326
10468
  sourceEdges.push(edge);
10327
10469
  this.edgeIndex.set(sourceId, sourceEdges);
@@ -10333,12 +10475,8 @@ ${JSON.stringify(results.map((n61) => ({ id: n61.id, label: n61.label, propertie
10333
10475
  if (firstKey) {
10334
10476
  this.nodeCache.delete(firstKey);
10335
10477
  this.edgeIndex.delete(firstKey);
10336
- await this.memory.delete(`${this.config.namespace}:node:${firstKey}`);
10337
10478
  }
10338
10479
  }
10339
- await this.memory.set(`${this.config.namespace}:node:${node.id}`, node, {
10340
- namespace: this.config.namespace
10341
- });
10342
10480
  this.nodeCache.set(node.id, node);
10343
10481
  }
10344
10482
  async extractEntities(filePath) {
@@ -10729,11 +10867,7 @@ ${JSON.stringify(results.map((n61) => ({ id: n61.id, label: n61.label, propertie
10729
10867
  return true;
10730
10868
  });
10731
10869
  }
10732
- async storeIndexMetadata(metadata) {
10733
- await this.memory.set(`${this.config.namespace}:metadata:index`, metadata, {
10734
- namespace: this.config.namespace,
10735
- persist: true
10736
- });
10870
+ async storeIndexMetadata(_metadata) {
10737
10871
  }
10738
10872
  async generateEmbedding(entity) {
10739
10873
  const text = `${entity.type} ${entity.name} ${entity.visibility}${entity.isAsync ? " async" : ""}`;
@@ -13812,31 +13946,6 @@ var init_pattern_store = __esm({
13812
13946
  * Load existing patterns from memory with timeout protection
13813
13947
  */
13814
13948
  async loadPatterns() {
13815
- try {
13816
- const timeoutMs = 5e3;
13817
- const searchPromise = this.memory.search(`${this.config.namespace}:pattern:*`, 1e4);
13818
- const timeoutPromise = new Promise(
13819
- (_56, reject) => setTimeout(() => reject(new Error("Pattern load timeout")), timeoutMs)
13820
- );
13821
- const keys = await Promise.race([searchPromise, timeoutPromise]);
13822
- const BATCH_SIZE = 50;
13823
- for (let i58 = 0; i58 < keys.length; i58 += BATCH_SIZE) {
13824
- const batch = keys.slice(i58, i58 + BATCH_SIZE);
13825
- const patterns = await Promise.all(
13826
- batch.map((key) => this.memory.get(key).catch(() => null))
13827
- );
13828
- for (const pattern of patterns) {
13829
- if (pattern) {
13830
- this.indexPattern(pattern);
13831
- }
13832
- }
13833
- }
13834
- if (this.patternCache.size > 0) {
13835
- console.log(`[PatternStore] Loaded ${this.patternCache.size} patterns`);
13836
- }
13837
- } catch (error) {
13838
- console.log(`[PatternStore] Starting fresh (no existing patterns loaded): ${error instanceof Error ? error.message : "unknown error"}`);
13839
- }
13840
13949
  }
13841
13950
  /**
13842
13951
  * Index a pattern in local caches
@@ -13884,10 +13993,6 @@ var init_pattern_store = __esm({
13884
13993
  if (domainCount >= this.config.maxPatternsPerDomain) {
13885
13994
  await this.cleanupDomain(pattern.qeDomain);
13886
13995
  }
13887
- const key = `${this.config.namespace}:pattern:${pattern.id}`;
13888
- await this.memory.set(key, pattern, {
13889
- persist: true
13890
- });
13891
13996
  this.indexPattern(pattern);
13892
13997
  if (pattern.embedding) {
13893
13998
  const hnsw = await this.ensureHNSW();
@@ -13984,15 +14089,7 @@ var init_pattern_store = __esm({
13984
14089
  if (!this.initialized) {
13985
14090
  await this.initialize();
13986
14091
  }
13987
- const cached = this.patternCache.get(id);
13988
- if (cached) return cached;
13989
- const key = `${this.config.namespace}:pattern:${id}`;
13990
- const pattern = await this.memory.get(key);
13991
- if (pattern) {
13992
- this.indexPattern(pattern);
13993
- return pattern;
13994
- }
13995
- return null;
14092
+ return this.patternCache.get(id) ?? null;
13996
14093
  }
13997
14094
  /**
13998
14095
  * Search for patterns
@@ -14189,10 +14286,6 @@ var init_pattern_store = __esm({
14189
14286
  if (shouldPromote && updated.tier === "short-term") {
14190
14287
  await this.promote(id);
14191
14288
  } else {
14192
- const key = `${this.config.namespace}:pattern:${id}`;
14193
- await this.memory.set(key, updated, {
14194
- persist: true
14195
- });
14196
14289
  this.patternCache.set(id, updated);
14197
14290
  }
14198
14291
  return ok(void 0);
@@ -14216,10 +14309,6 @@ var init_pattern_store = __esm({
14216
14309
  };
14217
14310
  this.tierIndex.get("short-term")?.delete(id);
14218
14311
  this.tierIndex.get("long-term")?.add(id);
14219
- const key = `${this.config.namespace}:pattern:${id}`;
14220
- await this.memory.set(key, promoted, {
14221
- persist: true
14222
- });
14223
14312
  this.patternCache.set(id, promoted);
14224
14313
  console.log(
14225
14314
  `[PatternStore] Promoted pattern ${id} (${pattern.name}) to long-term storage`
@@ -14235,8 +14324,6 @@ var init_pattern_store = __esm({
14235
14324
  return err(new Error(`Pattern not found: ${id}`));
14236
14325
  }
14237
14326
  this.unindexPattern(pattern);
14238
- const key = `${this.config.namespace}:pattern:${id}`;
14239
- await this.memory.delete(key);
14240
14327
  if (this.hnswIndex !== null) {
14241
14328
  try {
14242
14329
  await this.hnswIndex.delete(id);
@@ -15790,7 +15877,15 @@ var init_qe_reasoning_bank = __esm({
15790
15877
  await this.loadPretrainedPatterns();
15791
15878
  this.initialized = true;
15792
15879
  try {
15793
- await this.seedCrossDomainPatterns();
15880
+ const SEED_FLAG_KEY = "reasoning-bank:cross-domain-seeded";
15881
+ const alreadySeeded = await this.memory.get(SEED_FLAG_KEY);
15882
+ if (!alreadySeeded) {
15883
+ await this.memory.set(SEED_FLAG_KEY, true);
15884
+ await this.seedCrossDomainPatterns();
15885
+ } else {
15886
+ const stats = await this.patternStore.getStats();
15887
+ console.log(`[QEReasoningBank] Cross-domain transfer already complete (${stats.totalPatterns} patterns)`);
15888
+ }
15794
15889
  } catch (error) {
15795
15890
  console.warn("[QEReasoningBank] Cross-domain seeding failed (non-fatal):", error);
15796
15891
  }
@@ -17588,6 +17683,7 @@ var HybridMemoryBackend = class {
17588
17683
  unifiedMemory = null;
17589
17684
  config;
17590
17685
  cleanupInterval;
17686
+ cleanupCount = 0;
17591
17687
  initialized = false;
17592
17688
  constructor(config) {
17593
17689
  this.config = {
@@ -17804,6 +17900,31 @@ var HybridMemoryBackend = class {
17804
17900
  if (this.unifiedMemory?.isInitialized()) {
17805
17901
  try {
17806
17902
  await this.unifiedMemory.kvCleanupExpired();
17903
+ const db = this.unifiedMemory.getDatabase();
17904
+ try {
17905
+ const expired = db.prepare("DELETE FROM kv_store WHERE expires_at IS NOT NULL AND expires_at < ?").run(Date.now());
17906
+ if (expired.changes > 0) {
17907
+ console.log(`[HybridBackend] Expired ${expired.changes} kv_store entries`);
17908
+ }
17909
+ } catch (e20) {
17910
+ }
17911
+ this.cleanupCount++;
17912
+ if (this.cleanupCount % 10 === 0) {
17913
+ try {
17914
+ const kvCount = db.prepare("SELECT COUNT(*) as cnt FROM kv_store").get();
17915
+ if (kvCount.cnt > 5e3) {
17916
+ const deleted = db.prepare(`
17917
+ DELETE FROM kv_store WHERE rowid NOT IN (
17918
+ SELECT rowid FROM kv_store ORDER BY rowid DESC LIMIT 5000
17919
+ )
17920
+ `).run();
17921
+ if (deleted.changes > 0) {
17922
+ console.log(`[HybridBackend] kv_store retention: pruned ${deleted.changes} rows (kept 5000)`);
17923
+ }
17924
+ }
17925
+ } catch (e20) {
17926
+ }
17927
+ }
17807
17928
  } catch (error) {
17808
17929
  console.warn("[HybridBackend] Cleanup failed:", error);
17809
17930
  }
@@ -18015,6 +18136,7 @@ var SemanticAntiDriftMiddleware = class {
18015
18136
  // src/kernel/kernel.ts
18016
18137
  init_constants();
18017
18138
  init_unified_memory();
18139
+ init_unified_persistence();
18018
18140
  import * as path12 from "path";
18019
18141
  import * as fs11 from "fs";
18020
18142
 
@@ -29479,11 +29601,19 @@ var isConstitutionalEnforcerEnabled = () => governanceFlags.isGateEnabled("const
29479
29601
  var isStrictMode = () => governanceFlags.getFlags().global.strictMode;
29480
29602
 
29481
29603
  // src/governance/continue-gate-integration.ts
29482
- var ContinueGateIntegration = class {
29604
+ init_unified_memory();
29605
+ var ContinueGateIntegration = class _ContinueGateIntegration {
29483
29606
  actionHistory = /* @__PURE__ */ new Map();
29484
29607
  throttledAgents = /* @__PURE__ */ new Map();
29485
29608
  guidanceContinueGate = null;
29486
29609
  initialized = false;
29610
+ db = null;
29611
+ persistCount = 0;
29612
+ static KV_NAMESPACE = "continue-gate-actions";
29613
+ static KV_KEY = "snapshot";
29614
+ static PERSIST_INTERVAL = 20;
29615
+ static KV_TTL = 3600;
29616
+ // 1 hour
29487
29617
  /**
29488
29618
  * Initialize the ContinueGate integration
29489
29619
  *
@@ -29494,8 +29624,48 @@ var ContinueGateIntegration = class {
29494
29624
  */
29495
29625
  async initialize() {
29496
29626
  if (this.initialized) return;
29627
+ try {
29628
+ this.db = getUnifiedMemory();
29629
+ if (!this.db.isInitialized()) await this.db.initialize();
29630
+ await this.loadFromKv();
29631
+ } catch (error) {
29632
+ console.warn("[ContinueGateIntegration] DB init failed, using memory-only:", error instanceof Error ? error.message : String(error));
29633
+ this.db = null;
29634
+ }
29497
29635
  this.initialized = true;
29498
29636
  }
29637
+ async loadFromKv() {
29638
+ if (!this.db) return;
29639
+ const data = await this.db.kvGet(_ContinueGateIntegration.KV_KEY, _ContinueGateIntegration.KV_NAMESPACE);
29640
+ if (data) {
29641
+ for (const [agentId, actions] of data.actionHistory) {
29642
+ this.actionHistory.set(agentId, actions);
29643
+ }
29644
+ const now = Date.now();
29645
+ for (const [agentId, until] of data.throttledAgents) {
29646
+ if (until > now) this.throttledAgents.set(agentId, until);
29647
+ }
29648
+ console.log("[ContinueGateIntegration] Loaded state from DB");
29649
+ }
29650
+ }
29651
+ async persistSnapshot() {
29652
+ if (!this.db) return;
29653
+ try {
29654
+ await this.db.kvSet(
29655
+ _ContinueGateIntegration.KV_KEY,
29656
+ {
29657
+ actionHistory: Array.from(this.actionHistory.entries()).map(
29658
+ ([agentId, actions]) => [agentId, actions.slice(-50)]
29659
+ ),
29660
+ throttledAgents: Array.from(this.throttledAgents.entries())
29661
+ },
29662
+ _ContinueGateIntegration.KV_NAMESPACE,
29663
+ _ContinueGateIntegration.KV_TTL
29664
+ );
29665
+ } catch (error) {
29666
+ console.warn("[ContinueGateIntegration] Persist failed:", error instanceof Error ? error.message : String(error));
29667
+ }
29668
+ }
29499
29669
  /**
29500
29670
  * Record an agent action for loop detection
29501
29671
  */
@@ -29507,6 +29677,11 @@ var ContinueGateIntegration = class {
29507
29677
  history.shift();
29508
29678
  }
29509
29679
  this.actionHistory.set(action.agentId, history);
29680
+ this.persistCount++;
29681
+ if (this.persistCount % _ContinueGateIntegration.PERSIST_INTERVAL === 0) {
29682
+ this.persistSnapshot().catch(() => {
29683
+ });
29684
+ }
29510
29685
  }
29511
29686
  /**
29512
29687
  * Evaluate whether an agent should continue
@@ -30786,6 +30961,7 @@ var DeterministicGatewayIntegration = class {
30786
30961
  var deterministicGatewayIntegration = new DeterministicGatewayIntegration();
30787
30962
 
30788
30963
  // src/governance/evolution-pipeline-integration.ts
30964
+ init_unified_memory();
30789
30965
  function isEvolutionPipelineEnabled() {
30790
30966
  const flags = governanceFlags.getFlags();
30791
30967
  if (!flags.global.enableAllGates) return false;
@@ -30801,11 +30977,18 @@ function getEvolutionFlags() {
30801
30977
  learningRate: 0.1
30802
30978
  };
30803
30979
  }
30804
- var EvolutionPipelineIntegration = class {
30980
+ var EvolutionPipelineIntegration = class _EvolutionPipelineIntegration {
30805
30981
  rules = /* @__PURE__ */ new Map();
30806
30982
  variantTests = /* @__PURE__ */ new Map();
30807
30983
  taskOutcomes = /* @__PURE__ */ new Map();
30808
30984
  initialized = false;
30985
+ // KV persistence
30986
+ db = null;
30987
+ persistCount = 0;
30988
+ static NAMESPACE = "rule-evolution";
30989
+ static TTL_SECONDS = 604800;
30990
+ // 7 days
30991
+ static PERSIST_INTERVAL = 10;
30809
30992
  // Statistics
30810
30993
  stats = {
30811
30994
  autoPromotions: 0,
@@ -30823,6 +31006,14 @@ var EvolutionPipelineIntegration = class {
30823
31006
  */
30824
31007
  async initialize() {
30825
31008
  if (this.initialized) return;
31009
+ try {
31010
+ this.db = getUnifiedMemory();
31011
+ if (!this.db.isInitialized()) await this.db.initialize();
31012
+ await this.loadFromKv();
31013
+ } catch (error) {
31014
+ console.warn("[EvolutionPipeline] DB init failed, using memory-only:", error instanceof Error ? error.message : String(error));
31015
+ this.db = null;
31016
+ }
30826
31017
  this.initialized = true;
30827
31018
  this.logEvent("initialize", "Evolution Pipeline initialized");
30828
31019
  }
@@ -30844,6 +31035,7 @@ var EvolutionPipelineIntegration = class {
30844
31035
  record.applications.push(application);
30845
31036
  this.pruneApplicationHistory(record);
30846
31037
  this.checkAutoPromotionDemotion(ruleId);
31038
+ this.persistSnapshot();
30847
31039
  this.logEvent("rule_application", `Rule ${ruleId} applied: ${success ? "success" : "failure"}`);
30848
31040
  }
30849
31041
  /**
@@ -31268,6 +31460,36 @@ var EvolutionPipelineIntegration = class {
31268
31460
  this.rules.delete(ruleId);
31269
31461
  }
31270
31462
  // ============================================================================
31463
+ // KV Persistence
31464
+ // ============================================================================
31465
+ /**
31466
+ * Load rules snapshot from KV store
31467
+ */
31468
+ async loadFromKv() {
31469
+ if (!this.db) return;
31470
+ const data = await this.db.kvGet("snapshot", _EvolutionPipelineIntegration.NAMESPACE);
31471
+ if (data) {
31472
+ for (const [key, record] of Object.entries(data)) {
31473
+ this.rules.set(key, record);
31474
+ }
31475
+ }
31476
+ }
31477
+ /**
31478
+ * Persist rules snapshot to KV store on interval
31479
+ */
31480
+ persistSnapshot() {
31481
+ if (!this.db) return;
31482
+ this.persistCount++;
31483
+ if (this.persistCount % _EvolutionPipelineIntegration.PERSIST_INTERVAL !== 0) return;
31484
+ try {
31485
+ const snapshot = Object.fromEntries(this.rules);
31486
+ this.db.kvSet("snapshot", snapshot, _EvolutionPipelineIntegration.NAMESPACE, _EvolutionPipelineIntegration.TTL_SECONDS).catch(() => {
31487
+ });
31488
+ } catch (error) {
31489
+ console.warn("[EvolutionPipeline] Persist failed:", error instanceof Error ? error.message : String(error));
31490
+ }
31491
+ }
31492
+ // ============================================================================
31271
31493
  // Private Helpers
31272
31494
  // ============================================================================
31273
31495
  /**
@@ -33612,6 +33834,7 @@ var ProofEnvelopeIntegration = class {
33612
33834
  var proofEnvelopeIntegration = new ProofEnvelopeIntegration();
33613
33835
 
33614
33836
  // src/governance/compliance-reporter.ts
33837
+ init_unified_memory();
33615
33838
  var DEFAULT_COMPLIANCE_REPORTER_FLAGS = {
33616
33839
  enabled: true,
33617
33840
  autoRecordViolations: true,
@@ -33628,7 +33851,7 @@ var SEVERITY_WEIGHTS = {
33628
33851
  var DEFAULT_SCORE = 100;
33629
33852
  var SCORE_DECAY_RATE = 0.5;
33630
33853
  var TREND_THRESHOLD = 5;
33631
- var ComplianceReporter = class {
33854
+ var ComplianceReporter = class _ComplianceReporter {
33632
33855
  violations = /* @__PURE__ */ new Map();
33633
33856
  alertThresholds = /* @__PURE__ */ new Map();
33634
33857
  proofIntegration;
@@ -33636,6 +33859,13 @@ var ComplianceReporter = class {
33636
33859
  initialized = false;
33637
33860
  scoreHistory = [];
33638
33861
  alertListeners = /* @__PURE__ */ new Set();
33862
+ // KV persistence
33863
+ db = null;
33864
+ persistCount = 0;
33865
+ static NAMESPACE = "compliance-audit";
33866
+ static TTL_SECONDS = 2592e3;
33867
+ // 30 days
33868
+ static PERSIST_INTERVAL = 10;
33639
33869
  /**
33640
33870
  * Create a new ComplianceReporter instance
33641
33871
  *
@@ -33651,6 +33881,14 @@ var ComplianceReporter = class {
33651
33881
  */
33652
33882
  async initialize() {
33653
33883
  if (this.initialized) return;
33884
+ try {
33885
+ this.db = getUnifiedMemory();
33886
+ if (!this.db.isInitialized()) await this.db.initialize();
33887
+ await this.loadFromKv();
33888
+ } catch (error) {
33889
+ console.warn("[ComplianceReporter] DB init failed, using memory-only:", error instanceof Error ? error.message : String(error));
33890
+ this.db = null;
33891
+ }
33654
33892
  if (!this.proofIntegration.isInitialized()) {
33655
33893
  await this.proofIntegration.initialize();
33656
33894
  }
@@ -33719,6 +33957,7 @@ var ComplianceReporter = class {
33719
33957
  if (this.flags.alertOnCritical && violation.severity === "critical") {
33720
33958
  this.triggerAlert(violation.gate, "Critical violation detected", "critical");
33721
33959
  }
33960
+ this.persistSnapshot();
33722
33961
  this.cleanupOldViolations();
33723
33962
  return id;
33724
33963
  }
@@ -34148,6 +34387,45 @@ var ComplianceReporter = class {
34148
34387
  this.initialized = false;
34149
34388
  }
34150
34389
  // ============================================================================
34390
+ // KV Persistence
34391
+ // ============================================================================
34392
+ /**
34393
+ * Load violations and score history from KV store
34394
+ */
34395
+ async loadFromKv() {
34396
+ if (!this.db) return;
34397
+ const data = await this.db.kvGet("snapshot", _ComplianceReporter.NAMESPACE);
34398
+ if (data) {
34399
+ if (data.violations) {
34400
+ for (const [key, violation] of Object.entries(data.violations)) {
34401
+ this.violations.set(key, violation);
34402
+ }
34403
+ }
34404
+ if (data.scoreHistory) {
34405
+ this.scoreHistory = data.scoreHistory;
34406
+ }
34407
+ }
34408
+ }
34409
+ /**
34410
+ * Persist violations and score history to KV store on interval
34411
+ */
34412
+ persistSnapshot() {
34413
+ if (!this.db) return;
34414
+ this.persistCount++;
34415
+ if (this.persistCount % _ComplianceReporter.PERSIST_INTERVAL !== 0) return;
34416
+ try {
34417
+ const violationEntries = Array.from(this.violations.entries()).slice(-500);
34418
+ const snapshot = {
34419
+ violations: Object.fromEntries(violationEntries),
34420
+ scoreHistory: this.scoreHistory.slice(-100)
34421
+ };
34422
+ this.db.kvSet("snapshot", snapshot, _ComplianceReporter.NAMESPACE, _ComplianceReporter.TTL_SECONDS).catch(() => {
34423
+ });
34424
+ } catch (error) {
34425
+ console.warn("[ComplianceReporter] Persist failed:", error instanceof Error ? error.message : String(error));
34426
+ }
34427
+ }
34428
+ // ============================================================================
34151
34429
  // Private Methods
34152
34430
  // ============================================================================
34153
34431
  /**
@@ -70941,9 +71219,11 @@ var CodeIntelligenceCoordinator = class {
70941
71219
  async initializeHypergraph() {
70942
71220
  try {
70943
71221
  const Database = (await Promise.resolve().then(() => (init_better_sqlite3(), better_sqlite3_exports))).default;
70944
- const dbPath = this.config.hypergraphDbPath || ".agentic-qe/hypergraph.db";
70945
71222
  const fs21 = await import("fs");
70946
71223
  const path23 = await import("path");
71224
+ const { findProjectRoot: findProjectRoot2 } = await Promise.resolve().then(() => (init_unified_memory(), unified_memory_exports));
71225
+ const projectRoot = findProjectRoot2();
71226
+ const dbPath = this.config.hypergraphDbPath || path23.join(projectRoot, ".agentic-qe", "hypergraph.db");
70947
71227
  const dir = path23.dirname(dbPath);
70948
71228
  if (!fs21.existsSync(dir)) {
70949
71229
  fs21.mkdirSync(dir, { recursive: true });
@@ -73574,17 +73854,22 @@ var SASTScanner = class {
73574
73854
  * Store scan results in memory
73575
73855
  */
73576
73856
  async storeScanResults(scanId, scanType, vulnerabilities, summary) {
73857
+ const scanSummary = {
73858
+ scanId,
73859
+ scanType,
73860
+ summary,
73861
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
73862
+ vulnerabilityCount: vulnerabilities.length,
73863
+ // Keep only critical/high vulnerabilities in stored result
73864
+ criticalVulnerabilities: vulnerabilities.filter(
73865
+ (v62) => v62.severity === "critical" || v62.severity === "high"
73866
+ )
73867
+ };
73577
73868
  await this.memory.set(
73578
73869
  `security:scan:${scanId}`,
73579
- {
73580
- scanId,
73581
- scanType,
73582
- vulnerabilities,
73583
- summary,
73584
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
73585
- },
73586
- { namespace: "security-compliance", ttl: 86400 * 7 }
73587
- // 7 days
73870
+ scanSummary,
73871
+ { namespace: "security-compliance", ttl: 86400 * 2 }
73872
+ // 2 days (reduced from 7)
73588
73873
  );
73589
73874
  }
73590
73875
  // ==========================================================================
@@ -101917,6 +102202,13 @@ var QEKernelImpl = class {
101917
102202
  if (this._initialized) {
101918
102203
  return;
101919
102204
  }
102205
+ if (this._config.memoryBackend === "memory") {
102206
+ const tmpDbPath = path12.join(
102207
+ __require("os").tmpdir(),
102208
+ `aqe-test-${Date.now()}-${Math.random().toString(36).slice(2)}.db`
102209
+ );
102210
+ await initializeUnifiedPersistence({ dbPath: tmpDbPath });
102211
+ }
101920
102212
  await this._memory.initialize();
101921
102213
  const antiDriftMiddleware = new SemanticAntiDriftMiddleware({
101922
102214
  agentId: "qe-kernel"
@@ -103369,8 +103661,34 @@ var MinCutPersistence = class {
103369
103661
  JSON.stringify(snapshot.vertices),
103370
103662
  JSON.stringify(snapshot.edges)
103371
103663
  );
103664
+ await this.enforceRetention();
103372
103665
  return id;
103373
103666
  }
103667
+ /**
103668
+ * Enforce retention limits on snapshots and history to prevent DB bloat (Issue #258)
103669
+ */
103670
+ async enforceRetention(maxSnapshots = 200) {
103671
+ const db = this.memory.getDatabase();
103672
+ if (!db) return 0;
103673
+ const countRow = db.prepare("SELECT COUNT(*) as count FROM mincut_snapshots").get();
103674
+ if (!countRow || countRow.count <= maxSnapshots) return 0;
103675
+ const deleteCount = countRow.count - maxSnapshots;
103676
+ db.prepare(`
103677
+ DELETE FROM mincut_snapshots WHERE id IN (
103678
+ SELECT id FROM mincut_snapshots ORDER BY created_at ASC LIMIT ?
103679
+ )
103680
+ `).run(deleteCount);
103681
+ const historyCount = db.prepare("SELECT COUNT(*) as count FROM mincut_history").get();
103682
+ if (historyCount.count > 500) {
103683
+ const historyDelete = historyCount.count - 500;
103684
+ db.prepare(`
103685
+ DELETE FROM mincut_history WHERE id IN (
103686
+ SELECT id FROM mincut_history ORDER BY created_at ASC LIMIT ?
103687
+ )
103688
+ `).run(historyDelete);
103689
+ }
103690
+ return deleteCount;
103691
+ }
103374
103692
  /**
103375
103693
  * Get a snapshot by ID
103376
103694
  */
@@ -103922,7 +104240,10 @@ var QueenMinCutBridge = class {
103922
104240
  }
103923
104241
  this.eventSubscriptions = [];
103924
104242
  if (this.config.persistData) {
103925
- await this.saveSnapshot();
104243
+ try {
104244
+ await this.saveSnapshot();
104245
+ } catch {
104246
+ }
103926
104247
  }
103927
104248
  this.initialized = false;
103928
104249
  }
@@ -109347,7 +109668,8 @@ var DEFAULT_DYNAMIC_SCALING_CONFIG = {
109347
109668
 
109348
109669
  // src/coordination/dynamic-scaling/dynamic-scaler.ts
109349
109670
  import { randomUUID as randomUUID5 } from "node:crypto";
109350
- var DynamicScaler = class {
109671
+ init_unified_memory();
109672
+ var DynamicScaler = class _DynamicScaler {
109351
109673
  config;
109352
109674
  policy;
109353
109675
  metricsHistory = [];
@@ -109358,6 +109680,13 @@ var DynamicScaler = class {
109358
109680
  totalDecisions = 0;
109359
109681
  currentAgents;
109360
109682
  lastDecision;
109683
+ // KV store persistence (Tier 2)
109684
+ db = null;
109685
+ persistCount = 0;
109686
+ static KV_NAMESPACE = "scaling-metrics";
109687
+ static KV_KEY = "dynamic-scaler-snapshot";
109688
+ static PERSIST_INTERVAL = 10;
109689
+ static KV_TTL = 7200;
109361
109690
  /**
109362
109691
  * Create a new DynamicScaler.
109363
109692
  *
@@ -109383,6 +109712,11 @@ var DynamicScaler = class {
109383
109712
  if (this.metricsHistory.length > this.config.metricsHistorySize) {
109384
109713
  this.metricsHistory.shift();
109385
109714
  }
109715
+ this.persistCount++;
109716
+ if (this.persistCount % _DynamicScaler.PERSIST_INTERVAL === 0) {
109717
+ this.persistSnapshot().catch(() => {
109718
+ });
109719
+ }
109386
109720
  }
109387
109721
  // --------------------------------------------------------------------------
109388
109722
  // Evaluation
@@ -109580,6 +109914,23 @@ var DynamicScaler = class {
109580
109914
  // --------------------------------------------------------------------------
109581
109915
  // Lifecycle
109582
109916
  // --------------------------------------------------------------------------
109917
+ /**
109918
+ * Initialize persistence layer and load last snapshot from KV store.
109919
+ * Safe to call multiple times; will not throw on DB failure.
109920
+ */
109921
+ async initialize() {
109922
+ try {
109923
+ this.db = getUnifiedMemory();
109924
+ if (!this.db.isInitialized()) await this.db.initialize();
109925
+ await this.loadFromKv();
109926
+ } catch (error) {
109927
+ console.warn(
109928
+ "[DynamicScaler] DB init failed, using memory-only:",
109929
+ error instanceof Error ? error.message : String(error)
109930
+ );
109931
+ this.db = null;
109932
+ }
109933
+ }
109583
109934
  /**
109584
109935
  * Release internal buffers. The scaler should not be used after disposal.
109585
109936
  */
@@ -109620,12 +109971,68 @@ var DynamicScaler = class {
109620
109971
  }
109621
109972
  /**
109622
109973
  * Record a scaling event, evicting the oldest when the history cap is hit.
109974
+ * Triggers periodic persistence to KV store.
109623
109975
  */
109624
109976
  recordEvent(event) {
109625
109977
  this.events.push(event);
109626
109978
  if (this.events.length > this.config.decisionHistorySize) {
109627
109979
  this.events.shift();
109628
109980
  }
109981
+ this.persistCount++;
109982
+ if (this.persistCount % _DynamicScaler.PERSIST_INTERVAL === 0) {
109983
+ this.persistSnapshot().catch(() => {
109984
+ });
109985
+ }
109986
+ }
109987
+ /**
109988
+ * Load last persisted snapshot from KV store into in-memory state.
109989
+ */
109990
+ async loadFromKv() {
109991
+ if (!this.db) return;
109992
+ try {
109993
+ const snapshot = await this.db.kvGet(_DynamicScaler.KV_KEY, _DynamicScaler.KV_NAMESPACE);
109994
+ if (snapshot) {
109995
+ if (Array.isArray(snapshot.metricsHistory)) {
109996
+ for (const m74 of snapshot.metricsHistory) {
109997
+ this.metricsHistory.push(m74);
109998
+ }
109999
+ }
110000
+ if (Array.isArray(snapshot.events)) {
110001
+ for (const e20 of snapshot.events) {
110002
+ this.events.push(e20);
110003
+ }
110004
+ }
110005
+ }
110006
+ } catch (error) {
110007
+ console.warn(
110008
+ "[DynamicScaler] Failed to load KV snapshot:",
110009
+ error instanceof Error ? error.message : String(error)
110010
+ );
110011
+ }
110012
+ }
110013
+ /**
110014
+ * Persist a trimmed snapshot of metricsHistory and events to KV store.
110015
+ * Keeps only the last 50 entries of each to limit storage size.
110016
+ */
110017
+ async persistSnapshot() {
110018
+ if (!this.db) return;
110019
+ try {
110020
+ const snapshot = {
110021
+ metricsHistory: this.metricsHistory.slice(-50),
110022
+ events: this.events.slice(-50)
110023
+ };
110024
+ await this.db.kvSet(
110025
+ _DynamicScaler.KV_KEY,
110026
+ snapshot,
110027
+ _DynamicScaler.KV_NAMESPACE,
110028
+ _DynamicScaler.KV_TTL
110029
+ );
110030
+ } catch (error) {
110031
+ console.warn(
110032
+ "[DynamicScaler] Failed to persist KV snapshot:",
110033
+ error instanceof Error ? error.message : String(error)
110034
+ );
110035
+ }
109629
110036
  }
109630
110037
  };
109631
110038
  function createDynamicScaler(initialAgents, config) {
@@ -112275,6 +112682,7 @@ var EarlyExitTokenOptimizer = class {
112275
112682
  init_pattern_store();
112276
112683
 
112277
112684
  // src/learning/token-tracker.ts
112685
+ init_unified_memory();
112278
112686
  import { randomUUID as randomUUID6 } from "crypto";
112279
112687
  var DEFAULT_COST_CONFIG = {
112280
112688
  costPerInputToken: 3e-3 / 1e3,
@@ -112288,7 +112696,7 @@ var DEFAULT_PERSISTENCE_CONFIG2 = {
112288
112696
  // Auto-save every minute
112289
112697
  maxMetricsInMemory: 1e4
112290
112698
  };
112291
- var TokenMetricsCollectorImpl = class {
112699
+ var TokenMetricsCollectorImpl = class _TokenMetricsCollectorImpl {
112292
112700
  taskMetrics = [];
112293
112701
  agentMetrics = /* @__PURE__ */ new Map();
112294
112702
  domainMetrics = /* @__PURE__ */ new Map();
@@ -112304,6 +112712,15 @@ var TokenMetricsCollectorImpl = class {
112304
112712
  persistenceConfig = DEFAULT_PERSISTENCE_CONFIG2;
112305
112713
  autoSaveTimer = null;
112306
112714
  isDirty = false;
112715
+ // kv_store persistence
112716
+ db = null;
112717
+ kvPersistCount = 0;
112718
+ static KV_NAMESPACE = "token-usage-metrics";
112719
+ static KV_KEY = "token-tracker-snapshot";
112720
+ static KV_TTL = 604800;
112721
+ // 7 days
112722
+ static KV_PERSIST_INTERVAL = 10;
112723
+ // every 10 operations
112307
112724
  constructor() {
112308
112725
  this.sessionId = `session-${Date.now()}-${randomUUID6().substring(0, 8)}`;
112309
112726
  this.sessionStartTime = Date.now();
@@ -112718,6 +113135,88 @@ var TokenMetricsCollectorImpl = class {
112718
113135
  return this.isDirty;
112719
113136
  }
112720
113137
  // ============================================================================
113138
+ // kv_store Persistence
113139
+ // ============================================================================
113140
+ /**
113141
+ * Initialize kv_store persistence and restore snapshot if available.
113142
+ * This supplements the existing file-based persistence.
113143
+ */
113144
+ async initializeDb() {
113145
+ try {
113146
+ this.db = getUnifiedMemory();
113147
+ if (!this.db.isInitialized()) await this.db.initialize();
113148
+ await this.loadFromKv();
113149
+ } catch (error) {
113150
+ console.warn("[TokenMetricsCollector] DB init failed, using memory-only:", error instanceof Error ? error.message : String(error));
113151
+ this.db = null;
113152
+ }
113153
+ }
113154
+ /**
113155
+ * Persist current state snapshot to kv_store
113156
+ */
113157
+ async persistToKv() {
113158
+ if (!this.db) return;
113159
+ const snapshot = {
113160
+ version: "1.0.0",
113161
+ sessionId: this.sessionId,
113162
+ sessionStartTime: this.sessionStartTime,
113163
+ taskMetrics: this.taskMetrics.slice(-this.persistenceConfig.maxMetricsInMemory),
113164
+ optimizationStats: {
113165
+ cacheHits: this.cacheHits,
113166
+ earlyExits: this.earlyExits,
113167
+ totalTokensSaved: this.totalTokensSaved,
113168
+ totalPatternsReused: this.totalPatternsReused
113169
+ },
113170
+ lastSavedAt: Date.now()
113171
+ };
113172
+ await this.db.kvSet(
113173
+ _TokenMetricsCollectorImpl.KV_KEY,
113174
+ snapshot,
113175
+ _TokenMetricsCollectorImpl.KV_NAMESPACE,
113176
+ _TokenMetricsCollectorImpl.KV_TTL
113177
+ );
113178
+ }
113179
+ /**
113180
+ * Load state snapshot from kv_store
113181
+ */
113182
+ async loadFromKv() {
113183
+ if (!this.db) return false;
113184
+ const snapshot = await this.db.kvGet(
113185
+ _TokenMetricsCollectorImpl.KV_KEY,
113186
+ _TokenMetricsCollectorImpl.KV_NAMESPACE
113187
+ );
113188
+ if (!snapshot) return false;
113189
+ if (!snapshot.version || !snapshot.version.startsWith("1.")) {
113190
+ console.warn("[TokenMetricsCollector] Incompatible kv_store data version, skipping load");
113191
+ return false;
113192
+ }
113193
+ const historicalMetrics = snapshot.taskMetrics || [];
113194
+ this.taskMetrics = [...historicalMetrics, ...this.taskMetrics];
113195
+ this.cacheHits += snapshot.optimizationStats?.cacheHits || 0;
113196
+ this.earlyExits += snapshot.optimizationStats?.earlyExits || 0;
113197
+ this.totalTokensSaved += snapshot.optimizationStats?.totalTokensSaved || 0;
113198
+ this.totalPatternsReused += snapshot.optimizationStats?.totalPatternsReused || 0;
113199
+ for (const metric of historicalMetrics) {
113200
+ this.updateAgentMetrics(metric.agentId, metric.usage, metric.patternReused, metric.tokensSaved || 0);
113201
+ this.updateDomainMetrics(metric.domain, metric.usage);
113202
+ }
113203
+ if (this.taskMetrics.length > this.persistenceConfig.maxMetricsInMemory) {
113204
+ this.taskMetrics = this.taskMetrics.slice(-this.persistenceConfig.maxMetricsInMemory);
113205
+ }
113206
+ return true;
113207
+ }
113208
+ /**
113209
+ * Track state changes and persist to kv_store periodically
113210
+ */
113211
+ maybePersistToKv() {
113212
+ this.kvPersistCount++;
113213
+ if (this.kvPersistCount >= _TokenMetricsCollectorImpl.KV_PERSIST_INTERVAL) {
113214
+ this.kvPersistCount = 0;
113215
+ this.persistToKv().catch(() => {
113216
+ });
113217
+ }
113218
+ }
113219
+ // ============================================================================
112721
113220
  // Private Helper Methods
112722
113221
  // ============================================================================
112723
113222
  ensureInitialized() {
@@ -114421,7 +114920,7 @@ var ALL_DOMAINS2 = [
114421
114920
  "enterprise-integration"
114422
114921
  ];
114423
114922
  function getAQEVersion() {
114424
- return true ? "3.6.6" : "3.0.0";
114923
+ return true ? "3.6.8" : "3.0.0";
114425
114924
  }
114426
114925
  function createDefaultConfig(projectName, projectRoot) {
114427
114926
  return {
@@ -118935,9 +119434,22 @@ var HooksPhase = class extends BasePhase {
118935
119434
  * Uses `npx agentic-qe` for portability - works without global installation.
118936
119435
  * All hooks use --json output for structured data and fail silently with continueOnError.
118937
119436
  */
118938
- generateHooksConfig(config) {
119437
+ generateHooksConfig(_config) {
118939
119438
  return {
118940
119439
  PreToolUse: [
119440
+ // File guardian — MUST be first to block before learning hooks run
119441
+ {
119442
+ matcher: "^(Write|Edit|MultiEdit)$",
119443
+ hooks: [
119444
+ {
119445
+ type: "command",
119446
+ command: 'npx agentic-qe hooks guard --file "$TOOL_INPUT_file_path" --json',
119447
+ timeout: 3e3,
119448
+ continueOnError: true
119449
+ }
119450
+ ]
119451
+ },
119452
+ // Learning: pre-edit context
118941
119453
  {
118942
119454
  matcher: "^(Write|Edit|MultiEdit)$",
118943
119455
  hooks: [
@@ -118949,17 +119461,19 @@ var HooksPhase = class extends BasePhase {
118949
119461
  }
118950
119462
  ]
118951
119463
  },
119464
+ // Command bouncer — blocks dangerous commands
118952
119465
  {
118953
119466
  matcher: "^Bash$",
118954
119467
  hooks: [
118955
119468
  {
118956
119469
  type: "command",
118957
119470
  command: 'npx agentic-qe hooks pre-command --command "$TOOL_INPUT_command" --json',
118958
- timeout: 5e3,
119471
+ timeout: 3e3,
118959
119472
  continueOnError: true
118960
119473
  }
118961
119474
  ]
118962
119475
  },
119476
+ // Task routing
118963
119477
  {
118964
119478
  matcher: "^Task$",
118965
119479
  hooks: [
@@ -118978,7 +119492,7 @@ var HooksPhase = class extends BasePhase {
118978
119492
  hooks: [
118979
119493
  {
118980
119494
  type: "command",
118981
- command: 'npx agentic-qe hooks post-edit --file "$TOOL_INPUT_file_path" --success "$TOOL_SUCCESS" --json',
119495
+ command: 'npx agentic-qe hooks post-edit --file "$TOOL_INPUT_file_path" --success --json',
118982
119496
  timeout: 5e3,
118983
119497
  continueOnError: true
118984
119498
  }
@@ -118989,7 +119503,7 @@ var HooksPhase = class extends BasePhase {
118989
119503
  hooks: [
118990
119504
  {
118991
119505
  type: "command",
118992
- command: 'npx agentic-qe hooks post-command --command "$TOOL_INPUT_command" --success "$TOOL_SUCCESS" --json',
119506
+ command: 'npx agentic-qe hooks post-command --command "$TOOL_INPUT_command" --success --json',
118993
119507
  timeout: 5e3,
118994
119508
  continueOnError: true
118995
119509
  }
@@ -119000,7 +119514,7 @@ var HooksPhase = class extends BasePhase {
119000
119514
  hooks: [
119001
119515
  {
119002
119516
  type: "command",
119003
- command: 'npx agentic-qe hooks post-task --task-id "$TOOL_RESULT_agent_id" --success "$TOOL_SUCCESS" --json',
119517
+ command: 'npx agentic-qe hooks post-task --task-id "$TOOL_RESULT_agent_id" --success --json',
119004
119518
  timeout: 5e3,
119005
119519
  continueOnError: true
119006
119520
  }
@@ -137839,13 +138353,19 @@ Examples:
137839
138353
  });
137840
138354
  const result = results[0] || { success: true, guidance: [], routing: null };
137841
138355
  if (options.json) {
138356
+ const guidanceLines = result.guidance || [];
138357
+ const agentHint = result.routing?.recommendedAgent ? `Recommended agent: ${result.routing.recommendedAgent} (${(result.routing.confidence * 100).toFixed(0)}% confidence).` : "";
138358
+ const contextStr = [
138359
+ agentHint,
138360
+ ...guidanceLines.map((g67) => g67)
138361
+ ].filter(Boolean).join(" ");
137842
138362
  printJson({
137843
- success: result.success,
138363
+ hookSpecificOutput: {
138364
+ hookEventName: "PreToolUse",
138365
+ additionalContext: contextStr || void 0
138366
+ },
137844
138367
  file: options.file,
137845
138368
  operation: options.operation,
137846
- guidance: result.guidance || [],
137847
- recommendedAgent: result.routing?.recommendedAgent,
137848
- confidence: result.routing?.confidence,
137849
138369
  patterns: result.routing?.patterns?.length || 0
137850
138370
  });
137851
138371
  } else {
@@ -138161,18 +138681,32 @@ Registered: ${events.length}/${Object.keys(QE_HOOK_EVENTS).length}`)
138161
138681
  dreamState.totalDreamsThisSession = 0;
138162
138682
  }
138163
138683
  await memoryBackend2.set(DREAM_STATE_KEY, dreamState);
138684
+ const contextParts = [];
138685
+ contextParts.push(`AQE Learning: ${stats.totalPatterns} patterns loaded`);
138686
+ const domainEntries = Object.entries(stats.byDomain).filter(([, count]) => count > 0).sort(([, a37], [, b68]) => b68 - a37).slice(0, 5);
138687
+ if (domainEntries.length > 0) {
138688
+ contextParts.push(`Top domains: ${domainEntries.map(([d74, c70]) => `${d74}(${c70})`).join(", ")}`);
138689
+ }
138690
+ if (stats.patternSuccessRate > 0) {
138691
+ contextParts.push(`Pattern success rate: ${(stats.patternSuccessRate * 100).toFixed(0)}%`);
138692
+ }
138693
+ if (stats.routingRequests > 0) {
138694
+ contextParts.push(`Routing confidence: ${(stats.avgRoutingConfidence * 100).toFixed(0)}% across ${stats.routingRequests} requests`);
138695
+ }
138696
+ const additionalContext = contextParts.join(". ") + ".";
138164
138697
  if (options.json) {
138165
138698
  printJson({
138166
- success: true,
138699
+ hookSpecificOutput: {
138700
+ hookEventName: "SessionStart",
138701
+ additionalContext
138702
+ },
138167
138703
  sessionId,
138168
138704
  initialized: true,
138169
138705
  patternsLoaded: stats.totalPatterns,
138170
138706
  dreamScheduler: {
138171
138707
  enabled: true,
138172
138708
  lastDreamTime: dreamState.lastDreamTime,
138173
- pendingExperiences: dreamState.experienceCount,
138174
- intervalMs: DREAM_INTERVAL_MS,
138175
- experienceThreshold: DREAM_EXPERIENCE_THRESHOLD
138709
+ pendingExperiences: dreamState.experienceCount
138176
138710
  }
138177
138711
  });
138178
138712
  } else {
@@ -138199,8 +138733,9 @@ Registered: ${events.length}/${Object.keys(QE_HOOK_EVENTS).length}`)
138199
138733
  }
138200
138734
  }
138201
138735
  if (options.json) {
138736
+ const summary = stats ? `Session complete: ${stats.totalPatterns} patterns, ${stats.routingRequests} routings, ${(stats.patternSuccessRate * 100).toFixed(0)}% success rate` : "Session complete";
138202
138737
  printJson({
138203
- success: true,
138738
+ continue: true,
138204
138739
  sessionId,
138205
138740
  stateSaved: options.saveState || false,
138206
138741
  metricsExported: options.exportMetrics || false,
@@ -138324,34 +138859,119 @@ Registered: ${events.length}/${Object.keys(QE_HOOK_EVENTS).length}`)
138324
138859
  process.exit(0);
138325
138860
  }
138326
138861
  });
138327
- hooks.command("pre-command").description("Get context before executing a Bash command").option("-c, --command <cmd>", "Command to be executed").option("--json", "Output as JSON").action(async (options) => {
138328
- try {
138329
- const command = options.command || "";
138330
- const warnings = [];
138331
- if (command.includes("rm -rf /") || command.includes("rm -rf ~")) {
138332
- warnings.push("Dangerous recursive delete detected");
138333
- }
138334
- if (command.includes("> /dev/sd") || command.includes("dd if=")) {
138335
- warnings.push("Direct disk write detected");
138336
- }
138337
- if (command.includes(".agentic-qe") && command.includes("rm")) {
138338
- warnings.push("Deleting AQE data files");
138862
+ hooks.command("guard").description("File guardian - block edits to protected files").requiredOption("-f, --file <path>", "File path to check").option("--json", "Output as JSON (required for hook API)").action(async (options) => {
138863
+ try {
138864
+ const filePath = options.file || "";
138865
+ const normalizedPath = filePath.replace(/\\/g, "/");
138866
+ const protectedPatterns = [
138867
+ { pattern: /^\.env($|\.)/, reason: "Environment file contains secrets" },
138868
+ { pattern: /\.env\.[a-zA-Z]+$/, reason: "Environment file contains secrets" },
138869
+ { pattern: /\.lock$/, reason: "Lock files are auto-generated" },
138870
+ { pattern: /(^|\/)node_modules\//, reason: "node_modules is managed by package manager" },
138871
+ { pattern: /(^|\/)\.agentic-qe\/memory\.db/, reason: "AQE memory database must not be directly edited" },
138872
+ { pattern: /(^|\/)\.agentic-qe\/memory\.db-wal$/, reason: "AQE WAL file must not be directly edited" },
138873
+ { pattern: /(^|\/)\.agentic-qe\/memory\.db-shm$/, reason: "AQE shared memory file must not be directly edited" }
138874
+ ];
138875
+ const match = protectedPatterns.find((p74) => p74.pattern.test(normalizedPath));
138876
+ if (match) {
138877
+ if (options.json) {
138878
+ printJson({
138879
+ hookSpecificOutput: {
138880
+ hookEventName: "PreToolUse",
138881
+ permissionDecision: "deny",
138882
+ permissionDecisionReason: `Protected file: ${match.reason} (${filePath})`
138883
+ }
138884
+ });
138885
+ } else {
138886
+ printError(`Blocked: ${match.reason} (${filePath})`);
138887
+ }
138888
+ } else {
138889
+ if (options.json) {
138890
+ printJson({
138891
+ hookSpecificOutput: {
138892
+ hookEventName: "PreToolUse",
138893
+ permissionDecision: "allow"
138894
+ }
138895
+ });
138896
+ } else {
138897
+ printSuccess(`Allowed: ${filePath}`);
138898
+ }
138339
138899
  }
138900
+ process.exit(0);
138901
+ } catch (error) {
138340
138902
  if (options.json) {
138341
138903
  printJson({
138342
- success: true,
138343
- command: command.substring(0, 100),
138344
- warnings,
138345
- safe: warnings.length === 0
138904
+ hookSpecificOutput: {
138905
+ hookEventName: "PreToolUse",
138906
+ permissionDecision: "allow"
138907
+ }
138346
138908
  });
138347
- } else if (warnings.length > 0) {
138348
- console.log(chalk27.yellow("\n\u26A0\uFE0F Command Warnings:"));
138349
- warnings.forEach((w54) => console.log(chalk27.yellow(` - ${w54}`)));
138909
+ }
138910
+ process.exit(0);
138911
+ }
138912
+ });
138913
+ hooks.command("pre-command").description("Get context before executing a Bash command").option("-c, --command <cmd>", "Command to be executed").option("--json", "Output as JSON").action(async (options) => {
138914
+ try {
138915
+ const command = options.command || "";
138916
+ const dangerousPatterns = [
138917
+ { pattern: /rm\s+(-[a-zA-Z]*f[a-zA-Z]*\s+)?-[a-zA-Z]*r[a-zA-Z]*\s+\/(?!\w)/, reason: "Recursive delete of root filesystem" },
138918
+ { pattern: /rm\s+(-[a-zA-Z]*r[a-zA-Z]*\s+)?-[a-zA-Z]*f[a-zA-Z]*\s+\/(?!\w)/, reason: "Recursive delete of root filesystem" },
138919
+ { pattern: /rm\s+-rf\s+~/, reason: "Recursive delete of home directory" },
138920
+ { pattern: /DROP\s+(TABLE|DATABASE|SCHEMA)/i, reason: "Destructive SQL operation" },
138921
+ { pattern: /git\s+push\s+.*--force(?!-)/, reason: "Force push can overwrite remote history" },
138922
+ { pattern: /git\s+reset\s+--hard/, reason: "Hard reset discards uncommitted changes" },
138923
+ { pattern: />\s*\/dev\/sd[a-z]/, reason: "Direct write to block device" },
138924
+ { pattern: /dd\s+if=.*of=\/dev\/sd/, reason: "Direct disk write via dd" },
138925
+ { pattern: /chmod\s+777\s/, reason: "World-writable permissions are a security risk" },
138926
+ { pattern: /:\(\)\s*\{\s*:\|\s*:&\s*\}\s*;?\s*:/, reason: "Fork bomb detected" },
138927
+ { pattern: /mkfs\./, reason: "Filesystem format operation" },
138928
+ { pattern: />\s*\/dev\/null\s*2>&1\s*&\s*disown/, reason: "Stealth background process" }
138929
+ ];
138930
+ const warningPatterns = [
138931
+ { pattern: /\.agentic-qe.*rm/, reason: "Deleting AQE data files" },
138932
+ { pattern: /rm\s+-rf\s/, reason: "Recursive force delete" },
138933
+ { pattern: /git\s+clean\s+-[a-zA-Z]*f/, reason: "Force cleaning untracked files" }
138934
+ ];
138935
+ const dangerMatch = dangerousPatterns.find((p74) => p74.pattern.test(command));
138936
+ const warnings = warningPatterns.filter((p74) => p74.pattern.test(command)).map((p74) => p74.reason);
138937
+ if (dangerMatch) {
138938
+ if (options.json) {
138939
+ printJson({
138940
+ hookSpecificOutput: {
138941
+ hookEventName: "PreToolUse",
138942
+ permissionDecision: "deny",
138943
+ permissionDecisionReason: `Dangerous command blocked: ${dangerMatch.reason}`
138944
+ }
138945
+ });
138946
+ } else {
138947
+ printError(`Blocked: ${dangerMatch.reason}`);
138948
+ }
138949
+ } else {
138950
+ if (options.json) {
138951
+ const result = {
138952
+ hookSpecificOutput: {
138953
+ hookEventName: "PreToolUse",
138954
+ permissionDecision: "allow"
138955
+ }
138956
+ };
138957
+ if (warnings.length > 0) {
138958
+ result.hookSpecificOutput.additionalContext = `Warnings: ${warnings.join("; ")}`;
138959
+ }
138960
+ printJson(result);
138961
+ } else if (warnings.length > 0) {
138962
+ console.log(chalk27.yellow("\n\u26A0\uFE0F Command Warnings:"));
138963
+ warnings.forEach((w54) => console.log(chalk27.yellow(` - ${w54}`)));
138964
+ }
138350
138965
  }
138351
138966
  process.exit(0);
138352
138967
  } catch (error) {
138353
138968
  if (options.json) {
138354
- printJson({ success: false, error: error instanceof Error ? error.message : "unknown" });
138969
+ printJson({
138970
+ hookSpecificOutput: {
138971
+ hookEventName: "PreToolUse",
138972
+ permissionDecision: "allow"
138973
+ }
138974
+ });
138355
138975
  }
138356
138976
  process.exit(0);
138357
138977
  }
@@ -140349,7 +140969,7 @@ async function cleanupAndExit(code = 0) {
140349
140969
  process.exit(code);
140350
140970
  }
140351
140971
  var program = new Command18();
140352
- var VERSION = true ? "3.6.6" : "0.0.0-dev";
140972
+ var VERSION = true ? "3.6.8" : "0.0.0-dev";
140353
140973
  program.name("aqe").description("Agentic QE - Domain-Driven Quality Engineering").version(VERSION);
140354
140974
  var registry = createCommandRegistry(context, cleanupAndExit, ensureInitialized);
140355
140975
  registry.registerAll(program);