@remnic/core 9.30.1 → 9.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (504) hide show
  1. package/dist/access-admin-ops-surface.d.ts +10 -10
  2. package/dist/access-admin-ops-surface.js +55 -44
  3. package/dist/access-authorization-probe.d.ts +10 -10
  4. package/dist/access-authorization-probe.js +56 -45
  5. package/dist/access-boundary.d.ts +13 -11
  6. package/dist/access-boundary.js +55 -44
  7. package/dist/access-cli.js +170 -126
  8. package/dist/access-cli.js.map +1 -1
  9. package/dist/access-extraction-force-flush.d.ts +119 -0
  10. package/dist/access-extraction-force-flush.js +171 -0
  11. package/dist/access-health-types.d.ts +1 -1
  12. package/dist/access-http-lcm-compaction.d.ts +47 -13
  13. package/dist/access-http-lcm-compaction.js +7 -3
  14. package/dist/access-http-lifecycle-flush.d.ts +132 -0
  15. package/dist/access-http-lifecycle-flush.js +9 -0
  16. package/dist/access-http-lifecycle-flush.js.map +1 -0
  17. package/dist/access-http.d.ts +11 -10
  18. package/dist/access-http.js +71 -59
  19. package/dist/access-identity-continuity-surface.d.ts +8 -8
  20. package/dist/access-identity-continuity-surface.js +55 -44
  21. package/dist/access-lcm-surface.d.ts +10 -10
  22. package/dist/access-lcm-surface.js +55 -44
  23. package/dist/access-mcp-output-schemas.js +1 -1
  24. package/dist/access-mcp.d.ts +16 -10
  25. package/dist/access-mcp.js +63 -52
  26. package/dist/access-memory-search-fanout.d.ts +2 -2
  27. package/dist/{access-namespace-preflight-VfXssvoI.d.ts → access-namespace-preflight-COhbXBqS.d.ts} +1 -1
  28. package/dist/access-namespace-preflight.d.ts +3 -3
  29. package/dist/access-namespace-preflight.js +55 -44
  30. package/dist/access-observe-helpers.d.ts +22 -0
  31. package/dist/access-observe-helpers.js +10 -0
  32. package/dist/access-observe-helpers.js.map +1 -0
  33. package/dist/access-observe-write-surface.d.ts +51 -47
  34. package/dist/access-observe-write-surface.js +55 -44
  35. package/dist/access-operations-batch.js +58 -47
  36. package/dist/access-operations.d.ts +11 -11
  37. package/dist/access-operations.js +60 -49
  38. package/dist/access-recall-concurrency.d.ts +10 -10
  39. package/dist/access-recall-concurrency.js +55 -44
  40. package/dist/access-recall-response.d.ts +10 -10
  41. package/dist/access-recall-response.js +55 -44
  42. package/dist/access-recall-surface.d.ts +10 -10
  43. package/dist/access-recall-surface.js +55 -44
  44. package/dist/access-schema.d.ts +37 -7
  45. package/dist/access-schema.js +5 -3
  46. package/dist/{access-service-B5RwVsTV.d.ts → access-service-BmBTtEKO.d.ts} +44 -20
  47. package/dist/access-service-helpers.d.ts +113 -0
  48. package/dist/access-service-helpers.js +8 -0
  49. package/dist/access-service-helpers.js.map +1 -0
  50. package/dist/access-service.d.ts +10 -10
  51. package/dist/access-service.js +55 -44
  52. package/dist/access-surface-catalog.d.ts +10 -10
  53. package/dist/access-surface-catalog.js +2 -0
  54. package/dist/access-surface-catalog.js.map +1 -1
  55. package/dist/access-wearables-meetings-surface.d.ts +3 -3
  56. package/dist/action-confidence.d.ts +1 -1
  57. package/dist/active-memory-bridge.d.ts +1 -1
  58. package/dist/active-recall.d.ts +1 -1
  59. package/dist/active-recall.js +2 -2
  60. package/dist/adapters/index.js +7 -7
  61. package/dist/adapters/registry.js +3 -3
  62. package/dist/behavior-learner.d.ts +1 -1
  63. package/dist/behavior-signals.d.ts +1 -1
  64. package/dist/bootstrap.d.ts +8 -8
  65. package/dist/briefing.d.ts +2 -2
  66. package/dist/briefing.js +14 -14
  67. package/dist/buffer-surprise-report.d.ts +1 -1
  68. package/dist/buffer-turn-helpers.d.ts +5 -0
  69. package/dist/buffer-turn-helpers.js +24 -0
  70. package/dist/buffer-turn-helpers.js.map +1 -0
  71. package/dist/buffer.d.ts +17 -4
  72. package/dist/buffer.js +21 -1
  73. package/dist/bulk-import/index.d.ts +3 -3
  74. package/dist/calibration.d.ts +1 -1
  75. package/dist/capabilities.d.ts +1 -1
  76. package/dist/{capsule-crypto-GWVG7LGC.js → capsule-crypto-7FJQINUR.js} +2 -2
  77. package/dist/capsule-crypto-7FJQINUR.js.map +1 -0
  78. package/dist/{capsule-merge-5KKJQBWQ.js → capsule-merge-2H2IUTBT.js} +4 -4
  79. package/dist/{catalog-V7inUQdp.d.ts → catalog-Dm-DvNBY.d.ts} +1 -1
  80. package/dist/causal-behavior.d.ts +1 -1
  81. package/dist/causal-behavior.js +2 -2
  82. package/dist/causal-chain.js +2 -2
  83. package/dist/causal-consolidation.d.ts +1 -1
  84. package/dist/causal-consolidation.js +21 -22
  85. package/dist/causal-consolidation.js.map +1 -1
  86. package/dist/causal-retrieval.js +2 -2
  87. package/dist/causal-trajectory-graph.d.ts +1 -1
  88. package/dist/causal-trajectory.js +1 -1
  89. package/dist/{chunk-LEPOP46W.js → chunk-227UFSEQ.js} +4 -4
  90. package/dist/{chunk-I5NLEENJ.js → chunk-27HHNYSQ.js} +3 -3
  91. package/dist/{chunk-2SA56WMI.js → chunk-2LTDWSR6.js} +4 -4
  92. package/dist/{chunk-OWHERGF2.js → chunk-2NLLXCJG.js} +2 -2
  93. package/dist/{chunk-SPJXKAVF.js → chunk-2NTGBZLZ.js} +14 -13
  94. package/dist/chunk-2NTGBZLZ.js.map +1 -0
  95. package/dist/{chunk-P5PXWTW7.js → chunk-2Q4JJ3FZ.js} +3 -3
  96. package/dist/{chunk-G5R3D5UP.js → chunk-2QIMTVEJ.js} +6 -5
  97. package/dist/chunk-2QIMTVEJ.js.map +1 -0
  98. package/dist/{chunk-H5CPS5JP.js → chunk-35IVNNRK.js} +3 -3
  99. package/dist/{chunk-LBOD4U5B.js → chunk-3EQ2XB3W.js} +6 -6
  100. package/dist/{chunk-YTSNAUXN.js → chunk-3F2LKUMU.js} +22 -8
  101. package/dist/chunk-3F2LKUMU.js.map +1 -0
  102. package/dist/chunk-3QL24R5Y.js +9 -0
  103. package/dist/chunk-3QL24R5Y.js.map +1 -0
  104. package/dist/chunk-4RNZMRAV.js +60 -0
  105. package/dist/chunk-4RNZMRAV.js.map +1 -0
  106. package/dist/chunk-5IVLTFOV.js +65 -0
  107. package/dist/chunk-5IVLTFOV.js.map +1 -0
  108. package/dist/{chunk-2EUVEDF5.js → chunk-5WZVQRHV.js} +2 -2
  109. package/dist/{chunk-ALSGMEJR.js → chunk-65ZPVYTA.js} +7 -7
  110. package/dist/{chunk-GIBMDSJ2.js → chunk-6P7MTSU5.js} +2 -2
  111. package/dist/{chunk-5VQJBH2G.js → chunk-6TAUHL33.js} +2 -2
  112. package/dist/{chunk-WVO4G37W.js → chunk-7TEZUUGM.js} +3 -3
  113. package/dist/{chunk-MJCGLM25.js → chunk-7VUAG236.js} +5 -5
  114. package/dist/{chunk-CZRYLSSW.js → chunk-AJL6NNX6.js} +2 -2
  115. package/dist/{chunk-LGHKJABJ.js → chunk-AQEJE3WO.js} +40 -18
  116. package/dist/chunk-AQEJE3WO.js.map +1 -0
  117. package/dist/{chunk-66772WBP.js → chunk-AQWVJURR.js} +5 -5
  118. package/dist/{chunk-RKNJBZ55.js → chunk-AU7Q3LSC.js} +7 -7
  119. package/dist/{chunk-IYZ5K7MU.js → chunk-BUE5E2HL.js} +4 -187
  120. package/dist/chunk-BUE5E2HL.js.map +1 -0
  121. package/dist/{chunk-NHWB6HG2.js → chunk-CE5355TT.js} +21 -5
  122. package/dist/chunk-CE5355TT.js.map +1 -0
  123. package/dist/{chunk-M3C2V3PV.js → chunk-CJDNT45S.js} +12 -12
  124. package/dist/{chunk-D2ANTDGO.js → chunk-E6BMSH7U.js} +2 -2
  125. package/dist/{chunk-CKMO4RDY.js → chunk-EMDLM3LW.js} +4 -4
  126. package/dist/chunk-ER7W6H4T.js +112 -0
  127. package/dist/chunk-ER7W6H4T.js.map +1 -0
  128. package/dist/{chunk-RGIWINDN.js → chunk-FHBITMRY.js} +30 -30
  129. package/dist/{chunk-6FUPCJUL.js → chunk-FMFLGS5Z.js} +54 -54
  130. package/dist/chunk-FMFLGS5Z.js.map +1 -0
  131. package/dist/{chunk-FDAMS4PK.js → chunk-G2YQ57YO.js} +4 -4
  132. package/dist/{chunk-6U7F52DE.js → chunk-HFQQWAMS.js} +62 -62
  133. package/dist/{chunk-5W4ZLBEZ.js → chunk-HKPJPOW7.js} +2 -2
  134. package/dist/{chunk-JCBWCYEJ.js → chunk-IGWFKW4B.js} +2 -2
  135. package/dist/{chunk-AITCS2RC.js → chunk-IJ7HK452.js} +4 -4
  136. package/dist/{chunk-4WKA6I65.js → chunk-J3ZGPYXB.js} +1135 -311
  137. package/dist/chunk-J3ZGPYXB.js.map +1 -0
  138. package/dist/{chunk-D3LMYTBV.js → chunk-J7WZUL2K.js} +9 -9
  139. package/dist/{chunk-5W7CTZ2E.js → chunk-KQAFEZQX.js} +4 -4
  140. package/dist/{chunk-YNQBRLC5.js → chunk-LUQ443JP.js} +520 -2011
  141. package/dist/chunk-LUQ443JP.js.map +1 -0
  142. package/dist/{chunk-Z54EM5YZ.js → chunk-MAXVH44E.js} +7 -7
  143. package/dist/{chunk-WZFAPHIK.js → chunk-MU7ZHSZE.js} +2 -2
  144. package/dist/chunk-N5Z4EVOR.js +123 -0
  145. package/dist/chunk-N5Z4EVOR.js.map +1 -0
  146. package/dist/{chunk-AZ5BTEKX.js → chunk-NQUF7XKR.js} +2 -2
  147. package/dist/{chunk-W4FBGYGK.js → chunk-NRV4Y3PM.js} +1 -1
  148. package/dist/{chunk-62U4J2GN.js → chunk-ODGOP7P2.js} +2 -2
  149. package/dist/{chunk-QJAQNXWI.js → chunk-ONHRRJZM.js} +6 -6
  150. package/dist/{chunk-ACXPX4AG.js → chunk-OPBTPRGY.js} +2 -2
  151. package/dist/{chunk-XOZ4ALGB.js → chunk-QDTZ2HF7.js} +3 -3
  152. package/dist/{chunk-GBJ4RDFR.js → chunk-QIHIHZYC.js} +66 -91
  153. package/dist/chunk-QIHIHZYC.js.map +1 -0
  154. package/dist/{chunk-ZPSVBSOF.js → chunk-QMWFQBIL.js} +3 -3
  155. package/dist/{chunk-W5EG6LE3.js → chunk-THCPRMRF.js} +3 -3
  156. package/dist/{chunk-4A6YGWQN.js → chunk-TL4TO3EA.js} +115 -120
  157. package/dist/chunk-TL4TO3EA.js.map +1 -0
  158. package/dist/{chunk-VI2JQPNQ.js → chunk-U7QYBSQJ.js} +2 -2
  159. package/dist/chunk-ULARSG5Z.js +203 -0
  160. package/dist/chunk-ULARSG5Z.js.map +1 -0
  161. package/dist/{chunk-TH2LSRMG.js → chunk-UORKJ34C.js} +2 -2
  162. package/dist/{chunk-4Z4XNEWZ.js → chunk-VCD4PSK2.js} +56 -12
  163. package/dist/chunk-VCD4PSK2.js.map +1 -0
  164. package/dist/{chunk-K5GB36ME.js → chunk-VMZ56EE3.js} +2 -2
  165. package/dist/{chunk-HUHX2OCX.js → chunk-VVDPPDDF.js} +1 -1
  166. package/dist/chunk-VVDPPDDF.js.map +1 -0
  167. package/dist/{chunk-RMMVQQA6.js → chunk-WDISJRMG.js} +2 -2
  168. package/dist/{chunk-B6JDYXL7.js → chunk-WWUVONGW.js} +7 -1
  169. package/dist/chunk-WWUVONGW.js.map +1 -0
  170. package/dist/{chunk-UVYI6VIX.js → chunk-X7Y7WX73.js} +1 -1
  171. package/dist/{chunk-CVILPI77.js → chunk-XOQSEF7X.js} +6 -6
  172. package/dist/{chunk-RPW2NOU6.js → chunk-YIAA2X3D.js} +41 -1
  173. package/dist/chunk-YIAA2X3D.js.map +1 -0
  174. package/dist/chunk-YPC7W6GA.js +1604 -0
  175. package/dist/chunk-YPC7W6GA.js.map +1 -0
  176. package/dist/{chunk-YTQNQ4KB.js → chunk-YX5LN6JR.js} +3 -3
  177. package/dist/{chunk-IC6CBHCA.js → chunk-Z7XKUWYS.js} +2 -2
  178. package/dist/{chunk-PHWUFPCO.js → chunk-ZCPP5OW6.js} +61 -53
  179. package/dist/chunk-ZCPP5OW6.js.map +1 -0
  180. package/dist/{cli-C4GbETPC.d.ts → cli-DRJLv1Xt.d.ts} +5 -5
  181. package/dist/cli.d.ts +12 -12
  182. package/dist/cli.js +96 -86
  183. package/dist/compounding/engine.d.ts +2 -2
  184. package/dist/compounding/engine.js +14 -14
  185. package/dist/compounding/preference-consolidator.d.ts +1 -1
  186. package/dist/compression-optimizer.d.ts +1 -1
  187. package/dist/config.d.ts +1 -1
  188. package/dist/config.js +2 -2
  189. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  190. package/dist/connectors/codex-materialize-runner.js +14 -15
  191. package/dist/connectors/codex-materialize.d.ts +1 -1
  192. package/dist/connectors/index.d.ts +3 -2
  193. package/dist/connectors/index.js +24 -23
  194. package/dist/consolidation-provenance-check.d.ts +2 -2
  195. package/dist/consolidation-provenance-check.js +5 -5
  196. package/dist/consolidation-undo.d.ts +2 -2
  197. package/dist/consolidation-undo.js +3 -3
  198. package/dist/contradiction/index.d.ts +2 -2
  199. package/dist/contradiction/index.js +4 -4
  200. package/dist/conversation-index/backend.d.ts +1 -1
  201. package/dist/conversation-index/backend.js +2 -2
  202. package/dist/conversation-index/chunker.d.ts +1 -1
  203. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  204. package/dist/conversation-index/indexer.d.ts +1 -1
  205. package/dist/conversation-index/search.d.ts +1 -1
  206. package/dist/corpus-watermark.d.ts +1 -1
  207. package/dist/corpus-watermark.js +26 -26
  208. package/dist/day-summary.d.ts +1 -1
  209. package/dist/delinearize.d.ts +1 -1
  210. package/dist/direct-answer-wiring.d.ts +1 -1
  211. package/dist/direct-answer.d.ts +1 -1
  212. package/dist/embedding-fallback.d.ts +1 -1
  213. package/dist/enrichment/index.d.ts +1 -1
  214. package/dist/entity-retrieval.d.ts +2 -2
  215. package/dist/entity-retrieval.js +14 -14
  216. package/dist/entity-schema.d.ts +1 -1
  217. package/dist/explicit-capture.d.ts +8 -8
  218. package/dist/extraction-error-classification.d.ts +1 -1
  219. package/dist/extraction-faithfulness.d.ts +1 -1
  220. package/dist/extraction-judge-telemetry.d.ts +1 -1
  221. package/dist/extraction-judge-training.d.ts +1 -1
  222. package/dist/extraction-judge.d.ts +1 -1
  223. package/dist/extraction-liveness.d.ts +1 -1
  224. package/dist/extraction-source-grounding-rules.d.ts +1 -1
  225. package/dist/extraction-source-grounding.d.ts +15 -2
  226. package/dist/extraction-source-grounding.js +10 -1
  227. package/dist/extraction.d.ts +2 -15
  228. package/dist/extraction.js +5 -4
  229. package/dist/fallback-llm.d.ts +1 -1
  230. package/dist/graph-dashboard-diff.d.ts +1 -1
  231. package/dist/graph-dashboard-key.d.ts +1 -1
  232. package/dist/graph-dashboard-parser.d.ts +1 -1
  233. package/dist/graph-edge-reinforcement.d.ts +1 -1
  234. package/dist/graph-snapshot.d.ts +1 -1
  235. package/dist/graph.d.ts +1 -1
  236. package/dist/importance.d.ts +1 -1
  237. package/dist/importers/index.d.ts +1 -1
  238. package/dist/in-flight-reads.d.ts +1 -1
  239. package/dist/index.d.ts +19 -19
  240. package/dist/index.js +253 -246
  241. package/dist/intent.d.ts +1 -1
  242. package/dist/lcm/engine.d.ts +1 -1
  243. package/dist/lcm/engine.js +3 -3
  244. package/dist/lcm/index.d.ts +1 -1
  245. package/dist/lcm/index.js +6 -6
  246. package/dist/lcm/tools.d.ts +1 -1
  247. package/dist/lifecycle.d.ts +1 -1
  248. package/dist/live-connectors-runner.d.ts +1 -1
  249. package/dist/local-llm-helpers.d.ts +7 -0
  250. package/dist/local-llm-helpers.js +16 -0
  251. package/dist/local-llm-helpers.js.map +1 -0
  252. package/dist/local-llm.d.ts +3 -6
  253. package/dist/local-llm.js +2 -1
  254. package/dist/local-model-endpoint.d.ts +1 -1
  255. package/dist/maintenance/memory-governance.d.ts +1 -1
  256. package/dist/maintenance/memory-governance.js +14 -14
  257. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
  258. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +14 -14
  259. package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
  260. package/dist/maintenance/rebuild-memory-projection.js +15 -15
  261. package/dist/{maintenance-CL30NWtc.d.ts → maintenance-C6Pffz30.d.ts} +3 -3
  262. package/dist/mcp-memory-inspector-app.d.ts +10 -10
  263. package/dist/memory-action-policy.d.ts +1 -1
  264. package/dist/memory-cache.d.ts +1 -1
  265. package/dist/memory-corpus-version.js +2 -2
  266. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  267. package/dist/memory-projection-store.d.ts +1 -1
  268. package/dist/memory-provenance.d.ts +1 -1
  269. package/dist/memory-worth-outcomes.d.ts +2 -2
  270. package/dist/models-json.d.ts +1 -1
  271. package/dist/namespaces/migrate.d.ts +3 -3
  272. package/dist/namespaces/migrate.js +24 -24
  273. package/dist/namespaces/principal.d.ts +1 -1
  274. package/dist/namespaces/search.d.ts +1 -1
  275. package/dist/namespaces/search.js +9 -9
  276. package/dist/namespaces/storage.d.ts +3 -3
  277. package/dist/namespaces/storage.js +14 -14
  278. package/dist/native-knowledge.d.ts +1 -1
  279. package/dist/offline-sync-impression-drain.d.ts +1 -1
  280. package/dist/offline-sync-impression-drain.js +6 -5
  281. package/dist/operator-doctor-corpus.d.ts +1 -1
  282. package/dist/operator-doctor-corpus.js +29 -29
  283. package/dist/operator-doctor-replica.d.ts +1 -1
  284. package/dist/operator-doctor-replica.js +3 -3
  285. package/dist/operator-toolkit.d.ts +3 -3
  286. package/dist/operator-toolkit.js +39 -38
  287. package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
  288. package/dist/orchestration/maintenance.d.ts +4 -4
  289. package/dist/orchestration/maintenance.js +22 -21
  290. package/dist/{orchestrator-CKTCRwWV.d.ts → orchestrator-eQlmasno.d.ts} +72 -34
  291. package/dist/orchestrator.d.ts +8 -8
  292. package/dist/orchestrator.js +169 -162
  293. package/dist/page-versioning.js +3 -3
  294. package/dist/patterns-cli.d.ts +1 -1
  295. package/dist/{pipeline-B7wj4rRZ.d.ts → pipeline-CZGmAMQ2.d.ts} +1 -1
  296. package/dist/policy-runtime.d.ts +1 -1
  297. package/dist/proactive-contention.d.ts +1 -1
  298. package/dist/provenance.d.ts +1 -1
  299. package/dist/{qmd-q9tg4dHp.d.ts → qmd-DBj4MF8T.d.ts} +1 -1
  300. package/dist/qmd-preflight.d.ts +2 -2
  301. package/dist/qmd-recall-cache.d.ts +1 -1
  302. package/dist/qmd.d.ts +2 -2
  303. package/dist/qmd.js +4 -4
  304. package/dist/recall-concurrency-config.d.ts +1 -1
  305. package/dist/recall-disclosure-escalation.d.ts +1 -1
  306. package/dist/recall-explain-renderer.d.ts +1 -1
  307. package/dist/recall-explain-renderer.js +3 -3
  308. package/dist/recall-memory-map.d.ts +1 -1
  309. package/dist/recall-planner-llm.d.ts +1 -1
  310. package/dist/recall-state.d.ts +1 -1
  311. package/dist/recall-tag-filter.d.ts +1 -1
  312. package/dist/recall-timings.d.ts +1 -1
  313. package/dist/recall-xray-cli.d.ts +1 -1
  314. package/dist/recall-xray-cli.js +4 -4
  315. package/dist/recall-xray-renderer.d.ts +1 -1
  316. package/dist/recall-xray-renderer.js +3 -3
  317. package/dist/recall-xray.d.ts +1 -1
  318. package/dist/recall-xray.js +2 -2
  319. package/dist/replay/normalizers/chatgpt.d.ts +1 -1
  320. package/dist/replay/normalizers/claude.d.ts +1 -1
  321. package/dist/replay/normalizers/openclaw.d.ts +1 -1
  322. package/dist/replay/normalizers/shared.d.ts +1 -1
  323. package/dist/replay/runner.d.ts +1 -1
  324. package/dist/replay/types.d.ts +1 -1
  325. package/dist/replica-divergence.d.ts +1 -1
  326. package/dist/replica-divergence.js +2 -2
  327. package/dist/replica-peers-config.d.ts +1 -1
  328. package/dist/resolve-auth-token.d.ts +1 -1
  329. package/dist/resume-bundles.js +2 -2
  330. package/dist/retrieval-agents.d.ts +2 -2
  331. package/dist/retrieval-tiers.d.ts +1 -1
  332. package/dist/routing/engine.d.ts +1 -1
  333. package/dist/routing/store.d.ts +1 -1
  334. package/dist/salvage-envelope.d.ts +1 -1
  335. package/dist/{scope-profiles-CWDyglPM.d.ts → scope-profiles-S85lrsUn.d.ts} +1 -1
  336. package/dist/search/embed-helper.d.ts +1 -1
  337. package/dist/search/factory.d.ts +1 -1
  338. package/dist/search/factory.js +8 -8
  339. package/dist/search/index.d.ts +1 -1
  340. package/dist/search/index.js +12 -12
  341. package/dist/search/lancedb-backend.d.ts +1 -1
  342. package/dist/search/meilisearch-backend.d.ts +1 -1
  343. package/dist/search/noop-backend.d.ts +1 -1
  344. package/dist/search/orama-backend.d.ts +1 -1
  345. package/dist/search/port.d.ts +1 -1
  346. package/dist/search/remote-backend.d.ts +1 -1
  347. package/dist/{semantic-consolidation-BUE3deLn.d.ts → semantic-consolidation-DVzDcV6x.d.ts} +1 -1
  348. package/dist/semantic-consolidation.d.ts +2 -2
  349. package/dist/semantic-consolidation.js +17 -18
  350. package/dist/semantic-rule-promotion.js +14 -14
  351. package/dist/semantic-rule-verifier.d.ts +1 -1
  352. package/dist/semantic-rule-verifier.js +14 -14
  353. package/dist/{service-CXgM0bQG.d.ts → service-C2M-wD4W.d.ts} +2 -2
  354. package/dist/session-observer-bands.d.ts +1 -1
  355. package/dist/session-observer-state.d.ts +1 -1
  356. package/dist/shared-context/manager.d.ts +1 -1
  357. package/dist/signal.d.ts +1 -1
  358. package/dist/{storage-DysJq-XH.d.ts → storage-dyBC3Q84.d.ts} +1 -1
  359. package/dist/storage.d.ts +2 -2
  360. package/dist/storage.js +13 -13
  361. package/dist/summarizer.d.ts +1 -1
  362. package/dist/summarizer.js +3 -2
  363. package/dist/summary-snapshot.d.ts +1 -1
  364. package/dist/temporal-supersession.d.ts +2 -2
  365. package/dist/temporal-timeline-recall.d.ts +1 -1
  366. package/dist/temporal-validity.d.ts +1 -1
  367. package/dist/threading.d.ts +1 -1
  368. package/dist/tier-migration.d.ts +2 -2
  369. package/dist/tier-routing.d.ts +1 -1
  370. package/dist/tokens.js +2 -2
  371. package/dist/topics.d.ts +1 -1
  372. package/dist/transcript.d.ts +1 -1
  373. package/dist/transfer/backup.js +2 -2
  374. package/dist/transfer/capsule-export.js +2 -2
  375. package/dist/transfer/capsule-import.js +5 -5
  376. package/dist/trust-score-stage.d.ts +1 -1
  377. package/dist/trust-score.d.ts +1 -1
  378. package/dist/{types-aPPzhnjT.d.ts → types-D63ZI--P.d.ts} +23 -2
  379. package/dist/types.d.ts +1 -1
  380. package/dist/types.js +1 -1
  381. package/dist/utility-runtime.d.ts +1 -1
  382. package/dist/verified-recall.js +14 -14
  383. package/dist/write-envelope.d.ts +1 -1
  384. package/package.json +2 -2
  385. package/src/access-boundary.ts +3 -0
  386. package/src/access-cli.test.ts +93 -0
  387. package/src/access-cli.ts +56 -2
  388. package/src/access-extraction-force-flush.ts +177 -0
  389. package/src/access-http-extraction-force-flush.test.ts +132 -0
  390. package/src/access-http-lcm-compaction.ts +99 -22
  391. package/src/access-http-lifecycle-flush.ts +81 -0
  392. package/src/access-http.test.ts +227 -0
  393. package/src/access-http.ts +33 -40
  394. package/src/access-mcp-output-schemas.ts +6 -0
  395. package/src/access-mcp.test.ts +40 -0
  396. package/src/access-mcp.ts +32 -1
  397. package/src/access-observe-helpers.ts +180 -0
  398. package/src/access-observe-write-surface.ts +78 -19
  399. package/src/access-operations-batch.ts +2 -1
  400. package/src/access-schema-pi.test.ts +17 -0
  401. package/src/access-schema.ts +28 -11
  402. package/src/access-service-helpers.ts +46 -0
  403. package/src/access-service-observe-lcm-parity.test.ts +781 -31
  404. package/src/access-service-observe-scope.test.ts +88 -0
  405. package/src/access-service.ts +46 -128
  406. package/src/access-surface-catalog.test.ts +32 -0
  407. package/src/access-surface-catalog.ts +2 -0
  408. package/src/buffer-session.test.ts +148 -0
  409. package/src/buffer-turn-helpers.ts +152 -0
  410. package/src/buffer.ts +126 -201
  411. package/src/connectors/index.ts +1 -1
  412. package/src/connectors/label.ts +18 -0
  413. package/src/correction/correction-access-wiring.ts +79 -27
  414. package/src/correction/correction-executor.test.ts +542 -1
  415. package/src/correction/correction-executor.ts +309 -89
  416. package/src/correction/correction-planner.test.ts +35 -1
  417. package/src/correction/correction-planner.ts +50 -3
  418. package/src/correction/correction-service.ts +12 -7
  419. package/src/correction/correction-storage-integration.test.ts +172 -1
  420. package/src/correction/passive-capture.test.ts +35 -0
  421. package/src/correction/passive-capture.ts +17 -3
  422. package/src/extraction-source-grounding.ts +55 -1
  423. package/src/extraction-timeout.test.ts +51 -0
  424. package/src/extraction.ts +64 -90
  425. package/src/local-llm-headers-timeout.test.ts +48 -0
  426. package/src/local-llm-helpers.ts +58 -0
  427. package/src/local-llm.ts +62 -58
  428. package/src/orchestration/extraction-run-helpers.ts +309 -0
  429. package/src/orchestration/extraction-run.test.ts +350 -7
  430. package/src/orchestration/extraction-run.ts +327 -250
  431. package/src/orchestration/recall-result-formatter.ts +21 -2
  432. package/src/orchestration/recall-search-pipeline.test.ts +34 -0
  433. package/src/orchestration/recall-search-pipeline.ts +9 -1
  434. package/src/orchestration/session-context.ts +193 -18
  435. package/src/orchestration/turn-ingestion.ts +61 -11
  436. package/src/orchestrator-flush.test.ts +511 -5
  437. package/src/orchestrator.ts +8 -6
  438. package/src/recall-source-connector-label.test.ts +300 -0
  439. package/src/types.ts +3 -3
  440. package/dist/chunk-3UXOZBHV.js +0 -20
  441. package/dist/chunk-3UXOZBHV.js.map +0 -1
  442. package/dist/chunk-4A6YGWQN.js.map +0 -1
  443. package/dist/chunk-4WKA6I65.js.map +0 -1
  444. package/dist/chunk-4Z4XNEWZ.js.map +0 -1
  445. package/dist/chunk-6FUPCJUL.js.map +0 -1
  446. package/dist/chunk-B6JDYXL7.js.map +0 -1
  447. package/dist/chunk-G5R3D5UP.js.map +0 -1
  448. package/dist/chunk-GBJ4RDFR.js.map +0 -1
  449. package/dist/chunk-HUHX2OCX.js.map +0 -1
  450. package/dist/chunk-IYZ5K7MU.js.map +0 -1
  451. package/dist/chunk-LGHKJABJ.js.map +0 -1
  452. package/dist/chunk-NHWB6HG2.js.map +0 -1
  453. package/dist/chunk-PHWUFPCO.js.map +0 -1
  454. package/dist/chunk-RPW2NOU6.js.map +0 -1
  455. package/dist/chunk-SPJXKAVF.js.map +0 -1
  456. package/dist/chunk-YNQBRLC5.js.map +0 -1
  457. package/dist/chunk-YTSNAUXN.js.map +0 -1
  458. /package/dist/{capsule-crypto-GWVG7LGC.js.map → access-extraction-force-flush.js.map} +0 -0
  459. /package/dist/{capsule-merge-5KKJQBWQ.js.map → capsule-merge-2H2IUTBT.js.map} +0 -0
  460. /package/dist/{chunk-LEPOP46W.js.map → chunk-227UFSEQ.js.map} +0 -0
  461. /package/dist/{chunk-I5NLEENJ.js.map → chunk-27HHNYSQ.js.map} +0 -0
  462. /package/dist/{chunk-2SA56WMI.js.map → chunk-2LTDWSR6.js.map} +0 -0
  463. /package/dist/{chunk-OWHERGF2.js.map → chunk-2NLLXCJG.js.map} +0 -0
  464. /package/dist/{chunk-P5PXWTW7.js.map → chunk-2Q4JJ3FZ.js.map} +0 -0
  465. /package/dist/{chunk-H5CPS5JP.js.map → chunk-35IVNNRK.js.map} +0 -0
  466. /package/dist/{chunk-LBOD4U5B.js.map → chunk-3EQ2XB3W.js.map} +0 -0
  467. /package/dist/{chunk-2EUVEDF5.js.map → chunk-5WZVQRHV.js.map} +0 -0
  468. /package/dist/{chunk-ALSGMEJR.js.map → chunk-65ZPVYTA.js.map} +0 -0
  469. /package/dist/{chunk-GIBMDSJ2.js.map → chunk-6P7MTSU5.js.map} +0 -0
  470. /package/dist/{chunk-5VQJBH2G.js.map → chunk-6TAUHL33.js.map} +0 -0
  471. /package/dist/{chunk-WVO4G37W.js.map → chunk-7TEZUUGM.js.map} +0 -0
  472. /package/dist/{chunk-MJCGLM25.js.map → chunk-7VUAG236.js.map} +0 -0
  473. /package/dist/{chunk-CZRYLSSW.js.map → chunk-AJL6NNX6.js.map} +0 -0
  474. /package/dist/{chunk-66772WBP.js.map → chunk-AQWVJURR.js.map} +0 -0
  475. /package/dist/{chunk-RKNJBZ55.js.map → chunk-AU7Q3LSC.js.map} +0 -0
  476. /package/dist/{chunk-M3C2V3PV.js.map → chunk-CJDNT45S.js.map} +0 -0
  477. /package/dist/{chunk-D2ANTDGO.js.map → chunk-E6BMSH7U.js.map} +0 -0
  478. /package/dist/{chunk-CKMO4RDY.js.map → chunk-EMDLM3LW.js.map} +0 -0
  479. /package/dist/{chunk-RGIWINDN.js.map → chunk-FHBITMRY.js.map} +0 -0
  480. /package/dist/{chunk-FDAMS4PK.js.map → chunk-G2YQ57YO.js.map} +0 -0
  481. /package/dist/{chunk-6U7F52DE.js.map → chunk-HFQQWAMS.js.map} +0 -0
  482. /package/dist/{chunk-5W4ZLBEZ.js.map → chunk-HKPJPOW7.js.map} +0 -0
  483. /package/dist/{chunk-JCBWCYEJ.js.map → chunk-IGWFKW4B.js.map} +0 -0
  484. /package/dist/{chunk-AITCS2RC.js.map → chunk-IJ7HK452.js.map} +0 -0
  485. /package/dist/{chunk-D3LMYTBV.js.map → chunk-J7WZUL2K.js.map} +0 -0
  486. /package/dist/{chunk-5W7CTZ2E.js.map → chunk-KQAFEZQX.js.map} +0 -0
  487. /package/dist/{chunk-Z54EM5YZ.js.map → chunk-MAXVH44E.js.map} +0 -0
  488. /package/dist/{chunk-WZFAPHIK.js.map → chunk-MU7ZHSZE.js.map} +0 -0
  489. /package/dist/{chunk-AZ5BTEKX.js.map → chunk-NQUF7XKR.js.map} +0 -0
  490. /package/dist/{chunk-W4FBGYGK.js.map → chunk-NRV4Y3PM.js.map} +0 -0
  491. /package/dist/{chunk-62U4J2GN.js.map → chunk-ODGOP7P2.js.map} +0 -0
  492. /package/dist/{chunk-QJAQNXWI.js.map → chunk-ONHRRJZM.js.map} +0 -0
  493. /package/dist/{chunk-ACXPX4AG.js.map → chunk-OPBTPRGY.js.map} +0 -0
  494. /package/dist/{chunk-XOZ4ALGB.js.map → chunk-QDTZ2HF7.js.map} +0 -0
  495. /package/dist/{chunk-ZPSVBSOF.js.map → chunk-QMWFQBIL.js.map} +0 -0
  496. /package/dist/{chunk-W5EG6LE3.js.map → chunk-THCPRMRF.js.map} +0 -0
  497. /package/dist/{chunk-VI2JQPNQ.js.map → chunk-U7QYBSQJ.js.map} +0 -0
  498. /package/dist/{chunk-TH2LSRMG.js.map → chunk-UORKJ34C.js.map} +0 -0
  499. /package/dist/{chunk-K5GB36ME.js.map → chunk-VMZ56EE3.js.map} +0 -0
  500. /package/dist/{chunk-RMMVQQA6.js.map → chunk-WDISJRMG.js.map} +0 -0
  501. /package/dist/{chunk-UVYI6VIX.js.map → chunk-X7Y7WX73.js.map} +0 -0
  502. /package/dist/{chunk-CVILPI77.js.map → chunk-XOQSEF7X.js.map} +0 -0
  503. /package/dist/{chunk-YTQNQ4KB.js.map → chunk-YX5LN6JR.js.map} +0 -0
  504. /package/dist/{chunk-IC6CBHCA.js.map → chunk-Z7XKUWYS.js.map} +0 -0
