@remnic/core 9.22.0 → 9.22.2

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 (402) hide show
  1. package/dist/access-admin-ops-surface.d.ts +15 -12
  2. package/dist/access-admin-ops-surface.js +25 -24
  3. package/dist/access-audit.js +2 -2
  4. package/dist/access-boundary.d.ts +13 -10
  5. package/dist/access-boundary.js +25 -24
  6. package/dist/access-cli.js +84 -82
  7. package/dist/access-cli.js.map +1 -1
  8. package/dist/access-http.d.ts +16 -9
  9. package/dist/access-http.js +33 -32
  10. package/dist/access-identity-continuity-surface.d.ts +9 -7
  11. package/dist/access-identity-continuity-surface.js +25 -24
  12. package/dist/access-lcm-surface.d.ts +12 -9
  13. package/dist/access-lcm-surface.js +25 -24
  14. package/dist/access-mcp-output-schemas.js +1 -1
  15. package/dist/access-mcp.d.ts +22 -10
  16. package/dist/access-mcp.js +31 -30
  17. package/dist/access-memory-search-fanout.d.ts +2 -2
  18. package/dist/{access-namespace-preflight-tmwQgCT6.d.ts → access-namespace-preflight-CmErR03h.d.ts} +1 -1
  19. package/dist/access-namespace-preflight.d.ts +3 -3
  20. package/dist/access-namespace-preflight.js +25 -24
  21. package/dist/access-observe-write-surface.d.ts +12 -9
  22. package/dist/access-observe-write-surface.js +25 -24
  23. package/dist/access-operations-batch.js +27 -26
  24. package/dist/access-operations.d.ts +16 -13
  25. package/dist/access-operations.js +28 -27
  26. package/dist/access-recall-concurrency.d.ts +12 -9
  27. package/dist/access-recall-concurrency.js +25 -24
  28. package/dist/access-recall-response.d.ts +12 -9
  29. package/dist/access-recall-response.js +25 -24
  30. package/dist/access-recall-surface.d.ts +14 -11
  31. package/dist/access-recall-surface.js +25 -24
  32. package/dist/access-schema.d.ts +76 -76
  33. package/dist/{access-service-BtxW52vv.d.ts → access-service-CKEROeFP.d.ts} +22 -11
  34. package/dist/access-service.d.ts +13 -10
  35. package/dist/access-service.js +25 -24
  36. package/dist/access-surface-catalog.d.ts +12 -9
  37. package/dist/access-surface-catalog.js +6 -0
  38. package/dist/access-surface-catalog.js.map +1 -1
  39. package/dist/access-wearables-meetings-surface.d.ts +78 -0
  40. package/dist/access-wearables-meetings-surface.js +22 -0
  41. package/dist/access-wearables-meetings-surface.js.map +1 -0
  42. package/dist/action-confidence.d.ts +1 -1
  43. package/dist/active-memory-bridge.d.ts +1 -1
  44. package/dist/active-recall.d.ts +1 -1
  45. package/dist/active-recall.js +2 -2
  46. package/dist/{auto-sync-UPTUVE4X.js → auto-sync-5OE5QOZB.js} +3 -3
  47. package/dist/behavior-learner.d.ts +1 -1
  48. package/dist/behavior-signals.d.ts +1 -1
  49. package/dist/bootstrap.d.ts +9 -7
  50. package/dist/briefing.d.ts +2 -2
  51. package/dist/briefing.js +5 -5
  52. package/dist/buffer-surprise-report.d.ts +1 -1
  53. package/dist/buffer.d.ts +2 -2
  54. package/dist/bulk-import/index.d.ts +3 -3
  55. package/dist/calibration.d.ts +1 -1
  56. package/dist/capabilities.d.ts +1 -1
  57. package/dist/{catalog-iWvWz61I.d.ts → catalog-BFTVo2Ez.d.ts} +1 -1
  58. package/dist/causal-behavior.d.ts +1 -1
  59. package/dist/causal-behavior.js +2 -2
  60. package/dist/causal-chain.js +2 -2
  61. package/dist/causal-consolidation.d.ts +1 -1
  62. package/dist/causal-consolidation.js +9 -9
  63. package/dist/causal-retrieval.js +2 -2
  64. package/dist/causal-trajectory-graph.d.ts +1 -1
  65. package/dist/causal-trajectory.js +1 -1
  66. package/dist/{chunk-GF22HWS2.js → chunk-2PHX3I5C.js} +7 -7
  67. package/dist/{chunk-JFDEYXF7.js → chunk-3NAHZQU3.js} +2 -2
  68. package/dist/{chunk-XBRPEGXF.js → chunk-3UOSVTFR.js} +5 -5
  69. package/dist/{chunk-TTKWTT72.js → chunk-3ZW6ZQO6.js} +3 -3
  70. package/dist/{chunk-UV72DEZD.js → chunk-4B77XSG5.js} +5 -5
  71. package/dist/{chunk-IC2TCZJ2.js → chunk-57QKLRBV.js} +3 -1
  72. package/dist/chunk-57QKLRBV.js.map +1 -0
  73. package/dist/{chunk-LMHDFOVV.js → chunk-5CPI2QWG.js} +3 -3
  74. package/dist/{chunk-P72WZMWQ.js → chunk-5FZQ74K5.js} +2 -2
  75. package/dist/{chunk-BRT7KEXU.js → chunk-6TWXQ4E2.js} +5 -5
  76. package/dist/{chunk-CV6ZYXK3.js → chunk-7I7AYIUQ.js} +3 -3
  77. package/dist/{chunk-TVVEYCNW.js → chunk-7K5Q6COX.js} +4 -4
  78. package/dist/{chunk-MONWCSVL.js → chunk-7RAJ3GXO.js} +2 -1
  79. package/dist/chunk-7RAJ3GXO.js.map +1 -0
  80. package/dist/{chunk-SQEDDWAM.js → chunk-A2RFKL3V.js} +5 -34
  81. package/dist/chunk-A2RFKL3V.js.map +1 -0
  82. package/dist/{chunk-JN57HZCD.js → chunk-ATEAL5EI.js} +6 -6
  83. package/dist/{chunk-4PYLBXX6.js → chunk-AYAROCWD.js} +2 -2
  84. package/dist/chunk-BLDBT6HZ.js +39 -0
  85. package/dist/chunk-BLDBT6HZ.js.map +1 -0
  86. package/dist/{chunk-NB2P47N7.js → chunk-CUUY5CC4.js} +6 -6
  87. package/dist/{chunk-KL5Y6PEV.js → chunk-E3ZMFFQZ.js} +2 -2
  88. package/dist/{chunk-55FDQYPS.js → chunk-ES5IHQ6M.js} +2 -2
  89. package/dist/{chunk-N47ZWQBO.js → chunk-G2NSSQES.js} +2 -2
  90. package/dist/{chunk-GSWPU5CR.js → chunk-GD3QOBMB.js} +2 -2
  91. package/dist/{chunk-6ANPNUVL.js → chunk-IIXLB5E7.js} +58 -36
  92. package/dist/chunk-IIXLB5E7.js.map +1 -0
  93. package/dist/{chunk-SACPRJ7F.js → chunk-JNIJBXVK.js} +2 -2
  94. package/dist/{chunk-W3XT32W7.js → chunk-JVGUY2AU.js} +23 -13
  95. package/dist/chunk-JVGUY2AU.js.map +1 -0
  96. package/dist/{chunk-DGLON3AL.js → chunk-KNRG6ZGJ.js} +6 -6
  97. package/dist/{chunk-GEUDRENF.js → chunk-MMTG3SCJ.js} +2 -2
  98. package/dist/{chunk-WZFAPHIK.js → chunk-MU7ZHSZE.js} +2 -2
  99. package/dist/{chunk-W4FBGYGK.js → chunk-NRV4Y3PM.js} +1 -1
  100. package/dist/{chunk-QTO2FGBT.js → chunk-OUW4PAY4.js} +191 -117
  101. package/dist/chunk-OUW4PAY4.js.map +1 -0
  102. package/dist/{chunk-KQ2XCQYN.js → chunk-P2BLHUL2.js} +2 -2
  103. package/dist/{chunk-ACGGTPU4.js → chunk-QCKQEBIY.js} +17 -9
  104. package/dist/chunk-QCKQEBIY.js.map +1 -0
  105. package/dist/{chunk-6L775BUB.js → chunk-QE63OHLB.js} +2 -2
  106. package/dist/{chunk-ONHRRJZM.js → chunk-QJAQNXWI.js} +6 -6
  107. package/dist/{chunk-EQYBHXRR.js → chunk-ROUL7RZU.js} +385 -59
  108. package/dist/chunk-ROUL7RZU.js.map +1 -0
  109. package/dist/{chunk-N6M7MRVN.js → chunk-RT4TSR2C.js} +9034 -8726
  110. package/dist/chunk-RT4TSR2C.js.map +1 -0
  111. package/dist/{chunk-6NZ7U4R4.js → chunk-SCOT5DTA.js} +1 -1
  112. package/dist/chunk-SCOT5DTA.js.map +1 -0
  113. package/dist/{chunk-6RYWNBSA.js → chunk-SVZGA2MK.js} +2 -2
  114. package/dist/chunk-SYOIVK7K.js +63 -0
  115. package/dist/chunk-SYOIVK7K.js.map +1 -0
  116. package/dist/{chunk-DM5A4ZFL.js → chunk-TWCOYET2.js} +11 -1
  117. package/dist/chunk-TWCOYET2.js.map +1 -0
  118. package/dist/{chunk-7S5OMI76.js → chunk-WS32QRLO.js} +109 -44
  119. package/dist/chunk-WS32QRLO.js.map +1 -0
  120. package/dist/{chunk-OCMLGND7.js → chunk-WWZ35GWW.js} +5 -5
  121. package/dist/{chunk-QMGIQUBG.js → chunk-XWPFZX6S.js} +503 -139
  122. package/dist/chunk-XWPFZX6S.js.map +1 -0
  123. package/dist/{chunk-A5N6ISRK.js → chunk-ZN4UZWMT.js} +2 -2
  124. package/dist/{chunk-7M6APKJL.js → chunk-ZYU7ZFLT.js} +2 -2
  125. package/dist/{cli-D9vXgWwM.d.ts → cli-BrwT9YMD.d.ts} +5 -5
  126. package/dist/cli.d.ts +14 -11
  127. package/dist/cli.js +57 -56
  128. package/dist/compounding/engine.d.ts +2 -2
  129. package/dist/compounding/engine.js +5 -5
  130. package/dist/compounding/preference-consolidator.d.ts +1 -1
  131. package/dist/compression-optimizer.d.ts +1 -1
  132. package/dist/config.d.ts +1 -1
  133. package/dist/config.js +2 -2
  134. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  135. package/dist/connectors/codex-materialize-runner.js +5 -5
  136. package/dist/connectors/codex-materialize.d.ts +1 -1
  137. package/dist/connectors/index.d.ts +1 -1
  138. package/dist/connectors/index.js +5 -5
  139. package/dist/consolidation-provenance-check.d.ts +2 -2
  140. package/dist/consolidation-undo.d.ts +2 -2
  141. package/dist/contradiction/index.d.ts +2 -2
  142. package/dist/conversation-index/backend.d.ts +1 -1
  143. package/dist/conversation-index/chunker.d.ts +1 -1
  144. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  145. package/dist/conversation-index/indexer.d.ts +1 -1
  146. package/dist/conversation-index/search.d.ts +1 -1
  147. package/dist/day-summary.d.ts +1 -1
  148. package/dist/delinearize.d.ts +1 -1
  149. package/dist/direct-answer-wiring.d.ts +1 -1
  150. package/dist/direct-answer.d.ts +1 -1
  151. package/dist/embedding-fallback.d.ts +1 -1
  152. package/dist/enrichment/index.d.ts +1 -1
  153. package/dist/entity-retrieval.d.ts +2 -2
  154. package/dist/entity-retrieval.js +5 -5
  155. package/dist/entity-schema.d.ts +1 -1
  156. package/dist/explicit-capture.d.ts +9 -7
  157. package/dist/extraction-error-classification.d.ts +22 -0
  158. package/dist/extraction-error-classification.js +11 -0
  159. package/dist/extraction-error-classification.js.map +1 -0
  160. package/dist/extraction-faithfulness.d.ts +1 -1
  161. package/dist/extraction-judge-telemetry.d.ts +1 -1
  162. package/dist/extraction-judge-training.d.ts +1 -1
  163. package/dist/extraction-judge.d.ts +1 -1
  164. package/dist/extraction.d.ts +3 -17
  165. package/dist/extraction.js +5 -3
  166. package/dist/fallback-llm.d.ts +1 -1
  167. package/dist/{first-start-migration-LEXL3XYL.js → first-start-migration-BKNGOFED.js} +4 -4
  168. package/dist/graph-dashboard-diff.d.ts +1 -1
  169. package/dist/graph-dashboard-key.d.ts +1 -1
  170. package/dist/graph-dashboard-parser.d.ts +1 -1
  171. package/dist/graph-edge-reinforcement.d.ts +1 -1
  172. package/dist/graph-snapshot.d.ts +1 -1
  173. package/dist/graph.d.ts +1 -1
  174. package/dist/importance.d.ts +1 -1
  175. package/dist/importers/index.d.ts +1 -1
  176. package/dist/in-flight-reads.d.ts +1 -1
  177. package/dist/index.d.ts +713 -923
  178. package/dist/index.js +176 -140
  179. package/dist/intent.d.ts +1 -1
  180. package/dist/lcm/engine.d.ts +1 -1
  181. package/dist/lcm/engine.js +3 -3
  182. package/dist/lcm/index.d.ts +1 -1
  183. package/dist/lcm/index.js +11 -11
  184. package/dist/lcm/tools.d.ts +1 -1
  185. package/dist/lifecycle.d.ts +1 -1
  186. package/dist/live-connectors-runner.d.ts +1 -1
  187. package/dist/local-llm.d.ts +1 -1
  188. package/dist/local-model-endpoint.d.ts +1 -1
  189. package/dist/maintenance/memory-governance.d.ts +1 -1
  190. package/dist/maintenance/memory-governance.js +6 -6
  191. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
  192. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +5 -5
  193. package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
  194. package/dist/maintenance/rebuild-memory-projection.js +7 -7
  195. package/dist/maintenance-C98njYb8.d.ts +366 -0
  196. package/dist/mcp-memory-inspector-app.d.ts +12 -9
  197. package/dist/mcp-read-only-tools.js +1 -1
  198. package/dist/memory-action-policy.d.ts +1 -1
  199. package/dist/memory-cache.d.ts +1 -1
  200. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  201. package/dist/memory-projection-store.d.ts +1 -1
  202. package/dist/memory-provenance.d.ts +1 -1
  203. package/dist/memory-worth-outcomes.d.ts +2 -2
  204. package/dist/models-json.d.ts +1 -1
  205. package/dist/namespaces/migrate.d.ts +3 -3
  206. package/dist/namespaces/migrate.js +12 -12
  207. package/dist/namespaces/principal.d.ts +1 -1
  208. package/dist/namespaces/search.d.ts +1 -1
  209. package/dist/namespaces/search.js +6 -6
  210. package/dist/namespaces/storage.d.ts +3 -3
  211. package/dist/namespaces/storage.js +5 -5
  212. package/dist/native-knowledge.d.ts +1 -1
  213. package/dist/offline-sync-impression-drain.d.ts +1 -1
  214. package/dist/operator-toolkit.d.ts +2 -2
  215. package/dist/operator-toolkit.js +18 -18
  216. package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
  217. package/dist/orchestration/maintenance.d.ts +6 -223
  218. package/dist/orchestration/maintenance.js +12 -12
  219. package/dist/{orchestrator-DB93S48I.d.ts → orchestrator-C9ZVppNh.d.ts} +12 -481
  220. package/dist/orchestrator.d.ts +10 -8
  221. package/dist/orchestrator.js +84 -82
  222. package/dist/patterns-cli.d.ts +1 -1
  223. package/dist/{pipeline-DmGc-H66.d.ts → pipeline-id_-sqYm.d.ts} +1 -1
  224. package/dist/policy-runtime.d.ts +1 -1
  225. package/dist/proactive-contention.d.ts +1 -1
  226. package/dist/provenance.d.ts +1 -1
  227. package/dist/{qmd-cJT0crkF.d.ts → qmd-R6XaQOZK.d.ts} +1 -1
  228. package/dist/qmd-preflight.d.ts +2 -2
  229. package/dist/qmd-recall-cache.d.ts +1 -1
  230. package/dist/qmd.d.ts +2 -2
  231. package/dist/qmd.js +4 -4
  232. package/dist/recall-concurrency-config.d.ts +1 -1
  233. package/dist/recall-disclosure-escalation.d.ts +1 -1
  234. package/dist/recall-explain-renderer.d.ts +1 -1
  235. package/dist/recall-explain-renderer.js +3 -3
  236. package/dist/recall-memory-map.d.ts +1 -1
  237. package/dist/recall-planner-llm.d.ts +1 -1
  238. package/dist/recall-state.d.ts +1 -1
  239. package/dist/recall-tag-filter.d.ts +1 -1
  240. package/dist/recall-timings.d.ts +1 -1
  241. package/dist/recall-xray-cli.d.ts +1 -1
  242. package/dist/recall-xray-cli.js +4 -4
  243. package/dist/recall-xray-renderer.d.ts +1 -1
  244. package/dist/recall-xray-renderer.js +3 -3
  245. package/dist/recall-xray.d.ts +1 -1
  246. package/dist/recall-xray.js +2 -2
  247. package/dist/replay/normalizers/chatgpt.d.ts +1 -1
  248. package/dist/replay/normalizers/claude.d.ts +1 -1
  249. package/dist/replay/normalizers/openclaw.d.ts +1 -1
  250. package/dist/replay/normalizers/shared.d.ts +1 -1
  251. package/dist/replay/runner.d.ts +1 -1
  252. package/dist/replay/types.d.ts +1 -1
  253. package/dist/resolve-auth-token.d.ts +1 -1
  254. package/dist/resume-bundles.js +4 -4
  255. package/dist/retrieval-agents.d.ts +2 -2
  256. package/dist/retrieval-tiers.d.ts +1 -1
  257. package/dist/routing/engine.d.ts +1 -1
  258. package/dist/routing/store.d.ts +1 -1
  259. package/dist/salvage-envelope.d.ts +1 -1
  260. package/dist/schemas.d.ts +76 -76
  261. package/dist/{scope-profiles-KG2nODX7.d.ts → scope-profiles-EhyuAKkd.d.ts} +1 -1
  262. package/dist/search/embed-helper.d.ts +1 -1
  263. package/dist/search/factory.d.ts +1 -1
  264. package/dist/search/factory.js +5 -5
  265. package/dist/search/index.d.ts +1 -1
  266. package/dist/search/index.js +9 -9
  267. package/dist/search/lancedb-backend.d.ts +1 -1
  268. package/dist/search/meilisearch-backend.d.ts +1 -1
  269. package/dist/search/noop-backend.d.ts +1 -1
  270. package/dist/search/orama-backend.d.ts +1 -1
  271. package/dist/search/port.d.ts +1 -1
  272. package/dist/search/remote-backend.d.ts +1 -1
  273. package/dist/{semantic-consolidation-BaZlg0D8.d.ts → semantic-consolidation-B2xo26UQ.d.ts} +1 -1
  274. package/dist/semantic-consolidation.d.ts +2 -2
  275. package/dist/semantic-consolidation.js +7 -7
  276. package/dist/semantic-rule-promotion.js +5 -5
  277. package/dist/semantic-rule-verifier.d.ts +1 -1
  278. package/dist/semantic-rule-verifier.js +6 -6
  279. package/dist/service-DgFWlZ-r.d.ts +835 -0
  280. package/dist/session-observer-bands.d.ts +1 -1
  281. package/dist/session-observer-state.d.ts +1 -1
  282. package/dist/shared-context/manager.d.ts +9 -9
  283. package/dist/signal.d.ts +1 -1
  284. package/dist/{storage-BKhHHnRo.d.ts → storage-XGawwqXE.d.ts} +131 -2
  285. package/dist/storage.d.ts +2 -2
  286. package/dist/storage.js +4 -4
  287. package/dist/summarizer.d.ts +1 -1
  288. package/dist/summary-snapshot.d.ts +1 -1
  289. package/dist/temporal-supersession.d.ts +2 -2
  290. package/dist/temporal-timeline-recall.d.ts +1 -1
  291. package/dist/temporal-validity.d.ts +1 -1
  292. package/dist/threading.d.ts +1 -1
  293. package/dist/tier-migration.d.ts +2 -2
  294. package/dist/tier-routing.d.ts +1 -1
  295. package/dist/topics.d.ts +1 -1
  296. package/dist/transcript.d.ts +1 -1
  297. package/dist/transfer/types.d.ts +66 -66
  298. package/dist/trust-score-stage.d.ts +1 -1
  299. package/dist/trust-score.d.ts +1 -1
  300. package/dist/{types-GBQZuT7l.d.ts → types-Bbs0qz6b.d.ts} +2 -3
  301. package/dist/types.d.ts +1 -1
  302. package/dist/types.js +1 -1
  303. package/dist/utility-runtime.d.ts +1 -1
  304. package/dist/verified-recall.js +6 -6
  305. package/dist/write-envelope.d.ts +1 -1
  306. package/package.json +2 -2
  307. package/src/access-boundary.ts +3 -0
  308. package/src/access-http.test.ts +63 -0
  309. package/src/access-http.ts +26 -37
  310. package/src/access-mcp-output-schemas.ts +10 -0
  311. package/src/access-mcp.ts +4 -121
  312. package/src/access-operations-batch.ts +10 -5
  313. package/src/access-service.ts +43 -46
  314. package/src/access-surface-catalog.ts +6 -0
  315. package/src/access-wearables-meetings-surface.ts +139 -0
  316. package/src/activity/digest.ts +1 -1
  317. package/src/activity/runner.test.ts +37 -0
  318. package/src/activity/runner.ts +12 -0
  319. package/src/activity/scheduler.test.ts +1 -0
  320. package/src/activity/sync-registration.ts +13 -0
  321. package/src/cli/meetings-commands.ts +70 -0
  322. package/src/cli.ts +7 -6
  323. package/src/extraction-error-classification.ts +52 -0
  324. package/src/extraction.ts +2 -50
  325. package/src/mcp-read-only-tools.ts +2 -0
  326. package/src/meetings/build-memory.test.ts +364 -0
  327. package/src/meetings/build-scheduler.test.ts +55 -0
  328. package/src/meetings/build-scheduler.ts +96 -0
  329. package/src/meetings/day-source.test.ts +275 -0
  330. package/src/meetings/day-source.ts +352 -0
  331. package/src/meetings/http-glue.ts +126 -0
  332. package/src/meetings/index.ts +5 -4
  333. package/src/meetings/manual-sync-flush.test.ts +72 -0
  334. package/src/meetings/mcp-tools.ts +65 -0
  335. package/src/meetings/memory-gen.test.ts +498 -0
  336. package/src/meetings/memory-gen.ts +549 -0
  337. package/src/meetings/memory-generator.ts +5 -0
  338. package/src/meetings/namespace-isolation.test.ts +159 -0
  339. package/src/meetings/service.test.ts +195 -0
  340. package/src/meetings/service.ts +157 -0
  341. package/src/meetings/summary-extractor.test.ts +287 -0
  342. package/src/meetings/summary-extractor.ts +264 -0
  343. package/src/orchestration/maintenance.ts +8 -0
  344. package/src/orchestration/orchestrator-init.ts +6 -1
  345. package/src/orchestration/workspace-ops.ts +172 -8
  346. package/src/orchestrator.ts +12 -13
  347. package/src/storage.ts +21 -0
  348. package/src/testing/subjects/meetings-namespace-harness.ts +159 -0
  349. package/src/testing/subjects/meetings-namespace.test.ts +93 -0
  350. package/src/types.ts +1 -2
  351. package/src/wearables/cli.ts +2 -1
  352. package/src/wearables/index.ts +1 -0
  353. package/src/wearables/mcp-tools.ts +143 -0
  354. package/src/wearables/registry.test.ts +11 -0
  355. package/src/wearables/registry.ts +13 -0
  356. package/src/wearables/service.test.ts +62 -1
  357. package/src/wearables/service.ts +30 -2
  358. package/src/wearables/transcript-search-namespace-isolation.test.ts +98 -0
  359. package/dist/chunk-6ANPNUVL.js.map +0 -1
  360. package/dist/chunk-6NZ7U4R4.js.map +0 -1
  361. package/dist/chunk-7S5OMI76.js.map +0 -1
  362. package/dist/chunk-ACGGTPU4.js.map +0 -1
  363. package/dist/chunk-DM5A4ZFL.js.map +0 -1
  364. package/dist/chunk-EQYBHXRR.js.map +0 -1
  365. package/dist/chunk-IC2TCZJ2.js.map +0 -1
  366. package/dist/chunk-MONWCSVL.js.map +0 -1
  367. package/dist/chunk-N6M7MRVN.js.map +0 -1
  368. package/dist/chunk-QMGIQUBG.js.map +0 -1
  369. package/dist/chunk-QTO2FGBT.js.map +0 -1
  370. package/dist/chunk-SQEDDWAM.js.map +0 -1
  371. package/dist/chunk-W3XT32W7.js.map +0 -1
  372. /package/dist/{auto-sync-UPTUVE4X.js.map → auto-sync-5OE5QOZB.js.map} +0 -0
  373. /package/dist/{chunk-GF22HWS2.js.map → chunk-2PHX3I5C.js.map} +0 -0
  374. /package/dist/{chunk-JFDEYXF7.js.map → chunk-3NAHZQU3.js.map} +0 -0
  375. /package/dist/{chunk-XBRPEGXF.js.map → chunk-3UOSVTFR.js.map} +0 -0
  376. /package/dist/{chunk-TTKWTT72.js.map → chunk-3ZW6ZQO6.js.map} +0 -0
  377. /package/dist/{chunk-UV72DEZD.js.map → chunk-4B77XSG5.js.map} +0 -0
  378. /package/dist/{chunk-LMHDFOVV.js.map → chunk-5CPI2QWG.js.map} +0 -0
  379. /package/dist/{chunk-P72WZMWQ.js.map → chunk-5FZQ74K5.js.map} +0 -0
  380. /package/dist/{chunk-BRT7KEXU.js.map → chunk-6TWXQ4E2.js.map} +0 -0
  381. /package/dist/{chunk-CV6ZYXK3.js.map → chunk-7I7AYIUQ.js.map} +0 -0
  382. /package/dist/{chunk-TVVEYCNW.js.map → chunk-7K5Q6COX.js.map} +0 -0
  383. /package/dist/{chunk-JN57HZCD.js.map → chunk-ATEAL5EI.js.map} +0 -0
  384. /package/dist/{chunk-4PYLBXX6.js.map → chunk-AYAROCWD.js.map} +0 -0
  385. /package/dist/{chunk-NB2P47N7.js.map → chunk-CUUY5CC4.js.map} +0 -0
  386. /package/dist/{chunk-KL5Y6PEV.js.map → chunk-E3ZMFFQZ.js.map} +0 -0
  387. /package/dist/{chunk-55FDQYPS.js.map → chunk-ES5IHQ6M.js.map} +0 -0
  388. /package/dist/{chunk-N47ZWQBO.js.map → chunk-G2NSSQES.js.map} +0 -0
  389. /package/dist/{chunk-GSWPU5CR.js.map → chunk-GD3QOBMB.js.map} +0 -0
  390. /package/dist/{chunk-SACPRJ7F.js.map → chunk-JNIJBXVK.js.map} +0 -0
  391. /package/dist/{chunk-DGLON3AL.js.map → chunk-KNRG6ZGJ.js.map} +0 -0
  392. /package/dist/{chunk-GEUDRENF.js.map → chunk-MMTG3SCJ.js.map} +0 -0
  393. /package/dist/{chunk-WZFAPHIK.js.map → chunk-MU7ZHSZE.js.map} +0 -0
  394. /package/dist/{chunk-W4FBGYGK.js.map → chunk-NRV4Y3PM.js.map} +0 -0
  395. /package/dist/{chunk-KQ2XCQYN.js.map → chunk-P2BLHUL2.js.map} +0 -0
  396. /package/dist/{chunk-6L775BUB.js.map → chunk-QE63OHLB.js.map} +0 -0
  397. /package/dist/{chunk-ONHRRJZM.js.map → chunk-QJAQNXWI.js.map} +0 -0
  398. /package/dist/{chunk-6RYWNBSA.js.map → chunk-SVZGA2MK.js.map} +0 -0
  399. /package/dist/{chunk-OCMLGND7.js.map → chunk-WWZ35GWW.js.map} +0 -0
  400. /package/dist/{chunk-A5N6ISRK.js.map → chunk-ZN4UZWMT.js.map} +0 -0
  401. /package/dist/{chunk-7M6APKJL.js.map → chunk-ZYU7ZFLT.js.map} +0 -0
  402. /package/dist/{first-start-migration-LEXL3XYL.js.map → first-start-migration-BKNGOFED.js.map} +0 -0
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Wearables MCP tool definitions (issue #1900 / #2123) — the five
3
+ * `engram.wearables_*` / `engram.transcript_*` tool-def objects, extracted from
4
+ * access-mcp.ts so the surface file stays under its structural ceiling. Spread
5
+ * back into `this.tools` (`...WEARABLES_MCP_TOOLS`); tools/list is verified at
6
+ * runtime. MCP_MIGRATED_OPERATIONS + callTool dispatch stay inline in
7
+ * access-mcp.ts. Each schema carries `namespace` + `sessionKey` so the MCP
8
+ * scope-override injects the caller namespace (caller-derived symmetry, #2123).
9
+ */
10
+
11
+ import type { McpTool } from "../access-mcp.js";
12
+
13
+ export const WEARABLES_MCP_TOOLS: McpTool[] = [
14
+ {
15
+ name: "engram.wearables_status",
16
+ description:
17
+ "Status of wearable transcript sources (Limitless / Bee / Omi): configured sources, connector availability, last sync, stored transcript days.",
18
+ inputSchema: {
19
+ type: "object",
20
+ properties: {
21
+ namespace: { type: "string", description: "Caller namespace to scope this operation to (issue #2123)." },
22
+ sessionKey: { type: "string", description: "Session key for principal/namespace resolution." },
23
+ },
24
+ additionalProperties: false,
25
+ },
26
+ },
27
+ {
28
+ name: "engram.wearables_sync",
29
+ description:
30
+ "Pull, clean, and store wearable transcripts for one source or all enabled sources; optionally creates trust-gated memories per the source's memoryMode.",
31
+ inputSchema: {
32
+ type: "object",
33
+ properties: {
34
+ namespace: { type: "string", description: "Caller namespace to scope this operation to (issue #2123)." },
35
+ sessionKey: { type: "string", description: "Session key for principal/namespace resolution." },
36
+ source: {
37
+ type: "string",
38
+ description: "Source id (e.g. limitless, bee, omi). Omit to sync every enabled source.",
39
+ },
40
+ date: {
41
+ type: "string",
42
+ description: "Sync exactly this day (YYYY-MM-DD). Overrides days.",
43
+ },
44
+ days: {
45
+ type: "integer",
46
+ minimum: 1,
47
+ maximum: 90,
48
+ description: "Lookback window in days ending today (default 2).",
49
+ },
50
+ forceMemories: {
51
+ type: "boolean",
52
+ description: "Re-run memory extraction even for unchanged days.",
53
+ },
54
+ },
55
+ additionalProperties: false,
56
+ },
57
+ },
58
+ {
59
+ name: "engram.transcript_day",
60
+ description:
61
+ "Return the full stored wearable transcript(s) for a day, across all sources or one source, with cross-source overlap hints.",
62
+ inputSchema: {
63
+ type: "object",
64
+ properties: {
65
+ namespace: { type: "string", description: "Caller namespace to scope this operation to (issue #2123)." },
66
+ sessionKey: { type: "string", description: "Session key for principal/namespace resolution." },
67
+ date: {
68
+ type: "string",
69
+ description: "Day to read (YYYY-MM-DD). Required.",
70
+ },
71
+ source: {
72
+ type: "string",
73
+ description: "Optional source id to scope to (e.g. limitless).",
74
+ },
75
+ },
76
+ required: ["date"],
77
+ additionalProperties: false,
78
+ },
79
+ },
80
+ {
81
+ name: "engram.transcript_search",
82
+ description:
83
+ "Search stored wearable transcripts. Results carry source + date so callers can pull the full day via engram.transcript_day.",
84
+ inputSchema: {
85
+ type: "object",
86
+ properties: {
87
+ namespace: { type: "string", description: "Caller namespace to scope this operation to (issue #2123)." },
88
+ sessionKey: { type: "string", description: "Session key for principal/namespace resolution." },
89
+ query: {
90
+ type: "string",
91
+ description: "Search query. Required; non-empty.",
92
+ },
93
+ source: {
94
+ type: "string",
95
+ description: "Optional source id filter.",
96
+ },
97
+ from: {
98
+ type: "string",
99
+ description: "Optional inclusive start date (YYYY-MM-DD).",
100
+ },
101
+ to: {
102
+ type: "string",
103
+ description: "Optional inclusive end date (YYYY-MM-DD).",
104
+ },
105
+ limit: {
106
+ type: "integer",
107
+ minimum: 1,
108
+ maximum: 50,
109
+ description: "Maximum results (default 10).",
110
+ },
111
+ },
112
+ required: ["query"],
113
+ additionalProperties: false,
114
+ },
115
+ },
116
+ {
117
+ name: "engram.transcript_memories",
118
+ description:
119
+ "List memories created from wearable transcripts, filterable by source and/or day. Includes pending_review candidates awaiting approval.",
120
+ inputSchema: {
121
+ type: "object",
122
+ properties: {
123
+ namespace: { type: "string", description: "Caller namespace to scope this operation to (issue #2123)." },
124
+ sessionKey: { type: "string", description: "Session key for principal/namespace resolution." },
125
+ source: {
126
+ type: "string",
127
+ description: "Optional source id filter (e.g. limitless).",
128
+ },
129
+ date: {
130
+ type: "string",
131
+ description: "Optional transcript day filter (YYYY-MM-DD).",
132
+ },
133
+ limit: {
134
+ type: "integer",
135
+ minimum: 1,
136
+ maximum: 200,
137
+ description: "Maximum results (default 50).",
138
+ },
139
+ },
140
+ additionalProperties: false,
141
+ },
142
+ }
143
+ ];
@@ -2,6 +2,7 @@ import assert from "node:assert/strict";
2
2
  import { afterEach, test } from "node:test";
3
3
 
4
4
  import {
5
+ builtInConnectorPackageSpecifier,
5
6
  clearWearableConnectors,
6
7
  ensureBuiltInWearableConnectors,
7
8
  getWearableConnector,
@@ -60,3 +61,13 @@ test("ensureBuiltInWearableConnectors tolerates absent optional packages", async
60
61
  await ensureBuiltInWearableConnectors();
61
62
  assert.ok(Array.isArray(listWearableConnectors()));
62
63
  });
64
+
65
+ test("builtInConnectorPackageSpecifier maps a source to its real optional package (AC9 install hint)", () => {
66
+ // desktop ships in @remnic/capture-audio, NOT the nonexistent
67
+ // @remnic/connector-desktop — the missing-package hint must be installable.
68
+ assert.equal(builtInConnectorPackageSpecifier("desktop"), "@remnic/capture-audio");
69
+ assert.equal(builtInConnectorPackageSpecifier("limitless"), "@remnic/connector-limitless");
70
+ assert.equal(builtInConnectorPackageSpecifier("bee"), "@remnic/connector-bee");
71
+ // An unknown id keeps the connector-<id> convention.
72
+ assert.equal(builtInConnectorPackageSpecifier("acme"), "@remnic/connector-acme");
73
+ });
@@ -86,8 +86,21 @@ const BUILT_IN_CONNECTOR_PACKAGES: Array<{ id: string; suffix: string }> = [
86
86
  { id: "omi", suffix: "connector-omi" },
87
87
  { id: "fireflies", suffix: "connector-fireflies" },
88
88
  { id: "granola", suffix: "connector-granola" },
89
+ { id: "desktop", suffix: "capture-audio" },
89
90
  ];
90
91
 
92
+ /**
93
+ * npm specifier of the optional package that provides a source's connector.
94
+ * Built-in sources map to their real package (e.g. `desktop` ->
95
+ * `@remnic/capture-audio`, not the nonexistent `@remnic/connector-desktop`);
96
+ * unknown ids fall back to the `connector-<id>` convention. Used by
97
+ * missing-connector install hints so they name the exact install command.
98
+ */
99
+ export function builtInConnectorPackageSpecifier(id: string): string {
100
+ const entry = BUILT_IN_CONNECTOR_PACKAGES.find((e) => e.id === id);
101
+ return `@remnic/${entry ? entry.suffix : `connector-${id}`}`;
102
+ }
103
+
91
104
  const loadFailuresWarned = new Set<string>();
92
105
 
93
106
  export async function ensureBuiltInWearableConnectors(): Promise<void> {
@@ -31,7 +31,15 @@ import {
31
31
  } from "./service.js";
32
32
  import { sealedWriteToLegacyArgs } from "../write-envelope.js";
33
33
  import { defaultWearablesConfig, defaultWearableSourceSettings } from "./config.js";
34
- import type { WearableConversation, WearablesConfig } from "./types.js";
34
+ import {
35
+ clearWearableConnectors,
36
+ registerWearableConnector,
37
+ } from "./registry.js";
38
+ import type {
39
+ WearableConversation,
40
+ WearableSourceConnector,
41
+ WearablesConfig,
42
+ } from "./types.js";
35
43
 
36
44
  function makeStorage(memoryDir: string): WearableStorageIo & {
37
45
  files: Map<string, string>;
@@ -1621,3 +1629,56 @@ test("searchTranscripts scan decodes segment text so snippets show the original
1621
1629
  rmSync(dir, { recursive: true, force: true });
1622
1630
  }
1623
1631
  });
1632
+
1633
+ function syncOnlyConnector(): WearableSourceConnector {
1634
+ return {
1635
+ id: "testsource",
1636
+ displayName: "Test Source",
1637
+ async verifyAuth() {
1638
+ return { ok: true };
1639
+ },
1640
+ async fetchConversations() {
1641
+ return { conversations: [], nextCursor: null };
1642
+ },
1643
+ };
1644
+ }
1645
+
1646
+ test("sync fires onDaysSynced with the synced days so a MANUAL wearables sync triggers the meeting tail-step (issue #1900)", async () => {
1647
+ const dir = mkdtempSync(path.join(tmpdir(), "wearables-on-days-synced-"));
1648
+ try {
1649
+ clearWearableConnectors();
1650
+ registerWearableConnector({
1651
+ id: "testsource",
1652
+ displayName: "Test Source",
1653
+ factory: () => syncOnlyConnector(),
1654
+ });
1655
+ const storage = makeStorage(dir);
1656
+ const synced: string[][] = [];
1657
+ const service = new WearablesService({
1658
+ config: {
1659
+ ...defaultWearablesConfig(),
1660
+ enabled: true,
1661
+ timezone: "UTC",
1662
+ sources: { testsource: { ...defaultWearableSourceSettings(), enabled: true } },
1663
+ },
1664
+ getStorage: async () => storage,
1665
+ extract: null,
1666
+ searchBackend: null,
1667
+ // Stands in for the workspace-ops wiring that calls the meetings service's
1668
+ // debounced requestBuild — the manual HTTP/MCP/CLI sync path reaches this
1669
+ // same shared service, so the tail-step must fire here, not only in the
1670
+ // auto-sync adapter.
1671
+ onDaysSynced: (days) => {
1672
+ synced.push([...days]);
1673
+ },
1674
+ });
1675
+ const summaries = await service.sync({ source: "testsource", days: 1 });
1676
+ const expected = [...new Set(summaries.flatMap((summary) => summary.days))].sort();
1677
+ assert.ok(expected.length > 0, "the sync touched at least one day");
1678
+ assert.equal(synced.length, 1, "the shared sync path fires the meeting tail-step exactly once");
1679
+ assert.deepEqual([...synced[0]!].sort(), expected, "the hook receives the union of synced days");
1680
+ } finally {
1681
+ clearWearableConnectors();
1682
+ rmSync(dir, { recursive: true, force: true });
1683
+ }
1684
+ });
@@ -41,6 +41,7 @@ import {
41
41
  type WearableSyncOptions,
42
42
  } from "./pipeline.js";
43
43
  import {
44
+ builtInConnectorPackageSpecifier,
44
45
  ensureBuiltInWearableConnectors,
45
46
  getWearableConnector,
46
47
  listWearableConnectors,
@@ -132,6 +133,15 @@ export interface WearablesServiceDeps {
132
133
  searchBackend: WearableSearchBackend | null;
133
134
  /** Fired after transcript writes so the search index refreshes. */
134
135
  reindexSearch?: () => Promise<void>;
136
+ /**
137
+ * Meeting tail-step (issue #1900): fired once after a sync with the union of
138
+ * days it touched, so a dependent subsystem (meeting building) can rebuild the
139
+ * affected day(s). Wired for EVERY sync path — auto-sync AND manual
140
+ * HTTP/MCP/CLI backfill — because they all share this one service. Optional;
141
+ * omitted by hosts that do not build meetings. The hook self-gates and never
142
+ * fails the sync.
143
+ */
144
+ onDaysSynced?: (days: readonly string[]) => void | Promise<void>;
135
145
  }
136
146
 
137
147
  export interface WearableTranscriptSearchResult {
@@ -326,7 +336,7 @@ export class WearablesService {
326
336
  if (!registration) {
327
337
  throw new WearablesInputError(
328
338
  `wearable source '${sourceId}' is enabled but its connector package is not installed.\n` +
329
- `Install it alongside Remnic:\n npm install @remnic/connector-${sourceId}`,
339
+ `Install it alongside Remnic:\n npm install ${builtInConnectorPackageSpecifier(sourceId)}`,
330
340
  );
331
341
  }
332
342
  const connector = registration.factory({
@@ -398,6 +408,24 @@ export class WearablesService {
398
408
  );
399
409
  summaries.push(summary);
400
410
  }
411
+ // Tail step (issue #1900): a wearable sync changed a day's audio, so fan out
412
+ // the affected days to the injected build hook (wired to the meetings
413
+ // service's debounced rebuild). Fires for every sync path — auto-sync and
414
+ // manual HTTP/MCP/CLI backfill alike — since they all share this service.
415
+ // The hook self-gates on meetings.enabled and coalesces; a failure here
416
+ // never fails the sync that called us.
417
+ const syncedDays = [...new Set(summaries.flatMap((summary) => summary.days))];
418
+ if (syncedDays.length > 0 && this.deps.onDaysSynced) {
419
+ try {
420
+ await this.deps.onDaysSynced(syncedDays);
421
+ } catch (err) {
422
+ log.warn(
423
+ `wearables: post-sync meeting build hook failed (non-fatal): ${
424
+ err instanceof Error ? err.message : String(err)
425
+ }`,
426
+ );
427
+ }
428
+ }
401
429
  return summaries;
402
430
  }
403
431
 
@@ -414,7 +442,7 @@ export class WearablesService {
414
442
  if (!registration) {
415
443
  return {
416
444
  ok: false,
417
- detail: `connector package @remnic/connector-${sourceId} is not installed`,
445
+ detail: `connector package ${builtInConnectorPackageSpecifier(sourceId)} is not installed`,
418
446
  };
419
447
  }
420
448
  const connector = registration.factory({
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Wearable transcript SEARCH namespace isolation (issue #2123, P1 gap).
3
+ *
4
+ * getWearablesService(namespace) reads transcript FILES from the caller's
5
+ * namespace storage, but the injected `searchBackend.search` used to call the
6
+ * ROOT qmd collection unconditionally. In a namespace-enabled deployment that
7
+ * let a non-default caller's transcript_search surface root/other-namespace
8
+ * transcripts — a data-isolation breach that the file-scoping alone did not
9
+ * close (the indexed path returns hits using the index snippet even when the
10
+ * caller-namespace file read is null).
11
+ *
12
+ * The fix scopes the indexed search to the CALLER namespace's collection. This
13
+ * two-principal test drives a fake collection-partitioned qmd backend:
14
+ * 1. principal A (non-default nsA) sees ONLY nsA's transcript;
15
+ * 2. principal B (non-default nsB) sees ONLY nsB's transcript — a transcript
16
+ * that exists only under the default/root namespace is NOT returned to B;
17
+ * 3. the default/machine-owner caller still sees the default transcript.
18
+ *
19
+ * Before the fix every caller searched the root collection (collection
20
+ * undefined), so B received the default transcript and this fails.
21
+ */
22
+ import assert from "node:assert/strict";
23
+ import test from "node:test";
24
+
25
+ import { namespaceCollectionName } from "../namespaces/search.js";
26
+ import type { SearchBackend, SearchResult } from "../search/port.js";
27
+ import { buildMeetingsNamespaceHarness } from "../testing/subjects/meetings-namespace-harness.js";
28
+
29
+ const SOURCE = "faketest";
30
+ const DATE_A = "2026-04-01";
31
+ const DATE_B = "2026-04-02";
32
+ const DATE_DEFAULT = "2026-04-03";
33
+
34
+ const transcriptFile = (body: string): string =>
35
+ `---\nkind: wearable-transcript\n---\n\n${body}\n`;
36
+
37
+ const dates = (results: ReadonlyArray<{ date: string }>): string[] =>
38
+ results.map((r) => r.date).sort();
39
+
40
+ test("transcript search is scoped to the caller namespace: A sees only A, B never sees the default transcript, the default caller still sees default (#2123)", async () => {
41
+ const h = await buildMeetingsNamespaceHarness();
42
+ try {
43
+ // Physical transcripts under each namespace root.
44
+ await (await h.storageForNs("nsA")).writeWearableDayTranscript(SOURCE, DATE_A, transcriptFile("alpha standup notes"));
45
+ await (await h.storageForNs("nsB")).writeWearableDayTranscript(SOURCE, DATE_B, transcriptFile("bravo standup notes"));
46
+ await (await h.storageForNs("default")).writeWearableDayTranscript(SOURCE, DATE_DEFAULT, transcriptFile("delta standup notes"));
47
+
48
+ const base = h.orchestrator.config.qmdCollection;
49
+ const collFor = (ns: string, legacy: boolean): string =>
50
+ namespaceCollectionName(base, ns, { defaultNamespace: "default", useLegacyDefaultCollection: legacy });
51
+ const hit = (date: string, snippet: string): SearchResult =>
52
+ ({ path: `wearables/${SOURCE}/${date}.md`, score: 0.9, snippet } as unknown as SearchResult);
53
+
54
+ // Collection-partitioned index. The default hit is ALSO registered under
55
+ // the root key (collection === undefined) so a non-scoped (pre-fix) search
56
+ // returns the default transcript — that is exactly the breach under test.
57
+ const index: Record<string, SearchResult[]> = {
58
+ "\u0000root": [hit(DATE_DEFAULT, "delta standup notes")],
59
+ [base]: [hit(DATE_DEFAULT, "delta standup notes")],
60
+ [collFor("default", false)]: [hit(DATE_DEFAULT, "delta standup notes")],
61
+ [collFor("nsA", false)]: [hit(DATE_A, "alpha standup notes")],
62
+ [collFor("nsB", false)]: [hit(DATE_B, "bravo standup notes")],
63
+ };
64
+ const searchedCollections: Array<string | undefined> = [];
65
+ h.orchestrator.qmd = {
66
+ isAvailable: () => true,
67
+ search: async (_query: string, collection?: string, maxResults?: number) => {
68
+ searchedCollections.push(collection);
69
+ return (index[collection ?? "\u0000root"] ?? []).slice(0, maxResults);
70
+ },
71
+ } as unknown as SearchBackend;
72
+
73
+ const search = (namespace: string, authenticatedPrincipal: string) =>
74
+ h.service.wearablesTranscriptSearch({ query: "standup", namespace, authenticatedPrincipal });
75
+
76
+ const aRes = await search("nsA", "pA");
77
+ assert.deepEqual(dates(aRes), [DATE_A], "principal A sees only nsA's transcript");
78
+
79
+ const bRes = await search("nsB", "pB");
80
+ assert.deepEqual(dates(bRes), [DATE_B], "principal B sees only nsB's transcript");
81
+ assert.ok(
82
+ !bRes.some((r) => r.date === DATE_DEFAULT),
83
+ "the default/root transcript is NOT leaked to a non-default caller",
84
+ );
85
+
86
+ const dRes = await search("default", "op");
87
+ assert.deepEqual(dates(dRes), [DATE_DEFAULT], "the default/machine-owner caller still sees default transcripts");
88
+
89
+ // The indexed search was scoped per caller: no query ran against the root
90
+ // collection (undefined) — that is the pre-fix breach.
91
+ assert.ok(
92
+ !searchedCollections.includes(undefined),
93
+ "no transcript search targeted the unscoped root collection",
94
+ );
95
+ } finally {
96
+ await h.cleanup();
97
+ }
98
+ });