agentic-qe 1.8.3 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (290) hide show
  1. package/.claude/skills/agentic-jujutsu/SKILL.md +645 -0
  2. package/.claude/skills/cicd-pipeline-qe-orchestrator/README.md +2 -2
  3. package/.claude/skills/cicd-pipeline-qe-orchestrator/SKILL.md +6 -6
  4. package/CHANGELOG.md +595 -0
  5. package/README.md +117 -16
  6. package/config/constitution.schema.json +423 -0
  7. package/config/otel-collector.yaml +234 -0
  8. package/dist/App.d.ts +5 -0
  9. package/dist/App.d.ts.map +1 -0
  10. package/dist/App.js +15 -0
  11. package/dist/App.js.map +1 -0
  12. package/dist/cli/commands/constitution.d.ts +34 -0
  13. package/dist/cli/commands/constitution.d.ts.map +1 -0
  14. package/dist/cli/commands/constitution.js +679 -0
  15. package/dist/cli/commands/constitution.js.map +1 -0
  16. package/dist/cli/commands/init-claude-md-template.js +3 -3
  17. package/dist/cli/commands/init.d.ts +8 -75
  18. package/dist/cli/commands/init.d.ts.map +1 -1
  19. package/dist/cli/commands/init.js +22 -2292
  20. package/dist/cli/commands/init.js.map +1 -1
  21. package/dist/cli/commands/telemetry.d.ts +36 -0
  22. package/dist/cli/commands/telemetry.d.ts.map +1 -0
  23. package/dist/cli/commands/telemetry.js +364 -0
  24. package/dist/cli/commands/telemetry.js.map +1 -0
  25. package/dist/cli/index.js +66 -0
  26. package/dist/cli/index.js.map +1 -1
  27. package/dist/cli/init/agents.d.ts +22 -0
  28. package/dist/cli/init/agents.d.ts.map +1 -0
  29. package/dist/cli/init/agents.js +522 -0
  30. package/dist/cli/init/agents.js.map +1 -0
  31. package/dist/cli/init/bash-wrapper.d.ts +14 -0
  32. package/dist/cli/init/bash-wrapper.d.ts.map +1 -0
  33. package/dist/cli/init/bash-wrapper.js +47 -0
  34. package/dist/cli/init/bash-wrapper.js.map +1 -0
  35. package/dist/cli/init/claude-config.d.ts +24 -0
  36. package/dist/cli/init/claude-config.d.ts.map +1 -0
  37. package/dist/cli/init/claude-config.js +275 -0
  38. package/dist/cli/init/claude-config.js.map +1 -0
  39. package/dist/cli/init/claude-md.d.ts +19 -0
  40. package/dist/cli/init/claude-md.d.ts.map +1 -0
  41. package/dist/cli/init/claude-md.js +153 -0
  42. package/dist/cli/init/claude-md.js.map +1 -0
  43. package/dist/cli/init/commands.d.ts +6 -0
  44. package/dist/cli/init/commands.d.ts.map +1 -0
  45. package/dist/cli/init/commands.js +83 -0
  46. package/dist/cli/init/commands.js.map +1 -0
  47. package/dist/cli/init/database-init.d.ts +15 -0
  48. package/dist/cli/init/database-init.d.ts.map +1 -0
  49. package/dist/cli/init/database-init.js +203 -0
  50. package/dist/cli/init/database-init.js.map +1 -0
  51. package/dist/cli/init/directory-structure.d.ts +14 -0
  52. package/dist/cli/init/directory-structure.d.ts.map +1 -0
  53. package/dist/cli/init/directory-structure.js +107 -0
  54. package/dist/cli/init/directory-structure.js.map +1 -0
  55. package/dist/cli/init/documentation.d.ts +14 -0
  56. package/dist/cli/init/documentation.d.ts.map +1 -0
  57. package/dist/cli/init/documentation.js +195 -0
  58. package/dist/cli/init/documentation.js.map +1 -0
  59. package/dist/cli/init/fleet-config.d.ts +34 -0
  60. package/dist/cli/init/fleet-config.d.ts.map +1 -0
  61. package/dist/cli/init/fleet-config.js +269 -0
  62. package/dist/cli/init/fleet-config.js.map +1 -0
  63. package/dist/cli/init/helpers.d.ts +6 -0
  64. package/dist/cli/init/helpers.d.ts.map +1 -0
  65. package/dist/cli/init/helpers.js +94 -0
  66. package/dist/cli/init/helpers.js.map +1 -0
  67. package/dist/cli/init/index.d.ts +32 -0
  68. package/dist/cli/init/index.d.ts.map +1 -0
  69. package/dist/cli/init/index.js +294 -0
  70. package/dist/cli/init/index.js.map +1 -0
  71. package/dist/cli/init/skills.d.ts +6 -0
  72. package/dist/cli/init/skills.d.ts.map +1 -0
  73. package/dist/cli/init/skills.js +138 -0
  74. package/dist/cli/init/skills.js.map +1 -0
  75. package/dist/cli/init/utils/file-utils.d.ts +74 -0
  76. package/dist/cli/init/utils/file-utils.d.ts.map +1 -0
  77. package/dist/cli/init/utils/file-utils.js +187 -0
  78. package/dist/cli/init/utils/file-utils.js.map +1 -0
  79. package/dist/cli/init/utils/index.d.ts +18 -0
  80. package/dist/cli/init/utils/index.d.ts.map +1 -0
  81. package/dist/cli/init/utils/index.js +48 -0
  82. package/dist/cli/init/utils/index.js.map +1 -0
  83. package/dist/cli/init/utils/log-utils.d.ts +47 -0
  84. package/dist/cli/init/utils/log-utils.d.ts.map +1 -0
  85. package/dist/cli/init/utils/log-utils.js +68 -0
  86. package/dist/cli/init/utils/log-utils.js.map +1 -0
  87. package/dist/cli/init/utils/path-utils.d.ts +91 -0
  88. package/dist/cli/init/utils/path-utils.d.ts.map +1 -0
  89. package/dist/cli/init/utils/path-utils.js +208 -0
  90. package/dist/cli/init/utils/path-utils.js.map +1 -0
  91. package/dist/cli/init/utils/validation-utils.d.ts +44 -0
  92. package/dist/cli/init/utils/validation-utils.d.ts.map +1 -0
  93. package/dist/cli/init/utils/validation-utils.js +68 -0
  94. package/dist/cli/init/utils/validation-utils.js.map +1 -0
  95. package/dist/cli/init/utils.d.ts +183 -0
  96. package/dist/cli/init/utils.d.ts.map +1 -0
  97. package/dist/cli/init/utils.js +354 -0
  98. package/dist/cli/init/utils.js.map +1 -0
  99. package/dist/components/Dashboard/Dashboard.d.ts +4 -0
  100. package/dist/components/Dashboard/Dashboard.d.ts.map +1 -0
  101. package/dist/components/Dashboard/Dashboard.js +148 -0
  102. package/dist/components/Dashboard/Dashboard.js.map +1 -0
  103. package/dist/components/Dashboard/DashboardHeader.d.ts +4 -0
  104. package/dist/components/Dashboard/DashboardHeader.d.ts.map +1 -0
  105. package/dist/components/Dashboard/DashboardHeader.js +138 -0
  106. package/dist/components/Dashboard/DashboardHeader.js.map +1 -0
  107. package/dist/constitution/evaluators/ast-evaluator.d.ts +42 -0
  108. package/dist/constitution/evaluators/ast-evaluator.d.ts.map +1 -0
  109. package/dist/constitution/evaluators/ast-evaluator.js +303 -0
  110. package/dist/constitution/evaluators/ast-evaluator.js.map +1 -0
  111. package/dist/constitution/evaluators/base.d.ts +144 -0
  112. package/dist/constitution/evaluators/base.d.ts.map +1 -0
  113. package/dist/constitution/evaluators/base.js +144 -0
  114. package/dist/constitution/evaluators/base.js.map +1 -0
  115. package/dist/constitution/evaluators/index.d.ts +19 -0
  116. package/dist/constitution/evaluators/index.d.ts.map +1 -0
  117. package/dist/constitution/evaluators/index.js +56 -0
  118. package/dist/constitution/evaluators/index.js.map +1 -0
  119. package/dist/constitution/evaluators/metric-evaluator.d.ts +59 -0
  120. package/dist/constitution/evaluators/metric-evaluator.d.ts.map +1 -0
  121. package/dist/constitution/evaluators/metric-evaluator.js +195 -0
  122. package/dist/constitution/evaluators/metric-evaluator.js.map +1 -0
  123. package/dist/constitution/evaluators/pattern-evaluator.d.ts +66 -0
  124. package/dist/constitution/evaluators/pattern-evaluator.d.ts.map +1 -0
  125. package/dist/constitution/evaluators/pattern-evaluator.js +221 -0
  126. package/dist/constitution/evaluators/pattern-evaluator.js.map +1 -0
  127. package/dist/constitution/evaluators/semantic-evaluator.d.ts +68 -0
  128. package/dist/constitution/evaluators/semantic-evaluator.d.ts.map +1 -0
  129. package/dist/constitution/evaluators/semantic-evaluator.js +250 -0
  130. package/dist/constitution/evaluators/semantic-evaluator.js.map +1 -0
  131. package/dist/constitution/index.d.ts +105 -0
  132. package/dist/constitution/index.d.ts.map +1 -0
  133. package/dist/constitution/index.js +207 -0
  134. package/dist/constitution/index.js.map +1 -0
  135. package/dist/constitution/loader.d.ts +141 -0
  136. package/dist/constitution/loader.d.ts.map +1 -0
  137. package/dist/constitution/loader.js +515 -0
  138. package/dist/constitution/loader.js.map +1 -0
  139. package/dist/constitution/schema.d.ts +409 -0
  140. package/dist/constitution/schema.d.ts.map +1 -0
  141. package/dist/constitution/schema.js +71 -0
  142. package/dist/constitution/schema.js.map +1 -0
  143. package/dist/contexts/DashboardContext.d.ts +41 -0
  144. package/dist/contexts/DashboardContext.d.ts.map +1 -0
  145. package/dist/contexts/DashboardContext.js +187 -0
  146. package/dist/contexts/DashboardContext.js.map +1 -0
  147. package/dist/core/memory/MemoryManagerFactory.d.ts +77 -0
  148. package/dist/core/memory/MemoryManagerFactory.d.ts.map +1 -0
  149. package/dist/core/memory/MemoryManagerFactory.js +270 -0
  150. package/dist/core/memory/MemoryManagerFactory.js.map +1 -0
  151. package/dist/core/memory/SwarmMemoryManager.d.ts +58 -0
  152. package/dist/core/memory/SwarmMemoryManager.d.ts.map +1 -1
  153. package/dist/core/memory/SwarmMemoryManager.js +375 -131
  154. package/dist/core/memory/SwarmMemoryManager.js.map +1 -1
  155. package/dist/core/memory/index.d.ts +1 -0
  156. package/dist/core/memory/index.d.ts.map +1 -1
  157. package/dist/core/memory/index.js +12 -1
  158. package/dist/core/memory/index.js.map +1 -1
  159. package/dist/hooks/useKeyboardShortcuts.d.ts +12 -0
  160. package/dist/hooks/useKeyboardShortcuts.d.ts.map +1 -0
  161. package/dist/hooks/useKeyboardShortcuts.js +69 -0
  162. package/dist/hooks/useKeyboardShortcuts.js.map +1 -0
  163. package/dist/mcp/handlers/memory/memory-backup.js +6 -6
  164. package/dist/mcp/handlers/memory/memory-backup.js.map +1 -1
  165. package/dist/mcp/handlers/phase2/Phase2Tools.d.ts.map +1 -1
  166. package/dist/mcp/handlers/phase2/Phase2Tools.js +4 -2
  167. package/dist/mcp/handlers/phase2/Phase2Tools.js.map +1 -1
  168. package/dist/mcp/server.d.ts.map +1 -1
  169. package/dist/mcp/server.js +4 -38
  170. package/dist/mcp/server.js.map +1 -1
  171. package/dist/mcp/services/AgentRegistry.d.ts.map +1 -1
  172. package/dist/mcp/services/AgentRegistry.js +4 -4
  173. package/dist/mcp/services/AgentRegistry.js.map +1 -1
  174. package/dist/persistence/event-store.d.ts +162 -0
  175. package/dist/persistence/event-store.d.ts.map +1 -0
  176. package/dist/persistence/event-store.js +315 -0
  177. package/dist/persistence/event-store.js.map +1 -0
  178. package/dist/persistence/index.d.ts +145 -0
  179. package/dist/persistence/index.d.ts.map +1 -0
  180. package/dist/persistence/index.js +227 -0
  181. package/dist/persistence/index.js.map +1 -0
  182. package/dist/persistence/metrics-aggregator.d.ts +187 -0
  183. package/dist/persistence/metrics-aggregator.d.ts.map +1 -0
  184. package/dist/persistence/metrics-aggregator.js +495 -0
  185. package/dist/persistence/metrics-aggregator.js.map +1 -0
  186. package/dist/persistence/reasoning-store.d.ts +178 -0
  187. package/dist/persistence/reasoning-store.d.ts.map +1 -0
  188. package/dist/persistence/reasoning-store.js +440 -0
  189. package/dist/persistence/reasoning-store.js.map +1 -0
  190. package/dist/persistence/schema.d.ts +181 -0
  191. package/dist/persistence/schema.d.ts.map +1 -0
  192. package/dist/persistence/schema.js +186 -0
  193. package/dist/persistence/schema.js.map +1 -0
  194. package/dist/telemetry/bootstrap.d.ts +67 -0
  195. package/dist/telemetry/bootstrap.d.ts.map +1 -0
  196. package/dist/telemetry/bootstrap.js +320 -0
  197. package/dist/telemetry/bootstrap.js.map +1 -0
  198. package/dist/telemetry/index.d.ts +16 -0
  199. package/dist/telemetry/index.d.ts.map +1 -0
  200. package/dist/telemetry/index.js +84 -0
  201. package/dist/telemetry/index.js.map +1 -0
  202. package/dist/telemetry/instrumentation/agent.d.ts +158 -0
  203. package/dist/telemetry/instrumentation/agent.d.ts.map +1 -0
  204. package/dist/telemetry/instrumentation/agent.js +372 -0
  205. package/dist/telemetry/instrumentation/agent.js.map +1 -0
  206. package/dist/telemetry/instrumentation/index.d.ts +24 -0
  207. package/dist/telemetry/instrumentation/index.d.ts.map +1 -0
  208. package/dist/telemetry/instrumentation/index.js +54 -0
  209. package/dist/telemetry/instrumentation/index.js.map +1 -0
  210. package/dist/telemetry/instrumentation/memory.d.ts +313 -0
  211. package/dist/telemetry/instrumentation/memory.d.ts.map +1 -0
  212. package/dist/telemetry/instrumentation/memory.js +552 -0
  213. package/dist/telemetry/instrumentation/memory.js.map +1 -0
  214. package/dist/telemetry/instrumentation/task.d.ts +146 -0
  215. package/dist/telemetry/instrumentation/task.d.ts.map +1 -0
  216. package/dist/telemetry/instrumentation/task.js +305 -0
  217. package/dist/telemetry/instrumentation/task.js.map +1 -0
  218. package/dist/telemetry/metrics/agent-metrics.d.ts +109 -0
  219. package/dist/telemetry/metrics/agent-metrics.d.ts.map +1 -0
  220. package/dist/telemetry/metrics/agent-metrics.js +213 -0
  221. package/dist/telemetry/metrics/agent-metrics.js.map +1 -0
  222. package/dist/telemetry/metrics/collectors/cost.d.ts +246 -0
  223. package/dist/telemetry/metrics/collectors/cost.d.ts.map +1 -0
  224. package/dist/telemetry/metrics/collectors/cost.js +526 -0
  225. package/dist/telemetry/metrics/collectors/cost.js.map +1 -0
  226. package/dist/telemetry/metrics/collectors/pricing-config.d.ts +87 -0
  227. package/dist/telemetry/metrics/collectors/pricing-config.d.ts.map +1 -0
  228. package/dist/telemetry/metrics/collectors/pricing-config.js +207 -0
  229. package/dist/telemetry/metrics/collectors/pricing-config.js.map +1 -0
  230. package/dist/telemetry/metrics/index.d.ts +54 -0
  231. package/dist/telemetry/metrics/index.d.ts.map +1 -0
  232. package/dist/telemetry/metrics/index.js +116 -0
  233. package/dist/telemetry/metrics/index.js.map +1 -0
  234. package/dist/telemetry/metrics/quality-metrics.d.ts +171 -0
  235. package/dist/telemetry/metrics/quality-metrics.d.ts.map +1 -0
  236. package/dist/telemetry/metrics/quality-metrics.js +259 -0
  237. package/dist/telemetry/metrics/quality-metrics.js.map +1 -0
  238. package/dist/telemetry/metrics/system-metrics.d.ts +129 -0
  239. package/dist/telemetry/metrics/system-metrics.d.ts.map +1 -0
  240. package/dist/telemetry/metrics/system-metrics.js +380 -0
  241. package/dist/telemetry/metrics/system-metrics.js.map +1 -0
  242. package/dist/telemetry/types.d.ts +195 -0
  243. package/dist/telemetry/types.d.ts.map +1 -0
  244. package/dist/telemetry/types.js +90 -0
  245. package/dist/telemetry/types.js.map +1 -0
  246. package/dist/visualization/api/RestEndpoints.d.ts +136 -0
  247. package/dist/visualization/api/RestEndpoints.d.ts.map +1 -0
  248. package/dist/visualization/api/RestEndpoints.js +428 -0
  249. package/dist/visualization/api/RestEndpoints.js.map +1 -0
  250. package/dist/visualization/api/WebSocketServer.d.ts +165 -0
  251. package/dist/visualization/api/WebSocketServer.d.ts.map +1 -0
  252. package/dist/visualization/api/WebSocketServer.js +518 -0
  253. package/dist/visualization/api/WebSocketServer.js.map +1 -0
  254. package/dist/visualization/core/DataTransformer.d.ts +89 -0
  255. package/dist/visualization/core/DataTransformer.d.ts.map +1 -0
  256. package/dist/visualization/core/DataTransformer.js +478 -0
  257. package/dist/visualization/core/DataTransformer.js.map +1 -0
  258. package/dist/visualization/index.d.ts +92 -0
  259. package/dist/visualization/index.d.ts.map +1 -0
  260. package/dist/visualization/index.js +121 -0
  261. package/dist/visualization/index.js.map +1 -0
  262. package/dist/visualization/types.d.ts +148 -0
  263. package/dist/visualization/types.d.ts.map +1 -0
  264. package/dist/visualization/types.js +7 -0
  265. package/dist/visualization/types.js.map +1 -0
  266. package/dist/voting/consensus.d.ts +87 -0
  267. package/dist/voting/consensus.d.ts.map +1 -0
  268. package/dist/voting/consensus.js +568 -0
  269. package/dist/voting/consensus.js.map +1 -0
  270. package/dist/voting/index.d.ts +12 -0
  271. package/dist/voting/index.d.ts.map +1 -0
  272. package/dist/voting/index.js +36 -0
  273. package/dist/voting/index.js.map +1 -0
  274. package/dist/voting/orchestrator.d.ts +65 -0
  275. package/dist/voting/orchestrator.d.ts.map +1 -0
  276. package/dist/voting/orchestrator.js +306 -0
  277. package/dist/voting/orchestrator.js.map +1 -0
  278. package/dist/voting/panel-assembly.d.ts +54 -0
  279. package/dist/voting/panel-assembly.d.ts.map +1 -0
  280. package/dist/voting/panel-assembly.js +192 -0
  281. package/dist/voting/panel-assembly.js.map +1 -0
  282. package/dist/voting/protocol.d.ts +119 -0
  283. package/dist/voting/protocol.d.ts.map +1 -0
  284. package/dist/voting/protocol.js +18 -0
  285. package/dist/voting/protocol.js.map +1 -0
  286. package/dist/voting/types.d.ts +125 -0
  287. package/dist/voting/types.d.ts.map +1 -0
  288. package/dist/voting/types.js +7 -0
  289. package/dist/voting/types.js.map +1 -0
  290. package/package.json +43 -2
