@jungjaehoon/mama-core 1.4.2 → 1.6.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 (181) hide show
  1. package/README.md +48 -10
  2. package/db/migrations/026-create-canonical-entity-tables.sql +99 -0
  3. package/db/migrations/027-create-entity-review-support.sql +44 -0
  4. package/db/migrations/028-create-entity-audit-tables.sql +45 -0
  5. package/db/migrations/029-extend-entity-observations-observation-type.sql +60 -0
  6. package/db/migrations/030-case-first-memory-substrate.sql +901 -0
  7. package/db/migrations/031-wiki-page-index-provenance-columns.sql +2 -0
  8. package/db/migrations/032-add-memory-provenance-columns.sql +21 -0
  9. package/db/migrations/033-create-model-runs-and-tool-traces.sql +53 -0
  10. package/db/migrations/034-add-connector-event-scope-columns.sql +14 -0
  11. package/db/migrations/035-create-twin-edges.sql +63 -0
  12. package/db/migrations/036-create-agent-situation-packets.sql +61 -0
  13. package/dist/agent-graph/alias-write.d.ts +3 -0
  14. package/dist/agent-graph/alias-write.js +231 -0
  15. package/dist/agent-graph/entity-resolve.d.ts +3 -0
  16. package/dist/agent-graph/entity-resolve.js +275 -0
  17. package/dist/agent-graph/errors.d.ts +4 -0
  18. package/dist/agent-graph/errors.js +11 -0
  19. package/dist/agent-graph/graph-query.d.ts +5 -0
  20. package/dist/agent-graph/graph-query.js +359 -0
  21. package/dist/agent-graph/index.d.ts +6 -0
  22. package/dist/agent-graph/index.js +22 -0
  23. package/dist/agent-graph/types.d.ts +162 -0
  24. package/dist/agent-graph/types.js +3 -0
  25. package/dist/agent-situation/builder.d.ts +8 -0
  26. package/dist/agent-situation/builder.js +239 -0
  27. package/dist/agent-situation/cache-key.d.ts +4 -0
  28. package/dist/agent-situation/cache-key.js +64 -0
  29. package/dist/agent-situation/index.d.ts +7 -0
  30. package/dist/agent-situation/index.js +28 -0
  31. package/dist/agent-situation/packet-store.d.ts +27 -0
  32. package/dist/agent-situation/packet-store.js +228 -0
  33. package/dist/agent-situation/ranking-policy.d.ts +18 -0
  34. package/dist/agent-situation/ranking-policy.js +75 -0
  35. package/dist/agent-situation/source-readers.d.ts +52 -0
  36. package/dist/agent-situation/source-readers.js +300 -0
  37. package/dist/agent-situation/types.d.ts +195 -0
  38. package/dist/agent-situation/types.js +3 -0
  39. package/dist/canonicalize.d.ts +38 -0
  40. package/dist/canonicalize.js +106 -0
  41. package/dist/cases/case-links.d.ts +116 -0
  42. package/dist/cases/case-links.js +794 -0
  43. package/dist/cases/composition-overrides.d.ts +90 -0
  44. package/dist/cases/composition-overrides.js +724 -0
  45. package/dist/cases/corrections.d.ts +156 -0
  46. package/dist/cases/corrections.js +1045 -0
  47. package/dist/cases/freshness.d.ts +57 -0
  48. package/dist/cases/freshness.js +283 -0
  49. package/dist/cases/live-state.d.ts +48 -0
  50. package/dist/cases/live-state.js +256 -0
  51. package/dist/cases/membership-explain.d.ts +56 -0
  52. package/dist/cases/membership-explain.js +140 -0
  53. package/dist/cases/membership-matcher.d.ts +23 -0
  54. package/dist/cases/membership-matcher.js +193 -0
  55. package/dist/cases/merge-split.d.ts +61 -0
  56. package/dist/cases/merge-split.js +368 -0
  57. package/dist/cases/role-inference.d.ts +10 -0
  58. package/dist/cases/role-inference.js +85 -0
  59. package/dist/cases/search-rollup.d.ts +27 -0
  60. package/dist/cases/search-rollup.js +309 -0
  61. package/dist/cases/sqlite-transaction.d.ts +10 -0
  62. package/dist/cases/sqlite-transaction.js +62 -0
  63. package/dist/cases/store.d.ts +74 -0
  64. package/dist/cases/store.js +816 -0
  65. package/dist/cases/target-ref.d.ts +25 -0
  66. package/dist/cases/target-ref.js +22 -0
  67. package/dist/cases/timeline-range.d.ts +6 -0
  68. package/dist/cases/timeline-range.js +322 -0
  69. package/dist/cases/tombstone-sweeper.d.ts +13 -0
  70. package/dist/cases/tombstone-sweeper.js +128 -0
  71. package/dist/cases/types.d.ts +244 -0
  72. package/dist/cases/types.js +47 -0
  73. package/dist/cases/wiki-page-index.d.ts +50 -0
  74. package/dist/cases/wiki-page-index.js +350 -0
  75. package/dist/connectors/event-index.d.ts +45 -0
  76. package/dist/connectors/event-index.js +381 -0
  77. package/dist/connectors/raw-query.d.ts +18 -0
  78. package/dist/connectors/raw-query.js +305 -0
  79. package/dist/connectors/types.d.ts +109 -0
  80. package/dist/connectors/types.js +3 -0
  81. package/dist/db-adapter/node-sqlite-adapter.d.ts +6 -0
  82. package/dist/db-adapter/node-sqlite-adapter.js +131 -0
  83. package/dist/db-manager.d.ts +12 -1
  84. package/dist/db-manager.js +60 -5
  85. package/dist/decision-formatter.d.ts +2 -0
  86. package/dist/decision-formatter.js +11 -8
  87. package/dist/edges/ref-validation.d.ts +8 -0
  88. package/dist/edges/ref-validation.js +262 -0
  89. package/dist/edges/store.d.ts +10 -0
  90. package/dist/edges/store.js +343 -0
  91. package/dist/edges/types.d.ts +86 -0
  92. package/dist/edges/types.js +18 -0
  93. package/dist/embedding-server/mobile/daemon.d.ts +1 -0
  94. package/dist/embedding-server/mobile/daemon.js +11 -1
  95. package/dist/embeddings.js +13 -0
  96. package/dist/entities/audit-metrics.d.ts +73 -0
  97. package/dist/entities/audit-metrics.js +128 -0
  98. package/dist/entities/candidate-generator.d.ts +9 -0
  99. package/dist/entities/candidate-generator.js +436 -0
  100. package/dist/entities/entity-impact.d.ts +41 -0
  101. package/dist/entities/entity-impact.js +140 -0
  102. package/dist/entities/entity-linked-decision-counts.d.ts +2 -0
  103. package/dist/entities/entity-linked-decision-counts.js +29 -0
  104. package/dist/entities/entity-list.d.ts +23 -0
  105. package/dist/entities/entity-list.js +99 -0
  106. package/dist/entities/entity-orphan-list.d.ts +26 -0
  107. package/dist/entities/entity-orphan-list.js +91 -0
  108. package/dist/entities/entity-search.d.ts +21 -0
  109. package/dist/entities/entity-search.js +150 -0
  110. package/dist/entities/errors.d.ts +65 -0
  111. package/dist/entities/errors.js +124 -0
  112. package/dist/entities/exact-merge-backfill.d.ts +11 -0
  113. package/dist/entities/exact-merge-backfill.js +161 -0
  114. package/dist/entities/lineage-backfill.d.ts +12 -0
  115. package/dist/entities/lineage-backfill.js +101 -0
  116. package/dist/entities/lineage-store.d.ts +51 -0
  117. package/dist/entities/lineage-store.js +308 -0
  118. package/dist/entities/normalization.d.ts +14 -0
  119. package/dist/entities/normalization.js +63 -0
  120. package/dist/entities/policy-store.d.ts +17 -0
  121. package/dist/entities/policy-store.js +263 -0
  122. package/dist/entities/policy-types.d.ts +72 -0
  123. package/dist/entities/policy-types.js +59 -0
  124. package/dist/entities/projection.d.ts +8 -0
  125. package/dist/entities/projection.js +82 -0
  126. package/dist/entities/provenance-query.d.ts +33 -0
  127. package/dist/entities/provenance-query.js +167 -0
  128. package/dist/entities/read-identity.d.ts +31 -0
  129. package/dist/entities/read-identity.js +264 -0
  130. package/dist/entities/recall-bridge.d.ts +5 -0
  131. package/dist/entities/recall-bridge.js +171 -0
  132. package/dist/entities/resolution-engine.d.ts +15 -0
  133. package/dist/entities/resolution-engine.js +69 -0
  134. package/dist/entities/rollback-preview.d.ts +39 -0
  135. package/dist/entities/rollback-preview.js +235 -0
  136. package/dist/entities/source-locator.d.ts +3 -0
  137. package/dist/entities/source-locator.js +32 -0
  138. package/dist/entities/store.d.ts +75 -0
  139. package/dist/entities/store.js +465 -0
  140. package/dist/entities/types.d.ts +162 -0
  141. package/dist/entities/types.js +30 -0
  142. package/dist/index.d.ts +62 -3
  143. package/dist/index.js +116 -26
  144. package/dist/mama-api.d.ts +53 -35
  145. package/dist/mama-api.js +437 -78
  146. package/dist/memory/api.d.ts +26 -38
  147. package/dist/memory/api.js +772 -68
  148. package/dist/memory/event-store.d.ts +3 -0
  149. package/dist/memory/event-store.js +21 -2
  150. package/dist/memory/provenance-audit.d.ts +22 -0
  151. package/dist/memory/provenance-audit.js +112 -0
  152. package/dist/memory/provenance-query.d.ts +11 -0
  153. package/dist/memory/provenance-query.js +193 -0
  154. package/dist/memory/provenance.d.ts +29 -0
  155. package/dist/memory/provenance.js +136 -0
  156. package/dist/memory/scope-backfill.d.ts +17 -0
  157. package/dist/memory/scope-backfill.js +77 -0
  158. package/dist/memory/types.d.ts +97 -16
  159. package/dist/model-runs/store.d.ts +13 -0
  160. package/dist/model-runs/store.js +457 -0
  161. package/dist/model-runs/tool-trace-store.d.ts +4 -0
  162. package/dist/model-runs/tool-trace-store.js +114 -0
  163. package/dist/model-runs/types.d.ts +69 -0
  164. package/dist/model-runs/types.js +5 -0
  165. package/dist/runtime/trusted-provenance.d.ts +3 -0
  166. package/dist/runtime/trusted-provenance.js +6 -0
  167. package/dist/search/feedback-store.d.ts +59 -0
  168. package/dist/search/feedback-store.js +211 -0
  169. package/dist/search/question-type.d.ts +5 -0
  170. package/dist/search/question-type.js +41 -0
  171. package/dist/search/ranker-features.d.ts +23 -0
  172. package/dist/search/ranker-features.js +104 -0
  173. package/dist/search/ranker-rescore.d.ts +31 -0
  174. package/dist/search/ranker-rescore.js +226 -0
  175. package/dist/search/ranker-trainer.d.ts +94 -0
  176. package/dist/search/ranker-trainer.js +860 -0
  177. package/dist/search/search-quality.d.ts +36 -0
  178. package/dist/search/search-quality.js +29 -0
  179. package/dist/test-utils.d.ts +14 -0
  180. package/dist/test-utils.js +52 -0
  181. package/package.json +28 -3