@@ -30,6 +30,7 @@ import type { VerifiedEpisodeResult } from "../verified-recall.js";
30
30
  import type { VerifiedSemanticRuleResult } from "../semantic-rule-verifier.js";
31
31
  import type { WorkProductLedgerSearchResult } from "../work-product-ledger.js";
32
32
  import { trustResultFor, type TrustStageResultItem } from "../trust-score-stage.js";
33
+ import { CONNECTOR_ID_PATTERN, CONNECTOR_LABEL_MAX_LENGTH } from "../connectors/label.js";
33
34
  import type {
34
35
  ContinuityIncidentRecord,
35
36
  IdentityInjectionMode,
@@ -38,6 +39,22 @@ import type {
38
39
  RecallPlanMode,
39
40
  } from "../types.js";
40
41
 
42
+ /**
43
+ * Issue #2183 — render the persisted `sourceConnector` carried on the result
44
+ * (hydrated where the memory is loaded) as `[agent: <connector>]`. The value
45
+ * reaches model-visible recall context, so it is validated against the canonical
46
+ * persisted-ID charset (CONNECTOR_ID_PATTERN — IDs the system accepts,
47
+ * including '.'/'_', keep their label) and TRUNCATED past CONNECTOR_LABEL_MAX
48
+ * with an explicit marker (attribution survives; suppression would lose the
49
+ * exact signal this PR adds). One resolver at the single render site.
50
+ */
51
+ function renderConnectorLabel(connector: string | undefined): string | null {
52
+ if (!connector || !CONNECTOR_ID_PATTERN.test(connector)) return null;
53
+ return connector.length <= CONNECTOR_LABEL_MAX_LENGTH
54
+ ? connector
55
+ : `${connector.slice(0, CONNECTOR_LABEL_MAX_LENGTH - 1)}…`;
56
+ }
57
+
41
58
  // ---------------------------------------------------------------------------
42
59
  // Identity injection mode helpers (moved verbatim from orchestrator.ts)
43
60
  // ---------------------------------------------------------------------------
@@ -211,14 +228,16 @@ export class RecallResultFormatter {
211
228
  const head = `[${i + 1}] ${source} (score: ${r.score.toFixed(3)})\n${snippet}`;
212
229
  const handle = handleByIndex.get(i);
213
230
  const withHandle = handle ? `${head.trimEnd()} ${handle}` : head.trimEnd();
231
+ const connectorLabel = renderConnectorLabel(r.sourceConnector);
232
+ const withConnector = connectorLabel ? `${withHandle} [agent: ${connectorLabel}]` : withHandle;
214
233
  if (hedgeMap) {
215
234
  const item = trustResultFor(hedgeMap, r);
216
235
  if (item) {
217
236
  const hedge = renderEpistemicHedge(item.trust);
218
- if (hedge.length > 0) return `${withHandle} ${hedge}`;
237
+ if (hedge.length > 0) return `${withConnector} ${hedge}`;
219
238
  }
220
239
  }
221
- return withHandle;
240
+ return withConnector;
222
241
  });