@@ -46,6 +46,9 @@ Object.defineProperty(exports, "AccessLevel", { enumerable: true, get: function
46
46
  Object.defineProperty(exports, "Permission", { enumerable: true, get: function () { return AccessControl_1.Permission; } });
47
47
  Object.defineProperty(exports, "AccessControlError", { enumerable: true, get: function () { return AccessControl_1.AccessControlError; } });
48
48
  const AgentDBManager_1 = require("./AgentDBManager");
49
+ const PatternCache_1 = require("./PatternCache");
50
+ const memory_1 = require("../../telemetry/instrumentation/memory");
51
+ const types_1 = require("../../types");
49
52
  /**
50
53
  * SwarmMemoryManager - Manages persistent memory for agent swarm coordination
51
54
  *
@@ -84,6 +87,12 @@ class SwarmMemoryManager {
84
87
  this.accessControl = new AccessControl_1.AccessControl();
85
88
  this.aclCache = new Map();
86
89
  this.lastModifiedTimestamps = new Map();
90
+ // Initialize pattern cache with LRU eviction (100 entries, 60s TTL)
91
+ this.patternCache = new PatternCache_1.PatternCache({
92
+ maxSize: 100,
93
+ ttl: 60000,
94
+ enableStats: true
95
+ });
87
96
  }
88
97
  run(sql, params = []) {
89
98
  if (!this.db) {
@@ -192,8 +201,18 @@ class SwarmMemoryManager {
192
201
  metadata TEXT,
193
202
  ttl INTEGER NOT NULL DEFAULT ${this.TTL_POLICY.patterns},
194
203
  expires_at INTEGER,
195
- created_at INTEGER NOT NULL
204
+ created_at INTEGER NOT NULL,
205
+ agent_id TEXT
196
206
  )
207
+ `);
208
+ // Create indexes for O(log n) pattern queries (Issue #57)
209
+ await this.run(`
210
+ CREATE INDEX IF NOT EXISTS idx_patterns_agent_confidence
211
+ ON patterns(agent_id, confidence DESC)
212
+ `);
213
+ await this.run(`
214
+ CREATE INDEX IF NOT EXISTS idx_patterns_agent
215
+ ON patterns(agent_id)
197
216
  `);
198
217
  // Table 6: Consensus State (TTL: 7 days)
199
218
  await this.run(`
@@ -384,6 +403,16 @@ class SwarmMemoryManager {
384
403
  await this.run(`CREATE INDEX IF NOT EXISTS idx_learning_metrics_agent ON learning_metrics(agent_id)`);
385
404
  this.initialized = true;
386
405
  }
406
+ /**
407
+ * Store a key-value pair in memory with OpenTelemetry instrumentation
408
+ *
409
+ * Automatically instruments the memory store operation with distributed tracing.
410
+ * Records namespace, key, value size, TTL, and operation performance metrics.
411
+ *
412
+ * @param key - Memory key
413
+ * @param value - Value to store (will be JSON serialized)
414
+ * @param options - Store options including partition, TTL, access control
415
+ */
387
416
  async store(key, value, options = {}) {
388
417
  // Auto-initialize if not initialized
389
418
  if (!this.initialized) {
@@ -395,44 +424,73 @@ class SwarmMemoryManager {
395
424
  const partition = options.partition || 'default';
396
425
  const owner = options.owner || 'system';
397
426
  const accessLevel = options.accessLevel || AccessControl_1.AccessLevel.PRIVATE;
398
- const createdAt = Date.now();
399
- const expiresAt = options.ttl ? createdAt + (options.ttl * 1000) : null;
400
- const metadata = options.metadata ? JSON.stringify(options.metadata) : null;
401
- // Check write permission if updating existing entry
402
- const existing = await this.queryOne(`SELECT owner, access_level, team_id, swarm_id FROM memory_entries WHERE key = ? AND partition = ?`, [key, partition]);
403
- if (existing && options.owner) {
404
- // Verify write permission
405
- const permCheck = this.accessControl.checkPermission({
406
- agentId: options.owner,
407
- resourceOwner: existing.owner,
408
- accessLevel: existing.access_level,
409
- permission: AccessControl_1.Permission.WRITE,
410
- teamId: options.teamId,
411
- resourceTeamId: existing.team_id,
412
- swarmId: options.swarmId,
413
- resourceSwarmId: existing.swarm_id
414
- });
415
- if (!permCheck.allowed) {
416
- throw new AccessControl_1.AccessControlError(`Write denied: ${permCheck.reason}`);
427
+ const valueJson = JSON.stringify(value);
428
+ const valueSize = valueJson.length;
429
+ // Create instrumentation span
430
+ const { span, context: spanContext } = memory_1.memorySpanManager.startStoreSpan({
431
+ agentId: { id: owner, type: types_1.QEAgentType.FLEET_COMMANDER, created: new Date() },
432
+ namespace: partition,
433
+ key,
434
+ valueSize,
435
+ ttl: options.ttl,
436
+ });
437
+ const startTime = Date.now();
438
+ try {
439
+ const createdAt = Date.now();
440
+ const expiresAt = options.ttl ? createdAt + (options.ttl * 1000) : null;
441
+ const metadata = options.metadata ? JSON.stringify(options.metadata) : null;
442
+ // Check write permission if updating existing entry
443
+ const existing = await this.queryOne(`SELECT owner, access_level, team_id, swarm_id FROM memory_entries WHERE key = ? AND partition = ?`, [key, partition]);
444
+ if (existing && options.owner) {
445
+ // Verify write permission
446
+ const permCheck = this.accessControl.checkPermission({
447
+ agentId: options.owner,
448
+ resourceOwner: existing.owner,
449
+ accessLevel: existing.access_level,
450
+ permission: AccessControl_1.Permission.WRITE,
451
+ teamId: options.teamId,
452
+ resourceTeamId: existing.team_id,
453
+ swarmId: options.swarmId,
454
+ resourceSwarmId: existing.swarm_id
455
+ });
456
+ if (!permCheck.allowed) {
457
+ throw new AccessControl_1.AccessControlError(`Write denied: ${permCheck.reason}`);
458
+ }
417
459
  }
460
+ await this.run(`INSERT OR REPLACE INTO memory_entries
461
+ (key, partition, value, metadata, created_at, expires_at, owner, access_level, team_id, swarm_id)
462
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
463
+ key,
464
+ partition,
465
+ valueJson,
466
+ metadata,
467
+ createdAt,
468
+ expiresAt,
469
+ owner,
470
+ accessLevel,
471
+ options.teamId || null,
472
+ options.swarmId || null
473
+ ]);
474
+ // Track modification for QUIC sync
475
+ const entryKey = `${partition}:${key}`;
476
+ this.lastModifiedTimestamps.set(entryKey, createdAt);
477
+ // Complete span successfully
478
+ const durationMs = Date.now() - startTime;
479
+ memory_1.memorySpanManager.completeStoreSpan(span, {
480
+ success: true,
481
+ durationMs,
482
+ });
483
+ }
484
+ catch (error) {
485
+ // Complete span with error
486
+ const durationMs = Date.now() - startTime;
487
+ memory_1.memorySpanManager.completeStoreSpan(span, {
488
+ success: false,
489
+ durationMs,
490
+ error: error,
491
+ });
492
+ throw error;
418
493
  }
419
- await this.run(`INSERT OR REPLACE INTO memory_entries
420
- (key, partition, value, metadata, created_at, expires_at, owner, access_level, team_id, swarm_id)
421
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
422
- key,
423
- partition,
424
- JSON.stringify(value),
425
- metadata,
426
- createdAt,
427
- expiresAt,
428
- owner,
429
- accessLevel,
430
- options.teamId || null,
431
- options.swarmId || null
432
- ]);
433
- // Track modification for QUIC sync
434
- const entryKey = `${partition}:${key}`;
435
- this.lastModifiedTimestamps.set(entryKey, createdAt);
436
494
  }
437
495
  /**
438
496
  * Alias for store() method to maintain compatibility with MemoryStore interface
@@ -456,6 +514,16 @@ class SwarmMemoryManager {
456
514
  }
457
515
  return this.retrieve(key, options);
458
516
  }
517
+ /**
518
+ * Retrieve a value from memory with OpenTelemetry instrumentation
519
+ *
520
+ * Automatically instruments the memory retrieve operation with distributed tracing.
521
+ * Records namespace, key, whether the value was found, value size, and performance metrics.
522
+ *
523
+ * @param key - Memory key
524
+ * @param options - Retrieve options including partition, agentId for access control
525
+ * @returns Retrieved value or null if not found
526
+ */
459
527
  async retrieve(key, options = {}) {
460
528
  // Auto-initialize if not initialized
461
529
  if (!this.initialized) {
@@ -465,55 +533,35 @@ class SwarmMemoryManager {
465
533
  throw new Error('Memory manager not initialized. Call initialize() first.');
466
534
  }
467
535
  const partition = options.partition || 'default';
468
- const now = Date.now();
469
- let query = `SELECT value, owner, access_level, team_id, swarm_id
470
- FROM memory_entries WHERE key = ? AND partition = ?`;
471
- const params = [key, partition];
472
- if (!options.includeExpired) {
473
- query += ` AND (expires_at IS NULL OR expires_at > ?)`;
474
- params.push(now);
475
- }
476
- const row = await this.queryOne(query, params);
477
- if (!row) {
478
- return null;
479
- }
480
- // Check read permission if agentId provided
481
- if (options.agentId) {
482
- const permCheck = this.accessControl.checkPermission({
483
- agentId: options.agentId,
484
- resourceOwner: row.owner,
485
- accessLevel: row.access_level,
486
- permission: AccessControl_1.Permission.READ,
487
- teamId: options.teamId,
488
- resourceTeamId: row.team_id,
489
- swarmId: options.swarmId,
490
- resourceSwarmId: row.swarm_id,
491
- isSystemAgent: options.isSystemAgent
492
- });
493
- if (!permCheck.allowed) {
494
- throw new AccessControl_1.AccessControlError(`Read denied: ${permCheck.reason}`);
536
+ const agentId = options.agentId || 'system';
537
+ // Create instrumentation span
538
+ const { span, context: spanContext } = memory_1.memorySpanManager.startRetrieveSpan({
539
+ agentId: { id: agentId, type: types_1.QEAgentType.FLEET_COMMANDER, created: new Date() },
540
+ namespace: partition,
541
+ key,
542
+ });
543
+ const startTime = Date.now();
544
+ try {
545
+ const now = Date.now();
546
+ let query = `SELECT value, owner, access_level, team_id, swarm_id
547
+ FROM memory_entries WHERE key = ? AND partition = ?`;
548
+ const params = [key, partition];
549
+ if (!options.includeExpired) {
550
+ query += ` AND (expires_at IS NULL OR expires_at > ?)`;
551
+ params.push(now);
495
552
  }
496
- }
497
- return JSON.parse(row.value);
498
- }
499
- async query(pattern, options = {}) {
500
- if (!this.db) {
501
- throw new Error('Memory manager not initialized');
502
- }
503
- const partition = options.partition || 'default';
504
- const now = Date.now();
505
- let query = `SELECT key, value, partition, created_at, expires_at, owner, access_level, team_id, swarm_id
506
- FROM memory_entries
507
- WHERE partition = ? AND key LIKE ?`;
508
- const params = [partition, pattern];
509
- if (!options.includeExpired) {
510
- query += ` AND (expires_at IS NULL OR expires_at > ?)`;
511
- params.push(now);
512
- }
513
- const rows = await this.queryAll(query, params);
514
- // Filter by access control if agentId provided
515
- const filteredRows = options.agentId
516
- ? rows.filter((row) => {
553
+ const row = await this.queryOne(query, params);
554
+ if (!row) {
555
+ // Complete span - not found
556
+ const durationMs = Date.now() - startTime;
557
+ memory_1.memorySpanManager.completeRetrieveSpan(span, {
558
+ found: false,
559
+ durationMs,
560
+ });
561
+ return null;
562
+ }
563
+ // Check read permission if agentId provided
564
+ if (options.agentId) {
517
565
  const permCheck = this.accessControl.checkPermission({
518
566
  agentId: options.agentId,
519
567
  resourceOwner: row.owner,
@@ -525,50 +573,178 @@ class SwarmMemoryManager {
525
573
  resourceSwarmId: row.swarm_id,
526
574
  isSystemAgent: options.isSystemAgent
527
575
  });
528
- return permCheck.allowed;
529
- })
530
- : rows;
531
- return filteredRows.map((row) => ({
532
- key: row.key,
533
- value: JSON.parse(row.value),
534
- partition: row.partition,
535
- createdAt: row.created_at,
536
- expiresAt: row.expires_at,
537
- owner: row.owner,
538
- accessLevel: row.access_level,
539
- teamId: row.team_id,
540
- swarmId: row.swarm_id
541
- }));
576
+ if (!permCheck.allowed) {
577
+ throw new AccessControl_1.AccessControlError(`Read denied: ${permCheck.reason}`);
578
+ }
579
+ }
580
+ const valueSize = row.value.length;
581
+ const parsedValue = JSON.parse(row.value);
582
+ // Complete span successfully
583
+ const durationMs = Date.now() - startTime;
584
+ memory_1.memorySpanManager.completeRetrieveSpan(span, {
585
+ found: true,
586
+ valueSize,
587
+ durationMs,
588
+ });
589
+ return parsedValue;
590
+ }
591
+ catch (error) {
592
+ // Complete span with error
593
+ const durationMs = Date.now() - startTime;
594
+ memory_1.memorySpanManager.completeRetrieveSpan(span, {
595
+ found: false,
596
+ durationMs,
597
+ error: error,
598
+ });
599
+ throw error;
600
+ }
542
601
  }
602
+ /**
603
+ * Query/search memory entries by pattern with OpenTelemetry instrumentation
604
+ *
605
+ * Automatically instruments the memory search operation with distributed tracing.
606
+ * Records namespace, search pattern, result count, and performance metrics.
607
+ *
608
+ * @param pattern - SQL LIKE pattern for key matching
609
+ * @param options - Retrieve options including partition, agentId for access control
610
+ * @returns Array of matching memory entries
611
+ */
612
+ async query(pattern, options = {}) {
613
+ if (!this.db) {
614
+ throw new Error('Memory manager not initialized');
615
+ }
616
+ const partition = options.partition || 'default';
617
+ const agentId = options.agentId || 'system';
618
+ // Create instrumentation span
619
+ const { span, context: spanContext } = memory_1.memorySpanManager.startSearchSpan({
620
+ agentId: { id: agentId, type: types_1.QEAgentType.FLEET_COMMANDER, created: new Date() },
621
+ namespace: partition,
622
+ pattern,
623
+ });
624
+ const startTime = Date.now();
625
+ try {
626
+ const now = Date.now();
627
+ let query = `SELECT key, value, partition, created_at, expires_at, owner, access_level, team_id, swarm_id
628
+ FROM memory_entries
629
+ WHERE partition = ? AND key LIKE ?`;
630
+ const params = [partition, pattern];
631
+ if (!options.includeExpired) {
632
+ query += ` AND (expires_at IS NULL OR expires_at > ?)`;
633
+ params.push(now);
634
+ }
635
+ const rows = await this.queryAll(query, params);
636
+ // Filter by access control if agentId provided
637
+ const filteredRows = options.agentId
638
+ ? rows.filter((row) => {
639
+ const permCheck = this.accessControl.checkPermission({
640
+ agentId: options.agentId,
641
+ resourceOwner: row.owner,
642
+ accessLevel: row.access_level,
643
+ permission: AccessControl_1.Permission.READ,
644
+ teamId: options.teamId,
645
+ resourceTeamId: row.team_id,
646
+ swarmId: options.swarmId,
647
+ resourceSwarmId: row.swarm_id,
648
+ isSystemAgent: options.isSystemAgent
649
+ });
650
+ return permCheck.allowed;
651
+ })
652
+ : rows;
653
+ const results = filteredRows.map((row) => ({
654
+ key: row.key,
655
+ value: JSON.parse(row.value),
656
+ partition: row.partition,
657
+ createdAt: row.created_at,
658
+ expiresAt: row.expires_at,
659
+ owner: row.owner,
660
+ accessLevel: row.access_level,
661
+ teamId: row.team_id,
662
+ swarmId: row.swarm_id
663
+ }));
664
+ // Complete span successfully
665
+ const durationMs = Date.now() - startTime;
666
+ memory_1.memorySpanManager.completeSearchSpan(span, {
667
+ resultCount: results.length,
668
+ durationMs,
669
+ });
670
+ return results;
671
+ }
672
+ catch (error) {
673
+ // Complete span with error
674
+ const durationMs = Date.now() - startTime;
675
+ memory_1.memorySpanManager.completeSearchSpan(span, {
676
+ resultCount: 0,
677
+ durationMs,
678
+ error: error,
679
+ });
680
+ throw error;
681
+ }
682
+ }
683
+ /**
684
+ * Delete a key from memory with OpenTelemetry instrumentation
685
+ *
686
+ * Automatically instruments the memory delete operation with distributed tracing.
687
+ * Records namespace, key, and operation performance metrics.
688
+ *
689
+ * @param key - Memory key to delete
690
+ * @param partition - Memory partition (namespace)
691
+ * @param options - Delete options including agentId for access control
692
+ */
543
693
  async delete(key, partition = 'default', options = {}) {
544
694
  if (!this.db) {
545
695
  throw new Error('Memory manager not initialized');
546
696
  }
547
- // Check delete permission if agentId provided
548
- if (options.agentId) {
549
- const row = await this.queryOne(`SELECT owner, access_level, team_id, swarm_id FROM memory_entries WHERE key = ? AND partition = ?`, [key, partition]);
550
- if (row) {
551
- const permCheck = this.accessControl.checkPermission({
552
- agentId: options.agentId,
553
- resourceOwner: row.owner,
554
- accessLevel: row.access_level,
555
- permission: AccessControl_1.Permission.DELETE,
556
- teamId: options.teamId,
557
- resourceTeamId: row.team_id,
558
- swarmId: options.swarmId,
559
- resourceSwarmId: row.swarm_id,
560
- isSystemAgent: options.isSystemAgent
561
- });
562
- if (!permCheck.allowed) {
563
- throw new AccessControl_1.AccessControlError(`Delete denied: ${permCheck.reason}`);
697
+ const agentId = options.agentId || 'system';
698
+ // Create instrumentation span
699
+ const { span, context: spanContext } = memory_1.memorySpanManager.startDeleteSpan({
700
+ agentId: { id: agentId, type: types_1.QEAgentType.FLEET_COMMANDER, created: new Date() },
701
+ namespace: partition,
702
+ key,
703
+ });
704
+ const startTime = Date.now();
705
+ try {
706
+ // Check delete permission if agentId provided
707
+ if (options.agentId) {
708
+ const row = await this.queryOne(`SELECT owner, access_level, team_id, swarm_id FROM memory_entries WHERE key = ? AND partition = ?`, [key, partition]);
709
+ if (row) {
710
+ const permCheck = this.accessControl.checkPermission({
711
+ agentId: options.agentId,
712
+ resourceOwner: row.owner,
713
+ accessLevel: row.access_level,
714
+ permission: AccessControl_1.Permission.DELETE,
715
+ teamId: options.teamId,
716
+ resourceTeamId: row.team_id,
717
+ swarmId: options.swarmId,
718
+ resourceSwarmId: row.swarm_id,
719
+ isSystemAgent: options.isSystemAgent
720
+ });
721
+ if (!permCheck.allowed) {
722
+ throw new AccessControl_1.AccessControlError(`Delete denied: ${permCheck.reason}`);
723
+ }
564
724
  }
565
725
  }
726
+ await this.run(`DELETE FROM memory_entries WHERE key = ? AND partition = ?`, [key, partition]);
727
+ // Clean up ACL if exists
728
+ const resourceId = `${partition}:${key}`;
729
+ await this.run(`DELETE FROM memory_acl WHERE resource_id = ?`, [resourceId]);
730
+ this.aclCache.delete(resourceId);
731
+ // Complete span successfully
732
+ const durationMs = Date.now() - startTime;
733
+ memory_1.memorySpanManager.completeDeleteSpan(span, {
734
+ success: true,
735
+ durationMs,
736
+ });
737
+ }
738
+ catch (error) {
739
+ // Complete span with error
740
+ const durationMs = Date.now() - startTime;
741
+ memory_1.memorySpanManager.completeDeleteSpan(span, {
742
+ success: false,
743
+ durationMs,
744
+ error: error,
745
+ });
746
+ throw error;
566
747
  }
567
- await this.run(`DELETE FROM memory_entries WHERE key = ? AND partition = ?`, [key, partition]);
568
- // Clean up ACL if exists
569
- const resourceId = `${partition}:${key}`;
570
- await this.run(`DELETE FROM memory_acl WHERE resource_id = ?`, [resourceId]);
571
- this.aclCache.delete(resourceId);
572
748
  }
573
749
  async clear(partition = 'default') {
574
750
  if (!this.db) {
@@ -797,8 +973,10 @@ class SwarmMemoryManager {
797
973
  const now = Date.now();
798
974
  const ttl = pattern.ttl !== undefined ? pattern.ttl : this.TTL_POLICY.patterns;
799
975
  const expiresAt = ttl > 0 ? now + (ttl * 1000) : null;
800
- await this.run(`INSERT OR REPLACE INTO patterns (id, pattern, confidence, usage_count, metadata, ttl, expires_at, created_at)
801
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, [
976
+ // Extract agent_id from metadata for indexed lookups (O(log n) vs O(n))
977
+ const agentId = pattern.metadata?.agent_id || pattern.metadata?.agentId || null;
978
+ await this.run(`INSERT OR REPLACE INTO patterns (id, pattern, confidence, usage_count, metadata, ttl, expires_at, created_at, agent_id)
979
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
802
980
  id,
803
981
  pattern.pattern,
804
982
  pattern.confidence,
@@ -806,8 +984,11 @@ class SwarmMemoryManager {
806
984
  pattern.metadata ? JSON.stringify(pattern.metadata) : null,
807
985
  ttl,
808
986
  expiresAt,
809
- now
987
+ now,
988
+ agentId
810
989
  ]);
990
+ // Invalidate cache for this agent to ensure consistency
991
+ this.invalidatePatternCacheForAgent(agentId);
811
992
  return id;
812
993
  }
813
994
  async getPattern(patternName) {
@@ -835,9 +1016,31 @@ class SwarmMemoryManager {
835
1016
  if (!this.db) {
836
1017
  throw new Error('Memory manager not initialized');
837
1018
  }
838
- await this.run(`UPDATE patterns
1019
+ // Get the agent_id before updating to invalidate correct cache entries
1020
+ const pattern = this.queryOne(`SELECT agent_id, metadata FROM patterns WHERE pattern = ?`, [patternName]);
1021
+ this.run(`UPDATE patterns
839
1022
  SET usage_count = usage_count + 1
840
1023
  WHERE pattern = ?`, [patternName]);
1024
+ // Invalidate cache for affected agent
1025
+ if (pattern) {
1026
+ const agentId = pattern.agent_id ||
1027
+ (pattern.metadata ? JSON.parse(pattern.metadata).agent_id || JSON.parse(pattern.metadata).agentId : null);
1028
+ this.invalidatePatternCacheForAgent(agentId);
1029
+ }
1030
+ }
1031
+ /**
1032
+ * Invalidate pattern cache for a specific agent
1033
+ * Call this after any pattern mutation to maintain cache coherence
1034
+ */
1035
+ invalidatePatternCacheForAgent(agentId) {
1036
+ if (agentId) {
1037
+ this.patternCache.invalidate(agentId);
1038
+ }
1039
+ else {
1040
+ // Nuclear option for NULL agent_id - clear entire cache
1041
+ // This is expensive but ensures correctness for pre-migration data
1042
+ this.patternCache.clear();
1043
+ }
841
1044
  }
842
1045
  async queryPatternsByConfidence(threshold) {
843
1046
  if (!this.db) {
@@ -865,23 +1068,49 @@ class SwarmMemoryManager {
865
1068
  * @param minConfidence Minimum confidence threshold (default: 0)
866
1069
  * @returns Array of patterns belonging to the agent
867
1070
  */
1071
+ /**
1072
+ * Escape special LIKE pattern characters to prevent SQL injection
1073
+ */
1074
+ escapeLikePattern(value) {
1075
+ return value.replace(/[%_\\]/g, '\\$&');
1076
+ }
868
1077
  async queryPatternsByAgent(agentId, minConfidence = 0) {
869
1078
  if (!this.db) {
870
1079
  throw new Error('Memory manager not initialized');
871
1080
  }
1081
+ // Check cache first (O(1) lookup)
1082
+ const cacheKey = PatternCache_1.PatternCache.generateKey(agentId, minConfidence);
1083
+ const cached = this.patternCache.get(cacheKey);
1084
+ if (cached) {
1085
+ return cached;
1086
+ }
872
1087
  const now = Date.now();
873
- const rows = await this.queryAll(`SELECT id, pattern, confidence, usage_count, metadata, ttl, created_at
1088
+ const escapedAgentId = this.escapeLikePattern(agentId);
1089
+ // Split into two queries to ensure index usage on the fast path
1090
+ // Query 1: O(log n) - Use index for agent_id column (post-migration data)
1091
+ const indexedRows = this.queryAll(`SELECT id, pattern, confidence, usage_count, metadata, ttl, created_at
874
1092
  FROM patterns
875
- WHERE confidence >= ?
1093
+ WHERE agent_id = ?
1094
+ AND confidence >= ?
876
1095
  AND (expires_at IS NULL OR expires_at > ?)
877
- AND (metadata LIKE ? OR metadata LIKE ?)
1096
+ ORDER BY confidence DESC`, [agentId, minConfidence, now]);
1097
+ // Query 2: O(n) - Fallback LIKE scan for pre-migration data (agent_id IS NULL)
1098
+ const nullRows = this.queryAll(`SELECT id, pattern, confidence, usage_count, metadata, ttl, created_at
1099
+ FROM patterns
1100
+ WHERE agent_id IS NULL
1101
+ AND confidence >= ?
1102
+ AND (expires_at IS NULL OR expires_at > ?)
1103
+ AND (metadata LIKE ? ESCAPE '\\' OR metadata LIKE ? ESCAPE '\\')
878
1104
  ORDER BY confidence DESC`, [
879
1105
  minConfidence,
880
1106
  now,
881
- `%"agent_id":"${agentId}"%`,
882
- `%"agentId":"${agentId}"%`
1107
+ `%"agent_id":"${escapedAgentId}"%`,
1108
+ `%"agentId":"${escapedAgentId}"%`
883
1109
  ]);
884
- return rows.map((row) => ({
1110
+ // Combine results and sort by confidence (descending)
1111
+ const allRows = [...indexedRows, ...nullRows];
1112
+ allRows.sort((a, b) => b.confidence - a.confidence);
1113
+ const patterns = allRows.map((row) => ({
885
1114
  id: row.id,
886
1115
  pattern: row.pattern,
887
1116
  confidence: row.confidence,
@@ -890,6 +1119,21 @@ class SwarmMemoryManager {
890
1119
  ttl: row.ttl,
891
1120
  createdAt: row.created_at
892
1121
  }));
1122
+ // Cache results for subsequent lookups
1123
+ this.patternCache.set(cacheKey, patterns);
1124
+ return patterns;
1125
+ }
1126
+ /**
1127
+ * Get pattern cache statistics for monitoring
1128
+ */
1129
+ getPatternCacheStats() {
1130
+ return this.patternCache.getStats();
1131
+ }
1132
+ /**
1133
+ * Clear pattern cache (useful after bulk updates)
1134
+ */
1135
+ clearPatternCache() {
1136
+ this.patternCache.clear();
893
1137
  }
894
1138
  // ============================================================================
895
1139
  // Table 6: Consensus State (TTL: 7 days)