package/dist/mama-api.js CHANGED
@@ -22,8 +22,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
22
22
  return (mod && mod.__esModule) ? mod : { "default": mod };
23
23
  };
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
- exports.listRecentMemoryEvents = exports.listOpenAuditFindings = exports.getChannelSummary = exports.upsertChannelSummary = exports.recordMemoryAudit = exports.createAuditAck = exports.buildMemoryBootstrap = exports.evolveMemory = exports.ingestMemory = exports.buildProfile = exports.recallMemory = exports.saveMemory = void 0;
25
+ exports.listToolTracesForRun = exports.appendToolTrace = exports.getModelRunInAdapter = exports.getModelRun = exports.failModelRunInAdapter = exports.failModelRun = exports.commitModelRunInAdapter = exports.commitModelRun = exports.beginModelRunInAdapter = exports.beginModelRun = exports.listRecentMemoryEvents = exports.listMemoryEventsForMemory = exports.listMemoriesByModelRunId = exports.listMemoriesByGatewayCallId = exports.listMemoriesByEnvelopeHash = exports.getMemoryProvenance = exports.listOpenAuditFindings = exports.getChannelSummary = exports.upsertChannelSummary = exports.recordMemoryAudit = exports.createAuditAck = exports.buildMemoryBootstrap = exports.evolveMemory = exports.ingestConversationWithTrustedProvenance = exports.ingestConversation = exports.ingestWithTrustedProvenance = exports.ingestMemory = exports.buildProfile = exports.recallMemory = exports.saveMemoryWithTrustedProvenance = exports.saveMemory = void 0;
26
26
  exports.save = save;
