@jungjaehoon/mama-os 0.20.0 → 0.21.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 (296) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/dist/agent/agent-loop.d.ts +2 -1
  3. package/dist/agent/agent-loop.d.ts.map +1 -1
  4. package/dist/agent/agent-loop.js +65 -19
  5. package/dist/agent/agent-loop.js.map +1 -1
  6. package/dist/agent/claude-cli-wrapper.d.ts.map +1 -1
  7. package/dist/agent/claude-cli-wrapper.js +6 -2
  8. package/dist/agent/claude-cli-wrapper.js.map +1 -1
  9. package/dist/agent/cli-arg-redaction.d.ts +2 -0
  10. package/dist/agent/cli-arg-redaction.d.ts.map +1 -0
  11. package/dist/agent/cli-arg-redaction.js +18 -0
  12. package/dist/agent/cli-arg-redaction.js.map +1 -0
  13. package/dist/agent/code-act/constants.d.ts +1 -1
  14. package/dist/agent/code-act/constants.d.ts.map +1 -1
  15. package/dist/agent/code-act/constants.js +24 -3
  16. package/dist/agent/code-act/constants.js.map +1 -1
  17. package/dist/agent/code-act/host-bridge.d.ts +2 -0
  18. package/dist/agent/code-act/host-bridge.d.ts.map +1 -1
  19. package/dist/agent/code-act/host-bridge.js +43 -7
  20. package/dist/agent/code-act/host-bridge.js.map +1 -1
  21. package/dist/agent/code-act/type-definition-generator.d.ts +2 -2
  22. package/dist/agent/code-act/type-definition-generator.d.ts.map +1 -1
  23. package/dist/agent/code-act/type-definition-generator.js +29 -4
  24. package/dist/agent/code-act/type-definition-generator.js.map +1 -1
  25. package/dist/agent/codex-home.d.ts +1 -1
  26. package/dist/agent/codex-home.d.ts.map +1 -1
  27. package/dist/agent/codex-home.js +43 -1
  28. package/dist/agent/codex-home.js.map +1 -1
  29. package/dist/agent/codex-mcp-process.d.ts +2 -0
  30. package/dist/agent/codex-mcp-process.d.ts.map +1 -1
  31. package/dist/agent/codex-mcp-process.js +1 -1
  32. package/dist/agent/codex-mcp-process.js.map +1 -1
  33. package/dist/agent/context-compile-service.d.ts +47 -0
  34. package/dist/agent/context-compile-service.d.ts.map +1 -0
  35. package/dist/agent/context-compile-service.js +435 -0
  36. package/dist/agent/context-compile-service.js.map +1 -0
  37. package/dist/agent/gateway-tool-executor.d.ts +16 -11
  38. package/dist/agent/gateway-tool-executor.d.ts.map +1 -1
  39. package/dist/agent/gateway-tool-executor.js +539 -109
  40. package/dist/agent/gateway-tool-executor.js.map +1 -1
  41. package/dist/agent/gateway-tools.md +4 -3
  42. package/dist/agent/mama-tool-handlers.d.ts.map +1 -1
  43. package/dist/agent/mama-tool-handlers.js +37 -1
  44. package/dist/agent/mama-tool-handlers.js.map +1 -1
  45. package/dist/agent/managed-agent-runtime-sync.d.ts.map +1 -1
  46. package/dist/agent/managed-agent-runtime-sync.js +2 -4
  47. package/dist/agent/managed-agent-runtime-sync.js.map +1 -1
  48. package/dist/agent/managed-agent-validation.d.ts.map +1 -1
  49. package/dist/agent/managed-agent-validation.js +2 -1
  50. package/dist/agent/managed-agent-validation.js.map +1 -1
  51. package/dist/agent/os-agent-capabilities.md +13 -12
  52. package/dist/agent/persistent-cli-process.d.ts +1 -0
  53. package/dist/agent/persistent-cli-process.d.ts.map +1 -1
  54. package/dist/agent/persistent-cli-process.js +6 -1
  55. package/dist/agent/persistent-cli-process.js.map +1 -1
  56. package/dist/agent/tool-registry.d.ts.map +1 -1
  57. package/dist/agent/tool-registry.js +10 -2
  58. package/dist/agent/tool-registry.js.map +1 -1
  59. package/dist/agent/types.d.ts +30 -5
  60. package/dist/agent/types.d.ts.map +1 -1
  61. package/dist/agent/types.js.map +1 -1
  62. package/dist/api/agent-context-handler.d.ts +10 -0
  63. package/dist/api/agent-context-handler.d.ts.map +1 -0
  64. package/dist/api/agent-context-handler.js +216 -0
  65. package/dist/api/agent-context-handler.js.map +1 -0
  66. package/dist/api/agent-handler.d.ts +2 -0
  67. package/dist/api/agent-handler.d.ts.map +1 -1
  68. package/dist/api/agent-handler.js +14 -7
  69. package/dist/api/agent-handler.js.map +1 -1
  70. package/dist/api/graph-api-types.d.ts +6 -1
  71. package/dist/api/graph-api-types.d.ts.map +1 -1
  72. package/dist/api/graph-api.d.ts +2 -1
  73. package/dist/api/graph-api.d.ts.map +1 -1
  74. package/dist/api/graph-api.js +193 -11
  75. package/dist/api/graph-api.js.map +1 -1
  76. package/dist/api/index.d.ts +11 -1
  77. package/dist/api/index.d.ts.map +1 -1
  78. package/dist/api/index.js +13 -2
  79. package/dist/api/index.js.map +1 -1
  80. package/dist/api/intelligence-handler.d.ts +17 -6
  81. package/dist/api/intelligence-handler.d.ts.map +1 -1
  82. package/dist/api/intelligence-handler.js +59 -1
  83. package/dist/api/intelligence-handler.js.map +1 -1
  84. package/dist/api/operator-handler.d.ts +17 -0
  85. package/dist/api/operator-handler.d.ts.map +1 -0
  86. package/dist/api/operator-handler.js +88 -0
  87. package/dist/api/operator-handler.js.map +1 -0
  88. package/dist/api/report-handler.d.ts +7 -0
  89. package/dist/api/report-handler.d.ts.map +1 -1
  90. package/dist/api/report-handler.js +30 -0
  91. package/dist/api/report-handler.js.map +1 -1
  92. package/dist/api/report-persistence.d.ts +17 -0
  93. package/dist/api/report-persistence.d.ts.map +1 -0
  94. package/dist/api/report-persistence.js +91 -0
  95. package/dist/api/report-persistence.js.map +1 -0
  96. package/dist/cli/commands/start.d.ts +45 -0
  97. package/dist/cli/commands/start.d.ts.map +1 -1
  98. package/dist/cli/commands/start.js +610 -197
  99. package/dist/cli/commands/start.js.map +1 -1
  100. package/dist/cli/config/config-manager.d.ts.map +1 -1
  101. package/dist/cli/config/config-manager.js +171 -4
  102. package/dist/cli/config/config-manager.js.map +1 -1
  103. package/dist/cli/config/types.d.ts +25 -5
  104. package/dist/cli/config/types.d.ts.map +1 -1
  105. package/dist/cli/config/types.js +5 -0
  106. package/dist/cli/config/types.js.map +1 -1
  107. package/dist/cli/runtime/agent-loop-init.d.ts +3 -0
  108. package/dist/cli/runtime/agent-loop-init.d.ts.map +1 -1
  109. package/dist/cli/runtime/agent-loop-init.js +2 -0
  110. package/dist/cli/runtime/agent-loop-init.js.map +1 -1
  111. package/dist/cli/runtime/api-routes-init.d.ts.map +1 -1
  112. package/dist/cli/runtime/api-routes-init.js +396 -259
  113. package/dist/cli/runtime/api-routes-init.js.map +1 -1
  114. package/dist/cli/runtime/api-server-init.d.ts +2 -0
  115. package/dist/cli/runtime/api-server-init.d.ts.map +1 -1
  116. package/dist/cli/runtime/api-server-init.js +19 -8
  117. package/dist/cli/runtime/api-server-init.js.map +1 -1
  118. package/dist/cli/runtime/connector-init.d.ts +26 -7
  119. package/dist/cli/runtime/connector-init.d.ts.map +1 -1
  120. package/dist/cli/runtime/connector-init.js +79 -16
  121. package/dist/cli/runtime/connector-init.js.map +1 -1
  122. package/dist/cli/runtime/envelope-bootstrap.d.ts.map +1 -1
  123. package/dist/cli/runtime/envelope-bootstrap.js +8 -2
  124. package/dist/cli/runtime/envelope-bootstrap.js.map +1 -1
  125. package/dist/cli/runtime/gateway-init.d.ts +1 -1
  126. package/dist/cli/runtime/gateway-init.d.ts.map +1 -1
  127. package/dist/cli/runtime/gateway-init.js.map +1 -1
  128. package/dist/cli/runtime/message-router-config.d.ts +4 -0
  129. package/dist/cli/runtime/message-router-config.d.ts.map +1 -0
  130. package/dist/cli/runtime/message-router-config.js +11 -0
  131. package/dist/cli/runtime/message-router-config.js.map +1 -0
  132. package/dist/cli/runtime/scheduler-init.d.ts.map +1 -1
  133. package/dist/cli/runtime/scheduler-init.js +12 -12
  134. package/dist/cli/runtime/scheduler-init.js.map +1 -1
  135. package/dist/cli/runtime/utilities.js +2 -2
  136. package/dist/cli/runtime/utilities.js.map +1 -1
  137. package/dist/connectors/framework/polling-scheduler.d.ts.map +1 -1
  138. package/dist/connectors/framework/polling-scheduler.js +101 -5
  139. package/dist/connectors/framework/polling-scheduler.js.map +1 -1
  140. package/dist/connectors/kagemusha/query-tools.d.ts.map +1 -1
  141. package/dist/connectors/kagemusha/query-tools.js +14 -3
  142. package/dist/connectors/kagemusha/query-tools.js.map +1 -1
  143. package/dist/db/agent-store.d.ts.map +1 -1
  144. package/dist/db/agent-store.js +10 -3
  145. package/dist/db/agent-store.js.map +1 -1
  146. package/dist/db/migrations/wiki-artifacts.d.ts +3 -0
  147. package/dist/db/migrations/wiki-artifacts.d.ts.map +1 -0
  148. package/dist/db/migrations/wiki-artifacts.js +24 -0
  149. package/dist/db/migrations/wiki-artifacts.js.map +1 -0
  150. package/dist/envelope/enforcer.d.ts.map +1 -1
  151. package/dist/envelope/enforcer.js +48 -4
  152. package/dist/envelope/enforcer.js.map +1 -1
  153. package/dist/envelope/key-provider.d.ts +1 -0
  154. package/dist/envelope/key-provider.d.ts.map +1 -1
  155. package/dist/envelope/key-provider.js +86 -0
  156. package/dist/envelope/key-provider.js.map +1 -1
  157. package/dist/gateways/message-router.d.ts.map +1 -1
  158. package/dist/gateways/message-router.js +15 -3
  159. package/dist/gateways/message-router.js.map +1 -1
  160. package/dist/gateways/types.d.ts +5 -1
  161. package/dist/gateways/types.d.ts.map +1 -1
  162. package/dist/mcp/code-act-server.js +50 -7
  163. package/dist/mcp/code-act-server.js.map +1 -1
  164. package/dist/memory/raw-backed-memory-ingest.d.ts +26 -0
  165. package/dist/memory/raw-backed-memory-ingest.d.ts.map +1 -0
  166. package/dist/memory/raw-backed-memory-ingest.js +214 -0
  167. package/dist/memory/raw-backed-memory-ingest.js.map +1 -0
  168. package/dist/memory/scope-context.js +1 -1
  169. package/dist/multi-agent/agent-event-bus.d.ts +10 -0
  170. package/dist/multi-agent/agent-event-bus.d.ts.map +1 -1
  171. package/dist/multi-agent/agent-event-bus.js +34 -0
  172. package/dist/multi-agent/agent-event-bus.js.map +1 -1
  173. package/dist/multi-agent/agent-process-manager.d.ts +3 -0
  174. package/dist/multi-agent/agent-process-manager.d.ts.map +1 -1
  175. package/dist/multi-agent/agent-process-manager.js +118 -13
  176. package/dist/multi-agent/agent-process-manager.js.map +1 -1
  177. package/dist/multi-agent/conductor-persona.js +2 -2
  178. package/dist/multi-agent/dashboard-agent-persona.d.ts +6 -2
  179. package/dist/multi-agent/dashboard-agent-persona.d.ts.map +1 -1
  180. package/dist/multi-agent/dashboard-agent-persona.js +57 -30
  181. package/dist/multi-agent/dashboard-agent-persona.js.map +1 -1
  182. package/dist/multi-agent/memory-agent-persona.d.ts +1 -1
  183. package/dist/multi-agent/memory-agent-persona.d.ts.map +1 -1
  184. package/dist/multi-agent/memory-agent-persona.js +25 -4
  185. package/dist/multi-agent/memory-agent-persona.js.map +1 -1
  186. package/dist/multi-agent/runtime-process.d.ts +1 -0
  187. package/dist/multi-agent/runtime-process.d.ts.map +1 -1
  188. package/dist/multi-agent/runtime-process.js +1 -0
  189. package/dist/multi-agent/runtime-process.js.map +1 -1
  190. package/dist/multi-agent/types.d.ts +14 -4
  191. package/dist/multi-agent/types.d.ts.map +1 -1
  192. package/dist/multi-agent/types.js.map +1 -1
  193. package/dist/multi-agent/wiki-agent-persona.d.ts +7 -1
  194. package/dist/multi-agent/wiki-agent-persona.d.ts.map +1 -1
  195. package/dist/multi-agent/wiki-agent-persona.js +83 -61
  196. package/dist/multi-agent/wiki-agent-persona.js.map +1 -1
  197. package/dist/multi-agent/workflow-types.d.ts +1 -1
  198. package/dist/multi-agent/workflow-types.d.ts.map +1 -1
  199. package/dist/operator/board-slot-instructions.d.ts +18 -0
  200. package/dist/operator/board-slot-instructions.d.ts.map +1 -0
  201. package/dist/operator/board-slot-instructions.js +52 -0
  202. package/dist/operator/board-slot-instructions.js.map +1 -0
  203. package/dist/operator/connector-delta-repo.d.ts +33 -0
  204. package/dist/operator/connector-delta-repo.d.ts.map +1 -0
  205. package/dist/operator/connector-delta-repo.js +0 -0
  206. package/dist/operator/connector-delta-repo.js.map +1 -0
  207. package/dist/operator/mama-memory-port.d.ts +13 -0
  208. package/dist/operator/mama-memory-port.d.ts.map +1 -0
  209. package/dist/operator/mama-memory-port.js +35 -0
  210. package/dist/operator/mama-memory-port.js.map +1 -0
  211. package/dist/operator/operator-interfaces.d.ts +136 -0
  212. package/dist/operator/operator-interfaces.d.ts.map +1 -0
  213. package/dist/operator/operator-interfaces.js +15 -0
  214. package/dist/operator/operator-interfaces.js.map +1 -0
  215. package/dist/operator/operator-trigger-loop.d.ts +106 -0
  216. package/dist/operator/operator-trigger-loop.d.ts.map +1 -0
  217. package/dist/operator/operator-trigger-loop.js +228 -0
  218. package/dist/operator/operator-trigger-loop.js.map +1 -0
  219. package/dist/operator/report-run.d.ts +78 -0
  220. package/dist/operator/report-run.d.ts.map +1 -0
  221. package/dist/operator/report-run.js +141 -0
  222. package/dist/operator/report-run.js.map +1 -0
  223. package/dist/operator/report-scheduler.d.ts +43 -0
  224. package/dist/operator/report-scheduler.d.ts.map +1 -0
  225. package/dist/operator/report-scheduler.js +87 -0
  226. package/dist/operator/report-scheduler.js.map +1 -0
  227. package/dist/operator/situation-report.d.ts +86 -0
  228. package/dist/operator/situation-report.d.ts.map +1 -0
  229. package/dist/operator/situation-report.js +211 -0
  230. package/dist/operator/situation-report.js.map +1 -0
  231. package/dist/operator/trigger-author.d.ts +45 -0
  232. package/dist/operator/trigger-author.d.ts.map +1 -0
  233. package/dist/operator/trigger-author.js +217 -0
  234. package/dist/operator/trigger-author.js.map +1 -0
  235. package/dist/operator/trigger-evolve.d.ts +31 -0
  236. package/dist/operator/trigger-evolve.d.ts.map +1 -0
  237. package/dist/operator/trigger-evolve.js +51 -0
  238. package/dist/operator/trigger-evolve.js.map +1 -0
  239. package/dist/operator/trigger-fire.d.ts +29 -0
  240. package/dist/operator/trigger-fire.d.ts.map +1 -0
  241. package/dist/operator/trigger-fire.js +41 -0
  242. package/dist/operator/trigger-fire.js.map +1 -0
  243. package/dist/operator/trigger-matcher.d.ts +19 -0
  244. package/dist/operator/trigger-matcher.d.ts.map +1 -0
  245. package/dist/operator/trigger-matcher.js +61 -0
  246. package/dist/operator/trigger-matcher.js.map +1 -0
  247. package/dist/operator/trigger-registry.d.ts +36 -0
  248. package/dist/operator/trigger-registry.d.ts.map +1 -0
  249. package/dist/operator/trigger-registry.js +135 -0
  250. package/dist/operator/trigger-registry.js.map +1 -0
  251. package/dist/operator/trigger-review.d.ts +23 -0
  252. package/dist/operator/trigger-review.d.ts.map +1 -0
  253. package/dist/operator/trigger-review.js +127 -0
  254. package/dist/operator/trigger-review.js.map +1 -0
  255. package/dist/operator/trigger-types.d.ts +84 -0
  256. package/dist/operator/trigger-types.d.ts.map +1 -0
  257. package/dist/operator/trigger-types.js +14 -0
  258. package/dist/operator/trigger-types.js.map +1 -0
  259. package/dist/scheduler/cron-worker.d.ts.map +1 -1
  260. package/dist/scheduler/cron-worker.js +3 -1
  261. package/dist/scheduler/cron-worker.js.map +1 -1
  262. package/dist/security/security-monitor.d.ts.map +1 -1
  263. package/dist/security/security-monitor.js +1 -0
  264. package/dist/security/security-monitor.js.map +1 -1
  265. package/dist/wiki/obsidian-writer.d.ts +1 -1
  266. package/dist/wiki/obsidian-writer.d.ts.map +1 -1
  267. package/dist/wiki/obsidian-writer.js +67 -27
  268. package/dist/wiki/obsidian-writer.js.map +1 -1
  269. package/dist/wiki/path-safety.d.ts +2 -0
  270. package/dist/wiki/path-safety.d.ts.map +1 -0
  271. package/dist/wiki/path-safety.js +40 -0
  272. package/dist/wiki/path-safety.js.map +1 -0
  273. package/dist/wiki/types.d.ts +4 -2
  274. package/dist/wiki/types.d.ts.map +1 -1
  275. package/dist/wiki/types.js +1 -1
  276. package/dist/wiki/types.js.map +1 -1
  277. package/dist/wiki-artifacts/normalization.d.ts +8 -0
  278. package/dist/wiki-artifacts/normalization.d.ts.map +1 -0
  279. package/dist/wiki-artifacts/normalization.js +41 -0
  280. package/dist/wiki-artifacts/normalization.js.map +1 -0
  281. package/dist/wiki-artifacts/types.d.ts +52 -0
  282. package/dist/wiki-artifacts/types.d.ts.map +1 -0
  283. package/dist/wiki-artifacts/types.js +3 -0
  284. package/dist/wiki-artifacts/types.js.map +1 -0
  285. package/dist/wiki-artifacts/wiki-publish-adapter.d.ts +14 -0
  286. package/dist/wiki-artifacts/wiki-publish-adapter.d.ts.map +1 -0
  287. package/dist/wiki-artifacts/wiki-publish-adapter.js +71 -0
  288. package/dist/wiki-artifacts/wiki-publish-adapter.js.map +1 -0
  289. package/package.json +6 -4
  290. package/public/ui/assets/index-BDsaQNGd.js +62 -0
  291. package/public/ui/assets/index-C4URnm_X.css +1 -0
  292. package/public/ui/index.html +13 -0
  293. package/public/viewer/js/utils/api.js +2 -2
  294. package/public/viewer/src/utils/api.ts +9 -2
  295. package/public/viewer/sw.js +1 -1
  296. package/public/viewer/viewer.html +6 -0