223
242
  return { heading: `## ${title}`, entries };
224
243
  }
@@ -70,6 +70,40 @@ test("recall safety keeps same relative path distinct across namespaces", async
70
70
  }
71
71
  });
72
72
 
73
+ test("recall safety derives sourceConnector exclusively from the hydrated memory (#2183)", async () => {
74
+ const memoryDir = await mkdtemp(path.join(os.tmpdir(), "remnic-conn-prov-"));
75
+ try {
76
+ const coordinator = await makeCoordinator(memoryDir);
77
+ // Both results arrive carrying an UNTRUSTED sourceConnector (e.g. a remote
78
+ // search backend casting arbitrary response objects). One's memory carries
79
+ // a real connector; the other's memory is connectorless.
80
+ const has = { ...result("default", "facts/has.md"), sourceConnector: "untrusted" };
81
+ const none = { ...result("default", "facts/none.md"), sourceConnector: "untrusted" };
82
+ const memHas = {
83
+ path: "facts/has.md",
84
+ content: "facts/has.md",
85
+ frontmatter: { status: "active", memoryKind: "fact", created: "2026-07-19T00:00:00.000Z", updated: "2026-07-19T00:00:00.000Z", sourceConnector: "trusted-pi" } as unknown as MemoryFile["frontmatter"],
86
+ };
87
+ const memNone = {
88
+ path: "facts/none.md",
89
+ content: "facts/none.md",
90
+ frontmatter: { status: "active", memoryKind: "fact", created: "2026-07-19T00:00:00.000Z", updated: "2026-07-19T00:00:00.000Z" } as unknown as MemoryFile["frontmatter"],
91
+ };
92
+ const memoryByPath = new Map<string, MemoryFile>([
93
+ ["default\0facts/has.md", memHas],
94
+ ["default\0facts/none.md", memNone],
95
+ ]);
96
+ const safe = coordinator.filterSearchResultsByRecallSafety([has, none], memoryByPath);
97
+ const byPath = new Map(safe.map((r) => [r.path, r.sourceConnector]));
98
+ assert.equal(byPath.get("facts/has.md"), "trusted-pi", "an untrusted result-supplied value is overwritten by the memory's connector");
99
+ assert.equal(byPath.get("facts/none.md"), undefined, "an untrusted value is cleared when the memory is connectorless");
100
+ // The shared/cached input objects are never mutated.
101
+ assert.equal(has.sourceConnector, "untrusted", "the input result object is not mutated (copy semantics, no cross-recall leak)");
102
+ } finally {
103
+ await rm(memoryDir, { recursive: true, force: true });
104
+ }
105
+ });
106
+
73
107
  function scopedCandidatesStub(
74
108
  seed: QmdSearchResult[],
75
109
  ): RecallSearchPipelineDeps["searchScopedMemoryCandidates"] {
@@ -1339,7 +1339,15 @@ export class RecallSearchPipelineCoordinator {
1339
1339
  continue;
1340
1340
  }
1341
1341
  }