27
+ exports.saveWithTrustedProvenance = saveWithTrustedProvenance;
27
28
  exports.suggest = suggest;
28
29
  exports.list = listDecisions;
29
30
  exports.listCheckpoints = listCheckpoints;
@@ -50,6 +51,7 @@ exports.restoreLinkBackup = restoreLinkBackup;
50
51
  exports.verifyBackupExists = verifyBackupExists;
51
52
  exports.deleteAutoLinks = deleteAutoLinks;
52
53
  exports.validateCleanupResult = validateCleanupResult;
54
+ exports.expandWithGraph = expandWithGraph;
53
55
  // Node built-ins
54
56
  const fs_1 = __importDefault(require("fs"));
55
57
  const path_1 = __importDefault(require("path"));
@@ -67,9 +69,13 @@ const ollama_client_js_1 = require("./ollama-client.js");
67
69
  const debug_logger_js_1 = require("./debug-logger.js");
68
70
  const api_js_1 = require("./memory/api.js");
69
71
  Object.defineProperty(exports, "saveMemory", { enumerable: true, get: function () { return api_js_1.saveMemory; } });
72
+ Object.defineProperty(exports, "saveMemoryWithTrustedProvenance", { enumerable: true, get: function () { return api_js_1.saveMemoryWithTrustedProvenance; } });
70
73
  Object.defineProperty(exports, "recallMemory", { enumerable: true, get: function () { return api_js_1.recallMemory; } });
71
74
  Object.defineProperty(exports, "buildProfile", { enumerable: true, get: function () { return api_js_1.buildProfile; } });
72
75
  Object.defineProperty(exports, "ingestMemory", { enumerable: true, get: function () { return api_js_1.ingestMemory; } });
76
+ Object.defineProperty(exports, "ingestWithTrustedProvenance", { enumerable: true, get: function () { return api_js_1.ingestWithTrustedProvenance; } });
77
+ Object.defineProperty(exports, "ingestConversation", { enumerable: true, get: function () { return api_js_1.ingestConversation; } });
78
+ Object.defineProperty(exports, "ingestConversationWithTrustedProvenance", { enumerable: true, get: function () { return api_js_1.ingestConversationWithTrustedProvenance; } });
73
79
  Object.defineProperty(exports, "evolveMemory", { enumerable: true, get: function () { return api_js_1.evolveMemory; } });
74
80
  Object.defineProperty(exports, "buildMemoryBootstrap", { enumerable: true, get: function () { return api_js_1.buildMemoryBootstrap; } });
75
81
  Object.defineProperty(exports, "createAuditAck", { enumerable: true, get: function () { return api_js_1.createAuditAck; } });
@@ -79,7 +85,29 @@ Object.defineProperty(exports, "getChannelSummary", { enumerable: true, get: fun
79
85
  const finding_store_js_1 = require("./memory/finding-store.js");
80
86
  Object.defineProperty(exports, "listOpenAuditFindings", { enumerable: true, get: function () { return finding_store_js_1.listOpenAuditFindings; } });
81
87
  const event_store_js_1 = require("./memory/event-store.js");
88
+ Object.defineProperty(exports, "listMemoryEventsForMemory", { enumerable: true, get: function () { return event_store_js_1.listMemoryEventsForMemory; } });
82
89
  Object.defineProperty(exports, "listRecentMemoryEvents", { enumerable: true, get: function () { return event_store_js_1.listRecentMemoryEvents; } });
90
+ const provenance_query_js_1 = require("./memory/provenance-query.js");
91
+ Object.defineProperty(exports, "getMemoryProvenance", { enumerable: true, get: function () { return provenance_query_js_1.getMemoryProvenance; } });
92
+ Object.defineProperty(exports, "listMemoriesByEnvelopeHash", { enumerable: true, get: function () { return provenance_query_js_1.listMemoriesByEnvelopeHash; } });
93
+ Object.defineProperty(exports, "listMemoriesByGatewayCallId", { enumerable: true, get: function () { return provenance_query_js_1.listMemoriesByGatewayCallId; } });
94
+ Object.defineProperty(exports, "listMemoriesByModelRunId", { enumerable: true, get: function () { return provenance_query_js_1.listMemoriesByModelRunId; } });
95
+ const store_js_1 = require("./model-runs/store.js");
96
+ Object.defineProperty(exports, "beginModelRun", { enumerable: true, get: function () { return store_js_1.beginModelRun; } });
97
+ Object.defineProperty(exports, "beginModelRunInAdapter", { enumerable: true, get: function () { return store_js_1.beginModelRunInAdapter; } });
98
+ Object.defineProperty(exports, "commitModelRun", { enumerable: true, get: function () { return store_js_1.commitModelRun; } });
99
+ Object.defineProperty(exports, "commitModelRunInAdapter", { enumerable: true, get: function () { return store_js_1.commitModelRunInAdapter; } });
100
+ Object.defineProperty(exports, "failModelRun", { enumerable: true, get: function () { return store_js_1.failModelRun; } });
101
+ Object.defineProperty(exports, "failModelRunInAdapter", { enumerable: true, get: function () { return store_js_1.failModelRunInAdapter; } });
102
+ Object.defineProperty(exports, "getModelRun", { enumerable: true, get: function () { return store_js_1.getModelRun; } });
103
+ Object.defineProperty(exports, "getModelRunInAdapter", { enumerable: true, get: function () { return store_js_1.getModelRunInAdapter; } });
104
+ const tool_trace_store_js_1 = require("./model-runs/tool-trace-store.js");
105
+ Object.defineProperty(exports, "appendToolTrace", { enumerable: true, get: function () { return tool_trace_store_js_1.appendToolTrace; } });
106
+ Object.defineProperty(exports, "listToolTracesForRun", { enumerable: true, get: function () { return tool_trace_store_js_1.listToolTracesForRun; } });
107
+ const search_rollup_js_1 = require("./cases/search-rollup.js");
108
+ const ranker_rescore_js_1 = require("./search/ranker-rescore.js");
109
+ const ranker_features_js_1 = require("./search/ranker-features.js");
110
+ const search_quality_js_1 = require("./search/search-quality.js");
83
111
  // Session-level warning cooldown cache (Story 1.1, 1.2)
84
112
  // Prevents spam by tracking warned topics per session
85
113
  const warnedTopicsCache = new Map();
@@ -111,7 +139,7 @@ const WARNING_COOLDOWN_MS = 5 * 60 * 1000; // 5 minutes
111
139
  * outcome: 'success'
112
140
  * });
113
141
  */