@@ -54,6 +54,7 @@ const os_1 = require("os");
54
54
  const child_process_1 = require("child_process");
55
55
  const util_1 = require("util");
56
56
  const debugLogger = __importStar(require("@jungjaehoon/mama-core/debug-logger"));
57
+ const mama_core_1 = require("@jungjaehoon/mama-core");
57
58
  const security_monitor_js_1 = require("../security/security-monitor.js");
58
59
  const scope_context_js_1 = require("../memory/scope-context.js");
59
60
  const types_js_1 = require("./types.js");
@@ -67,6 +68,7 @@ const managed_agent_runtime_sync_js_1 = require("./managed-agent-runtime-sync.js
67
68
  const managed_agent_validation_js_1 = require("./managed-agent-validation.js");
68
69
  const delegation_executor_js_1 = require("./delegation-executor.js");
69
70
  const index_js_1 = require("../envelope/index.js");
71
+ const wiki_publish_adapter_js_1 = require("../wiki-artifacts/wiki-publish-adapter.js");
70
72
  const { DebugLogger } = debugLogger;
71
73
  const securityLogger = new DebugLogger('SecurityAudit');
72
74
  const TRUTHY_ENV_VALUES = new Set(['1', 'true', 'yes', 'on']);
@@ -79,24 +81,153 @@ const AGENT_DETAIL_TABS = new Set([
79
81
  'validation',
80
82
  'history',
81
83
  ]);
84
+ const RECALL_TEXT_REDACTION_PATTERNS = [
85
+ /MAMA_SYNTHETIC_[A-Z0-9_]+_DO_NOT_LEAK/g,
86
+ /synthetic:\/\/raw[^\s"']*/g,
87
+ /raw:[^\s"']*/g,
88
+ /\bhttps?:\/\/[^\s"'<>()]+/gi,
89
+ /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi,
90
+ /\b(?:Bearer|Token|Authorization)\s*[:=]?\s*[A-Za-z0-9._~+/=-]{8,}/gi,
91
+ /\b(?:api[_-]?key|token|secret|password)\s*[:=]\s*[^\s"']{8,}/gi,
92
+ /(?:ghp|gho|ghu|ghs|ghr|github_pat)_[A-Za-z0-9_]{8,}\b/g,
93
+ /xox[baprs]-[A-Za-z0-9-]{10,}\b/g,
94
+ /sk-[A-Za-z0-9_-]{20,}\b/g,
95
+ /\b[CU][A-Z0-9]{8,}\b/g,
96
+ /\b[0-9]{17,20}\b/g,
97
+ /(?:\/Users|\/home|\/tmp)\/[^\s"']*/g,
98
+ /[A-Za-z]:\\Users\\[^\s"']*/g,
99
+ ];
100
+ const MAX_RECALL_TEXT_LENGTH = 280;
101
+ const RECALL_TEXT_REDACTION_SCAN_LIMIT = MAX_RECALL_TEXT_LENGTH + 2048;
82
102
  const managedAgentMutationTails = new Map();
83
103
  const MEMORY_SCOPE_AUDIT_TOOLS = new Set([
84
104
  'mama_save',
85
105
  'mama_search',
86
106
  'mama_recall',
107
+ 'context_compile',
87
108
  'mama_update',
88
109
  'mama_add',
89
110
  'mama_ingest',
90
111
  ]);
91
112
  const MEMORY_READ_PERMISSION_BEFORE_ENVELOPE_TOOLS = new Set([
113
+ 'mama_save',
92
114
  'mama_search',
93
115
  'mama_recall',
116
+ 'context_compile',
94
117
  ]);
95
118
  const ENVELOPE_REQUIRED_SURFACES = new Set([
96
119
  'model_tool',
97
120
  'reactive_internal',
98
121
  'code_act',
99
122
  ]);
123
+ class ContextPacketProvenanceError extends Error {
124
+ }
125
+ function asRecord(value) {
126
+ return value && typeof value === 'object' && !Array.isArray(value)
127
+ ? value
128
+ : null;
129
+ }
130
+ function stringField(record, field) {
131
+ const value = record[field];
132
+ return typeof value === 'string' ? value : undefined;
133
+ }
134
+ function numberField(record, field) {
135
+ const value = record[field];
136
+ return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
137
+ }
138
+ function sanitizeRecallText(value) {
139
+ if (!value) {
140
+ return undefined;
141
+ }
142
+ let sanitized = value.length > RECALL_TEXT_REDACTION_SCAN_LIMIT
143
+ ? value.slice(0, RECALL_TEXT_REDACTION_SCAN_LIMIT)
144
+ : value;
145
+ for (const pattern of RECALL_TEXT_REDACTION_PATTERNS) {
146
+ sanitized = sanitized.replace(pattern, '[redacted]');
147
+ }
148
+ const wasTruncated = value.length > MAX_RECALL_TEXT_LENGTH || sanitized.length > MAX_RECALL_TEXT_LENGTH;
149
+ if (sanitized.length > MAX_RECALL_TEXT_LENGTH) {
150
+ sanitized = sanitized.slice(0, MAX_RECALL_TEXT_LENGTH);
151
+ }
152
+ if (wasTruncated) {
153
+ sanitized = `${sanitized} [truncated]`;
154
+ }
155
+ return sanitized;
156
+ }
157
+ function sanitizeRecallMemory(value) {
158
+ const record = asRecord(value);
159
+ if (!record) {
160
+ return null;
161
+ }
162
+ const safe = {};
163
+ const topic = sanitizeRecallText(stringField(record, 'topic'));
164
+ const kind = sanitizeRecallText(stringField(record, 'kind'));
165
+ const summary = sanitizeRecallText(stringField(record, 'summary'));
166
+ const status = sanitizeRecallText(stringField(record, 'status'));
167
+ const confidence = numberField(record, 'confidence');
168
+ if (topic) {
169
+ safe.topic = topic;
170
+ }
171
+ if (kind) {
172
+ safe.kind = kind;
173
+ }
174
+ if (summary) {
175
+ safe.summary = summary;
176
+ }
177
+ if (status) {
178
+ safe.status = status;
179
+ }
180
+ if (confidence !== undefined) {
181
+ safe.confidence = confidence;
182
+ }
183
+ return Object.keys(safe).length > 0 ? safe : null;
184
+ }
185
+ function sanitizeRecallMemories(value) {
186
+ if (!Array.isArray(value)) {
187
+ return [];
188
+ }
189
+ return value
190
+ .map((memory) => sanitizeRecallMemory(memory))
191
+ .filter((memory) => memory !== null);
192
+ }
193
+ function sanitizeProfileEvidence(value) {
194
+ if (!Array.isArray(value)) {
195
+ return [];
196
+ }
197
+ return value
198
+ .map((item) => {
199
+ const record = asRecord(item);
200
+ if (!record) {
201
+ return null;
202
+ }
203
+ const evidence = {};
204
+ const topic = sanitizeRecallText(stringField(record, 'topic'));
205
+ if (topic) {
206
+ evidence.topic = topic;
207
+ }
208
+ return Object.keys(evidence).length > 0 ? evidence : null;
209
+ })
210
+ .filter((evidence) => evidence !== null);
211
+ }
212
+ function sanitizeMamaRecallBundle(bundle) {
213
+ const record = asRecord(bundle) ?? {};
214
+ const profile = asRecord(record.profile) ?? {};
215
+ const graphContext = asRecord(record.graph_context) ?? {};
216
+ const edges = Array.isArray(graphContext.edges) ? graphContext.edges : [];
217
+ return {
218
+ profile: {
219
+ static: sanitizeRecallMemories(profile.static),
220
+ dynamic: sanitizeRecallMemories(profile.dynamic),
221
+ evidence: sanitizeProfileEvidence(profile.evidence),
222
+ },
223
+ memories: sanitizeRecallMemories(record.memories),
224
+ graph_context: {
225
+ primary: sanitizeRecallMemories(graphContext.primary),
226
+ expanded: sanitizeRecallMemories(graphContext.expanded),
227
+ edge_count: edges.length,
228
+ },
229
+ };
230
+ }
100
231
  async function withManagedAgentMutationLock(agentId, fn) {
101
232
  const previous = managedAgentMutationTails.get(agentId) ?? Promise.resolve();
102
233
  let release;
@@ -147,6 +278,7 @@ class GatewayToolExecutor {
147
278
  envelopeEnforcer = new index_js_1.EnvelopeEnforcer();
148
279
  envelopeIssuanceMode;
149
280
  metricsStore;
281
+ contextCompileService;
150
282
  currentContext = null;
151
283
  memoryAgentProcessManager = null;
152
284
  agentProcessManager = null;
@@ -157,9 +289,12 @@ class GatewayToolExecutor {
157
289
  disallowedGatewayTools = new Set();
158
290
  reportPublisher = null;
159
291
  wikiPublisher = null;
292
+ wikiPublishAdapter = null;
160
293
  obsidianVaultPath = null;
161
- setObsidianVaultPath(vaultPath) {
294
+ obsidianVaultName = null;
295
+ setObsidianVaultPath(vaultPath, vaultName) {
162
296
  this.obsidianVaultPath = vaultPath;
297
+ this.obsidianVaultName = vaultName ?? null;
163
298
  }
164
299
  agentEventBus = null;
165
300
  setAgentEventBus(bus) {
@@ -387,6 +522,9 @@ class GatewayToolExecutor {
387
522
  setWikiPublisher(fn) {
388
523
  this.wikiPublisher = fn;
389
524
  }
525
+ setWikiPublishAdapter(adapter) {
526
+ this.wikiPublishAdapter = adapter;
527
+ }
390
528
  /** Check if a memory agent is available for routing memory writes. */
391
529
  hasMemoryAgent() {
392
530
  return this.memoryAgentProcessManager !== null;
@@ -423,6 +561,8 @@ class GatewayToolExecutor {
423
561
  this.sessionStore = options.sessionStore;
424
562
  this.envelopeIssuanceMode = options.envelopeIssuanceMode ?? 'enabled';
425
563
  this.metricsStore = options.metricsStore ?? null;
564
+ this.contextCompileService = options.contextCompileService;
565
+ this.wikiPublishAdapter = options.wikiPublishAdapter ?? null;
426
566
  this.browserTool = (0, browser_tool_js_1.getBrowserTool)({
427
567
  screenshotDir: (0, path_1.join)(process.env.HOME || '', '.mama', 'workspace', 'media', 'outbound'),
428
568
  });
@@ -474,6 +614,9 @@ class GatewayToolExecutor {
474
614
  setTelegramGateway(gateway) {
475
615
  this.telegramGateway = gateway;
476
616
  }
617
+ setContextCompileService(service) {
618
+ this.contextCompileService = service;
619
+ }
477
620
  /**
478
621
  * Initialize the MAMA API by importing from mcp-server package
479
622
  * Called lazily on first tool execution if not provided in constructor
@@ -818,6 +961,9 @@ class GatewayToolExecutor {
818
961
  return { requestedScopes, envelopeScopesSnapshot, mismatch: 0 };
819
962
  }
820
963
  if (!requestedScopes || requestedScopes.length === 0) {
964
+ if (toolName === 'context_compile' && Array.isArray(input.scopes)) {
965
+ return { requestedScopes, envelopeScopesSnapshot, mismatch: 0 };
966
+ }
821
967
  return {
822
968
  requestedScopes,
823
969
  envelopeScopesSnapshot,
@@ -836,7 +982,9 @@ class GatewayToolExecutor {
836
982
  if (toolName === 'mama_save') {
837
983
  return normalizeMemoryScopes(input.scopes);
838
984
  }
839
- if (toolName === 'mama_search' || toolName === 'mama_recall') {
985
+ if (toolName === 'mama_search' ||
986
+ toolName === 'mama_recall' ||
987
+ toolName === 'context_compile') {
840
988
  return normalizeMemoryScopes(input.scopes);
841
989
  }
842
990
  if (toolName === 'mama_update') {
@@ -867,6 +1015,52 @@ class GatewayToolExecutor {
867
1015
  projectId: process.env.MAMA_WORKSPACE || process.cwd(),
868
1016
  });
869
1017
  }
1018
+ resolveMamaRecallScopes(input) {
1019
+ const ctx = this.getExecutionState();
1020
+ const requestedScopes = normalizeMemoryScopes(input.scopes);
1021
+ const callerProvidedScopes = input.scopes !== undefined;
1022
+ const allowedScopes = ctx.envelope?.scope.memory_scopes ?? this.deriveMemoryScopesFromActiveContext(ctx) ?? [];
1023
+ const hasActiveScopeBoundary = Boolean(ctx.envelope || ctx.agentContext);
1024
+ if (callerProvidedScopes && !requestedScopes) {
1025
+ return {
1026
+ scopes: [],
1027
+ denial: {
1028
+ success: false,
1029
+ code: 'memory_scope_invalid',
1030
+ error: 'mama_recall scopes must be valid memory scope objects.',
1031
+ },
1032
+ };
1033
+ }
1034
+ if (!hasActiveScopeBoundary) {
1035
+ if (callerProvidedScopes) {
1036
+ return {
1037
+ scopes: [],
1038
+ denial: {
1039
+ success: false,
1040
+ code: 'memory_scope_denied',
1041
+ error: 'mama_recall requires an active session or envelope for caller-supplied scopes.',
1042
+ },
1043
+ };
1044
+ }
1045
+ return { scopes: [] };
1046
+ }
1047
+ if (!requestedScopes || requestedScopes.length === 0) {
1048
+ return { scopes: allowedScopes };
1049
+ }
1050
+ const allowedScopeKeys = new Set(allowedScopes.map(memoryScopeKey));
1051
+ const hasUnauthorizedScope = requestedScopes.some((scope) => !allowedScopeKeys.has(memoryScopeKey(scope)));
1052
+ if (hasUnauthorizedScope) {
1053
+ return {
1054
+ scopes: [],
1055
+ denial: {
1056
+ success: false,
1057
+ code: 'memory_scope_denied',
1058
+ error: 'mama_recall requested scopes outside the active session or envelope.',
1059
+ },
1060
+ };
1061
+ }
1062
+ return { scopes: requestedScopes };
1063
+ }
870
1064
  applyEnvelopeScopedReadDefaults(toolName, input, ctx) {
871
1065
  // Memory read tools must inherit envelope scopes consistently when the
872
1066
  // caller omits scopes. Otherwise recall can fall back to active-context
@@ -875,8 +1069,15 @@ class GatewayToolExecutor {
875
1069
  return input;
876
1070
  }
877
1071
  const scopedInput = input;
1072
+ if (toolName === 'mama_save' && hasContextPacketIdInput(scopedInput)) {
1073
+ // Invalid context_packet_id values are rejected later in the mama_save
1074
+ // handler. Skip default-scope injection for any present value so that
1075
+ // subsequent validation can return context_packet_denied without being
1076
+ // masked by envelope-scope defaults.
1077
+ return input;
1078
+ }
878
1079
  const hasCallerScopes = Array.isArray(scopedInput.scopes)
879
- ? scopedInput.scopes.length > 0
1080
+ ? toolName === 'context_compile' || scopedInput.scopes.length > 0
880
1081
  : scopedInput.scopes !== undefined;
881
1082
  if (hasCallerScopes) {
882
1083
  return input;
@@ -886,25 +1087,69 @@ class GatewayToolExecutor {
886
1087
  scopes: ctx.envelope.scope.memory_scopes,
887
1088
  };
888
1089
  }
889
- buildTrustedMemoryWriteOptions(toolName, gatewayCallId) {
1090
+ async buildTrustedMemoryWriteOptions(toolName, gatewayCallId, input) {
890
1091
  const ctx = this.mergeWithFallbackExecutionContext(this.executionContextStorage.getStore());
891
1092
  const capability = getTrustedProvenanceRuntime().createTrustedProvenanceCapability();
1093
+ const contextPacketId = getContextPacketIdForTrustedProvenance(input);
1094
+ const packetSourceRefs = [];
1095
+ let contextPacketScopes;
1096
+ if (contextPacketId) {
1097
+ if (!ctx?.envelope) {
1098
+ throw new ContextPacketProvenanceError('context_packet_id requires an active worker envelope.');
1099
+ }
1100
+ if (!ctx.modelRunId) {
1101
+ throw new ContextPacketProvenanceError('context_packet_id requires an active caller model run.');
1102
+ }
1103
+ let packet;
1104
+ try {
1105
+ packet = (0, mama_core_1.getContextPacketForTrustedUse)(await getContextPacketLookupAdapter(), {
1106
+ packetId: contextPacketId,
1107
+ envelopeHash: ctx.envelope.envelope_hash,
1108
+ callerModelRunId: ctx.modelRunId,
1109
+ });
1110
+ }
1111
+ catch (error) {
1112
+ throw new ContextPacketProvenanceError(error instanceof Error ? error.message : String(error));
1113
+ }
1114
+ if (!packet) {
1115
+ throw new ContextPacketProvenanceError(`Context packet not found: ${contextPacketId}`);
1116
+ }
1117
+ packetSourceRefs.push(...packet.source_refs.map(mama_core_1.serializeContextRefForProvenance));
1118
+ contextPacketScopes = packet.scopes.map((scope) => ({ kind: scope.kind, id: scope.id }));
1119
+ if (contextPacketScopes.length === 0) {
1120
+ throw new ContextPacketProvenanceError('Trusted context packet has no memory scopes.');
1121
+ }
1122
+ const requestedScopeValue = input.scopes;
1123
+ if (Array.isArray(requestedScopeValue) && requestedScopeValue.length === 0) {
1124
+ throw new ContextPacketProvenanceError('Requested save scope is outside the trusted context packet scope.');
1125
+ }
1126
+ const requestedScopes = normalizeMemoryScopes(requestedScopeValue);
1127
+ if (requestedScopes &&
1128
+ !requestedScopes.every((scope) => contextPacketScopes?.some((allowed) => memoryScopeKey(allowed) === memoryScopeKey(scope)))) {
1129
+ throw new ContextPacketProvenanceError('Requested save scope is outside the trusted context packet scope.');
1130
+ }
1131
+ }
892
1132
  return {
893
- capability,
894
- provenance: {
895
- actor: ctx?.agentContext?.roleName === 'memory_agent' ? 'memory_agent' : 'main_agent',
896
- agent_id: ctx?.agentId,
897
- model_run_id: ctx?.modelRunId ?? undefined,
898
- envelope_hash: ctx?.envelope?.envelope_hash,
899
- tool_name: toolName,
900
- gateway_call_id: gatewayCallId,
901
- source_turn_id: ctx?.sourceTurnId,
902
- source_message_ref: ctx?.sourceMessageRef,
903
- source_refs: [
904
- ...(ctx?.envelope?.envelope_hash ? [`envelope:${ctx.envelope.envelope_hash}`] : []),
905
- ...(ctx?.sourceMessageRef ? [`message:${ctx.sourceMessageRef}`] : []),
906
- ],
1133
+ options: {
1134
+ capability,
1135
+ provenance: {
1136
+ actor: ctx?.agentContext?.roleName === 'memory_agent' ? 'memory_agent' : 'main_agent',
1137
+ agent_id: ctx?.agentId,
1138
+ model_run_id: ctx?.modelRunId ?? undefined,
1139
+ envelope_hash: ctx?.envelope?.envelope_hash,
1140
+ tool_name: toolName,
1141
+ gateway_call_id: gatewayCallId,
1142
+ ...(contextPacketId ? { context_packet_id: contextPacketId } : {}),
1143
+ source_turn_id: ctx?.sourceTurnId,
1144
+ source_message_ref: ctx?.sourceMessageRef,
1145
+ source_refs: dedupeSourceRefs([
1146
+ ...(ctx?.envelope?.envelope_hash ? [`envelope:${ctx.envelope.envelope_hash}`] : []),
1147
+ ...(ctx?.sourceMessageRef ? [`message:${ctx.sourceMessageRef}`] : []),
1148
+ ...packetSourceRefs,
1149
+ ]),
1150
+ },
907
1151
  },
1152
+ contextPacketScopes,
908
1153
  };
909
1154
  }
910
1155
  supportsTrustedIngest(api) {
@@ -987,27 +1232,6 @@ class GatewayToolExecutor {
987
1232
  // Audit warnings must never affect tool execution.
988
1233
  }
989
1234
  }
990
- auditedAutoSave(parentToolName, input) {
991
- const parentContext = this.executionContextStorage.getStore();
992
- const task = (async () => {
993
- try {
994
- if (parentContext) {
995
- const autosaveContext = {
996
- ...parentContext,
997
- parentToolName,
998
- };
999
- await this.executionContextStorage.run(autosaveContext, () => this.execute('mama_save', input));
1000
- return;
1001
- }
1002
- await this.execute('mama_save', input);
1003
- }
1004
- catch {
1005
- // Autosave is intentionally non-fatal for report/wiki publish tools.
1006
- }
1007
- })();
1008
- parentContext?.backgroundTasks?.register(task);
1009
- void task;
1010
- }
1011
1235
  async executeWithEnvelopeAndPermissions(toolName, input, gatewayCallId) {
1012
1236
  if (!VALID_TOOLS.includes(toolName)) {
1013
1237
  throw new types_js_1.AgentError(`Unknown tool: ${toolName}. Valid tools: ${VALID_TOOLS.join(', ')}`, 'UNKNOWN_TOOL', undefined, false);
@@ -1318,16 +1542,72 @@ class GatewayToolExecutor {
1318
1542
  case 'mama_save': {
1319
1543
  const saveInput = input;
1320
1544
  const api = await getApi();
1321
- return await (0, mama_tool_handlers_js_1.handleSave)(api, saveInput, this.sessionStore?.getHistory
1545
+ let trustedOptions;
1546
+ let effectiveSaveInput = saveInput;
1547
+ let hasContextPacketId;
1548
+ try {
1549
+ hasContextPacketId = getContextPacketIdForTrustedProvenance(saveInput) !== null;
1550
+ }
1551
+ catch (error) {
1552
+ if (error instanceof ContextPacketProvenanceError) {
1553
+ return {
1554
+ success: false,
1555
+ code: 'context_packet_denied',
1556
+ error: error.message,
1557
+ };
1558
+ }
1559
+ throw error;
1560
+ }
1561
+ if (hasContextPacketId && !this.isMemoryDecisionSaveInput(saveInput)) {
1562
+ return {
1563
+ success: false,
1564
+ code: 'context_packet_denied',
1565
+ error: 'context_packet_id is only supported for trusted decision saves.',
1566
+ };
1567
+ }
1568
+ if (this.isMemoryDecisionSaveInput(saveInput) && hasContextPacketId) {
1569
+ if (!this.supportsTrustedSave(api)) {
1570
+ return {
1571
+ success: false,
1572
+ code: 'context_packet_denied',
1573
+ error: 'context_packet_id requires trusted save support.',
1574
+ };
1575
+ }
1576
+ try {
1577
+ const trustedBuild = await this.buildTrustedMemoryWriteOptions('mama_save', gatewayCallId, saveInput);
1578
+ trustedOptions = trustedBuild.options;
1579
+ if (!Array.isArray(saveInput.scopes) && trustedBuild.contextPacketScopes) {
1580
+ effectiveSaveInput = {
1581
+ ...saveInput,
1582
+ scopes: trustedBuild.contextPacketScopes,
1583
+ };
1584
+ }
1585
+ }
1586
+ catch (error) {
1587
+ if (error instanceof ContextPacketProvenanceError) {
1588
+ return {
1589
+ success: false,
1590
+ code: 'context_packet_denied',
1591
+ error: error.message,
1592
+ };
1593
+ }
1594
+ throw error;
1595
+ }
1596
+ }
1597
+ else if (this.isMemoryDecisionSaveInput(saveInput) && this.supportsTrustedSave(api)) {
1598
+ trustedOptions = (await this.buildTrustedMemoryWriteOptions('mama_save', gatewayCallId))
1599
+ .options;
1600
+ }
1601
+ return await (0, mama_tool_handlers_js_1.handleSave)(api, effectiveSaveInput, this.sessionStore?.getHistory
1322
1602
  ? () => this.sessionStore.getHistory('current')
1323
- : undefined, this.isMemoryDecisionSaveInput(saveInput) && this.supportsTrustedSave(api)
1324
- ? this.buildTrustedMemoryWriteOptions('mama_save', gatewayCallId)
1325
- : undefined);
1603
+ : undefined, trustedOptions);
1326
1604
  }
1327
1605
  case 'mama_search':
1328
1606
  return await (0, mama_tool_handlers_js_1.handleSearch)(await getApi(), input);
1329
1607
  case 'mama_recall':
1330
1608
  return await this.handleMamaRecall(input);
1609
+ case 'context_compile':
1610
+ return await this.handleContextCompile(input);
1331
1611
  case 'mama_update':
1332
1612
  return await (0, mama_tool_handlers_js_1.handleUpdate)(await getApi(), input);
1333
1613
  case 'mama_load_checkpoint':
@@ -1335,13 +1615,13 @@ class GatewayToolExecutor {
1335
1615
  case 'mama_add': {
1336
1616
  const api = await getApi();
1337
1617
  return await this.handleMamaAdd(input, this.supportsTrustedIngest(api)
1338
- ? this.buildTrustedMemoryWriteOptions('mama_add', gatewayCallId)
1618
+ ? (await this.buildTrustedMemoryWriteOptions('mama_add', gatewayCallId)).options
1339
1619
  : undefined);
1340
1620
  }
1341
1621
  case 'mama_ingest': {
1342
1622
  const api = await getApi();
1343
1623
  return await this.handleMamaIngest(input, this.supportsTrustedIngest(api)
1344
- ? this.buildTrustedMemoryWriteOptions('mama_ingest', gatewayCallId)
1624
+ ? (await this.buildTrustedMemoryWriteOptions('mama_ingest', gatewayCallId)).options
1345
1625
  : undefined);
1346
1626
  }
1347
1627
  case 'report_publish': {
@@ -1352,20 +1632,6 @@ class GatewayToolExecutor {
1352
1632
  if (this.reportPublisher) {
1353
1633
  this.reportPublisher(slotsInput);
1354
1634
  const slotNames = Object.keys(slotsInput);
1355
- // Persist report summary to mama memory for Conductor querying
1356
- const slotValues = Object.values(slotsInput).join(' ');
1357
- const textSummary = slotValues
1358
- .replace(/<[^>]+>/g, ' ')
1359
- .replace(/\s+/g, ' ')
1360
- .trim();
1361
- const truncated = textSummary.length > 1500 ? textSummary.substring(0, 1500) + '...' : textSummary;
1362
- this.auditedAutoSave('report_publish', {
1363
- type: 'decision',
1364
- topic: 'dashboard_briefing',
1365
- decision: `Dashboard briefing (${new Date().toISOString().split('T')[0]}): ${truncated}`,
1366
- reasoning: 'Auto-saved by dashboard agent after report_publish',
1367
- scopes: [{ kind: 'global', id: 'system' }],
1368
- });
1369
1635
  return {
1370
1636
  success: true,
1371
1637
  message: `Dashboard updated: ${slotNames.join(', ')} (${slotNames.length} slots)`,
@@ -1378,37 +1644,21 @@ class GatewayToolExecutor {
1378
1644
  if (!pagesInput || !Array.isArray(pagesInput)) {
1379
1645
  throw new types_js_1.AgentError('wiki_publish requires pages array', 'TOOL_ERROR', undefined, false);
1380
1646
  }
1381
- if (this.wikiPublisher) {
1382
- const now = new Date().toISOString();
1383
- const wikiPages = pagesInput.map((p) => ({
1384
- path: p.path,
1385
- title: p.title,
1386
- type: p.type || 'entity',
1387
- content: p.content,
1388
- sourceIds: [],
1389
- compiledAt: now,
1390
- confidence: p.confidence || 'medium',
1391
- }));
1392
- this.wikiPublisher(wikiPages);
1393
- // Persist wiki compilation summary to mama memory for Conductor querying
1394
- const pageSummary = pagesInput
1395
- .slice(0, 20)
1396
- .map((p) => `- ${p.title || p.path} (${p.type || 'page'})`)
1397
- .join('\n');
1398
- const wikiSummary = `Wiki compilation (${now.split('T')[0]}): ${pagesInput.length} pages\n${pageSummary}`;
1399
- this.auditedAutoSave('wiki_publish', {
1400
- type: 'decision',
1401
- topic: 'wiki_compilation',
1402
- decision: wikiSummary,
1403
- reasoning: 'Auto-saved by wiki agent after wiki_publish',
1404
- scopes: [{ kind: 'global', id: 'system' }],
1647
+ const adapter = this.wikiPublishAdapter ??
1648
+ (0, wiki_publish_adapter_js_1.createWikiPublishAdapter)({
1649
+ publisher: this.wikiPublisher,
1405
1650
  });
1651
+ try {
1652
+ const publishResult = adapter.publish({ pages: pagesInput });
1406
1653
  return {
1407
1654
  success: true,
1408
- message: `Wiki published: ${wikiPages.length} pages`,
1655
+ message: `Wiki published: ${publishResult.pagesPublished} pages`,
1656
+ artifactsStored: publishResult.artifactsStored,
1409
1657
  };
1410
1658
  }
1411
- throw new types_js_1.AgentError('Wiki publisher not configured', 'TOOL_ERROR', undefined, false);
1659
+ catch (error) {
1660
+ throw new types_js_1.AgentError(error instanceof Error ? error.message : 'Wiki publish failed', 'TOOL_ERROR', undefined, false);
1661
+ }
1412
1662
  }
1413
1663
  // Kagemusha query tools — progressive business data exploration
1414
1664
  case 'kagemusha_overview': {
@@ -2565,8 +2815,12 @@ class GatewayToolExecutor {
2565
2815
  };
2566
2816
  }
2567
2817
  // Obsidian CLI syntax: obsidian <command> key=value ... [flags]
2568
- // Vault is not passed as path Obsidian uses the default/focused vault
2818
+ // Without vault=<name> the CLI targets the FOCUSED vault, so wiki writes
2819
+ // could land in whatever vault the owner has open. Pin it when configured.
2569
2820
  const cliArgs = [command];
2821
+ if (this.obsidianVaultName) {
2822
+ cliArgs.push(`vault=${this.obsidianVaultName}`);
2823
+ }
2570
2824
  for (const [key, value] of Object.entries(args || {})) {
2571
2825
  if (value === 'true' && ['silent', 'overwrite', 'total'].includes(key)) {
2572
2826
  cliArgs.push(key);
@@ -2600,13 +2854,95 @@ class GatewayToolExecutor {
2600
2854
  };
2601
2855
  }
2602
2856
  }
2857
+ resolveCodeActSandboxRole(input, activeRole, registryNames) {
2858
+ const allowedResolution = this.normalizeCodeActToolPatterns(input.allowedTools, 'allowedTools', registryNames);
2859
+ if (allowedResolution.error) {
2860
+ return { error: allowedResolution.error };
2861
+ }
2862
+ const blockedResolution = this.normalizeCodeActToolPatterns(input.blockedTools, 'blockedTools', registryNames);
2863
+ if (blockedResolution.error) {
2864
+ return { error: blockedResolution.error };
2865
+ }
2866
+ if (!activeRole && !allowedResolution.patterns && !blockedResolution.patterns) {
2867
+ return {};
2868
+ }
2869
+ let effectiveToolNames = activeRole
2870
+ ? registryNames.filter((toolName) => this.roleManager.isToolAllowed(activeRole, toolName))
2871
+ : [...registryNames];
2872
+ const allowedPatterns = allowedResolution.patterns;
2873
+ if (allowedPatterns) {
2874
+ effectiveToolNames = effectiveToolNames.filter((toolName) => this.matchesAnyCodeActToolPattern(toolName, allowedPatterns));
2875
+ }
2876
+ const blockedPatterns = blockedResolution.patterns;
2877
+ if (blockedPatterns) {
2878
+ effectiveToolNames = effectiveToolNames.filter((toolName) => !this.matchesAnyCodeActToolPattern(toolName, blockedPatterns));
2879
+ }
2880
+ return {
2881
+ role: {
2882
+ ...activeRole,
2883
+ allowedTools: effectiveToolNames,
2884
+ blockedTools: undefined,
2885
+ allowedPaths: activeRole?.allowedPaths ?? [],
2886
+ systemControl: activeRole?.systemControl ?? false,
2887
+ sensitiveAccess: activeRole?.sensitiveAccess ?? false,
2888
+ },
2889
+ };
2890
+ }
2891
+ normalizeCodeActToolPatterns(value, fieldName, registryNames) {
2892
+ if (value === undefined) {
2893
+ return {};
2894
+ }
2895
+ if (!Array.isArray(value)) {
2896
+ return { error: `${fieldName} must be an array of gateway tool names.` };
2897
+ }
2898
+ const patterns = [];
2899
+ const seen = new Set();
2900
+ for (const item of value) {
2901
+ if (typeof item !== 'string' || item.trim().length === 0) {
2902
+ return { error: `${fieldName} must contain non-empty gateway tool names.` };
2903
+ }
2904
+ const pattern = item.trim();
2905
+ if (seen.has(pattern)) {
2906
+ continue;
2907
+ }
2908
+ if (!this.isKnownCodeActToolPattern(pattern, registryNames)) {
2909
+ return { error: `Unknown Code-Act tool pattern in ${fieldName}: ${pattern}` };
2910
+ }
2911
+ seen.add(pattern);
2912
+ patterns.push(pattern);
2913
+ }
2914
+ return { patterns };
2915
+ }
2916
+ isKnownCodeActToolPattern(pattern, registryNames) {
2917
+ return (pattern === '*' ||
2918
+ registryNames.some((toolName) => this.matchesCodeActToolPattern(toolName, pattern)));
2919
+ }
2920
+ matchesAnyCodeActToolPattern(toolName, patterns) {
2921
+ return patterns.some((pattern) => this.matchesCodeActToolPattern(toolName, pattern));
2922
+ }
2923
+ matchesCodeActToolPattern(toolName, pattern) {
2924
+ return this.roleManager.isToolAllowed({
2925
+ allowedTools: [pattern],
2926
+ allowedPaths: [],
2927
+ systemControl: false,
2928
+ sensitiveAccess: false,
2929
+ }, toolName);
2930
+ }
2603
2931
  async executeCodeAct(input) {
2604
2932
  const { CodeActSandbox, HostBridge } = await import('./code-act/index.js');
2605
2933
  const sandbox = new CodeActSandbox();
2606
- const bridge = new HostBridge(this);
2607
2934
  const context = this.getActiveContext();
2608
2935
  const tier = (context?.tier ?? 1);
2609
- bridge.injectInto(sandbox, tier, context?.role);
2936
+ const registryNames = HostBridge.getToolRegistry().map((meta) => meta.name);
2937
+ const sandboxRole = this.resolveCodeActSandboxRole(input, context?.role, registryNames);
2938
+ if (sandboxRole.error) {
2939
+ return {
2940
+ success: false,
2941
+ error: sandboxRole.error,
2942
+ };
2943
+ }
2944
+ const bridge = new HostBridge(this, this.roleManager);
2945
+ bridge.injectInto(sandbox, tier, sandboxRole.role);
2610
2946
  const result = await sandbox.execute(input.code);
2611
2947
  return {
2612
2948
  success: result.success,
@@ -2659,15 +2995,19 @@ class GatewayToolExecutor {
2659
2995
  error: 'Memory ingest API not available.',
2660
2996
  };
2661
2997
  }
2662
- const context = this.getActiveContext();
2663
- const fallbackScopes = context
2664
- ? (0, scope_context_js_1.deriveMemoryScopes)({
2665
- source: context.source,
2666
- channelId: context.session.channelId,
2667
- userId: context.session.userId,
2668
- projectId: process.env.MAMA_WORKSPACE || process.cwd(),
2669
- })
2670
- : [];
2998
+ const activeState = this.getExecutionState();
2999
+ const context = activeState.agentContext;
3000
+ const envelopeScopes = activeState.envelope?.scope.memory_scopes ?? null;
3001
+ const fallbackScopes = envelopeScopes && envelopeScopes.length > 0
3002
+ ? envelopeScopes
3003
+ : context
3004
+ ? (0, scope_context_js_1.deriveMemoryScopes)({
3005
+ source: context.source,
3006
+ channelId: context.session.channelId,
3007
+ userId: context.session.userId,
3008
+ projectId: process.env.MAMA_WORKSPACE || process.cwd(),
3009
+ })
3010
+ : [];
2671
3011
  let scopes = fallbackScopes;
2672
3012
  if (Array.isArray(input.scopes) && input.scopes.length > 0) {
2673
3013
  const derivedIds = new Set(fallbackScopes.map((s) => `${s.kind}:${s.id}`));
@@ -2714,17 +3054,11 @@ class GatewayToolExecutor {
2714
3054
  error: 'query is required and recallMemory API must be available',
2715
3055
  };
2716
3056
  }
2717
- const context = this.getActiveContext();
2718
- const fallbackScopes = context
2719
- ? (0, scope_context_js_1.deriveMemoryScopes)({
2720
- source: context.source,
2721
- channelId: context.session.channelId,
2722
- userId: context.session.userId,
2723
- projectId: process.env.MAMA_WORKSPACE || process.cwd(),
2724
- })
2725
- : [];
2726
- const inputScopes = Array.isArray(input.scopes) ? input.scopes : [];
2727
- const scopes = inputScopes.length > 0 ? inputScopes : fallbackScopes;
3057
+ const scopeResolution = this.resolveMamaRecallScopes(input);
3058
+ if (scopeResolution.denial) {
3059
+ return scopeResolution.denial;
3060
+ }
3061
+ const scopes = scopeResolution.scopes;
2728
3062
  if (scopes.length === 0) {
2729
3063
  return {
2730
3064
  success: false,
@@ -2736,7 +3070,7 @@ class GatewayToolExecutor {
2736
3070
  scopes,
2737
3071
  includeProfile: true,
2738
3072
  });
2739
- return { success: true, bundle };
3073
+ return { success: true, bundle: sanitizeMamaRecallBundle(bundle) };
2740
3074
  }
2741
3075
  catch (err) {
2742
3076
  return {
@@ -2754,6 +3088,57 @@ class GatewayToolExecutor {
2754
3088
  static isValidTool(toolName) {
2755
3089
  return VALID_TOOLS.includes(toolName);
2756
3090
  }
3091
+ async handleContextCompile(input) {
3092
+ if (!this.contextCompileService) {
3093
+ return {
3094
+ success: false,
3095
+ code: 'context_compile_unavailable',
3096
+ error: 'context_compile service is not available.',
3097
+ };
3098
+ }
3099
+ const ctx = this.mergeWithFallbackExecutionContext(this.executionContextStorage.getStore());
3100
+ // Fail closed: a Tier-3 designation in either source must block the call,
3101
+ // otherwise a non-Tier-3 fallback could mask a Tier-3 envelope.
3102
+ if (ctx?.agentContext?.tier === 3 || ctx?.envelope?.tier === 3) {
3103
+ return {
3104
+ success: false,
3105
+ code: 'permission_denied_tier3',
3106
+ error: 'context_compile is not allowed for Tier 3 agents.',
3107
+ };
3108
+ }
3109
+ if (!ctx?.envelope) {
3110
+ return {
3111
+ success: false,
3112
+ code: 'envelope_missing',
3113
+ error: 'context_compile requires an active worker envelope.',
3114
+ };
3115
+ }
3116
+ try {
3117
+ const result = await this.contextCompileService.compileAndPersistContext({
3118
+ caller: 'gateway',
3119
+ envelope: ctx.envelope,
3120
+ modelRunId: ctx.modelRunId ?? null,
3121
+ input,
3122
+ });
3123
+ return {
3124
+ success: true,
3125
+ packet: result.packet,
3126
+ packet_id: result.packet.packet_id,
3127
+ model_run_id: result.modelRunId,
3128
+ parent_model_run_id: result.parentModelRunId,
3129
+ };
3130
+ }
3131
+ catch (err) {
3132
+ const errorRecord = err && typeof err === 'object' ? err : undefined;
3133
+ const code = typeof errorRecord?.code === 'string' ? errorRecord.code : 'context_compile_failed';
3134
+ return {
3135
+ success: false,
3136
+ code,
3137
+ error: `context_compile failed: ${err instanceof Error ? err.message : String(err)}`,
3138
+ ...(errorRecord && 'details' in errorRecord ? { details: errorRecord.details } : {}),
3139
+ };
3140
+ }
3141
+ }
2757
3142
  }
2758
3143
  exports.GatewayToolExecutor = GatewayToolExecutor;
2759
3144
  function isTruthyEnv(name) {
@@ -2799,6 +3184,51 @@ function getTrustedProvenanceRuntime() {
2799
3184
  }
2800
3185
  throw new types_js_1.AgentError(`Trusted provenance runtime unavailable: ${lastError instanceof Error ? lastError.message : String(lastError)}`, 'TOOL_ERROR', lastError instanceof Error ? lastError : undefined, false);
2801
3186
  }
3187
+ async function getContextPacketLookupAdapter() {
3188
+ try {
3189
+ const dbManager = (await import('@jungjaehoon/mama-core/db-manager'));
3190
+ try {
3191
+ return dbManager.getAdapter();
3192
+ }
3193
+ catch (error) {
3194
+ if (typeof dbManager.initDB !== 'function') {
3195
+ throw error;
3196
+ }
3197
+ await dbManager.initDB();
3198
+ return dbManager.getAdapter();
3199
+ }
3200
+ }
3201
+ catch (error) {
3202
+ throw new ContextPacketProvenanceError(`Context packet store unavailable: ${error instanceof Error ? error.message : String(error)}`);
3203
+ }
3204
+ }
3205
+ function hasContextPacketIdInput(input) {
3206
+ if (!input || !('context_packet_id' in input)) {
3207
+ return false;
3208
+ }
3209
+ const value = input.context_packet_id;
3210
+ return value !== undefined && value !== null;
3211
+ }
3212
+ function getContextPacketIdForTrustedProvenance(input) {
3213
+ if (!input || !('context_packet_id' in input)) {
3214
+ return null;
3215
+ }
3216
+ const value = input.context_packet_id;
3217
+ if (value === undefined || value === null) {
3218
+ return null;
3219
+ }
3220
+ if (typeof value !== 'string') {
3221
+ throw new ContextPacketProvenanceError('context_packet_id must be a string when provided.');
3222
+ }
3223
+ const trimmed = value.trim();
3224
+ if (trimmed.length === 0) {
3225
+ throw new ContextPacketProvenanceError('context_packet_id must not be empty when provided.');
3226
+ }
3227
+ return trimmed;
3228
+ }
3229
+ function dedupeSourceRefs(refs) {
3230
+ return [...new Set(refs)];
3231
+ }
2802
3232
  function normalizeMemoryScopes(value) {
2803
3233
  if (!Array.isArray(value) || value.length === 0) {
2804
3234
  return null;