@remnic/core 9.21.0 → 9.22.1

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 (422) hide show
  1. package/dist/access-admin-ops-surface.d.ts +32 -12
  2. package/dist/access-admin-ops-surface.js +44 -43
  3. package/dist/access-audit.js +2 -2
  4. package/dist/access-boundary.d.ts +13 -10
  5. package/dist/access-boundary.js +44 -43
  6. package/dist/access-cli.js +125 -122
  7. package/dist/access-cli.js.map +1 -1
  8. package/dist/access-http.d.ts +16 -9
  9. package/dist/access-http.js +56 -54
  10. package/dist/access-identity-continuity-surface.d.ts +9 -7
  11. package/dist/access-identity-continuity-surface.js +44 -43
  12. package/dist/access-lcm-surface.d.ts +12 -9
  13. package/dist/access-lcm-surface.js +44 -43
  14. package/dist/access-mcp-admin-tools.d.ts +18 -0
  15. package/dist/access-mcp-admin-tools.js +10 -0
  16. package/dist/access-mcp-admin-tools.js.map +1 -0
  17. package/dist/access-mcp-output-schemas.js +1 -1
  18. package/dist/access-mcp.d.ts +22 -10
  19. package/dist/access-mcp.js +52 -50
  20. package/dist/access-memory-search-fanout.d.ts +2 -2
  21. package/dist/{access-namespace-preflight-tmwQgCT6.d.ts → access-namespace-preflight-CmErR03h.d.ts} +1 -1
  22. package/dist/access-namespace-preflight.d.ts +3 -3
  23. package/dist/access-namespace-preflight.js +44 -43
  24. package/dist/access-observe-write-surface.d.ts +12 -9
  25. package/dist/access-observe-write-surface.js +44 -43
  26. package/dist/access-operations-batch.js +46 -45
  27. package/dist/access-operations.d.ts +16 -13
  28. package/dist/access-operations.js +48 -47
  29. package/dist/access-recall-concurrency.d.ts +12 -9
  30. package/dist/access-recall-concurrency.js +44 -43
  31. package/dist/access-recall-response.d.ts +12 -9
  32. package/dist/access-recall-response.js +44 -43
  33. package/dist/access-recall-surface.d.ts +14 -11
  34. package/dist/access-recall-surface.js +44 -43
  35. package/dist/access-schema.d.ts +76 -76
  36. package/dist/{access-service-BqUii7LY.d.ts → access-service-CKEROeFP.d.ts} +32 -11
  37. package/dist/access-service.d.ts +13 -10
  38. package/dist/access-service.js +46 -45
  39. package/dist/access-surface-catalog.d.ts +12 -9
  40. package/dist/access-surface-catalog.js +7 -0
  41. package/dist/access-surface-catalog.js.map +1 -1
  42. package/dist/access-wearables-meetings-surface.d.ts +78 -0
  43. package/dist/access-wearables-meetings-surface.js +22 -0
  44. package/dist/access-wearables-meetings-surface.js.map +1 -0
  45. package/dist/action-confidence.d.ts +1 -1
  46. package/dist/active-memory-bridge.d.ts +1 -1
  47. package/dist/active-recall.d.ts +1 -1
  48. package/dist/active-recall.js +7 -7
  49. package/dist/adapters/index.js +4 -4
  50. package/dist/adapters/registry.js +2 -2
  51. package/dist/{auto-sync-UPTUVE4X.js → auto-sync-5OE5QOZB.js} +4 -4
  52. package/dist/behavior-learner.d.ts +1 -1
  53. package/dist/behavior-signals.d.ts +1 -1
  54. package/dist/bootstrap.d.ts +9 -7
  55. package/dist/briefing.d.ts +2 -2
  56. package/dist/briefing.js +11 -11
  57. package/dist/buffer-surprise-report.d.ts +1 -1
  58. package/dist/buffer.d.ts +2 -2
  59. package/dist/bulk-import/index.d.ts +3 -3
  60. package/dist/calibration.d.ts +1 -1
  61. package/dist/capabilities.d.ts +1 -1
  62. package/dist/{catalog-iWvWz61I.d.ts → catalog-BFTVo2Ez.d.ts} +1 -1
  63. package/dist/causal-behavior.d.ts +1 -1
  64. package/dist/causal-behavior.js +2 -2
  65. package/dist/causal-chain.js +2 -2
  66. package/dist/causal-consolidation.d.ts +1 -1
  67. package/dist/causal-consolidation.js +15 -15
  68. package/dist/causal-retrieval.js +2 -2
  69. package/dist/causal-trajectory-graph.d.ts +1 -1
  70. package/dist/causal-trajectory.js +1 -1
  71. package/dist/{chunk-Z54EM5YZ.js → chunk-2PHX3I5C.js} +10 -10
  72. package/dist/{chunk-JFDEYXF7.js → chunk-3NAHZQU3.js} +2 -2
  73. package/dist/{chunk-MJYYXODM.js → chunk-3UOSVTFR.js} +8 -8
  74. package/dist/{chunk-HPOY2PHQ.js → chunk-3ZW6ZQO6.js} +6 -6
  75. package/dist/{chunk-UV72DEZD.js → chunk-4B77XSG5.js} +5 -5
  76. package/dist/chunk-56BSXSHC.js +158 -0
  77. package/dist/chunk-56BSXSHC.js.map +1 -0
  78. package/dist/{chunk-IC2TCZJ2.js → chunk-57QKLRBV.js} +3 -1
  79. package/dist/chunk-57QKLRBV.js.map +1 -0
  80. package/dist/{chunk-LMHDFOVV.js → chunk-5CPI2QWG.js} +3 -3
  81. package/dist/{chunk-3ZUY2VQF.js → chunk-5FZQ74K5.js} +2 -2
  82. package/dist/{chunk-B7C3TF5H.js → chunk-6TWXQ4E2.js} +5 -5
  83. package/dist/{chunk-JN3IUA2Q.js → chunk-7I7AYIUQ.js} +3 -3
  84. package/dist/{chunk-TVVEYCNW.js → chunk-7K5Q6COX.js} +4 -4
  85. package/dist/{chunk-MONWCSVL.js → chunk-7RAJ3GXO.js} +2 -1
  86. package/dist/chunk-7RAJ3GXO.js.map +1 -0
  87. package/dist/{chunk-SQEDDWAM.js → chunk-A2RFKL3V.js} +5 -34
  88. package/dist/chunk-A2RFKL3V.js.map +1 -0
  89. package/dist/{chunk-5JQLAQUZ.js → chunk-ATEAL5EI.js} +6 -6
  90. package/dist/{chunk-4PYLBXX6.js → chunk-AYAROCWD.js} +2 -2
  91. package/dist/chunk-BLDBT6HZ.js +39 -0
  92. package/dist/chunk-BLDBT6HZ.js.map +1 -0
  93. package/dist/{chunk-EXU5IQ3S.js → chunk-CUUY5CC4.js} +6 -6
  94. package/dist/{chunk-X5QS5C2O.js → chunk-E3ZMFFQZ.js} +2 -2
  95. package/dist/{chunk-JWMYVQAM.js → chunk-ES5IHQ6M.js} +2 -2
  96. package/dist/{chunk-HJEEAO4O.js → chunk-G2NSSQES.js} +2 -2
  97. package/dist/{chunk-QO2KODU6.js → chunk-GD3QOBMB.js} +2 -2
  98. package/dist/{chunk-62QM5MKY.js → chunk-IIXLB5E7.js} +118 -62
  99. package/dist/chunk-IIXLB5E7.js.map +1 -0
  100. package/dist/{chunk-RKNJBZ55.js → chunk-JBPKEARU.js} +4 -4
  101. package/dist/{chunk-Q3FWRDCP.js → chunk-JNIJBXVK.js} +2 -2
  102. package/dist/{chunk-EILX7SQR.js → chunk-JVGUY2AU.js} +27 -16
  103. package/dist/chunk-JVGUY2AU.js.map +1 -0
  104. package/dist/{chunk-N7EVMKP6.js → chunk-KNRG6ZGJ.js} +11 -11
  105. package/dist/{chunk-GEUDRENF.js → chunk-MMTG3SCJ.js} +2 -2
  106. package/dist/{chunk-WZFAPHIK.js → chunk-MU7ZHSZE.js} +2 -2
  107. package/dist/{chunk-W4FBGYGK.js → chunk-NRV4Y3PM.js} +1 -1
  108. package/dist/{chunk-TCZWBJBO.js → chunk-OUW4PAY4.js} +199 -256
  109. package/dist/chunk-OUW4PAY4.js.map +1 -0
  110. package/dist/{chunk-275ENJDK.js → chunk-P2BLHUL2.js} +2 -2
  111. package/dist/{chunk-LRGSLV7M.js → chunk-PYHOAXTI.js} +4 -4
  112. package/dist/{chunk-V5TSUGRB.js → chunk-QCKQEBIY.js} +17 -9
  113. package/dist/chunk-QCKQEBIY.js.map +1 -0
  114. package/dist/{chunk-EZKKHVFY.js → chunk-QE63OHLB.js} +2 -2
  115. package/dist/{chunk-ONHRRJZM.js → chunk-QJAQNXWI.js} +6 -6
  116. package/dist/{chunk-KHRKEELC.js → chunk-ROUL7RZU.js} +395 -69
  117. package/dist/chunk-ROUL7RZU.js.map +1 -0
  118. package/dist/{chunk-AT3TDN6O.js → chunk-RT4TSR2C.js} +8953 -8645
  119. package/dist/chunk-RT4TSR2C.js.map +1 -0
  120. package/dist/{chunk-6NZ7U4R4.js → chunk-SCOT5DTA.js} +1 -1
  121. package/dist/chunk-SCOT5DTA.js.map +1 -0
  122. package/dist/{chunk-LI4ZOFHW.js → chunk-SVZGA2MK.js} +2 -2
  123. package/dist/chunk-SYOIVK7K.js +63 -0
  124. package/dist/chunk-SYOIVK7K.js.map +1 -0
  125. package/dist/{chunk-5RUE3GHQ.js → chunk-TWCOYET2.js} +17 -1
  126. package/dist/chunk-TWCOYET2.js.map +1 -0
  127. package/dist/{chunk-5IXPWEQB.js → chunk-WS32QRLO.js} +113 -48
  128. package/dist/chunk-WS32QRLO.js.map +1 -0
  129. package/dist/{chunk-53WDAG7X.js → chunk-WWZ35GWW.js} +5 -5
  130. package/dist/{chunk-4F6AANKS.js → chunk-XWPFZX6S.js} +507 -143
  131. package/dist/chunk-XWPFZX6S.js.map +1 -0
  132. package/dist/{chunk-SB4OKS6C.js → chunk-ZN4UZWMT.js} +2 -2
  133. package/dist/{chunk-7M6APKJL.js → chunk-ZYU7ZFLT.js} +2 -2
  134. package/dist/{cli-DPEhq0Cp.d.ts → cli-BrwT9YMD.d.ts} +5 -5
  135. package/dist/cli.d.ts +14 -11
  136. package/dist/cli.js +86 -84
  137. package/dist/compounding/engine.d.ts +2 -2
  138. package/dist/compounding/engine.js +11 -11
  139. package/dist/compounding/preference-consolidator.d.ts +1 -1
  140. package/dist/compression-optimizer.d.ts +1 -1
  141. package/dist/config.d.ts +1 -1
  142. package/dist/config.js +4 -4
  143. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  144. package/dist/connectors/codex-materialize-runner.js +11 -11
  145. package/dist/connectors/codex-materialize.d.ts +1 -1
  146. package/dist/connectors/index.d.ts +1 -1
  147. package/dist/connectors/index.js +12 -12
  148. package/dist/consolidation-provenance-check.d.ts +2 -2
  149. package/dist/consolidation-undo.d.ts +2 -2
  150. package/dist/contradiction/index.d.ts +2 -2
  151. package/dist/contradiction/index.js +1 -1
  152. package/dist/conversation-index/backend.d.ts +1 -1
  153. package/dist/conversation-index/chunker.d.ts +1 -1
  154. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  155. package/dist/conversation-index/indexer.d.ts +1 -1
  156. package/dist/conversation-index/search.d.ts +1 -1
  157. package/dist/day-summary.d.ts +1 -1
  158. package/dist/delinearize.d.ts +1 -1
  159. package/dist/direct-answer-wiring.d.ts +1 -1
  160. package/dist/direct-answer.d.ts +1 -1
  161. package/dist/embedding-fallback.d.ts +1 -1
  162. package/dist/enrichment/index.d.ts +1 -1
  163. package/dist/entity-retrieval.d.ts +2 -2
  164. package/dist/entity-retrieval.js +11 -11
  165. package/dist/entity-schema.d.ts +1 -1
  166. package/dist/explicit-capture.d.ts +9 -7
  167. package/dist/explicit-capture.js +1 -1
  168. package/dist/extraction-error-classification.d.ts +22 -0
  169. package/dist/extraction-error-classification.js +11 -0
  170. package/dist/extraction-error-classification.js.map +1 -0
  171. package/dist/extraction-faithfulness.d.ts +1 -1
  172. package/dist/extraction-judge-telemetry.d.ts +1 -1
  173. package/dist/extraction-judge-training.d.ts +1 -1
  174. package/dist/extraction-judge.d.ts +1 -1
  175. package/dist/extraction.d.ts +3 -17
  176. package/dist/extraction.js +5 -3
  177. package/dist/fallback-llm.d.ts +1 -1
  178. package/dist/{first-start-migration-LEXL3XYL.js → first-start-migration-BKNGOFED.js} +4 -4
  179. package/dist/graph-dashboard-diff.d.ts +1 -1
  180. package/dist/graph-dashboard-key.d.ts +1 -1
  181. package/dist/graph-dashboard-parser.d.ts +1 -1
  182. package/dist/graph-edge-reinforcement.d.ts +1 -1
  183. package/dist/graph-snapshot.d.ts +1 -1
  184. package/dist/graph.d.ts +1 -1
  185. package/dist/importance.d.ts +1 -1
  186. package/dist/importers/index.d.ts +1 -1
  187. package/dist/in-flight-reads.d.ts +1 -1
  188. package/dist/index.d.ts +713 -923
  189. package/dist/index.js +249 -212
  190. package/dist/intent.d.ts +1 -1
  191. package/dist/lcm/engine.d.ts +1 -1
  192. package/dist/lcm/engine.js +4 -4
  193. package/dist/lcm/index.d.ts +1 -1
  194. package/dist/lcm/index.js +13 -13
  195. package/dist/lcm/tools.d.ts +1 -1
  196. package/dist/lifecycle.d.ts +1 -1
  197. package/dist/live-connectors-runner.d.ts +1 -1
  198. package/dist/local-llm.d.ts +1 -1
  199. package/dist/local-model-endpoint.d.ts +1 -1
  200. package/dist/maintenance/memory-governance.d.ts +1 -1
  201. package/dist/maintenance/memory-governance.js +12 -12
  202. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
  203. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +11 -11
  204. package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
  205. package/dist/maintenance/rebuild-memory-projection.js +13 -13
  206. package/dist/maintenance-C98njYb8.d.ts +366 -0
  207. package/dist/mcp-memory-inspector-app.d.ts +12 -9
  208. package/dist/mcp-read-only-tools.js +1 -1
  209. package/dist/memory-action-policy.d.ts +1 -1
  210. package/dist/memory-cache.d.ts +1 -1
  211. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  212. package/dist/memory-projection-store.d.ts +1 -1
  213. package/dist/memory-provenance.d.ts +1 -1
  214. package/dist/memory-worth-outcomes.d.ts +2 -2
  215. package/dist/models-json.d.ts +1 -1
  216. package/dist/namespaces/migrate.d.ts +3 -3
  217. package/dist/namespaces/migrate.js +19 -19
  218. package/dist/namespaces/principal.d.ts +1 -1
  219. package/dist/namespaces/search.d.ts +1 -1
  220. package/dist/namespaces/search.js +7 -7
  221. package/dist/namespaces/storage.d.ts +3 -3
  222. package/dist/namespaces/storage.js +11 -11
  223. package/dist/native-knowledge.d.ts +1 -1
  224. package/dist/offline-sync-impression-drain.d.ts +1 -1
  225. package/dist/offline-sync-impression-drain.js +1 -1
  226. package/dist/operator-toolkit.d.ts +2 -2
  227. package/dist/operator-toolkit.js +28 -28
  228. package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
  229. package/dist/orchestration/maintenance.d.ts +6 -223
  230. package/dist/orchestration/maintenance.js +19 -19
  231. package/dist/{orchestrator-DB93S48I.d.ts → orchestrator-C9ZVppNh.d.ts} +12 -481
  232. package/dist/orchestrator.d.ts +10 -8
  233. package/dist/orchestrator.js +122 -119
  234. package/dist/patterns-cli.d.ts +1 -1
  235. package/dist/{pipeline-DmGc-H66.d.ts → pipeline-id_-sqYm.d.ts} +1 -1
  236. package/dist/policy-runtime.d.ts +1 -1
  237. package/dist/proactive-contention.d.ts +1 -1
  238. package/dist/provenance.d.ts +1 -1
  239. package/dist/{qmd-cJT0crkF.d.ts → qmd-R6XaQOZK.d.ts} +1 -1
  240. package/dist/qmd-preflight.d.ts +2 -2
  241. package/dist/qmd-recall-cache.d.ts +1 -1
  242. package/dist/qmd.d.ts +2 -2
  243. package/dist/qmd.js +4 -4
  244. package/dist/recall-concurrency-config.d.ts +1 -1
  245. package/dist/recall-disclosure-escalation.d.ts +1 -1
  246. package/dist/recall-explain-renderer.d.ts +1 -1
  247. package/dist/recall-explain-renderer.js +3 -3
  248. package/dist/recall-memory-map.d.ts +1 -1
  249. package/dist/recall-planner-llm.d.ts +1 -1
  250. package/dist/recall-state.d.ts +1 -1
  251. package/dist/recall-tag-filter.d.ts +1 -1
  252. package/dist/recall-timings.d.ts +1 -1
  253. package/dist/recall-xray-cli.d.ts +1 -1
  254. package/dist/recall-xray-cli.js +4 -4
  255. package/dist/recall-xray-renderer.d.ts +1 -1
  256. package/dist/recall-xray-renderer.js +3 -3
  257. package/dist/recall-xray.d.ts +1 -1
  258. package/dist/recall-xray.js +2 -2
  259. package/dist/replay/normalizers/chatgpt.d.ts +1 -1
  260. package/dist/replay/normalizers/claude.d.ts +1 -1
  261. package/dist/replay/normalizers/openclaw.d.ts +1 -1
  262. package/dist/replay/normalizers/shared.d.ts +1 -1
  263. package/dist/replay/runner.d.ts +1 -1
  264. package/dist/replay/types.d.ts +1 -1
  265. package/dist/resolution-3K27T4VO.js +1 -1
  266. package/dist/resolve-auth-token.d.ts +1 -1
  267. package/dist/resume-bundles.js +6 -6
  268. package/dist/retrieval-agents.d.ts +2 -2
  269. package/dist/retrieval-tiers.d.ts +1 -1
  270. package/dist/routing/engine.d.ts +1 -1
  271. package/dist/routing/store.d.ts +1 -1
  272. package/dist/salvage-envelope.d.ts +1 -1
  273. package/dist/salvage-envelope.js +1 -1
  274. package/dist/schemas.d.ts +76 -76
  275. package/dist/{scope-profiles-KG2nODX7.d.ts → scope-profiles-EhyuAKkd.d.ts} +1 -1
  276. package/dist/search/embed-helper.d.ts +1 -1
  277. package/dist/search/factory.d.ts +1 -1
  278. package/dist/search/factory.js +6 -6
  279. package/dist/search/index.d.ts +1 -1
  280. package/dist/search/index.js +12 -12
  281. package/dist/search/lancedb-backend.d.ts +1 -1
  282. package/dist/search/meilisearch-backend.d.ts +1 -1
  283. package/dist/search/noop-backend.d.ts +1 -1
  284. package/dist/search/orama-backend.d.ts +1 -1
  285. package/dist/search/port.d.ts +1 -1
  286. package/dist/search/remote-backend.d.ts +1 -1
  287. package/dist/{semantic-consolidation-BaZlg0D8.d.ts → semantic-consolidation-B2xo26UQ.d.ts} +1 -1
  288. package/dist/semantic-consolidation.d.ts +2 -2
  289. package/dist/semantic-consolidation.js +13 -13
  290. package/dist/semantic-rule-promotion.js +11 -11
  291. package/dist/semantic-rule-verifier.d.ts +1 -1
  292. package/dist/semantic-rule-verifier.js +12 -12
  293. package/dist/service-DgFWlZ-r.d.ts +835 -0
  294. package/dist/session-observer-bands.d.ts +1 -1
  295. package/dist/session-observer-state.d.ts +1 -1
  296. package/dist/shared-context/manager.d.ts +9 -9
  297. package/dist/signal.d.ts +1 -1
  298. package/dist/{storage-BKhHHnRo.d.ts → storage-XGawwqXE.d.ts} +131 -2
  299. package/dist/storage.d.ts +2 -2
  300. package/dist/storage.js +10 -10
  301. package/dist/summarizer.d.ts +1 -1
  302. package/dist/summary-snapshot.d.ts +1 -1
  303. package/dist/temporal-supersession.d.ts +2 -2
  304. package/dist/temporal-timeline-recall.d.ts +1 -1
  305. package/dist/temporal-validity.d.ts +1 -1
  306. package/dist/threading.d.ts +1 -1
  307. package/dist/tier-migration.d.ts +2 -2
  308. package/dist/tier-routing.d.ts +1 -1
  309. package/dist/topics.d.ts +1 -1
  310. package/dist/transcript.d.ts +1 -1
  311. package/dist/transfer/import-sqlite.js +2 -2
  312. package/dist/transfer/types.d.ts +66 -66
  313. package/dist/trust-score-stage.d.ts +1 -1
  314. package/dist/trust-score.d.ts +1 -1
  315. package/dist/{types-GBQZuT7l.d.ts → types-Bbs0qz6b.d.ts} +2 -3
  316. package/dist/types.d.ts +1 -1
  317. package/dist/types.js +1 -1
  318. package/dist/utility-runtime.d.ts +1 -1
  319. package/dist/verified-recall.js +12 -12
  320. package/dist/write-envelope.d.ts +1 -1
  321. package/dist/write-envelope.js +1 -1
  322. package/package.json +2 -2
  323. package/src/access-admin-ops-surface.ts +47 -0
  324. package/src/access-boundary.ts +4 -0
  325. package/src/access-http.test.ts +63 -0
  326. package/src/access-http.ts +27 -37
  327. package/src/access-mcp-admin-tools.ts +171 -0
  328. package/src/access-mcp-output-schemas.ts +16 -0
  329. package/src/access-mcp.ts +10 -262
  330. package/src/access-operations-batch.ts +11 -5
  331. package/src/access-service.ts +59 -46
  332. package/src/access-surface-catalog.ts +7 -0
  333. package/src/access-wearables-meetings-surface.ts +139 -0
  334. package/src/activity/digest.ts +1 -1
  335. package/src/activity/runner.test.ts +37 -0
  336. package/src/activity/runner.ts +12 -0
  337. package/src/activity/scheduler.test.ts +1 -0
  338. package/src/activity/sync-registration.ts +13 -0
  339. package/src/cli/meetings-commands.ts +70 -0
  340. package/src/cli.ts +7 -6
  341. package/src/extraction-error-classification.ts +52 -0
  342. package/src/extraction.ts +2 -50
  343. package/src/mcp-read-only-tools.ts +2 -0
  344. package/src/meetings/build-memory.test.ts +364 -0
  345. package/src/meetings/build-scheduler.test.ts +55 -0
  346. package/src/meetings/build-scheduler.ts +96 -0
  347. package/src/meetings/day-source.test.ts +275 -0
  348. package/src/meetings/day-source.ts +352 -0
  349. package/src/meetings/http-glue.ts +126 -0
  350. package/src/meetings/index.ts +5 -4
  351. package/src/meetings/manual-sync-flush.test.ts +72 -0
  352. package/src/meetings/mcp-tools.ts +65 -0
  353. package/src/meetings/memory-gen.test.ts +498 -0
  354. package/src/meetings/memory-gen.ts +549 -0
  355. package/src/meetings/memory-generator.ts +5 -0
  356. package/src/meetings/namespace-isolation.test.ts +159 -0
  357. package/src/meetings/service.test.ts +195 -0
  358. package/src/meetings/service.ts +157 -0
  359. package/src/meetings/summary-extractor.test.ts +287 -0
  360. package/src/meetings/summary-extractor.ts +264 -0
  361. package/src/orchestration/maintenance.ts +8 -0
  362. package/src/orchestration/orchestrator-init.ts +6 -1
  363. package/src/orchestration/workspace-ops.ts +172 -8
  364. package/src/orchestrator.ts +12 -13
  365. package/src/storage.ts +21 -0
  366. package/src/testing/subjects/meetings-namespace-harness.ts +159 -0
  367. package/src/testing/subjects/meetings-namespace.test.ts +93 -0
  368. package/src/types.ts +1 -2
  369. package/src/wearables/cli.ts +2 -1
  370. package/src/wearables/index.ts +1 -0
  371. package/src/wearables/mcp-tools.ts +143 -0
  372. package/src/wearables/registry.test.ts +11 -0
  373. package/src/wearables/registry.ts +13 -0
  374. package/src/wearables/service.test.ts +62 -1
  375. package/src/wearables/service.ts +30 -2
  376. package/src/wearables/transcript-search-namespace-isolation.test.ts +98 -0
  377. package/dist/chunk-4F6AANKS.js.map +0 -1
  378. package/dist/chunk-5IXPWEQB.js.map +0 -1
  379. package/dist/chunk-5RUE3GHQ.js.map +0 -1
  380. package/dist/chunk-62QM5MKY.js.map +0 -1
  381. package/dist/chunk-6NZ7U4R4.js.map +0 -1
  382. package/dist/chunk-AT3TDN6O.js.map +0 -1
  383. package/dist/chunk-EILX7SQR.js.map +0 -1
  384. package/dist/chunk-IC2TCZJ2.js.map +0 -1
  385. package/dist/chunk-KHRKEELC.js.map +0 -1
  386. package/dist/chunk-MONWCSVL.js.map +0 -1
  387. package/dist/chunk-SQEDDWAM.js.map +0 -1
  388. package/dist/chunk-TCZWBJBO.js.map +0 -1
  389. package/dist/chunk-V5TSUGRB.js.map +0 -1
  390. /package/dist/{auto-sync-UPTUVE4X.js.map → auto-sync-5OE5QOZB.js.map} +0 -0
  391. /package/dist/{chunk-Z54EM5YZ.js.map → chunk-2PHX3I5C.js.map} +0 -0
  392. /package/dist/{chunk-JFDEYXF7.js.map → chunk-3NAHZQU3.js.map} +0 -0
  393. /package/dist/{chunk-MJYYXODM.js.map → chunk-3UOSVTFR.js.map} +0 -0
  394. /package/dist/{chunk-HPOY2PHQ.js.map → chunk-3ZW6ZQO6.js.map} +0 -0
  395. /package/dist/{chunk-UV72DEZD.js.map → chunk-4B77XSG5.js.map} +0 -0
  396. /package/dist/{chunk-LMHDFOVV.js.map → chunk-5CPI2QWG.js.map} +0 -0
  397. /package/dist/{chunk-3ZUY2VQF.js.map → chunk-5FZQ74K5.js.map} +0 -0
  398. /package/dist/{chunk-B7C3TF5H.js.map → chunk-6TWXQ4E2.js.map} +0 -0
  399. /package/dist/{chunk-JN3IUA2Q.js.map → chunk-7I7AYIUQ.js.map} +0 -0
  400. /package/dist/{chunk-TVVEYCNW.js.map → chunk-7K5Q6COX.js.map} +0 -0
  401. /package/dist/{chunk-5JQLAQUZ.js.map → chunk-ATEAL5EI.js.map} +0 -0
  402. /package/dist/{chunk-4PYLBXX6.js.map → chunk-AYAROCWD.js.map} +0 -0
  403. /package/dist/{chunk-EXU5IQ3S.js.map → chunk-CUUY5CC4.js.map} +0 -0
  404. /package/dist/{chunk-X5QS5C2O.js.map → chunk-E3ZMFFQZ.js.map} +0 -0
  405. /package/dist/{chunk-JWMYVQAM.js.map → chunk-ES5IHQ6M.js.map} +0 -0
  406. /package/dist/{chunk-HJEEAO4O.js.map → chunk-G2NSSQES.js.map} +0 -0
  407. /package/dist/{chunk-QO2KODU6.js.map → chunk-GD3QOBMB.js.map} +0 -0
  408. /package/dist/{chunk-RKNJBZ55.js.map → chunk-JBPKEARU.js.map} +0 -0
  409. /package/dist/{chunk-Q3FWRDCP.js.map → chunk-JNIJBXVK.js.map} +0 -0
  410. /package/dist/{chunk-N7EVMKP6.js.map → chunk-KNRG6ZGJ.js.map} +0 -0
  411. /package/dist/{chunk-GEUDRENF.js.map → chunk-MMTG3SCJ.js.map} +0 -0
  412. /package/dist/{chunk-WZFAPHIK.js.map → chunk-MU7ZHSZE.js.map} +0 -0
  413. /package/dist/{chunk-W4FBGYGK.js.map → chunk-NRV4Y3PM.js.map} +0 -0
  414. /package/dist/{chunk-275ENJDK.js.map → chunk-P2BLHUL2.js.map} +0 -0
  415. /package/dist/{chunk-LRGSLV7M.js.map → chunk-PYHOAXTI.js.map} +0 -0
  416. /package/dist/{chunk-EZKKHVFY.js.map → chunk-QE63OHLB.js.map} +0 -0
  417. /package/dist/{chunk-ONHRRJZM.js.map → chunk-QJAQNXWI.js.map} +0 -0
  418. /package/dist/{chunk-LI4ZOFHW.js.map → chunk-SVZGA2MK.js.map} +0 -0
  419. /package/dist/{chunk-53WDAG7X.js.map → chunk-WWZ35GWW.js.map} +0 -0
  420. /package/dist/{chunk-SB4OKS6C.js.map → chunk-ZN4UZWMT.js.map} +0 -0
  421. /package/dist/{chunk-7M6APKJL.js.map → chunk-ZYU7ZFLT.js.map} +0 -0
  422. /package/dist/{first-start-migration-LEXL3XYL.js.map → first-start-migration-BKNGOFED.js.map} +0 -0