114
- async function save({ topic, decision, reasoning, confidence = 0.5, type = 'user_decision', outcome = 'pending', failure_reason = null, limitation = null, trust_context: _trust_context = null, is_static, scopes: inputScopes, event_date, }) {
142
+ async function saveInternal({ topic, decision, reasoning, confidence = 0.5, type = 'user_decision', outcome = 'pending', failure_reason = null, limitation = null, trust_context: _trust_context = null, is_static, scopes: inputScopes, event_date, timelineEvent, }, options) {
115
143
  // Validate required fields
116
144
  if (!topic || typeof topic !== 'string') {
117
145
  throw new Error('mama.save() requires topic (string)');
@@ -161,19 +189,35 @@ async function save({ topic, decision, reasoning, confidence = 0.5, type = 'user
161
189
  // Future: Will use decision_type column for proper distinction
162
190
  const _userInvolvement = type === 'user_decision' ? 'approved' : null;
163
191
  (0, progress_indicator_js_1.logProgress)(`Saving decision: ${topic.substring(0, 30)}...`);
164
- const { id: decisionId } = await (0, api_js_1.saveMemory)({
165
- topic,
166
- kind: is_static === 1 ? 'preference' : 'decision',
167
- summary: decision,
168
- details: reasoning,
169
- confidence,
170
- scopes: Array.isArray(inputScopes) && inputScopes.length > 0 ? inputScopes : [],
171
- source: {
172
- package: 'mama-core',
173
- source_type: 'legacy_save',
174
- },
175
- eventDate: event_date ?? undefined,
176
- });
192
+ const { id: decisionId, timeline_event_id: timelineEventId, timeline_event_ids: timelineEventIds, } = options
193
+ ? await (0, api_js_1.saveMemoryWithTrustedProvenance)({
194
+ topic,
195
+ kind: is_static === 1 ? 'preference' : 'decision',
196
+ summary: decision,
197
+ details: reasoning,
198
+ confidence,
199
+ scopes: Array.isArray(inputScopes) && inputScopes.length > 0 ? inputScopes : [],
200
+ source: {
201
+ package: 'mama-core',
202
+ source_type: 'legacy_save',
203
+ },
204
+ eventDate: event_date ?? undefined,
205
+ timelineEvent,
206
+ }, options)
207
+ : await (0, api_js_1.saveMemory)({
208
+ topic,
209
+ kind: is_static === 1 ? 'preference' : 'decision',
210
+ summary: decision,
211
+ details: reasoning,
212
+ confidence,
213
+ scopes: Array.isArray(inputScopes) && inputScopes.length > 0 ? inputScopes : [],
214
+ source: {
215
+ package: 'mama-core',
216
+ source_type: 'legacy_save',
217
+ },
218
+ eventDate: event_date ?? undefined,
219
+ timelineEvent,
220
+ });
177
221
  (0, progress_indicator_js_1.logComplete)(`Decision saved: ${decisionId.substring(0, 20)}...`);
178
222
  // Update user_involvement, outcome, failure_reason, limitation
179
223
  // Note: learnDecision always sets 'requested', we need to override it
@@ -255,13 +299,17 @@ async function save({ topic, decision, reasoning, confidence = 0.5, type = 'user
255
299
  if (searchResults && typeof searchResults === 'object' && 'results' in searchResults) {
256
300
  // Filter out the decision we just saved
257
301
  similar_decisions = searchResults.results
302
+ .filter((d) => d.source_type === 'decision')
258
303
  .filter((d) => d.id !== decisionId)
259
304
  .map((d) => ({
260
305
  id: d.id,
261
306
  topic: d.topic,
262
307
  decision: d.decision,
263
308
  similarity: d.similarity,
309
+ retrieval_score: d.retrieval_score ?? null,
264
310
  created_at: d.created_at,
311
+ event_date: d.event_date ?? null,
312
+ event_datetime: d.event_datetime ?? null,
265
313
  }));
266
314
  if (similar_decisions.length > 0) {
267
315
  (0, progress_indicator_js_1.logComplete)(`Found ${similar_decisions.length} related decision(s)`);
@@ -308,6 +356,9 @@ async function save({ topic, decision, reasoning, confidence = 0.5, type = 'user
308
356
  return {
309
357
  success: true,
310
358
  id: decisionId,
359
+ saved_decision_id: decisionId,
360
+ timeline_event_id: timelineEventId ?? null,
361
+ timeline_event_ids: timelineEventIds ?? [],
311
362
  ...(similar_decisions.length > 0 && { similar_decisions }),
312
363
  ...(warning && { warning }),
313
364
  ...(collaboration_hint && { collaboration_hint }),
@@ -698,62 +749,327 @@ function applyRecencyBoost(results, options = {}) {
698
749
  })
699
750
  .sort((a, b) => (b.final_score ?? 0) - (a.final_score ?? 0));
700
751
  }
752
+ /** Phase 3 Task 33: learned-ranker meta attached to mama.suggest response. */
753
+ function buildRankerMeta(applied, modelId, skippedReason) {
754
+ const meta = {
755
+ model_id: modelId,
756
+ feature_set_version: ranker_features_js_1.SEARCH_RANKER_FEATURE_SET_VERSION,
757
+ applied,
758
+ mode: 'offline',
759
+ };
760
+ if (skippedReason) {
761
+ meta.skipped_reason = skippedReason;
762
+ }
763
+ return meta;
764
+ }
765
+ function resultRecord(result) {
766
+ if (typeof result.record === 'object' &&
767
+ result.record !== null &&
768
+ !Array.isArray(result.record)) {
769
+ return result.record;
770
+ }
771
+ return {};
772
+ }
773
+ function stringOrNull(value) {
774
+ if (value === null || value === undefined) {
775
+ return null;
776
+ }
777
+ return String(value);
778
+ }
779
+ function numberOrNull(value) {
780
+ if (typeof value !== 'number' || !Number.isFinite(value)) {
781
+ return null;
782
+ }
783
+ return value;
784
+ }
785
+ function confidenceValue(record, fallback) {
786
+ const numeric = numberOrNull(record.confidence);
787
+ if (numeric !== null) {
788
+ return numeric;
789
+ }
790
+ switch (record.confidence) {
791
+ case 'high':
792
+ return 0.9;
793
+ case 'medium':
794
+ return 0.6;
795
+ case 'low':
796
+ return 0.3;
797
+ default:
798
+ return fallback;
799
+ }
800
+ }
801
+ function mapRolledUpResult(result) {
802
+ const record = resultRecord(result);
803
+ const retrievalDiagnostics = result.retrieval_diagnostics;
804
+ const topic = stringOrNull(record.topic ?? record.title) ?? result.source_id;
805
+ // For wiki_page leaves, prefer the markdown body (`content`) in `decision` so
806
+ // downstream consumers see the meaningful body rather than the short title.
807
+ // Decision/checkpoint records use their own fields (summary/decision).
808
+ const isWikiPageLeaf = result.source_type === 'wiki_page';
809
+ const decision = isWikiPageLeaf
810
+ ? (stringOrNull(record.content ?? record.summary ?? record.decision ?? record.title) ??
811
+ result.source_id)
812
+ : (stringOrNull(record.summary ?? record.decision ?? record.title ?? record.content) ??
813
+ result.source_id);
814
+ const reasoning = stringOrNull(record.details ?? record.reasoning ?? record.status_reason ?? record.content) ??
815
+ '';
816
+ return {
817
+ id: result.source_id,
818
+ topic,
819
+ decision,
820
+ reasoning,
821
+ confidence: confidenceValue(record, result.score),
822
+ // Back-compat with pre-rollup consumers (swarm-mama-adapter tests,
823
+ // older callers): similarity mirrors the retrieval score when we don't
824
+ // have a separate similarity measure. retrieval_score remains the
825
+ // authoritative field for Phase 3 code paths.
826
+ similarity: result.score,
827
+ retrieval_score: result.score,
828
+ created_at: record.created_at ?? null,
829
+ event_date: record.event_date ?? null,
830
+ event_datetime: record.event_datetime ?? null,
831
+ graph_source: retrievalDiagnostics?.graph_source ?? 'primary',
832
+ graph_rank: 1,
833
+ related_to: null,
834
+ edge_reason: null,
835
+ case_id: result.case_id,
836
+ source_type: result.source_type,
837
+ contributing_leaves: result.contributing_leaves ?? null,
838
+ ...(result.contributing_leaf_diagnostics
839
+ ? { contributing_leaf_diagnostics: result.contributing_leaf_diagnostics }
840
+ : {}),
841
+ ...(retrievalDiagnostics ? { retrieval_diagnostics: retrievalDiagnostics } : {}),
842
+ };
843
+ }
844
+ async function save(params) {
845
+ return saveInternal(params);
846
+ }
847
+ async function saveWithTrustedProvenance(params, options) {
848
+ return saveInternal(params, options);
849
+ }
701
850
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
702
851
  async function suggest(userQuestion, options = {}) {
703
852
  if (!userQuestion || typeof userQuestion !== 'string') {
704
853
  throw new Error('mama.suggest() requires userQuestion (string)');
705
854
  }
706
- const { format = 'json', limit = 5, threshold, useReranking = false,
855
+ const { format = 'json', limit = 5, threshold, useReranking = false, rerankWithLearned = false,
707
856
  // Recency boosting parameters (Gaussian Decay - Elasticsearch style)
708
857
  recencyWeight = 0.3, // 0-1: How much to weight recency (0.3 = 70% semantic, 30% recency)
709
858
  recencyScale = 7, // Days until recency score drops to 50%
710
859
  recencyDecay = 0.5, // Score at scale point (0.5 = 50%)
711
860
  disableRecency = false, // Set true to disable recency boosting entirely
712
- } = options;
861
+ strict, strictness, includeRelated, minLexicalSupport, diagnostics: includeDiagnostics, } = options;
862
+ const normalizedSearchOptions = (0, search_quality_js_1.normalizeSearchQualityOptions)({
863
+ threshold,
864
+ strict,
865
+ strictness,
866
+ disableRecency,
867
+ includeRelated,
868
+ topicPrefix: options.topicPrefix,
869
+ minLexicalSupport,
870
+ diagnostics: includeDiagnostics,
871
+ });
872
+ const memoryV2QualityContractRequested = threshold !== undefined ||
873
+ strict !== undefined ||
874
+ strictness !== undefined ||
875
+ includeRelated !== undefined ||
876
+ minLexicalSupport !== undefined ||
877
+ includeDiagnostics === true ||
878
+ options.topicPrefix !== undefined ||
879
+ options.scopes !== undefined;
880
+ const rerankPoolLimit = rerankWithLearned ? Math.max(limit * 4, limit + 5) : limit;
713
881
  try {
714
882
  const bundle = await (0, api_js_1.recallMemory)(userQuestion, {
715
883
  includeProfile: false,
716
884
  topicPrefix: options.topicPrefix,
885
+ limit: rerankPoolLimit,
886
+ threshold,
887
+ strict,
888
+ strictness,
889
+ disableRecency,
890
+ includeRelated,
891
+ minLexicalSupport,
892
+ diagnostics: includeDiagnostics,
717
893
  ...(options.scopes && { scopes: options.scopes }),
718
894
  });
895
+ const diagnosticsByMemoryId = new Map(bundle.memories
896
+ .filter((memory) => memory.retrieval_diagnostics)
897
+ .map((memory) => [memory.id, memory.retrieval_diagnostics]));
898
+ const rawFusedHits = bundle.fused_hits ?? [];
899
+ const fusedHits = rawFusedHits.map((hit) => {
900
+ if (hit.source_type !== 'decision') {
901
+ return hit;
902
+ }
903
+ const recordDiagnostics = typeof hit.record === 'object' && hit.record !== null && !Array.isArray(hit.record)
904
+ ? hit.record.retrieval_diagnostics
905
+ : undefined;
906
+ const retrievalDiagnostics = diagnosticsByMemoryId.get(hit.source_id) ?? recordDiagnostics;
907
+ if (!retrievalDiagnostics) {
908
+ return hit;
909
+ }
910
+ const record = typeof hit.record === 'object' && hit.record !== null && !Array.isArray(hit.record)
911
+ ? { ...hit.record, retrieval_diagnostics: retrievalDiagnostics }
912
+ : hit.record;
913
+ return {
914
+ ...hit,
915
+ record,
916
+ retrieval_diagnostics: retrievalDiagnostics,
917
+ };
918
+ });
919
+ const rolledUp = fusedHits.length > 0 ? (0, search_rollup_js_1.rollUpSearchHits)({ fusedHits, adapter: (0, memory_store_js_1.getAdapter)() }) : [];
920
+ const diagnosticsResponse = includeDiagnostics === true ? { diagnostics: bundle.search_meta.diagnostics ?? null } : {};
921
+ // Phase 3 Task 33: compute base ranker meta once so every return path
922
+ // (rolledUp, memories fallback, vector-search fallback) can attach it.
923
+ // rerankWithLearned-driven rescoring still only applies to result arrays
924
+ // that match the ranker's expected shape (id + source_type + case_id).
925
+ const baseRankerMeta = useReranking
926
+ ? buildRankerMeta(false, null, 'llm_reranking_requested')
927
+ : rerankWithLearned
928
+ ? null // marker: rescoring requested, actual meta set per-path after rescore
929
+ : buildRankerMeta(false, null, 'feature_disabled');
930
+ const applyLearnedRanker = (results) => {
931
+ if (baseRankerMeta !== null) {
932
+ return { results, meta: baseRankerMeta };
933
+ }
934
+ // Phase 3 Task 33: the caller opted in via rerankWithLearned, but the
935
+ // runtime `search_ranker_enabled` gate still has final say. This lets
936
+ // operators disable the learned ranker globally during rollback without
937
+ // touching any caller code.
938
+ let runtimeEnabled = true;
939
+ try {
940
+ runtimeEnabled = (0, ranker_rescore_js_1.isSearchRankerEnabled)((0, memory_store_js_1.getAdapter)());
941
+ }
942
+ catch (err) {
943
+ (0, debug_logger_js_1.warn)(`[mama.suggest] isSearchRankerEnabled check failed: ${String(err)}`);
944
+ }
945
+ if (!runtimeEnabled) {
946
+ return { results, meta: buildRankerMeta(false, null, 'feature_disabled') };
947
+ }
948
+ try {
949
+ const rescored = (0, ranker_rescore_js_1.rescoreSearchResults)((0, memory_store_js_1.getAdapter)(), {
950
+ query: userQuestion,
951
+ results,
952
+ });
953
+ return {
954
+ results: rescored.results,
955
+ meta: buildRankerMeta(rescored.skipped_reason === undefined, rescored.model_id, rescored.skipped_reason),
956
+ };
957
+ }
958
+ catch (err) {
959
+ (0, debug_logger_js_1.warn)(`[mama.suggest] learned-ranker rescore failed: ${String(err)}`);
960
+ return { results, meta: buildRankerMeta(false, null, 'rescore_error') };
961
+ }
962
+ };
963
+ const summarizeGraphExpansion = (rows) => {
964
+ const sources = {
965
+ primary: 0,
966
+ supersedes_chain: 0,
967
+ refines: 0,
968
+ refined_by: 0,
969
+ contradicts: 0,
970
+ };
971
+ let expandedCount = 0;
972
+ for (const row of rows) {
973
+ const graphSource = row.graph_source ?? 'primary';
974
+ if (graphSource === 'primary') {
975
+ sources.primary += 1;
976
+ continue;
977
+ }
978
+ expandedCount += 1;
979
+ if (graphSource in sources) {
980
+ const key = graphSource;
981
+ sources[key] += 1;
982
+ }
983
+ }
984
+ return {
985
+ total_results: rows.length,
986
+ primary_count: sources.primary,
987
+ expanded_count: expandedCount,
988
+ sources,
989
+ };
990
+ };
991
+ if (rolledUp.length > 0) {
992
+ const filteredResults = rolledUp.slice(0, rerankPoolLimit);
993
+ const { results: mappedResults, meta: rankerMeta } = applyLearnedRanker(filteredResults.map(mapRolledUpResult));
994
+ const limitedResults = mappedResults.slice(0, limit);
995
+ if (format === 'markdown') {
996
+ const context = limitedResults
997
+ .map((result, index) => `${index + 1}. [${result.topic}] ${result.decision}\n ${result.reasoning}`)
998
+ .join('\n');
999
+ return `🔍 Search method: memory_v2\n${context}`;
1000
+ }
1001
+ return {
1002
+ query: userQuestion,
1003
+ results: limitedResults,
1004
+ ...diagnosticsResponse,
1005
+ meta: {
1006
+ count: limitedResults.length,
1007
+ search_method: 'memory_v2',
1008
+ threshold: normalizedSearchOptions.threshold,
1009
+ recency_boost: disableRecency
1010
+ ? null
1011
+ : {
1012
+ weight: recencyWeight,
1013
+ scale: recencyScale,
1014
+ decay: recencyDecay,
1015
+ },
1016
+ graph_expansion: summarizeGraphExpansion(limitedResults),
1017
+ ranker: rankerMeta,
1018
+ },
1019
+ };
1020
+ }
719
1021
  if (bundle.memories.length > 0) {
720
1022
  // recallMemory uses RRF fusion — confidence is overwritten with the normalized
721
1023
  // retrieval score (0-1 range, where 1.0 = best match in this result set).
722
1024
  // The original stored confidence is lost after RRF normalization.
723
1025
  // We capture the retrieval score separately so `similarity` reflects search
724
1026
  // relevance while `confidence` is passed through as-is from the bundle.
725
- let filteredMemories = bundle.memories;
726
- // Apply limit
727
- filteredMemories = filteredMemories.slice(0, limit);
1027
+ const filteredMemories = bundle.memories.slice(0, rerankPoolLimit);
1028
+ const baseRows = filteredMemories.map((memory) => ({
1029
+ id: memory.id,
1030
+ topic: memory.topic,
1031
+ decision: memory.summary,
1032
+ reasoning: memory.details,
1033
+ confidence: memory.confidence,
1034
+ // recallMemory currently normalizes fused retrieval rank into `confidence`.
1035
+ // Keep that value visible as retrieval_score, but do not pretend it is
1036
+ // semantic similarity; save-time warning logic keys off `similarity`.
1037
+ similarity: null,
1038
+ retrieval_score: memory.confidence ?? null,
1039
+ final_score: memory.confidence ?? null,
1040
+ created_at: memory.created_at,
1041
+ event_date: memory.event_date ?? null,
1042
+ event_datetime: memory.event_datetime ?? null,
1043
+ graph_source: memory.retrieval_diagnostics?.graph_source ?? 'primary',
1044
+ graph_rank: 1,
1045
+ related_to: null,
1046
+ edge_reason: null,
1047
+ case_id: null,
1048
+ source_type: memory.kind ??
1049
+ memory.source?.source_type ??
1050
+ memory.source_type ??
1051
+ memory.type ??
1052
+ 'decision',
1053
+ ...(memory.retrieval_diagnostics
1054
+ ? { retrieval_diagnostics: memory.retrieval_diagnostics }
1055
+ : {}),
1056
+ }));
1057
+ const { results: rankedRows, meta: rankerMeta } = applyLearnedRanker(baseRows);
1058
+ const limitedRows = rankedRows.slice(0, limit);
728
1059
  if (format === 'markdown') {
729
- const context = filteredMemories
730
- .map((memory, index) => `${index + 1}. [${memory.topic}] ${memory.summary}\n ${memory.details}`)
1060
+ const context = limitedRows
1061
+ .map((row, index) => `${index + 1}. [${row.topic}] ${row.decision}\n ${row.reasoning}`)
731
1062
  .join('\n');
732
1063
  return `🔍 Search method: memory_v2\n${context}`;
733
1064
  }
734
1065
  return {
735
1066
  query: userQuestion,
736
- results: filteredMemories.map((memory, idx) => ({
737
- id: memory.id,
738
- topic: memory.topic,
739
- decision: memory.summary,
740
- reasoning: memory.details,
741
- confidence: memory.confidence,
742
- // memory.confidence is the normalized RRF retrieval score (0-1) after
743
- // recallMemory. Use it as similarity so the field reflects search relevance
744
- // rather than the original stored trust score.
745
- similarity: memory.confidence ?? 1 - idx * 0.01,
746
- created_at: memory.created_at,
747
- event_date: memory.event_date ?? null,
748
- graph_source: 'primary',
749
- graph_rank: 1,
750
- related_to: null,
751
- edge_reason: null,
752
- })),
1067
+ results: limitedRows,
1068
+ ...diagnosticsResponse,
753
1069
  meta: {
754
- count: filteredMemories.length,
1070
+ count: limitedRows.length,
755
1071
  search_method: 'memory_v2',
756
- threshold: threshold || 'adaptive',
1072
+ threshold: normalizedSearchOptions.threshold,
757
1073
  recency_boost: disableRecency
758
1074
  ? null
759
1075
  : {
@@ -761,18 +1077,34 @@ async function suggest(userQuestion, options = {}) {
761
1077
  scale: recencyScale,
762
1078
  decay: recencyDecay,
763
1079
  },
764
- graph_expansion: {
765
- total_results: filteredMemories.length,
766
- primary_count: bundle.graph_context.primary.length,
767
- expanded_count: bundle.graph_context.expanded.length,
768
- sources: {
769
- primary: bundle.graph_context.primary.length,
770
- supersedes_chain: 0,
771
- refines: 0,
772
- refined_by: 0,
773
- contradicts: 0,
1080
+ graph_expansion: summarizeGraphExpansion(limitedRows),
1081
+ ranker: rankerMeta,
1082
+ },
1083
+ };
1084
+ }
1085
+ if (memoryV2QualityContractRequested) {
1086
+ const emptyRows = [];
1087
+ const { meta: rankerMeta } = applyLearnedRanker(emptyRows);
1088
+ if (format === 'markdown') {
1089
+ return '🔍 Search method: memory_v2\n';
1090
+ }
1091
+ return {
1092
+ query: userQuestion,
1093
+ results: emptyRows,
1094
+ ...diagnosticsResponse,
1095
+ meta: {
1096
+ count: 0,
1097
+ search_method: 'memory_v2',
1098
+ threshold: normalizedSearchOptions.threshold,
1099
+ recency_boost: disableRecency
1100
+ ? null
1101
+ : {
1102
+ weight: recencyWeight,
1103
+ scale: recencyScale,
1104
+ decay: recencyDecay,
774
1105
  },
775
- },
1106
+ graph_expansion: summarizeGraphExpansion(emptyRows),
1107
+ ranker: rankerMeta,
776
1108
  },
777
1109
  };
778
1110
  }
@@ -791,7 +1123,7 @@ async function suggest(userQuestion, options = {}) {
791
1123
  const wordCount = userQuestion.split(/\s+/).length;
792
1124
  const adaptiveThreshold = threshold !== undefined ? threshold : wordCount < 3 ? 0.7 : 0.6;
793
1125
  // Vector search
794
- results = await (0, memory_store_js_1.vectorSearch)(queryEmbedding, limit * 2, 0.5); // Get more candidates
1126
+ results = await (0, memory_store_js_1.vectorSearch)(queryEmbedding, rerankPoolLimit * 2, 0.5); // Get more candidates
795
1127
  // Filter by adaptive threshold
796
1128
  results = results.filter((r) => r.similarity >= adaptiveThreshold);
797
1129
  // Stage 1.4: Temporal boost — detect time-related queries and boost matching results
@@ -839,7 +1171,7 @@ async function suggest(userQuestion, options = {}) {
839
1171
  // Stage 1.7: FTS5 hybrid merge (Haiku Memory Layer)
840
1172
  {
841
1173
  try {
842
- const ftsResults = await (0, db_manager_js_1.fts5Search)(userQuestion, limit * 2);
1174
+ const ftsResults = await (0, db_manager_js_1.fts5Search)(userQuestion, rerankPoolLimit * 2);
843
1175
  if (ftsResults.length > 0) {
844
1176
  // Normalize FTS5 ranks (BM25 returns negative values, closer to 0 = better)
845
1177
  const maxRank = Math.max(...ftsResults.map((r) => Math.abs(r.rank)));
@@ -924,7 +1256,7 @@ async function suggest(userQuestion, options = {}) {
924
1256
  ORDER BY created_at DESC
925
1257
  LIMIT ?
926
1258
  `);
927
- const rows = (await stmt.all(...likeParams, limit));
1259
+ const rows = (await stmt.all(...likeParams, rerankPoolLimit));
928
1260
  results = rows.map((row) => ({
929
1261
  ...row,
930
1262
  similarity: 0.75, // Assign moderate similarity for keyword matches
@@ -949,8 +1281,32 @@ async function suggest(userQuestion, options = {}) {
949
1281
  if (useReranking) {
950
1282
  results = await rerankWithLLM(userQuestion, results);
951
1283
  }
952
- // Slice to limit
953
- const finalResults = results.slice(0, limit);
1284
+ const rerankCandidateResults = results.slice(0, rerankPoolLimit);
1285
+ const vectorRows = rerankCandidateResults.map((r) => ({
1286
+ id: r.id,
1287
+ topic: r.topic,
1288
+ decision: r.decision,
1289
+ reasoning: r.reasoning,
1290
+ confidence: r.confidence,
1291
+ similarity: r.similarity,
1292
+ created_at: r.created_at,
1293
+ event_date: r.event_date ?? null,
1294
+ event_datetime: r.event_datetime ?? null,
1295
+ // Recency metadata (NEW - Gaussian Decay)
1296
+ recency_score: r.recency_score,
1297
+ recency_age_days: r.recency_age_days,
1298
+ final_score: r.final_score || r.similarity, // Falls back to similarity if no recency
1299
+ retrieval_score: r.similarity ?? null,
1300
+ // Graph metadata (NEW - Phase 1)
1301
+ graph_source: r.graph_source || 'primary',
1302
+ graph_rank: r.graph_rank || 1.0,
1303
+ related_to: r.related_to || null,
1304
+ edge_reason: r.edge_reason || null,
1305
+ case_id: null,
1306
+ source_type: 'decision',
1307
+ }));
1308
+ const { results: rankedVectorRows, meta: rankerMeta } = applyLearnedRanker(vectorRows);
1309
+ const finalResults = rankedVectorRows.slice(0, limit);
954
1310
  // Markdown format (for human display)
955
1311
  if (format === 'markdown') {
956
1312
  const context = (0, decision_formatter_js_1.formatContext)(finalResults, { maxTokens: 500 });
@@ -976,27 +1332,9 @@ async function suggest(userQuestion, options = {}) {
976
1332
  contradicts: finalResults.filter((r) => r.graph_source === 'contradicts').length,
977
1333
  },
978
1334
  };
979
- // JSON format (default - LLM-first)
980
1335
  return {
981
1336
  query: userQuestion,
982
- results: finalResults.map((r) => ({
983
- id: r.id,
984
- topic: r.topic,
985
- decision: r.decision,
986
- reasoning: r.reasoning,
987
- confidence: r.confidence,
988
- similarity: r.similarity,
989
- created_at: r.created_at,
990
- // Recency metadata (NEW - Gaussian Decay)
991
- recency_score: r.recency_score,
992
- recency_age_days: r.recency_age_days,
993
- final_score: r.final_score || r.similarity, // Falls back to similarity if no recency
994
- // Graph metadata (NEW - Phase 1)
995
- graph_source: r.graph_source || 'primary',
996
- graph_rank: r.graph_rank || 1.0,
997
- related_to: r.related_to || null,
998
- edge_reason: r.edge_reason || null,
999
- })),
1337
+ results: finalResults,
1000
1338
  meta: {
1001
1339
  count: finalResults.length,
1002
1340
  search_method: searchMethod,
@@ -1011,6 +1349,7 @@ async function suggest(userQuestion, options = {}) {
1011
1349
  },
1012
1350
  // Graph expansion stats (NEW - Phase 1)
1013
1351
  graph_expansion: searchMethod.includes('graph') ? graphStats : null,
1352
+ ranker: rankerMeta,
1014
1353
  },
1015
1354
  };
1016
1355
  }
@@ -1068,7 +1407,7 @@ async function listDecisions(options = {}) {
1068
1407
  JOIN memory_scope_bindings msb ON msb.memory_id = d.id
1069
1408
  WHERE msb.scope_id IN (${placeholders})
1070
1409
  AND d.superseded_by IS NULL
1071
- ORDER BY d.created_at DESC
1410
+ ORDER BY COALESCE(d.event_datetime, d.created_at) DESC, d.created_at DESC
1072
1411
  LIMIT ?
1073
1412
  `);
1074
1413
  decisions = await stmt.all(...scopeIds, limit);
@@ -1077,7 +1416,7 @@ async function listDecisions(options = {}) {
1077
1416
  const stmt = adapter.prepare(`
1078
1417
  SELECT * FROM decisions
1079
1418
  WHERE superseded_by IS NULL
1080
- ORDER BY created_at DESC
1419
+ ORDER BY COALESCE(event_datetime, created_at) DESC, created_at DESC
1081
1420
  LIMIT ?
1082
1421
  `);
1083
1422
  decisions = await stmt.all(limit);
@@ -2359,14 +2698,19 @@ function formatQualityReportMarkdown(report) {
2359
2698
  const mama = {
2360
2699
  // Core functions (used by 4 MCP tools)
2361
2700
  save,
2701
+ saveWithTrustedProvenance,
2362
2702
  suggest,
2363
2703
  saveMemory: api_js_1.saveMemory,
2704
+ saveMemoryWithTrustedProvenance: api_js_1.saveMemoryWithTrustedProvenance,
2364
2705
  recallMemory: api_js_1.recallMemory,
2365
2706
  list: listDecisions,
2366
2707
  listCheckpoints,
2367
2708
  updateOutcome,
2368
2709
  buildProfile: api_js_1.buildProfile,
2369
2710
  ingestMemory: api_js_1.ingestMemory,
2711
+ ingestWithTrustedProvenance: api_js_1.ingestWithTrustedProvenance,
2712
+ ingestConversation: api_js_1.ingestConversation,
2713
+ ingestConversationWithTrustedProvenance: api_js_1.ingestConversationWithTrustedProvenance,
2370
2714
  evolveMemory: api_js_1.evolveMemory,
2371
2715
  buildMemoryBootstrap: api_js_1.buildMemoryBootstrap,
2372
2716
  createAuditAck: api_js_1.createAuditAck,
@@ -2374,7 +2718,22 @@ const mama = {
2374
2718
  upsertChannelSummary: api_js_1.upsertChannelSummary,
2375
2719
  getChannelSummary: api_js_1.getChannelSummary,
2376
2720
  listAuditFindings: finding_store_js_1.listOpenAuditFindings,
2721
+ getMemoryProvenance: provenance_query_js_1.getMemoryProvenance,
2722
+ listMemoriesByEnvelopeHash: provenance_query_js_1.listMemoriesByEnvelopeHash,
2723
+ listMemoriesByGatewayCallId: provenance_query_js_1.listMemoriesByGatewayCallId,
2724
+ listMemoriesByModelRunId: provenance_query_js_1.listMemoriesByModelRunId,
2725
+ listMemoryEventsForMemory: event_store_js_1.listMemoryEventsForMemory,
2377
2726
  listRecentMemoryEvents: event_store_js_1.listRecentMemoryEvents,
2727
+ beginModelRun: store_js_1.beginModelRun,
2728
+ beginModelRunInAdapter: store_js_1.beginModelRunInAdapter,
2729
+ commitModelRun: store_js_1.commitModelRun,
2730
+ commitModelRunInAdapter: store_js_1.commitModelRunInAdapter,
2731
+ failModelRun: store_js_1.failModelRun,
2732
+ failModelRunInAdapter: store_js_1.failModelRunInAdapter,
2733
+ getModelRun: store_js_1.getModelRun,
2734
+ getModelRunInAdapter: store_js_1.getModelRunInAdapter,
2735
+ appendToolTrace: tool_trace_store_js_1.appendToolTrace,
2736
+ listToolTracesForRun: tool_trace_store_js_1.listToolTracesForRun,
2378
2737
  saveCheckpoint,
2379
2738
  loadCheckpoint,
2380
2739
  // Legacy functions (retained for internal use, not exposed via MCP)