1342
- filtered.push(r);
1342
+ // Issue #2183 — derive sourceConnector EXCLUSIVELY from the hydrated
1343
+ // memory, on a copy so a shared/cached result object (global QMD cache)
1344
+ // is never mutated across recalls and a result-supplied value (e.g.
1345
+ // RemoteSearchBackend casting arbitrary responses) cannot pose as trusted
1346
+ // provenance. Connectorless memory (or no memory) → cleared (undefined).
1347
+ filtered.push({
1348
+ ...r,
1349
+ sourceConnector: memory ? memory.frontmatter.sourceConnector : undefined,
1350
+ });
1343
1351
  }
1344
1352
  if (lifecycleFilteredCount > 0) {
1345
1353
  log.debug(
@@ -11,6 +11,7 @@
11
11
  * Behavior-preserving move (late-binding selfDeps wiring, seams 18–27).
12
12
  */
13
13
 
14
+ import { abortError, throwIfAborted } from "../abort-error.js";
14
15
  import { SmartBuffer } from "../buffer.js";
15
16
  import { resolveNamespaceCapabilities } from "../capabilities.js";
16
17
  import { combineNamespaces, resolveCodingNamespaceOverlay } from "../coding/coding-namespace.js";
@@ -21,9 +22,11 @@ import { StorageManager } from "../index.js";
21
22
  import { LocalLlmClient } from "../local-llm.js";
22
23
  import { log } from "../logger.js";
23
24
  import { canWriteNamespace, defaultNamespaceForPrincipal, recallNamespacesForPrincipal, resolvePrincipal } from "../namespaces/principal.js";
25
+ import { ExtractionDeadlineError } from "./extraction-run.js";
24
26
  import type { ExtractionRunResult } from "./extraction-run.js";
25
27
  import type { EntitySynthesisCoordinator } from "./entity-synthesis-coordinator.js";
26
28
  import type { BufferTurn, CodingContext, DaySummaryResult, MemoryFile, PluginConfig } from "../types.js";
29
+ import type { ResolvedScopeProfilePlan } from "../namespaces/scope-profiles.js";
27
30
  import {
28
31
  Orchestrator,
29
32
  } from "../orchestrator.js";
@@ -48,10 +51,12 @@ export interface SessionContextDeps {
48
51
  options?: {
49
52
  skipDedupeCheck?: boolean;
50
53
  clearBufferAfterExtraction?: boolean;
54
+ clearMatchingTurns?: boolean;
51
55
  skipCharThreshold?: boolean;
52
56
  skipUserTurnThreshold?: boolean;
53
57
  extractionDeadlineMs?: number;
54
58
  failOnExtractionFailure?: boolean;
59
+ onDurableCommit?: () => void;
55
60
  forceExtractionAttempt?: boolean;
56
61
  onTaskSettled?: (
57
62
  error?: unknown,
@@ -73,6 +78,7 @@ export interface SessionContextDeps {
73
78
  * authenticated principal instead of `resolvePrincipal(sessionKey)`.
74
79
  */
75
80
  principalOverride?: string;
81
+ scopeProfileWritePlan?: ResolvedScopeProfilePlan | null;
76
82
  },
77
83
  ): Promise<void>;
78
84
  resolvePrincipal(sessionKey?: string): string | undefined;
@@ -82,6 +88,89 @@ export interface SessionContextDeps {
82
88
  readonly orchestratorSelf: Orchestrator;
83
89
  }
84
90
 
91
+
92
+ export interface SessionFlushOptions {
93
+ reason: string;
94
+ abortSignal?: AbortSignal;
95
+ bufferKey?: string;
96
+ clearMatchingTurns?: boolean;
97
+ extractionDeadlineMs?: number;
98
+ writeNamespaceOverride?: string;
99
+ /** Called at the first durable extraction commit in this flush. */
100
+ onCommitted?: () => void;
101
+ failOnExtractionFailure?: boolean;
102
+ /** Resolved profile plan from access scope resolution; avoids recomputing from shared session context. */
103
+ scopeProfileWritePlan?: ResolvedScopeProfilePlan | null;
104
+ principalOverride?: string;
105
+ }
106
+
107
+ /** Scoped flushes must never claim an opaque buffer without trusted ingestion ownership. */
108
+ export class SessionOwnershipError extends Error {
109
+ constructor(message: string) {
110
+ super(message);
111
+ this.name = "SessionOwnershipError";
112
+ }
113
+ }
114
+
115
+ const MAX_SET_TIMEOUT_MS = 2_147_483_647;
116
+
117
+ export async function awaitSessionFlushPhase<T>(
118
+ task: () => Promise<T>,
119
+ options: Pick<SessionFlushOptions, "abortSignal" | "extractionDeadlineMs" | "reason"> & {
120
+ deadlineStage?: string;
121
+ onDeadline?: () => void;
122
+ },
123
+ ): Promise<T> {
124
+ const abortMessage =
125
+ options.reason === "access_force_flush" ? "extraction force-flush aborted" : "session flush aborted";
126
+ throwIfAborted(options.abortSignal, abortMessage);
127
+ const deadline = options.extractionDeadlineMs;
128
+ if (typeof deadline === "number" && Date.now() >= deadline) {
129
+ options.onDeadline?.();
130
+ throw new ExtractionDeadlineError(options.deadlineStage ?? "before_buffer_flush");
131
+ }
132
+
133
+ const taskPromise = Promise.resolve().then(task);
134
+ if (!options.abortSignal && typeof deadline !== "number") return taskPromise;
135
+
136
+ let abortHandler: (() => void) | undefined;
137
+ let deadlineTimer: ReturnType<typeof setTimeout> | undefined;
138
+ const abortPromise =
139
+ options.abortSignal === undefined
140
+ ? undefined
141
+ : new Promise<T>((_resolve, reject) => {
142
+ abortHandler = () => reject(abortError(abortMessage));
143
+ options.abortSignal?.addEventListener("abort", abortHandler, { once: true });
144
+ });
145
+ const deadlinePromise =
146
+ typeof deadline !== "number"
147
+ ? undefined
148
+ : new Promise<T>((_resolve, reject) => {
149
+ const schedule = (): void => {
150
+ const remainingMs = deadline - Date.now();
151
+ if (remainingMs <= 0) {
152
+ options.onDeadline?.();
153
+ reject(new ExtractionDeadlineError(options.deadlineStage ?? "before_buffer_flush"));
154
+ return;
155
+ }
156
+ deadlineTimer = setTimeout(schedule, Math.min(remainingMs, MAX_SET_TIMEOUT_MS));
157
+ deadlineTimer.unref?.();
158
+ };
159
+ schedule();
160
+ });
161
+ const races: Promise<T>[] = [taskPromise];
162
+ if (abortPromise) races.push(abortPromise);
163
+ if (deadlinePromise) races.push(deadlinePromise);
164
+ try {
165
+ return await Promise.race(races);
166
+ } finally {
167
+ if (abortHandler && options.abortSignal) {
168
+ options.abortSignal.removeEventListener("abort", abortHandler);
169
+ }
170
+ if (deadlineTimer) clearTimeout(deadlineTimer);
171
+ }
172
+ }
173
+
85
174
  export class SessionContextCoordinator {
86
175
  constructor(
87
176
  private readonly deps: SessionContextDeps,
@@ -316,11 +405,7 @@ export class SessionContextCoordinator {
316
405
 
317
406
  async flushSession(
318
407
  sessionKey: string,
319
- options: {
320
- reason: string;
321
- abortSignal?: AbortSignal;
322
- bufferKey?: string;
323
- },
408
+ options: SessionFlushOptions,
324
409
  ): Promise<void> {
325
410
  // Force any pending debounced buffer save to land durably BEFORE we read
326
411
  // and (via clearBufferAfterExtraction below) clear turns (issue #1909, PR
@@ -334,14 +419,20 @@ export class SessionContextCoordinator {
334
419
  // extraction leaves them on disk for re-extraction on next startup.
335
420
  // Durability-preserving AND fail-closed: pass throwOnFailure so a failed
336
421
  // durable save stops this lifecycle drain BEFORE any extraction runs
337
- // (issue #1909, PR #2016). flushPendingSave still retains the pending state
338
- // and re-arms a background retry on write failure, but it now rethrows so
339
- // flushSession rejects instead of clearing turns behind a non-durable save.
340
- // Without this, a force-drain could queue extraction with
341
- // clearBufferAfterExtraction on turns that never reached disk; if extraction
342
- // then failed and the host exited, the turn was lost.
422
+ // flushPendingSave retains pending state and re-arms a retry on failure.
343
423
  if (typeof this.deps.buffer.flushPendingSave === "function") {
344
- await this.deps.buffer.flushPendingSave({ throwOnFailure: true });
424
+ await awaitSessionFlushPhase(
425
+ () => this.deps.buffer.flushPendingSave!({ throwOnFailure: true }),
426
+ options,
427
+ );
428
+ } else {
429
+ throwIfAborted(
430
+ options.abortSignal,
431
+ options.reason === "access_force_flush" ? "extraction force-flush aborted" : "session flush aborted",
432
+ );
433
+ if (typeof options.extractionDeadlineMs === "number" && Date.now() >= options.extractionDeadlineMs) {
434
+ throw new ExtractionDeadlineError("before_buffer_flush");
435
+ }
345
436
  }
346
437
  const explicitBufferKey =
347
438
  typeof options.bufferKey === "string" && options.bufferKey.length > 0
@@ -353,7 +444,10 @@ export class SessionContextCoordinator {
353
444
  sessionKey.length === 0 ||
354
445
  typeof this.deps.buffer.findBufferKeysForSession !== "function"
355
446
  ? []
356
- : await this.deps.buffer.findBufferKeysForSession(sessionKey);
447
+ : await awaitSessionFlushPhase(
448
+ () => this.deps.buffer.findBufferKeysForSession!(sessionKey),
449
+ options,
450
+ );
357
451
  const bufferKeys = explicitBufferKey
358
452
  ? [explicitBufferKey]
359
453
  : discoveredBufferKeys.length > 0
@@ -361,20 +455,101 @@ export class SessionContextCoordinator {
361
455
  : typeof sessionKey === "string" && sessionKey.length > 0
362
456
  ? [sessionKey]
363
457
  : ["default"];
458
+ const namespacesEnabled =
459
+ this.deps.config === undefined ||
460
+ resolveNamespaceCapabilities(this.deps.config).namespaces === true;
461
+ const scopedRequest =
462
+ typeof options.writeNamespaceOverride === "string" ||
463
+ typeof options.principalOverride === "string";
464
+ const ownershipEnforced = namespacesEnabled && scopedRequest;
465
+ const ownerPrincipal =
466
+ typeof options.principalOverride === "string" && options.principalOverride.trim().length > 0
467
+ ? options.principalOverride.trim()
468
+ : undefined;
469
+ const resolvedSessionPrincipal =
470
+ ownershipEnforced && ownerPrincipal !== undefined && this.deps.config
471
+ ? resolvePrincipal(sessionKey, this.deps.config)
472
+ : undefined;
473
+ const opaqueScopedSession =
474
+ ownershipEnforced &&
475
+ ownerPrincipal !== undefined &&
476
+ (resolvedSessionPrincipal === undefined || resolvedSessionPrincipal === "default");
477
+ const belongsToSession = (turn: BufferTurn): boolean => {
478
+ if (turn.sessionKey !== sessionKey) return false;
479
+ if (!ownershipEnforced || ownerPrincipal === undefined) return true;
480
+ if (turn.sessionOwnerPrincipal === ownerPrincipal) return true;
481
+ return (
482
+ turn.sessionOwnerPrincipal === undefined &&
483
+ this.deps.config !== undefined &&
484
+ resolvePrincipal(turn.sessionKey, this.deps.config) === ownerPrincipal
485
+ );
486
+ };
487
+ if (
488
+ opaqueScopedSession &&
489
+ bufferKeys.some((bufferKey) =>
490
+ this.deps.buffer
491
+ .getTurns(bufferKey)
492
+ .some((turn) => turn.sessionKey === sessionKey && turn.sessionOwnerPrincipal === undefined),
493
+ )
494
+ ) {
495
+ throw new SessionOwnershipError(
496
+ `session ${sessionKey} has buffered turns without trusted ownership`,
497
+ );
498
+ }
364
499
  for (const bufferKey of bufferKeys) {
365
500
  const turns = this.deps.buffer.getTurns(bufferKey);
366
- if (turns.length === 0) continue;
367
- await new Promise<void>((resolve, reject) => {
368
- void this.deps.queueBufferedExtraction(turns, "trigger_mode", {
501
+ const turnsForSession = scopedRequest ? turns.filter(belongsToSession) : turns;
502
+ if (turnsForSession.length === 0) continue;
503
+ const retainedTurnsForOtherSessions =
504
+ scopedRequest && typeof this.deps.buffer.getRetainedDeferredTurns === "function"
505
+ ? this.deps.buffer
506
+ .getRetainedDeferredTurns(bufferKey)
507
+ .filter((turn) => !belongsToSession(turn))
508
+ : [];
509
+ try {
510
+ await new Promise<void>((resolve, reject) => {
511
+ void this.deps.queueBufferedExtraction(turnsForSession, "trigger_mode", {
369
512
  bufferKey,
370
513
  clearBufferAfterExtraction: true,
371
514
  skipDedupeCheck: true,
515
+ skipCharThreshold: true,
516
+ skipUserTurnThreshold: true,
517
+ failOnExtractionFailure: options.failOnExtractionFailure === true,
372
518
  forceExtractionAttempt: true,
373
519
  abortSignal: options.abortSignal,
520
+ extractionDeadlineMs: options.extractionDeadlineMs,
521
+ writeNamespaceOverride: options.writeNamespaceOverride,
522
+ principalOverride: options.principalOverride,
523
+ scopeProfileWritePlan: options.scopeProfileWritePlan,
524
+ clearMatchingTurns: options.clearMatchingTurns ?? scopedRequest,
525
+ onDurableCommit: options.onCommitted,
374
526
  onTaskSettled: (error) => (error ? reject(error) : resolve()),
375
527
  })
376
- .catch(reject);
377
- });
528
+ .catch(reject);
529
+ });
530
+ } finally {
531
+ if (
532
+ retainedTurnsForOtherSessions.length > 0 &&
533
+ typeof this.deps.buffer.retainDeferredTurns === "function"
534
+ ) {
535
+ const retainedAfterExtraction = this.deps.buffer.getRetainedDeferredTurns(bufferKey);
536
+ await this.deps.buffer
537
+ .retainDeferredTurns(
538
+ bufferKey,
539
+ [
540
+ ...retainedAfterExtraction.filter((turn) => belongsToSession(turn)),
541
+ ...retainedTurnsForOtherSessions,
542
+ ],
543
+ 10,
544
+ )
545
+ .catch((error: unknown) => {
546
+ log.warn(
547
+ `session flush could not restore retained turns for other sessions in ${bufferKey}`,
548
+ error,
549
+ );
550
+ });
551
+ }
552
+ }
378
553
  }
379
554
  }
380
555
 
@@ -17,6 +17,7 @@
17
17
  */
18
18
 
19
19
  import { createHash, randomBytes } from "node:crypto";
20
+ import { abortError } from "../abort-error.js";
20
21
  import { SmartBuffer } from "../buffer.js";
21
22
  import type { ImportTurn } from "../bulk-import/types.js";
22
23
  import { resolvePipelineProcessingCapabilities, resolveRecallAuxiliaryCapabilities } from "../capabilities.js";
@@ -28,13 +29,18 @@ import { StorageManager } from "../index.js";
28
29
  import { LcmEngine } from "../lcm/index.js";
29
30
  import { log } from "../logger.js";
30
31
  import { ExtractionQueueCoordinator } from "./extraction-queue-coordinator.js";
31
- import { ExtractionRunCoordinator, type ExtractionRunResult } from "./extraction-run.js";
32
+ import {
33
+ ExtractionDeadlineError,
34
+ ExtractionRunCoordinator,
35
+ type ExtractionRunResult,
36
+ } from "./extraction-run.js";
32
37
  import { stripHandles } from "../recall-handles.js";
33
38
  import { type ReplayTurn, normalizeReplaySessionKey } from "../replay/types.js";
34
39
  import { SessionObserverState } from "../session-observer-state.js";
35
40
  import { CODEX_THREAD_KEY_PREFIX } from "../thread-key.js";
36
41
  import { TranscriptManager } from "../transcript.js";
37
42
  import type { BufferTurn, PluginConfig, SourceConnectorProvenance } from "../types.js";
43
+ import type { ResolvedScopeProfilePlan } from "../namespaces/scope-profiles.js";
38
44
  import {
39
45
  BulkImportBatchPartialFailureError,
40
46
  splitTurnsBySourceValidAt,
@@ -64,10 +70,12 @@ export interface TurnIngestionDeps {
64
70
  options?: {
65
71
  skipDedupeCheck?: boolean;
66
72
  clearBufferAfterExtraction?: boolean;
73
+ clearMatchingTurns?: boolean;
67
74
  skipCharThreshold?: boolean;
68
75
  skipUserTurnThreshold?: boolean;
69
76
  extractionDeadlineMs?: number;
70
77
  failOnExtractionFailure?: boolean;
78
+ onDurableCommit?: () => void;
71
79
  forceExtractionAttempt?: boolean;
72
80
  onTaskSettled?: (
73
81
  error?: unknown,
@@ -88,6 +96,7 @@ export interface TurnIngestionDeps {
88
96
  * `runExtraction` so access `observe` can record provenance under the
89
97
  * authenticated principal instead of `resolvePrincipal(sessionKey)`.
90
98
  */
99
+ scopeProfileWritePlan?: ResolvedScopeProfilePlan | null;
91
100
  principalOverride?: string;
92
101
  },
93
102
  ): Promise<void>;
@@ -208,6 +217,12 @@ export class TurnIngestionCoordinator {
208
217
  * `principalOverride` (issue #570 PR 4).
209
218
  */
210
219
  principalOverride?: string;
220
+ /**
221
+ * Persist the authenticated principal that owns the replay session.
222
+ * Access observe supplies this from the transport auth boundary; replay
223
+ * and import callers leave it unset.
224
+ */
225
+ sessionOwnerPrincipal?: string;
211
226
  } = {},
212
227
  ): Promise<void> {
213
228
  if (!Array.isArray(turns) || turns.length === 0) return;
@@ -234,6 +249,7 @@ export class TurnIngestionCoordinator {
234
249
  timestamp: turn.timestamp,
235
250
  sourceValidAt: turn.sourceValidAt,
236
251
  sessionKey: key,
252
+ ...(options.sessionOwnerPrincipal ? { sessionOwnerPrincipal: options.sessionOwnerPrincipal } : {}),
237
253
  parts: turn.parts,
238
254
  rawContent: turn.rawContent,
239
255
  sourceFormat: turn.sourceFormat,
@@ -605,10 +621,12 @@ export class TurnIngestionCoordinator {
605
621
  options: {
606
622
  skipDedupeCheck?: boolean;
607
623
  clearBufferAfterExtraction?: boolean;
624
+ clearMatchingTurns?: boolean;
608
625
  skipCharThreshold?: boolean;
609
626
  skipUserTurnThreshold?: boolean;
610
627
  extractionDeadlineMs?: number;
611
628
  failOnExtractionFailure?: boolean;
629
+ onDurableCommit?: () => void;
612
630
  forceExtractionAttempt?: boolean;
613
631
  onTaskSettled?: (
614
632
  error?: unknown,
@@ -630,6 +648,7 @@ export class TurnIngestionCoordinator {
630
648
  * authenticated principal instead of `resolvePrincipal(sessionKey)`.
631
649
  */
632
650
  principalOverride?: string;
651
+ scopeProfileWritePlan?: ResolvedScopeProfilePlan | null;
633
652
  } = {},
634
653
  ): Promise<void> {
635
654
  const bufferKey = options.bufferKey ?? turnsToExtract[0]?.sessionKey ?? "default";
@@ -660,6 +679,13 @@ export class TurnIngestionCoordinator {
660
679
  timeout = undefined;
661
680
  }
662
681
  };
682
+ let abortHandler: (() => void) | undefined;
683
+ const clearAbortListener = (): void => {
684
+ if (abortHandler && options.abortSignal) {
685
+ options.abortSignal.removeEventListener("abort", abortHandler);
686
+ abortHandler = undefined;
687
+ }
688
+ };
663
689
  const settleTask = (
664
690
  error?: unknown,
665
691
  result?: ExtractionRunResult,
@@ -667,19 +693,38 @@ export class TurnIngestionCoordinator {
667
693
  if (settled) return false;
668
694
  settled = true;
669
695
  clearQueueWaitTimer();
696
+ clearAbortListener();
670
697
  options.onTaskSettled?.(error, result);
671
698
  return true;
672
699
  };
673
-
674
- if (typeof extractionDeadlineMs === "number") {
675
- const remainingMs = extractionDeadlineMs - Date.now();
676
- if (remainingMs <= 0) {
677
- settleTask(new Error("replay extraction deadline exceeded (queue_wait)"));
700
+ if (options.abortSignal) {
701
+ const signal = options.abortSignal;
702
+ abortHandler = () => settleTask(signal.reason ?? abortError("extraction aborted (queue_wait)"));
703
+ signal.addEventListener("abort", abortHandler, { once: true });
704
+ if (signal.aborted) {
705
+ settleTask(signal.reason ?? abortError("extraction aborted (queue_wait)"));
678
706
  return;
679
707
  }
680
- timeout = setTimeout(() => {
681
- settleTask(new Error("replay extraction deadline exceeded (queue_wait)"));
682
- }, remainingMs);
708
+ }
709
+
710
+ if (typeof extractionDeadlineMs === "number") {
711
+ const deadline = extractionDeadlineMs;
712
+ const maxTimerDelayMs = 2_147_483_647;
713
+ const scheduleQueueWaitTimeout = (): void => {
714
+ const remainingMs = deadline - Date.now();
715
+ if (remainingMs <= 0) {
716
+ settleTask(new ExtractionDeadlineError("queue_wait"));
717
+ return;
718
+ }
719
+ timeout = setTimeout(() => {
720
+ if (Date.now() >= deadline) {
721
+ settleTask(new ExtractionDeadlineError("queue_wait"));
722
+ } else {
723
+ scheduleQueueWaitTimeout();
724
+ }
725
+ }, Math.min(remainingMs, maxTimerDelayMs));
726
+ };
727
+ scheduleQueueWaitTimeout();
683
728
  }
684
729
 
685
730
  this.deps.extractionQueueCoordinator.enqueue(async () => {
@@ -688,7 +733,7 @@ export class TurnIngestionCoordinator {
688
733
  typeof extractionDeadlineMs === "number" &&
689
734
  extractionDeadlineMs <= Date.now()
690
735
  ) {
691
- settleTask(new Error("replay extraction deadline exceeded (queue_wait)"));
736
+ settleTask(new ExtractionDeadlineError("queue_wait"));
692
737
  return;
693
738
  }
694
739
  clearQueueWaitTimer();
@@ -696,14 +741,17 @@ export class TurnIngestionCoordinator {
696
741
  const result = await this.deps.runExtraction(turnsToExtract, {
697
742
  clearBufferAfterExtraction:
698
743
  options.clearBufferAfterExtraction ?? true,
744
+ clearMatchingTurns: options.clearMatchingTurns === true,
699
745
  skipCharThreshold: options.skipCharThreshold ?? false,
700
746
  skipUserTurnThreshold: options.skipUserTurnThreshold ?? false,
701
747
  deadlineMs: extractionDeadlineMs,
702
748
  bufferKey,
749
+ onDurableCommit: options.onDurableCommit,
703
750
  abortSignal: options.abortSignal,
704
751
  failOnExtractionFailure: options.failOnExtractionFailure === true,
705
752
  writeNamespaceOverride: options.writeNamespaceOverride,
706
753
  principalOverride: options.principalOverride,
754
+ scopeProfileWritePlan: options.scopeProfileWritePlan,
707
755
  forceExtractionAttempt: options.forceExtractionAttempt === true,
708
756
  });
709
757
  settleTask(undefined, result);
@@ -735,6 +783,7 @@ export class TurnIngestionCoordinator {
735
783
  namespace: string;
736
784
  bufferKey: string;
737
785
  isLiveSession: boolean;
786
+ abortSignal?: AbortSignal;
738
787
  },
739
788
  ): Promise<void> {
740
789
  const mode = this.deps.config.correctionCaptureMode;
@@ -765,10 +814,11 @@ export class TurnIngestionCoordinator {
765
814
  sessionKey: opts.sessionKey,
766
815
  principal: opts.principal,
767
816
  namespace: opts.namespace,
817
+ abortSignal: opts.abortSignal,
768
818
  },
769
819
  captureConfig,
770
820
  {
771
- planCorrection: (req) => service.plan(req),
821
+ planCorrection: (req, planOpts) => service.plan(req, planOpts),
772
822
  applyCorrection: (planId, applyOpts) => service.apply(planId, applyOpts),
773
823
  storageDir: async (ns) => (await this.deps.getStorage(ns)).dir,
774
824
  // Resolve `[m:xxxx]` handles to concrete memory ids via the single