package/src/access-mcp.ts CHANGED
@@ -1,4 +1,8 @@
1
1
  import { randomUUID } from "node:crypto";
2
+ import {
3
+ MCP_ADMIN_OPS_TOOLS,
4
+ MCP_GIT_CONTEXT_SCHEMA_PROPS_IGNORED,
5
+ } from "./access-mcp-admin-tools.js";
2
6
  import { readFile } from "node:fs/promises";
3
7
  import type { Readable, Writable } from "node:stream";
4
8
  // Importing access-operations registers the pilot boundary operations
@@ -39,7 +43,7 @@ import type { RecallDisclosure, RecallPlanMode } from "./types.js";
39
43
  import { expandTildePath } from "./utils/path.js";
40
44
 
41
45
  import { applyToolOutputSchemas } from "./access-mcp-output-schemas.js";
42
- import { MCP_READ_ONLY_TOOL_SUFFIXES } from "./mcp-read-only-tools.js";
46
+ import { MCP_READ_ONLY_TOOL_SUFFIXES } from "./mcp-read-only-tools.js";import { MEETINGS_MCP_TOOLS } from "./meetings/mcp-tools.js";import { WEARABLES_MCP_TOOLS } from "./wearables/mcp-tools.js";
43
47
  import { abortError, isAbortError } from "./abort-error.js";
44
48
  type JsonRpcId = string | number | null;
45
49
 
@@ -78,7 +82,7 @@ type McpRequestOptions = {
78
82
  abortSignal?: AbortSignal;
79
83
  };
80
84
 
81
- type McpTool = {
85
+ export type McpTool = {
82
86
  name: string;
83
87
  title?: string;
84
88
  description: string;
@@ -184,7 +188,7 @@ const MCP_MIGRATED_OPERATIONS: Readonly<Record<string, OperationName>> = {
184
188
  "engram.wearables_sync": "wearables_sync",
185
189
  "engram.transcript_day": "transcript_day",
186
190
  "engram.transcript_search": "transcript_search",
187
- "engram.transcript_memories": "transcript_memories",
191
+ "engram.transcript_memories": "transcript_memories", "engram.meetings_list": "meetings_list", "engram.meetings_get": "meetings_get", "engram.meetings_build": "meetings_build",
188
192
  "engram.action_confidence": "action_confidence",
189
193
  "engram.chatgpt_memory_inspector": "chatgpt_memory_inspector",
190
194
  "engram.day_summary": "day_summary",
@@ -192,6 +196,7 @@ const MCP_MIGRATED_OPERATIONS: Readonly<Record<string, OperationName>> = {
192
196
  "engram.capsule_import": "capsule_import",
193
197
  "engram.capsule_list": "capsule_list",
194
198
  "engram.memory_governance_run": "memory_governance_run",
199
+ "engram.entity_synthesis_run": "entity_synthesis_run",
195
200
  "engram.procedure_mining_run": "procedure_mining_run",
196
201
  "engram.pattern_reinforcement_run": "pattern_reinforcement_run",
197
202
  "engram.procedural_stats": "procedural_stats",
@@ -333,16 +338,6 @@ const MCP_GIT_CONTEXT_SCHEMA_PROPS_SCOPED: Record<string, unknown> = {
333
338
  "Optional project tag for non-git project scoping. When no explicit namespace is given, routes this write to the tagged project namespace.",
334
339
  },
335
340
  };
336
- const MCP_GIT_CONTEXT_SCHEMA_PROPS_IGNORED: Record<string, unknown> = {
337
- cwd: {
338
- type: "string",
339
- description: "Accepted for MCP client compatibility (git-context auto-injection); ignored by this tool.",
340
- },
341
- projectTag: {
342
- type: "string",
343
- description: "Accepted for MCP client compatibility; ignored by this tool.",
344
- },
345
- };
346
341
 
347
342
  function parseMcpRequest<N extends SchemaName>(schemaName: N, args: Record<string, unknown>): SchemaTypeFor<N> {
348
343
  const allowedKeys = STRICT_MCP_SCHEMA_KEYS[schemaName];
@@ -687,124 +682,7 @@ export class EngramMcpServer {
687
682
  additionalProperties: false,
688
683
  },
689
684
  },
690
- {
691
- name: "engram.wearables_status",
692
- description:
693
- "Status of wearable transcript sources (Limitless / Bee / Omi): configured sources, connector availability, last sync, stored transcript days.",
694
- inputSchema: {
695
- type: "object",
696
- properties: {},
697
- additionalProperties: false,
698
- },
699
- },
700
- {
701
- name: "engram.wearables_sync",
702
- description:
703
- "Pull, clean, and store wearable transcripts for one source or all enabled sources; optionally creates trust-gated memories per the source's memoryMode.",
704
- inputSchema: {
705
- type: "object",
706
- properties: {
707
- source: {
708
- type: "string",
709
- description: "Source id (e.g. limitless, bee, omi). Omit to sync every enabled source.",
710
- },
711
- date: {
712
- type: "string",
713
- description: "Sync exactly this day (YYYY-MM-DD). Overrides days.",
714
- },
715
- days: {
716
- type: "integer",
717
- minimum: 1,
718
- maximum: 90,
719
- description: "Lookback window in days ending today (default 2).",
720
- },
721
- forceMemories: {
722
- type: "boolean",
723
- description: "Re-run memory extraction even for unchanged days.",
724
- },
725
- },
726
- additionalProperties: false,
727
- },
728
- },
729
- {
730
- name: "engram.transcript_day",
731
- description:
732
- "Return the full stored wearable transcript(s) for a day, across all sources or one source, with cross-source overlap hints.",
733
- inputSchema: {
734
- type: "object",
735
- properties: {
736
- date: {
737
- type: "string",
738
- description: "Day to read (YYYY-MM-DD). Required.",
739
- },
740
- source: {
741
- type: "string",
742
- description: "Optional source id to scope to (e.g. limitless).",
743
- },
744
- },
745
- required: ["date"],
746
- additionalProperties: false,
747
- },
748
- },
749
- {
750
- name: "engram.transcript_search",
751
- description:
752
- "Search stored wearable transcripts. Results carry source + date so callers can pull the full day via engram.transcript_day.",
753
- inputSchema: {
754
- type: "object",
755
- properties: {
756
- query: {
757
- type: "string",
758
- description: "Search query. Required; non-empty.",
759
- },
760
- source: {
761
- type: "string",
762
- description: "Optional source id filter.",
763
- },
764
- from: {
765
- type: "string",
766
- description: "Optional inclusive start date (YYYY-MM-DD).",
767
- },
768
- to: {
769
- type: "string",
770
- description: "Optional inclusive end date (YYYY-MM-DD).",
771
- },
772
- limit: {
773
- type: "integer",
774
- minimum: 1,
775
- maximum: 50,
776
- description: "Maximum results (default 10).",
777
- },
778
- },
779
- required: ["query"],
780
- additionalProperties: false,
781
- },
782
- },
783
- {
784
- name: "engram.transcript_memories",
785
- description:
786
- "List memories created from wearable transcripts, filterable by source and/or day. Includes pending_review candidates awaiting approval.",
787
- inputSchema: {
788
- type: "object",
789
- properties: {
790
- source: {
791
- type: "string",
792
- description: "Optional source id filter (e.g. limitless).",
793
- },
794
- date: {
795
- type: "string",
796
- description: "Optional transcript day filter (YYYY-MM-DD).",
797
- },
798
- limit: {
799
- type: "integer",
800
- minimum: 1,
801
- maximum: 200,
802
- description: "Maximum results (default 50).",
803
- },
804
- },
805
- additionalProperties: false,
806
- },
807
- },
685
+ ...WEARABLES_MCP_TOOLS, ...MEETINGS_MCP_TOOLS,
808
686
  {
809
687
  name: "engram.action_confidence",
810
688
  description:
@@ -976,137 +854,7 @@ export class EngramMcpServer {
976
854
  additionalProperties: false,
977
855
  },
978
856
  },
979
- {
980
- name: "engram.capsule_export",
981
- description: "Export a portable Remnic capsule archive from the namespace-scoped memory store.",
982
- inputSchema: {
983
- type: "object",
984
- properties: {
985
- name: {
986
- type: "string",
987
- description: "Capsule id (alphanumeric with single dashes, max 64 characters).",
988
- },
989
- namespace: { type: "string" },
990
- since: {
991
- type: "string",
992
- description: "Only include files modified on or after this ISO 8601 timestamp.",
993
- },
994
- includeKinds: {
995
- type: "array",
996
- items: { type: "string" },
997
- description: "Optional top-level directory allow-list.",
998
- },
999
- peerIds: {
1000
- type: "array",
1001
- items: { type: "string" },
1002
- description: "Optional peer id allow-list for the peers/ subtree.",
1003
- },
1004
- includeTranscripts: { type: "boolean" },
1005
- encrypt: { type: "boolean" },
1006
- ...MCP_GIT_CONTEXT_SCHEMA_PROPS_IGNORED,
1007
- },
1008
- required: ["name"],
1009
- additionalProperties: false,
1010
- },
1011
- },
1012
- {
1013
- name: "engram.capsule_import",
1014
- description: "Import a Remnic capsule archive into the namespace-scoped memory store.",
1015
- inputSchema: {
1016
- type: "object",
1017
- properties: {
1018
- archivePath: {
1019
- type: "string",
1020
- description: "Path to a .capsule.json.gz or .capsule.json.gz.enc archive.",
1021
- },
1022
- namespace: { type: "string" },
1023
- mode: {
1024
- type: "string",
1025
- enum: ["skip", "overwrite", "fork"],
1026
- description: "Conflict handling mode. Defaults to skip.",
1027
- },
1028
- passphrase: {
1029
- type: "string",
1030
- description: "Passphrase for encrypted capsule archives.",
1031
- },
1032
- ...MCP_GIT_CONTEXT_SCHEMA_PROPS_IGNORED,
1033
- },
1034
- required: ["archivePath"],
1035
- additionalProperties: false,
1036
- },
1037
- },
1038
- {
1039
- name: "engram.capsule_list",
1040
- description: "List capsule archives in the namespace-scoped capsule store.",
1041
- inputSchema: {
1042
- type: "object",
1043
- properties: {
1044
- namespace: { type: "string" },
1045
- sessionKey: {
1046
- type: "string",
1047
- description:
1048
- "Optional session key used to derive namespace principal when no trusted transport principal is present.",
1049
- },
1050
- ...MCP_GIT_CONTEXT_SCHEMA_PROPS_IGNORED,
1051
- },
1052
- additionalProperties: false,
1053
- },
1054
- },
1055
- {
1056
- name: "engram.memory_governance_run",
1057
- description: "Run Remnic memory governance in a bounded shadow/apply pass.",
1058
- inputSchema: {
1059
- type: "object",
1060
- properties: {
1061
- namespace: { type: "string" },
1062
- mode: { type: "string", enum: ["shadow", "apply"] },
1063
- recentDays: { type: "number" },
1064
- maxMemories: { type: "number" },
1065
- batchSize: { type: "number" },
1066
- },
1067
- additionalProperties: false,
1068
- },
1069
- },
1070
- {
1071
- name: "engram.procedure_mining_run",
1072
- description:
1073
- "Run procedural memory mining from causal trajectories (issue #519). Respects procedural.enabled; writes under procedures/ when clusters qualify.",
1074
- inputSchema: {
1075
- type: "object",
1076
- properties: {
1077
- namespace: { type: "string" },
1078
- },
1079
- additionalProperties: false,
1080
- },
1081
- },
1082
- {
1083
- name: "engram.pattern_reinforcement_run",
1084
- description:
1085
- "Run the pattern-reinforcement maintenance job (issue #687 PR 2/4). Clusters duplicate non-procedural memories by normalized content, promotes the most-recent member to canonical, and supersedes the older duplicates. Gated on patternReinforcementEnabled and the patternReinforcementCadenceMs floor — pass force=true to bypass the cadence for an ad-hoc operator run.",
1086
- inputSchema: {
1087
- type: "object",
1088
- properties: {
1089
- namespace: { type: "string" },
1090
- force: { type: "boolean" },
1091
- },
1092
- additionalProperties: false,
1093
- },
1094
- },
1095
- {
1096
- // The canonical `remnic.procedural_stats` alias is added automatically
1097
- // by `withToolAliases` — the dual-naming invariant keeps both names
1098
- // alive for the legacy surface.
1099
- name: "engram.procedural_stats",
1100
- description:
1101
- "Procedural memory stats (issue #567): counts by status, recent write activity, and the active procedural.* config. Read-only, namespace-scoped.",
1102
- inputSchema: {
1103
- type: "object",
1104
- properties: {
1105
- namespace: { type: "string" },
1106
- },
1107
- additionalProperties: false,
1108
- },
1109
- },
857
+ ...MCP_ADMIN_OPS_TOOLS,
1110
858
  {
1111
859
  name: "engram.memory_get",
1112
860
  description: "Fetch one Remnic memory by id.",
@@ -140,11 +140,16 @@ defineOperation({ name: "namespace_writable", description: "Read-only preflight:
140
140
  } });
141
141
 
142
142
  // === WEARABLES ===
143
- defineOperation({ name: "wearables_status", description: "Wearables status.", schema: strictSchema({}), handler: async (_i, ctx) => ({ result: await ctx.service.wearablesStatus() }) });
144
- defineOperation({ name: "wearables_sync", description: "Sync wearables.", schema: strictSchema({ source: S.str, date: S.str, days: S.flexNum, forceMemories: S.bool }), handler: async (input, ctx) => ({ result: await ctx.service.wearablesSync({ source: optStr(input.source), date: optStr(input.date), days: typeof input.days === "number" ? input.days : typeof input.days === "string" && Number.isFinite(Number(input.days)) ? Number(input.days) : undefined, forceMemories: optBool(input.forceMemories) }) }) });
145
- defineOperation({ name: "transcript_day", description: "Transcript for a day.", schema: strictSchema({ date: S.str, source: S.str }), handler: async (input, ctx) => { const d = defStr(input.date, ""); if (d.trim().length === 0) throw new EngramAccessInputError("transcript_day: date is required (YYYY-MM-DD)"); return { result: await ctx.service.wearablesTranscriptDay({ date: d, source: optStr(input.source) }) }; } });
146
- defineOperation({ name: "transcript_search", description: "Search transcripts.", schema: strictSchema({ query: S.str, source: S.str, from: S.str, to: S.str, limit: S.flexNum }), handler: async (input, ctx) => { const q = defStr(input.query, ""); if (q.trim().length === 0) throw new EngramAccessInputError("transcript_search: query is required"); return { result: await ctx.service.wearablesTranscriptSearch({ query: q, source: optStr(input.source), from: optStr(input.from), to: optStr(input.to), limit: typeof input.limit === "number" ? input.limit : typeof input.limit === "string" && Number.isFinite(Number(input.limit)) ? Number(input.limit) : undefined }) }; } });
147
- defineOperation({ name: "transcript_memories", description: "Transcript memories.", schema: strictSchema({ source: S.str, date: S.str, limit: S.flexNum }), handler: async (input, ctx) => ({ result: await ctx.service.wearablesTranscriptMemories({ source: optStr(input.source), date: optStr(input.date), limit: typeof input.limit === "number" ? input.limit : typeof input.limit === "string" && Number.isFinite(Number(input.limit)) ? Number(input.limit) : undefined }) }) });
143
+ defineOperation({ name: "wearables_status", description: "Wearables status.", schema: strictSchema({ namespace: S.str, sessionKey: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.wearablesStatus({ authenticatedPrincipal: ctx.authenticatedPrincipal, namespace: optStr(input.namespace), sessionKey: optStr(input.sessionKey) }) }) });
144
+ defineOperation({ name: "wearables_sync", description: "Sync wearables.", schema: strictSchema({ source: S.str, date: S.str, days: S.flexNum, forceMemories: S.bool, namespace: S.str, sessionKey: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.wearablesSync({ source: optStr(input.source), date: optStr(input.date), days: typeof input.days === "number" ? input.days : typeof input.days === "string" && Number.isFinite(Number(input.days)) ? Number(input.days) : undefined, forceMemories: optBool(input.forceMemories), authenticatedPrincipal: ctx.authenticatedPrincipal, namespace: optStr(input.namespace), sessionKey: optStr(input.sessionKey) }) }) });
145
+ defineOperation({ name: "transcript_day", description: "Transcript for a day.", schema: strictSchema({ date: S.str, source: S.str, namespace: S.str, sessionKey: S.str }), handler: async (input, ctx) => { const d = defStr(input.date, ""); if (d.trim().length === 0) throw new EngramAccessInputError("transcript_day: date is required (YYYY-MM-DD)"); return { result: await ctx.service.wearablesTranscriptDay({ date: d, source: optStr(input.source), authenticatedPrincipal: ctx.authenticatedPrincipal, namespace: optStr(input.namespace), sessionKey: optStr(input.sessionKey) }) }; } });
146
+ defineOperation({ name: "transcript_search", description: "Search transcripts.", schema: strictSchema({ query: S.str, source: S.str, from: S.str, to: S.str, limit: S.flexNum, namespace: S.str, sessionKey: S.str }), handler: async (input, ctx) => { const q = defStr(input.query, ""); if (q.trim().length === 0) throw new EngramAccessInputError("transcript_search: query is required"); return { result: await ctx.service.wearablesTranscriptSearch({ query: q, source: optStr(input.source), from: optStr(input.from), to: optStr(input.to), limit: typeof input.limit === "number" ? input.limit : typeof input.limit === "string" && Number.isFinite(Number(input.limit)) ? Number(input.limit) : undefined, authenticatedPrincipal: ctx.authenticatedPrincipal, namespace: optStr(input.namespace), sessionKey: optStr(input.sessionKey) }) }; } });
147
+ defineOperation({ name: "transcript_memories", description: "Transcript memories.", schema: strictSchema({ source: S.str, date: S.str, limit: S.flexNum, namespace: S.str, sessionKey: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.wearablesTranscriptMemories({ source: optStr(input.source), date: optStr(input.date), limit: typeof input.limit === "number" ? input.limit : typeof input.limit === "string" && Number.isFinite(Number(input.limit)) ? Number(input.limit) : undefined, authenticatedPrincipal: ctx.authenticatedPrincipal, namespace: optStr(input.namespace), sessionKey: optStr(input.sessionKey) }) }) });
148
+
149
+ // === MEETINGS (issue #1900) ===
150
+ defineOperation({ name: "meetings_list", description: "List stored meeting records (all days, or one day).", schema: strictSchema({ date: S.str, namespace: S.str, sessionKey: S.str }), handler: async (input, ctx) => { const d = optStr(input.date); return { result: await ctx.service.meetingsList(d && d.length > 0 ? d : undefined, { authenticatedPrincipal: ctx.authenticatedPrincipal, namespace: optStr(input.namespace), sessionKey: optStr(input.sessionKey) }) }; } });
151
+ defineOperation({ name: "meetings_get", description: "Get a stored meeting record by id.", schema: strictSchema({ id: S.str, namespace: S.str, sessionKey: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.meetingsGet(reqStr(input.id, "id"), { authenticatedPrincipal: ctx.authenticatedPrincipal, namespace: optStr(input.namespace), sessionKey: optStr(input.sessionKey) }) }) });
152
+ defineOperation({ name: "meetings_build", description: "Detect + fuse + store a day's meetings.", schema: strictSchema({ date: S.str, namespace: S.str, sessionKey: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.meetingsBuild(reqStr(input.date, "date"), { authenticatedPrincipal: ctx.authenticatedPrincipal, namespace: optStr(input.namespace), sessionKey: optStr(input.sessionKey) }) }) });
148
153
 
149
154
  // === ACTION CONFIDENCE + INSPECTOR + CAPSULE ===
150
155
  defineOperation({ name: "action_confidence", description: "Action confidence.", schema: strictSchema({ intendedAction: S.str, confidence: S.num, risk: S.str, contextReadiness: S.str, currentContextScopes: S.strArr, userRules: z.array(z.unknown()).optional(), retrievedMemories: z.array(z.unknown()).optional() }), handler: async (input, ctx) => { const req: Record<string, unknown> = {}; if (input.intendedAction !== undefined) req.intendedAction = optStr(input.intendedAction); if (input.confidence !== undefined) req.confidence = optNum(input.confidence); if (input.risk !== undefined) req.risk = optStr(input.risk) as "low" | "medium" | "high" | "irreversible" | "restricted" | undefined; if (input.contextReadiness !== undefined) req.contextReadiness = optStr(input.contextReadiness) as "none" | "partial" | "sufficient" | undefined; if (input.currentContextScopes !== undefined) req.currentContextScopes = optStrArr(input.currentContextScopes); if (input.userRules !== undefined) req.userRules = input.userRules; if (input.retrievedMemories !== undefined) req.retrievedMemories = input.retrievedMemories; return { result: await ctx.service.actionConfidence(req) }; } });
@@ -175,6 +180,7 @@ defineOperation({ name: "capsule_list", description: "List capsules.", schema: s
175
180
 
176
181
  // === GOVERNANCE ===
177
182
  defineOperation({ name: "memory_governance_run", description: "Run governance.", schema: strictSchema({ namespace: S.str, mode: S.str, recentDays: S.num, maxMemories: S.num, batchSize: S.num }), handler: async (input, ctx) => ({ result: await ctx.service.governanceRun({ namespace: optStr(input.namespace), mode: optStr(input.mode) === "apply" ? "apply" : "shadow", recentDays: optNum(input.recentDays), maxMemories: optNum(input.maxMemories), batchSize: optNum(input.batchSize), authenticatedPrincipal: ctx.authenticatedPrincipal }, ctx.authenticatedPrincipal) }) });
183
+ defineOperation({ name: "entity_synthesis_run", description: "Bulk-drain the entity synthesis queue (issue #2136).", schema: strictSchema({ namespace: S.str, maxEntities: S.num }), handler: async (input, ctx) => ({ result: await ctx.service.entitySynthesisRun({ namespace: optStr(input.namespace), maxEntities: input.maxEntities === undefined ? undefined : (input.maxEntities as number), authenticatedPrincipal: ctx.authenticatedPrincipal }, ctx.authenticatedPrincipal) }) });
178
184
  defineOperation({ name: "procedure_mining_run", description: "Run procedure mining.", schema: strictSchema({ namespace: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.procedureMiningRun({ namespace: optStr(input.namespace), authenticatedPrincipal: ctx.authenticatedPrincipal }, ctx.authenticatedPrincipal) }) });
179
185
  defineOperation({ name: "pattern_reinforcement_run", description: "Run pattern reinforcement.", schema: strictSchema({ namespace: S.str, force: S.bool }), handler: async (input, ctx) => ({ result: await ctx.service.patternReinforcementRun({ namespace: optStr(input.namespace), force: input.force === true, authenticatedPrincipal: ctx.authenticatedPrincipal }, ctx.authenticatedPrincipal) }) });
180
186
  defineOperation({ name: "procedural_stats", description: "Procedural stats.", schema: strictSchema({ namespace: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.procedureStats({ namespace: optStr(input.namespace) }, ctx.authenticatedPrincipal) }) });
@@ -107,6 +107,12 @@ import { displayErrorDetail } from "./runtime/better-sqlite.js";
107
107
  import type { PatternReinforcementResult } from "./maintenance/pattern-reinforcement.js";
108
108
  import type { LiveConnectorsRunSummary } from "./live-connectors-runner.js";
109
109
  import type { WearablesService } from "./wearables/service.js";
110
+ import type { MeetingsGetResult, MeetingsListResult } from "./meetings/service.js";
111
+ import type { MeetingsDayBuildSummary } from "./meetings/build.js";
112
+
113
+ import * as wearablesMeetings from "./access-wearables-meetings-surface.js";
114
+ import type { WearablesMeetingsHost, WearablesMeetingsScope } from "./access-wearables-meetings-surface.js";
115
+ export type { WearablesMeetingsScope };
110
116
  import {
111
117
  computeProcedureStats,
112
118
  type ProcedureStatsReport,
@@ -3622,6 +3628,22 @@ export class EngramAccessService {
3622
3628
  );
3623
3629
  }
3624
3630
 
3631
+ async entitySynthesisRun(
3632
+ request: {
3633
+ namespace?: string;
3634
+ maxEntities?: number;
3635
+ authenticatedPrincipal?: string;
3636
+ },
3637
+ principal?: string,
3638
+ ): Promise<{
3639
+ namespace: string;
3640
+ requested: number;
3641
+ processed: number;
3642
+ remaining: number;
3643
+ }> {
3644
+ return this.accessAdminOpsSurface.entitySynthesisRun(request, principal);
3645
+ }
3646
+
3625
3647
  async procedureMiningRun(
3626
3648
  request: {
3627
3649
  namespace?: string;
@@ -5729,60 +5751,51 @@ export class EngramAccessService {
5729
5751
  // behavior and validation (renderer-sharing rule).
5730
5752
  // ---------------------------------------------------------------------------
5731
5753
 
5732
- async wearablesStatus(): Promise<
5733
- Awaited<ReturnType<WearablesService["status"]>>
5734
- > {
5735
- return this.orchestrator.getWearablesService().status();
5754
+ /**
5755
+ * Structural host bound per call so the wearables + meetings ops (issue
5756
+ * #2123) delegate to the pure surface module while the namespace/principal
5757
+ * resolvers stay private.
5758
+ */
5759
+ private get wmHost(): WearablesMeetingsHost {
5760
+ return {
5761
+ orchestrator: this.orchestrator,
5762
+ resolveReadableNamespace: this.resolveReadableNamespace.bind(this),
5763
+ writableNamespaceFor: this.writableNamespaceFor.bind(this),
5764
+ resolveRequestPrincipal: this.resolveRequestPrincipal.bind(this),
5765
+ };
5736
5766
  }
5737
5767
 
5738
- async wearablesSync(request: {
5739
- source?: string;
5740
- date?: string;
5741
- days?: number;
5742
- forceMemories?: boolean;
5743
- }): Promise<Awaited<ReturnType<WearablesService["sync"]>>> {
5744
- return this.orchestrator.getWearablesService().sync({
5745
- source: request.source,
5746
- date: request.date,
5747
- days: request.days,
5748
- forceMemories: request.forceMemories,
5749
- });
5768
+ async wearablesStatus(scope?: WearablesMeetingsScope): Promise<Awaited<ReturnType<WearablesService["status"]>>> {
5769
+ return wearablesMeetings.wearablesStatus(this.wmHost, scope);
5750
5770
  }
5751
5771
 
5752
- async wearablesTranscriptDay(request: {
5753
- date: string;
5754
- source?: string;
5755
- }): Promise<Awaited<ReturnType<WearablesService["dayTranscript"]>>> {
5756
- return this.orchestrator
5757
- .getWearablesService()
5758
- .dayTranscript(request.date, request.source);
5772
+ async wearablesSync(request: { source?: string; date?: string; days?: number; forceMemories?: boolean } & WearablesMeetingsScope): Promise<Awaited<ReturnType<WearablesService["sync"]>>> {
5773
+ return wearablesMeetings.wearablesSync(this.wmHost, request);
5759
5774
  }
5760
5775
 
5761
- async wearablesTranscriptSearch(request: {
5762
- query: string;
5763
- source?: string;
5764
- from?: string;
5765
- to?: string;
5766
- limit?: number;
5767
- }): Promise<Awaited<ReturnType<WearablesService["searchTranscripts"]>>> {
5768
- return this.orchestrator.getWearablesService().searchTranscripts(request.query, {
5769
- source: request.source,
5770
- from: request.from,
5771
- to: request.to,
5772
- limit: request.limit,
5773
- });
5776
+ async wearablesTranscriptDay(request: { date: string; source?: string } & WearablesMeetingsScope): Promise<Awaited<ReturnType<WearablesService["dayTranscript"]>>> {
5777
+ return wearablesMeetings.wearablesTranscriptDay(this.wmHost, request);
5774
5778
  }
5775
5779
 
5776
- async wearablesTranscriptMemories(request: {
5777
- source?: string;
5778
- date?: string;
5779
- limit?: number;
5780
- }): Promise<Awaited<ReturnType<WearablesService["transcriptMemories"]>>> {
5781
- return this.orchestrator.getWearablesService().transcriptMemories({
5782
- source: request.source,
5783
- date: request.date,
5784
- limit: request.limit,
5785
- });
5780
+ async wearablesTranscriptSearch(request: { query: string; source?: string; from?: string; to?: string; limit?: number } & WearablesMeetingsScope): Promise<Awaited<ReturnType<WearablesService["searchTranscripts"]>>> {
5781
+ return wearablesMeetings.wearablesTranscriptSearch(this.wmHost, request);
5782
+ }
5783
+
5784
+ async wearablesTranscriptMemories(request: { source?: string; date?: string; limit?: number } & WearablesMeetingsScope): Promise<Awaited<ReturnType<WearablesService["transcriptMemories"]>>> {
5785
+ return wearablesMeetings.wearablesTranscriptMemories(this.wmHost, request);
5786
+ }
5787
+
5788
+ // Meetings (issue #1900): thin delegations to the caller-ns MeetingsService.
5789
+ async meetingsList(date?: string, scope?: WearablesMeetingsScope): Promise<MeetingsListResult> {
5790
+ return wearablesMeetings.meetingsList(this.wmHost, date, scope);
5791
+ }
5792
+
5793
+ async meetingsGet(id: string, scope?: WearablesMeetingsScope): Promise<MeetingsGetResult> {
5794
+ return wearablesMeetings.meetingsGet(this.wmHost, id, scope);
5795
+ }
5796
+
5797
+ async meetingsBuild(date: string, scope?: WearablesMeetingsScope): Promise<MeetingsDayBuildSummary> {
5798
+ return wearablesMeetings.meetingsBuild(this.wmHost, date, scope);
5786
5799
  }
5787
5800
 
5788
5801
  // ── Admin console surfaces (issue #1502) ────────────────────────────────
@@ -59,6 +59,9 @@ export const MCP_TOOLS: readonly McpToolEntry[] = [
59
59
  { tool: "transcript_day", operation: "transcript_day" },
60
60
  { tool: "transcript_search", operation: "transcript_search" },
61
61
  { tool: "transcript_memories", operation: "transcript_memories" },
62
+ { tool: "meetings_list", operation: "meetings_list" },
63
+ { tool: "meetings_get", operation: "meetings_get" },
64
+ { tool: "meetings_build", operation: "meetings_build" },
62
65
  { tool: "action_confidence", operation: "action_confidence" },
63
66
  { tool: "chatgpt_memory_inspector", operation: "chatgpt_memory_inspector" },
64
67
  { tool: "day_summary", operation: "day_summary" },
@@ -66,6 +69,7 @@ export const MCP_TOOLS: readonly McpToolEntry[] = [
66
69
  { tool: "capsule_import", operation: "capsule_import" },
67
70
  { tool: "capsule_list", operation: "capsule_list" },
68
71
  { tool: "memory_governance_run", operation: "memory_governance_run" },
72
+ { tool: "entity_synthesis_run", operation: "entity_synthesis_run" },
69
73
  { tool: "procedure_mining_run", operation: "procedure_mining_run" },
70
74
  { tool: "pattern_reinforcement_run", operation: "pattern_reinforcement_run" },
71
75
  { tool: "procedural_stats", operation: "procedural_stats" },
@@ -189,6 +193,9 @@ export const HTTP_ROUTES: readonly HttpRouteEntry[] = [
189
193
  { method: "GET", pathname: "/engram/v1/wearables/transcript", operation: "transcript_day" },
190
194
  { method: "GET", pathname: "/engram/v1/wearables/transcripts/search", operation: "transcript_search" },
191
195
  { method: "GET", pathname: "/engram/v1/wearables/memories", operation: "transcript_memories" },
196
+ { method: "GET", pathname: "/engram/v1/meetings", operation: "meetings_list" },
197
+ { method: "POST", pathname: "/engram/v1/meetings/build", operation: "meetings_build" },
198
+ { method: "GET", pathname: "/engram/v1/meetings/:id", operation: "meetings_get" },
192
199
  { method: "POST", pathname: "/engram/v1/observe", operation: "observe" },
193
200
  { method: "POST", pathname: "/engram/v1/lcm/search", operation: "lcm_search" },
194
201
  { method: "POST", pathname: "/engram/v1/lcm/compaction/flush", operation: "lcm_compaction_flush" },
@@ -0,0 +1,139 @@
1
+ import type { WearablesService } from "./wearables/service.js";
2
+ import type { MeetingsService, MeetingsGetResult, MeetingsListResult } from "./meetings/service.js";
3
+ import type { MeetingsDayBuildSummary } from "./meetings/build.js";
4
+
5
+ /**
6
+ * Caller scope threaded into the wearables + meetings access ops so reads and
7
+ * writes resolve to the CALLER namespace (caller-derived namespace symmetry,
8
+ * issue #2123), not a machine-wide default. Every field is optional; omitting
9
+ * all three preserves the operator/CLI default-namespace behavior.
10
+ */
11
+ export type WearablesMeetingsScope = {
12
+ sessionKey?: string;
13
+ authenticatedPrincipal?: string;
14
+ namespace?: string;
15
+ };
16
+
17
+ /**
18
+ * The access-service capabilities the wearables + meetings surface needs.
19
+ * A structural host (not the class itself) so these ops stay pure delegators
20
+ * while EngramAccessService keeps its namespace/principal resolvers private.
21
+ */
22
+ export interface WearablesMeetingsHost {
23
+ readonly orchestrator: {
24
+ getWearablesService(namespace: string): WearablesService;
25
+ getMeetingsService(namespace: string): Promise<MeetingsService>;
26
+ readonly config: { readonly meetings: { readonly enabled: boolean } };
27
+ };
28
+ resolveReadableNamespace(namespace: string | undefined, principal?: string): string;
29
+ writableNamespaceFor(
30
+ namespace: string | undefined,
31
+ sessionKey: string | undefined,
32
+ authenticatedPrincipal?: string,
33
+ ): string;
34
+ resolveRequestPrincipal(sessionKey: string | undefined, authenticatedPrincipal?: string): string | undefined;
35
+ }
36
+
37
+ /**
38
+ * Wearables reads resolve to the CALLER namespace via resolveReadableNamespace;
39
+ * sync writes via writableNamespaceFor; build needs BOTH — it reads
40
+ * transcripts/records to derive, then writes episodes. Non-default callers are
41
+ * strictly isolated: no default-ns wearable fallback, no machine-global
42
+ * activity (machine-scoped, consumed only by the default ns).
43
+ */
44
+ function wearablesReadService(host: WearablesMeetingsHost, scope?: WearablesMeetingsScope): WearablesService {
45
+ return host.orchestrator.getWearablesService(
46
+ host.resolveReadableNamespace(scope?.namespace, host.resolveRequestPrincipal(scope?.sessionKey, scope?.authenticatedPrincipal)),
47
+ );
48
+ }
49
+
50
+ export function wearablesStatus(
51
+ host: WearablesMeetingsHost,
52
+ scope?: WearablesMeetingsScope,
53
+ ): Promise<Awaited<ReturnType<WearablesService["status"]>>> {
54
+ return wearablesReadService(host, scope).status();
55
+ }
56
+
57
+ export async function wearablesSync(
58
+ host: WearablesMeetingsHost,
59
+ request: { source?: string; date?: string; days?: number; forceMemories?: boolean } & WearablesMeetingsScope,
60
+ ): Promise<Awaited<ReturnType<WearablesService["sync"]>>> {
61
+ const namespace = host.writableNamespaceFor(request.namespace, request.sessionKey, request.authenticatedPrincipal);
62
+ const summaries = await host.orchestrator
63
+ .getWearablesService(namespace)
64
+ .sync({ source: request.source, date: request.date, days: request.days, forceMemories: request.forceMemories });
65
+ // Manual one-shot sync (HTTP/MCP/CLI): the meeting tail-step arms a
66
+ // debounced, unref'd timer a short-lived caller exits before firing. Drain
67
+ // it now so a manual sync's meeting build actually runs before we return.
68
+ // The long-lived auto-sync daemon does NOT flush — it keeps coalescing.
69
+ if (host.orchestrator.config.meetings.enabled) {
70
+ await (await host.orchestrator.getMeetingsService(namespace)).flushBuilds();
71
+ }
72
+ return summaries;
73
+ }
74
+
75
+ export function wearablesTranscriptDay(
76
+ host: WearablesMeetingsHost,
77
+ request: { date: string; source?: string } & WearablesMeetingsScope,
78
+ ): Promise<Awaited<ReturnType<WearablesService["dayTranscript"]>>> {
79
+ return wearablesReadService(host, request).dayTranscript(request.date, request.source);
80
+ }
81
+
82
+ export function wearablesTranscriptSearch(
83
+ host: WearablesMeetingsHost,
84
+ request: { query: string; source?: string; from?: string; to?: string; limit?: number } & WearablesMeetingsScope,
85
+ ): Promise<Awaited<ReturnType<WearablesService["searchTranscripts"]>>> {
86
+ return wearablesReadService(host, request).searchTranscripts(request.query, {
87
+ source: request.source,
88
+ from: request.from,
89
+ to: request.to,
90
+ limit: request.limit,
91
+ });
92
+ }
93
+
94
+ export function wearablesTranscriptMemories(
95
+ host: WearablesMeetingsHost,
96
+ request: { source?: string; date?: string; limit?: number } & WearablesMeetingsScope,
97
+ ): Promise<Awaited<ReturnType<WearablesService["transcriptMemories"]>>> {
98
+ return wearablesReadService(host, request).transcriptMemories({
99
+ source: request.source,
100
+ date: request.date,
101
+ limit: request.limit,
102
+ });
103
+ }
104
+
105
+ // Meetings (issue #1900): thin delegations to the caller-ns MeetingsService.
106
+ export async function meetingsList(
107
+ host: WearablesMeetingsHost,
108
+ date?: string,
109
+ scope?: WearablesMeetingsScope,
110
+ ): Promise<MeetingsListResult> {
111
+ return (
112
+ await host.orchestrator.getMeetingsService(
113
+ host.resolveReadableNamespace(scope?.namespace, host.resolveRequestPrincipal(scope?.sessionKey, scope?.authenticatedPrincipal)),
114
+ )
115
+ ).meetingsList(date);
116
+ }
117
+
118
+ export async function meetingsGet(
119
+ host: WearablesMeetingsHost,
120
+ id: string,
121
+ scope?: WearablesMeetingsScope,
122
+ ): Promise<MeetingsGetResult> {
123
+ return (
124
+ await host.orchestrator.getMeetingsService(
125
+ host.resolveReadableNamespace(scope?.namespace, host.resolveRequestPrincipal(scope?.sessionKey, scope?.authenticatedPrincipal)),
126
+ )
127
+ ).meetingsGet(id);
128
+ }
129
+
130
+ export async function meetingsBuild(
131
+ host: WearablesMeetingsHost,
132
+ date: string,
133
+ scope?: WearablesMeetingsScope,
134
+ ): Promise<MeetingsDayBuildSummary> {
135
+ const principal = host.resolveRequestPrincipal(scope?.sessionKey, scope?.authenticatedPrincipal);
136
+ const namespace = host.writableNamespaceFor(scope?.namespace, scope?.sessionKey, scope?.authenticatedPrincipal);
137
+ host.resolveReadableNamespace(namespace, principal);
138
+ return (await host.orchestrator.getMeetingsService(namespace)).meetingsBuild(date);
139
+ }