@remnic/core 9.30.0 → 9.31.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 (495) hide show
  1. package/dist/access-admin-ops-surface.d.ts +10 -10
  2. package/dist/access-admin-ops-surface.js +50 -44
  3. package/dist/access-authorization-probe.d.ts +10 -10
  4. package/dist/access-authorization-probe.js +51 -45
  5. package/dist/access-boundary.d.ts +13 -11
  6. package/dist/access-boundary.js +50 -44
  7. package/dist/access-cli.js +168 -123
  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 +166 -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 +66 -59
  19. package/dist/access-identity-continuity-surface.d.ts +8 -8
  20. package/dist/access-identity-continuity-surface.js +50 -44
  21. package/dist/access-lcm-surface.d.ts +10 -10
  22. package/dist/access-lcm-surface.js +50 -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 +58 -52
  26. package/dist/access-memory-search-fanout.d.ts +2 -2
  27. package/dist/{access-namespace-preflight-VfXssvoI.d.ts → access-namespace-preflight-D4vW97H1.d.ts} +1 -1
  28. package/dist/access-namespace-preflight.d.ts +3 -3
  29. package/dist/access-namespace-preflight.js +50 -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 +50 -44
  35. package/dist/access-operations-batch.js +53 -47
  36. package/dist/access-operations.d.ts +11 -11
  37. package/dist/access-operations.js +55 -49
  38. package/dist/access-recall-concurrency.d.ts +10 -10
  39. package/dist/access-recall-concurrency.js +50 -44
  40. package/dist/access-recall-response.d.ts +10 -10
  41. package/dist/access-recall-response.js +50 -44
  42. package/dist/access-recall-surface.d.ts +10 -10
  43. package/dist/access-recall-surface.js +50 -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-B6PZ_xUL.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 +50 -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 +1 -1
  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-CGFYmTT8.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 +19 -19
  85. package/dist/causal-retrieval.js +2 -2
  86. package/dist/causal-trajectory-graph.d.ts +1 -1
  87. package/dist/causal-trajectory.js +1 -1
  88. package/dist/{chunk-LEPOP46W.js → chunk-227UFSEQ.js} +4 -4
  89. package/dist/{chunk-GIBMDSJ2.js → chunk-27P5YVDU.js} +2 -2
  90. package/dist/{chunk-2SA56WMI.js → chunk-2LTDWSR6.js} +4 -4
  91. package/dist/{chunk-OWHERGF2.js → chunk-2NLLXCJG.js} +2 -2
  92. package/dist/{chunk-YTSNAUXN.js → chunk-3F2LKUMU.js} +22 -8
  93. package/dist/chunk-3F2LKUMU.js.map +1 -0
  94. package/dist/chunk-3QL24R5Y.js +9 -0
  95. package/dist/chunk-3QL24R5Y.js.map +1 -0
  96. package/dist/chunk-4RNZMRAV.js +60 -0
  97. package/dist/chunk-4RNZMRAV.js.map +1 -0
  98. package/dist/{chunk-6U7F52DE.js → chunk-4XHR3I67.js} +60 -60
  99. package/dist/chunk-5IVLTFOV.js +65 -0
  100. package/dist/chunk-5IVLTFOV.js.map +1 -0
  101. package/dist/{chunk-2EUVEDF5.js → chunk-5XA7PQ5I.js} +2 -2
  102. package/dist/{chunk-ALSGMEJR.js → chunk-65ZPVYTA.js} +7 -7
  103. package/dist/{chunk-5VQJBH2G.js → chunk-6TAUHL33.js} +2 -2
  104. package/dist/{chunk-HUHX2OCX.js → chunk-7DRETLP5.js} +1 -1
  105. package/dist/chunk-7DRETLP5.js.map +1 -0
  106. package/dist/{chunk-RGIWINDN.js → chunk-7G5MH4NT.js} +30 -30
  107. package/dist/{chunk-WVO4G37W.js → chunk-7TEZUUGM.js} +3 -3
  108. package/dist/{chunk-MJCGLM25.js → chunk-7VUAG236.js} +5 -5
  109. package/dist/{chunk-M3C2V3PV.js → chunk-AJEMDQNA.js} +12 -12
  110. package/dist/{chunk-RKNJBZ55.js → chunk-AU7Q3LSC.js} +7 -7
  111. package/dist/{chunk-ACXPX4AG.js → chunk-BR2K43MK.js} +2 -2
  112. package/dist/{chunk-IYZ5K7MU.js → chunk-BUE5E2HL.js} +4 -187
  113. package/dist/chunk-BUE5E2HL.js.map +1 -0
  114. package/dist/{chunk-CZRYLSSW.js → chunk-BUGVGH4N.js} +2 -2
  115. package/dist/{chunk-YTQNQ4KB.js → chunk-C4VQMFVM.js} +3 -3
  116. package/dist/{chunk-ZPSVBSOF.js → chunk-CIVDJD6P.js} +3 -3
  117. package/dist/{chunk-K5GB36ME.js → chunk-CZDOT5I2.js} +2 -2
  118. package/dist/{chunk-VI2JQPNQ.js → chunk-E4PWACUN.js} +2 -2
  119. package/dist/{chunk-D2ANTDGO.js → chunk-E6BMSH7U.js} +2 -2
  120. package/dist/{chunk-P5PXWTW7.js → chunk-EJCAV3QZ.js} +3 -3
  121. package/dist/{chunk-CKMO4RDY.js → chunk-EMDLM3LW.js} +4 -4
  122. package/dist/chunk-ER7W6H4T.js +112 -0
  123. package/dist/chunk-ER7W6H4T.js.map +1 -0
  124. package/dist/{chunk-6FUPCJUL.js → chunk-FI4F5X2V.js} +54 -54
  125. package/dist/chunk-FI4F5X2V.js.map +1 -0
  126. package/dist/{chunk-LGHKJABJ.js → chunk-GOUILH55.js} +40 -18
  127. package/dist/chunk-GOUILH55.js.map +1 -0
  128. package/dist/{chunk-G5R3D5UP.js → chunk-GTTAHHD3.js} +2 -2
  129. package/dist/{chunk-H5CPS5JP.js → chunk-H36LJIPD.js} +3 -3
  130. package/dist/{chunk-AITCS2RC.js → chunk-IJ7HK452.js} +4 -4
  131. package/dist/{chunk-D3LMYTBV.js → chunk-J7WZUL2K.js} +9 -9
  132. package/dist/{chunk-5W4ZLBEZ.js → chunk-JCFTIQBR.js} +2 -2
  133. package/dist/{chunk-XOZ4ALGB.js → chunk-KE353EWI.js} +3 -3
  134. package/dist/{chunk-W5EG6LE3.js → chunk-KIT6M7EB.js} +3 -3
  135. package/dist/{chunk-5W7CTZ2E.js → chunk-KQAFEZQX.js} +4 -4
  136. package/dist/{chunk-Z54EM5YZ.js → chunk-MAXVH44E.js} +7 -7
  137. package/dist/{chunk-WZFAPHIK.js → chunk-MU7ZHSZE.js} +2 -2
  138. package/dist/chunk-N5Z4EVOR.js +123 -0
  139. package/dist/chunk-N5Z4EVOR.js.map +1 -0
  140. package/dist/{chunk-66772WBP.js → chunk-NFXQJHJD.js} +5 -5
  141. package/dist/{chunk-AZ5BTEKX.js → chunk-NQUF7XKR.js} +2 -2
  142. package/dist/{chunk-W4FBGYGK.js → chunk-NRV4Y3PM.js} +1 -1
  143. package/dist/{chunk-NHWB6HG2.js → chunk-NYCGIQRA.js} +2 -2
  144. package/dist/{chunk-4WKA6I65.js → chunk-OGCNZPKX.js} +1119 -309
  145. package/dist/chunk-OGCNZPKX.js.map +1 -0
  146. package/dist/{chunk-QJAQNXWI.js → chunk-ONHRRJZM.js} +6 -6
  147. package/dist/{chunk-FDAMS4PK.js → chunk-PNPOWBGC.js} +2 -2
  148. package/dist/{chunk-IC6CBHCA.js → chunk-QGENAYVS.js} +2 -2
  149. package/dist/{chunk-GBJ4RDFR.js → chunk-QIHIHZYC.js} +66 -91
  150. package/dist/chunk-QIHIHZYC.js.map +1 -0
  151. package/dist/{chunk-PUS63Q3G.js → chunk-RUYJ7TWU.js} +517 -2011
  152. package/dist/chunk-RUYJ7TWU.js.map +1 -0
  153. package/dist/{chunk-4A6YGWQN.js → chunk-TL4TO3EA.js} +115 -120
  154. package/dist/chunk-TL4TO3EA.js.map +1 -0
  155. package/dist/{chunk-SPJXKAVF.js → chunk-U52AKICI.js} +14 -13
  156. package/dist/chunk-U52AKICI.js.map +1 -0
  157. package/dist/chunk-ULARSG5Z.js +203 -0
  158. package/dist/chunk-ULARSG5Z.js.map +1 -0
  159. package/dist/{chunk-62U4J2GN.js → chunk-UR77VKF7.js} +2 -2
  160. package/dist/{chunk-JCBWCYEJ.js → chunk-VANLTS5F.js} +2 -2
  161. package/dist/{chunk-4Z4XNEWZ.js → chunk-VCD4PSK2.js} +56 -12
  162. package/dist/chunk-VCD4PSK2.js.map +1 -0
  163. package/dist/{chunk-RMMVQQA6.js → chunk-WDISJRMG.js} +2 -2
  164. package/dist/{chunk-B6JDYXL7.js → chunk-WWUVONGW.js} +7 -1
  165. package/dist/chunk-WWUVONGW.js.map +1 -0
  166. package/dist/{chunk-UVYI6VIX.js → chunk-X7Y7WX73.js} +1 -1
  167. package/dist/{chunk-TH2LSRMG.js → chunk-XHDIB4T4.js} +2 -2
  168. package/dist/{chunk-CVILPI77.js → chunk-XOQSEF7X.js} +6 -6
  169. package/dist/{chunk-LBOD4U5B.js → chunk-YFOMN2II.js} +6 -6
  170. package/dist/{chunk-RPW2NOU6.js → chunk-YIAA2X3D.js} +41 -1
  171. package/dist/chunk-YIAA2X3D.js.map +1 -0
  172. package/dist/chunk-YPC7W6GA.js +1604 -0
  173. package/dist/chunk-YPC7W6GA.js.map +1 -0
  174. package/dist/{chunk-I5NLEENJ.js → chunk-Z4SWV4VW.js} +3 -3
  175. package/dist/{chunk-PHWUFPCO.js → chunk-ZCPP5OW6.js} +61 -53
  176. package/dist/chunk-ZCPP5OW6.js.map +1 -0
  177. package/dist/{cli-C4GbETPC.d.ts → cli-BptUDTtp.d.ts} +5 -5
  178. package/dist/cli.d.ts +12 -12
  179. package/dist/cli.js +91 -84
  180. package/dist/compounding/engine.d.ts +2 -2
  181. package/dist/compounding/engine.js +14 -14
  182. package/dist/compounding/preference-consolidator.d.ts +1 -1
  183. package/dist/compression-optimizer.d.ts +1 -1
  184. package/dist/config.d.ts +1 -1
  185. package/dist/config.js +1 -1
  186. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  187. package/dist/connectors/codex-materialize-runner.js +14 -14
  188. package/dist/connectors/codex-materialize.d.ts +1 -1
  189. package/dist/connectors/index.d.ts +1 -1
  190. package/dist/connectors/index.js +17 -17
  191. package/dist/consolidation-provenance-check.d.ts +2 -2
  192. package/dist/consolidation-provenance-check.js +5 -5
  193. package/dist/consolidation-undo.d.ts +2 -2
  194. package/dist/consolidation-undo.js +3 -3
  195. package/dist/contradiction/index.d.ts +2 -2
  196. package/dist/contradiction/index.js +4 -4
  197. package/dist/conversation-index/backend.d.ts +1 -1
  198. package/dist/conversation-index/backend.js +2 -2
  199. package/dist/conversation-index/chunker.d.ts +1 -1
  200. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  201. package/dist/conversation-index/indexer.d.ts +1 -1
  202. package/dist/conversation-index/search.d.ts +1 -1
  203. package/dist/corpus-watermark.d.ts +1 -1
  204. package/dist/corpus-watermark.js +26 -26
  205. package/dist/day-summary.d.ts +1 -1
  206. package/dist/delinearize.d.ts +1 -1
  207. package/dist/direct-answer-wiring.d.ts +1 -1
  208. package/dist/direct-answer.d.ts +1 -1
  209. package/dist/embedding-fallback.d.ts +1 -1
  210. package/dist/enrichment/index.d.ts +1 -1
  211. package/dist/entity-retrieval.d.ts +2 -2
  212. package/dist/entity-retrieval.js +14 -14
  213. package/dist/entity-schema.d.ts +1 -1
  214. package/dist/explicit-capture.d.ts +8 -8
  215. package/dist/extraction-error-classification.d.ts +1 -1
  216. package/dist/extraction-faithfulness.d.ts +1 -1
  217. package/dist/extraction-judge-telemetry.d.ts +1 -1
  218. package/dist/extraction-judge-training.d.ts +1 -1
  219. package/dist/extraction-judge.d.ts +1 -1
  220. package/dist/extraction-liveness.d.ts +1 -1
  221. package/dist/extraction-source-grounding-rules.d.ts +1 -1
  222. package/dist/extraction-source-grounding.d.ts +15 -2
  223. package/dist/extraction-source-grounding.js +10 -1
  224. package/dist/extraction.d.ts +2 -15
  225. package/dist/extraction.js +5 -4
  226. package/dist/fallback-llm.d.ts +1 -1
  227. package/dist/graph-dashboard-diff.d.ts +1 -1
  228. package/dist/graph-dashboard-key.d.ts +1 -1
  229. package/dist/graph-dashboard-parser.d.ts +1 -1
  230. package/dist/graph-edge-reinforcement.d.ts +1 -1
  231. package/dist/graph-snapshot.d.ts +1 -1
  232. package/dist/graph.d.ts +1 -1
  233. package/dist/importance.d.ts +1 -1
  234. package/dist/importers/index.d.ts +1 -1
  235. package/dist/in-flight-reads.d.ts +1 -1
  236. package/dist/index.d.ts +19 -19
  237. package/dist/index.js +215 -207
  238. package/dist/intent.d.ts +1 -1
  239. package/dist/lcm/engine.d.ts +1 -1
  240. package/dist/lcm/engine.js +3 -3
  241. package/dist/lcm/index.d.ts +1 -1
  242. package/dist/lcm/index.js +6 -6
  243. package/dist/lcm/tools.d.ts +1 -1
  244. package/dist/lifecycle.d.ts +1 -1
  245. package/dist/live-connectors-runner.d.ts +1 -1
  246. package/dist/local-llm-helpers.d.ts +7 -0
  247. package/dist/local-llm-helpers.js +16 -0
  248. package/dist/local-llm-helpers.js.map +1 -0
  249. package/dist/local-llm.d.ts +3 -6
  250. package/dist/local-llm.js +2 -1
  251. package/dist/local-model-endpoint.d.ts +1 -1
  252. package/dist/maintenance/memory-governance.d.ts +1 -1
  253. package/dist/maintenance/memory-governance.js +14 -14
  254. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
  255. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +14 -14
  256. package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
  257. package/dist/maintenance/rebuild-memory-projection.js +15 -15
  258. package/dist/{maintenance-CL30NWtc.d.ts → maintenance-b6f92bRz.d.ts} +3 -3
  259. package/dist/mcp-memory-inspector-app.d.ts +10 -10
  260. package/dist/memory-action-policy.d.ts +1 -1
  261. package/dist/memory-cache.d.ts +1 -1
  262. package/dist/memory-corpus-version.js +2 -2
  263. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  264. package/dist/memory-projection-store.d.ts +1 -1
  265. package/dist/memory-provenance.d.ts +1 -1
  266. package/dist/memory-worth-outcomes.d.ts +2 -2
  267. package/dist/models-json.d.ts +1 -1
  268. package/dist/namespaces/migrate.d.ts +3 -3
  269. package/dist/namespaces/migrate.js +24 -24
  270. package/dist/namespaces/principal.d.ts +1 -1
  271. package/dist/namespaces/search.d.ts +1 -1
  272. package/dist/namespaces/search.js +9 -9
  273. package/dist/namespaces/storage.d.ts +3 -3
  274. package/dist/namespaces/storage.js +14 -14
  275. package/dist/native-knowledge.d.ts +1 -1
  276. package/dist/offline-sync-impression-drain.d.ts +1 -1
  277. package/dist/offline-sync-impression-drain.js +6 -5
  278. package/dist/operator-doctor-corpus.d.ts +1 -1
  279. package/dist/operator-doctor-corpus.js +29 -29
  280. package/dist/operator-doctor-replica.d.ts +1 -1
  281. package/dist/operator-doctor-replica.js +3 -3
  282. package/dist/operator-toolkit.d.ts +3 -3
  283. package/dist/operator-toolkit.js +38 -37
  284. package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
  285. package/dist/orchestration/maintenance.d.ts +4 -4
  286. package/dist/orchestration/maintenance.js +22 -21
  287. package/dist/{orchestrator-CKTCRwWV.d.ts → orchestrator-3uGxC1qO.d.ts} +72 -34
  288. package/dist/orchestrator.d.ts +8 -8
  289. package/dist/orchestrator.js +167 -159
  290. package/dist/page-versioning.js +3 -3
  291. package/dist/patterns-cli.d.ts +1 -1
  292. package/dist/{pipeline-B7wj4rRZ.d.ts → pipeline-DepuNr-m.d.ts} +1 -1
  293. package/dist/policy-runtime.d.ts +1 -1
  294. package/dist/proactive-contention.d.ts +1 -1
  295. package/dist/provenance.d.ts +1 -1
  296. package/dist/{qmd-q9tg4dHp.d.ts → qmd-Dalr3Jby.d.ts} +1 -1
  297. package/dist/qmd-preflight.d.ts +2 -2
  298. package/dist/qmd-recall-cache.d.ts +1 -1
  299. package/dist/qmd.d.ts +2 -2
  300. package/dist/qmd.js +4 -4
  301. package/dist/recall-concurrency-config.d.ts +1 -1
  302. package/dist/recall-disclosure-escalation.d.ts +1 -1
  303. package/dist/recall-explain-renderer.d.ts +1 -1
  304. package/dist/recall-explain-renderer.js +3 -3
  305. package/dist/recall-memory-map.d.ts +1 -1
  306. package/dist/recall-planner-llm.d.ts +1 -1
  307. package/dist/recall-state.d.ts +1 -1
  308. package/dist/recall-tag-filter.d.ts +1 -1
  309. package/dist/recall-timings.d.ts +1 -1
  310. package/dist/recall-xray-cli.d.ts +1 -1
  311. package/dist/recall-xray-cli.js +4 -4
  312. package/dist/recall-xray-renderer.d.ts +1 -1
  313. package/dist/recall-xray-renderer.js +3 -3
  314. package/dist/recall-xray.d.ts +1 -1
  315. package/dist/recall-xray.js +2 -2
  316. package/dist/replay/normalizers/chatgpt.d.ts +1 -1
  317. package/dist/replay/normalizers/claude.d.ts +1 -1
  318. package/dist/replay/normalizers/openclaw.d.ts +1 -1
  319. package/dist/replay/normalizers/shared.d.ts +1 -1
  320. package/dist/replay/runner.d.ts +1 -1
  321. package/dist/replay/types.d.ts +1 -1
  322. package/dist/replica-divergence.d.ts +1 -1
  323. package/dist/replica-divergence.js +2 -2
  324. package/dist/replica-peers-config.d.ts +1 -1
  325. package/dist/resolve-auth-token.d.ts +1 -1
  326. package/dist/resume-bundles.js +1 -1
  327. package/dist/retrieval-agents.d.ts +2 -2
  328. package/dist/retrieval-tiers.d.ts +1 -1
  329. package/dist/routing/engine.d.ts +1 -1
  330. package/dist/routing/store.d.ts +1 -1
  331. package/dist/salvage-envelope.d.ts +1 -1
  332. package/dist/{scope-profiles-CWDyglPM.d.ts → scope-profiles-BpiM5hTU.d.ts} +1 -1
  333. package/dist/search/embed-helper.d.ts +1 -1
  334. package/dist/search/factory.d.ts +1 -1
  335. package/dist/search/factory.js +8 -8
  336. package/dist/search/index.d.ts +1 -1
  337. package/dist/search/index.js +12 -12
  338. package/dist/search/lancedb-backend.d.ts +1 -1
  339. package/dist/search/meilisearch-backend.d.ts +1 -1
  340. package/dist/search/noop-backend.d.ts +1 -1
  341. package/dist/search/orama-backend.d.ts +1 -1
  342. package/dist/search/port.d.ts +1 -1
  343. package/dist/search/remote-backend.d.ts +1 -1
  344. package/dist/{semantic-consolidation-BUE3deLn.d.ts → semantic-consolidation-CMtVrf9f.d.ts} +1 -1
  345. package/dist/semantic-consolidation.d.ts +2 -2
  346. package/dist/semantic-consolidation.js +16 -16
  347. package/dist/semantic-rule-promotion.js +14 -14
  348. package/dist/semantic-rule-verifier.d.ts +1 -1
  349. package/dist/semantic-rule-verifier.js +14 -14
  350. package/dist/{service-CXgM0bQG.d.ts → service-DuAxwSgg.d.ts} +2 -2
  351. package/dist/session-observer-bands.d.ts +1 -1
  352. package/dist/session-observer-state.d.ts +1 -1
  353. package/dist/shared-context/manager.d.ts +1 -1
  354. package/dist/signal.d.ts +1 -1
  355. package/dist/{storage-DysJq-XH.d.ts → storage-CF0Ih8GP.d.ts} +1 -1
  356. package/dist/storage.d.ts +2 -2
  357. package/dist/storage.js +13 -13
  358. package/dist/summarizer.d.ts +1 -1
  359. package/dist/summarizer.js +3 -2
  360. package/dist/summary-snapshot.d.ts +1 -1
  361. package/dist/temporal-supersession.d.ts +2 -2
  362. package/dist/temporal-timeline-recall.d.ts +1 -1
  363. package/dist/temporal-validity.d.ts +1 -1
  364. package/dist/threading.d.ts +1 -1
  365. package/dist/tier-migration.d.ts +2 -2
  366. package/dist/tier-routing.d.ts +1 -1
  367. package/dist/tokens.js +2 -2
  368. package/dist/topics.d.ts +1 -1
  369. package/dist/transcript.d.ts +1 -1
  370. package/dist/transfer/backup.js +2 -2
  371. package/dist/transfer/capsule-export.js +2 -2
  372. package/dist/transfer/capsule-import.js +5 -5
  373. package/dist/trust-score-stage.d.ts +1 -1
  374. package/dist/trust-score.d.ts +1 -1
  375. package/dist/{types-aPPzhnjT.d.ts → types-BpaYvJ6v.d.ts} +22 -2
  376. package/dist/types.d.ts +1 -1
  377. package/dist/types.js +1 -1
  378. package/dist/utility-runtime.d.ts +1 -1
  379. package/dist/verified-recall.js +14 -14
  380. package/dist/write-envelope.d.ts +1 -1
  381. package/package.json +2 -2
  382. package/src/access-boundary.ts +3 -0
  383. package/src/access-cli.test.ts +93 -0
  384. package/src/access-cli.ts +56 -2
  385. package/src/access-extraction-force-flush.ts +177 -0
  386. package/src/access-http-extraction-force-flush.test.ts +132 -0
  387. package/src/access-http-lcm-compaction.ts +99 -22
  388. package/src/access-http-lifecycle-flush.ts +81 -0
  389. package/src/access-http.test.ts +227 -0
  390. package/src/access-http.ts +33 -40
  391. package/src/access-mcp-output-schemas.ts +6 -0
  392. package/src/access-mcp.test.ts +40 -0
  393. package/src/access-mcp.ts +32 -1
  394. package/src/access-observe-helpers.ts +180 -0
  395. package/src/access-observe-write-surface.ts +78 -19
  396. package/src/access-operations-batch.ts +2 -1
  397. package/src/access-schema-pi.test.ts +17 -0
  398. package/src/access-schema.ts +28 -11
  399. package/src/access-service-helpers.ts +46 -0
  400. package/src/access-service-observe-lcm-parity.test.ts +781 -31
  401. package/src/access-service-observe-scope.test.ts +88 -0
  402. package/src/access-service.ts +46 -128
  403. package/src/access-surface-catalog.test.ts +32 -0
  404. package/src/access-surface-catalog.ts +2 -0
  405. package/src/buffer-session.test.ts +148 -0
  406. package/src/buffer-turn-helpers.ts +152 -0
  407. package/src/buffer.ts +126 -201
  408. package/src/correction/correction-access-wiring.ts +79 -27
  409. package/src/correction/correction-executor.test.ts +542 -1
  410. package/src/correction/correction-executor.ts +309 -89
  411. package/src/correction/correction-planner.test.ts +35 -1
  412. package/src/correction/correction-planner.ts +50 -3
  413. package/src/correction/correction-service.ts +12 -7
  414. package/src/correction/correction-storage-integration.test.ts +172 -1
  415. package/src/correction/passive-capture.test.ts +35 -0
  416. package/src/correction/passive-capture.ts +17 -3
  417. package/src/extraction-source-grounding.ts +55 -1
  418. package/src/extraction-timeout.test.ts +51 -0
  419. package/src/extraction.ts +64 -90
  420. package/src/local-llm-headers-timeout.test.ts +48 -0
  421. package/src/local-llm-helpers.ts +58 -0
  422. package/src/local-llm.ts +62 -58
  423. package/src/orchestration/extraction-run-helpers.ts +309 -0
  424. package/src/orchestration/extraction-run.test.ts +350 -7
  425. package/src/orchestration/extraction-run.ts +327 -250
  426. package/src/orchestration/recall-internal-deps.ts +385 -0
  427. package/src/orchestration/recall-internal.ts +16 -375
  428. package/src/orchestration/session-context.ts +193 -18
  429. package/src/orchestration/turn-ingestion.ts +61 -11
  430. package/src/orchestrator-flush.test.ts +511 -5
  431. package/src/orchestrator.ts +8 -6
  432. package/src/types.ts +2 -2
  433. package/dist/chunk-4A6YGWQN.js.map +0 -1
  434. package/dist/chunk-4WKA6I65.js.map +0 -1
  435. package/dist/chunk-4Z4XNEWZ.js.map +0 -1
  436. package/dist/chunk-6FUPCJUL.js.map +0 -1
  437. package/dist/chunk-B6JDYXL7.js.map +0 -1
  438. package/dist/chunk-GBJ4RDFR.js.map +0 -1
  439. package/dist/chunk-HUHX2OCX.js.map +0 -1
  440. package/dist/chunk-IYZ5K7MU.js.map +0 -1
  441. package/dist/chunk-LGHKJABJ.js.map +0 -1
  442. package/dist/chunk-PHWUFPCO.js.map +0 -1
  443. package/dist/chunk-PUS63Q3G.js.map +0 -1
  444. package/dist/chunk-RPW2NOU6.js.map +0 -1
  445. package/dist/chunk-SPJXKAVF.js.map +0 -1
  446. package/dist/chunk-YTSNAUXN.js.map +0 -1
  447. /package/dist/{capsule-crypto-GWVG7LGC.js.map → access-extraction-force-flush.js.map} +0 -0
  448. /package/dist/{capsule-merge-5KKJQBWQ.js.map → capsule-merge-2H2IUTBT.js.map} +0 -0
  449. /package/dist/{chunk-LEPOP46W.js.map → chunk-227UFSEQ.js.map} +0 -0
  450. /package/dist/{chunk-GIBMDSJ2.js.map → chunk-27P5YVDU.js.map} +0 -0
  451. /package/dist/{chunk-2SA56WMI.js.map → chunk-2LTDWSR6.js.map} +0 -0
  452. /package/dist/{chunk-OWHERGF2.js.map → chunk-2NLLXCJG.js.map} +0 -0
  453. /package/dist/{chunk-6U7F52DE.js.map → chunk-4XHR3I67.js.map} +0 -0
  454. /package/dist/{chunk-2EUVEDF5.js.map → chunk-5XA7PQ5I.js.map} +0 -0
  455. /package/dist/{chunk-ALSGMEJR.js.map → chunk-65ZPVYTA.js.map} +0 -0
  456. /package/dist/{chunk-5VQJBH2G.js.map → chunk-6TAUHL33.js.map} +0 -0
  457. /package/dist/{chunk-RGIWINDN.js.map → chunk-7G5MH4NT.js.map} +0 -0
  458. /package/dist/{chunk-WVO4G37W.js.map → chunk-7TEZUUGM.js.map} +0 -0
  459. /package/dist/{chunk-MJCGLM25.js.map → chunk-7VUAG236.js.map} +0 -0
  460. /package/dist/{chunk-M3C2V3PV.js.map → chunk-AJEMDQNA.js.map} +0 -0
  461. /package/dist/{chunk-RKNJBZ55.js.map → chunk-AU7Q3LSC.js.map} +0 -0
  462. /package/dist/{chunk-ACXPX4AG.js.map → chunk-BR2K43MK.js.map} +0 -0
  463. /package/dist/{chunk-CZRYLSSW.js.map → chunk-BUGVGH4N.js.map} +0 -0
  464. /package/dist/{chunk-YTQNQ4KB.js.map → chunk-C4VQMFVM.js.map} +0 -0
  465. /package/dist/{chunk-ZPSVBSOF.js.map → chunk-CIVDJD6P.js.map} +0 -0
  466. /package/dist/{chunk-K5GB36ME.js.map → chunk-CZDOT5I2.js.map} +0 -0
  467. /package/dist/{chunk-VI2JQPNQ.js.map → chunk-E4PWACUN.js.map} +0 -0
  468. /package/dist/{chunk-D2ANTDGO.js.map → chunk-E6BMSH7U.js.map} +0 -0
  469. /package/dist/{chunk-P5PXWTW7.js.map → chunk-EJCAV3QZ.js.map} +0 -0
  470. /package/dist/{chunk-CKMO4RDY.js.map → chunk-EMDLM3LW.js.map} +0 -0
  471. /package/dist/{chunk-G5R3D5UP.js.map → chunk-GTTAHHD3.js.map} +0 -0
  472. /package/dist/{chunk-H5CPS5JP.js.map → chunk-H36LJIPD.js.map} +0 -0
  473. /package/dist/{chunk-AITCS2RC.js.map → chunk-IJ7HK452.js.map} +0 -0
  474. /package/dist/{chunk-D3LMYTBV.js.map → chunk-J7WZUL2K.js.map} +0 -0
  475. /package/dist/{chunk-5W4ZLBEZ.js.map → chunk-JCFTIQBR.js.map} +0 -0
  476. /package/dist/{chunk-XOZ4ALGB.js.map → chunk-KE353EWI.js.map} +0 -0
  477. /package/dist/{chunk-W5EG6LE3.js.map → chunk-KIT6M7EB.js.map} +0 -0
  478. /package/dist/{chunk-5W7CTZ2E.js.map → chunk-KQAFEZQX.js.map} +0 -0
  479. /package/dist/{chunk-Z54EM5YZ.js.map → chunk-MAXVH44E.js.map} +0 -0
  480. /package/dist/{chunk-WZFAPHIK.js.map → chunk-MU7ZHSZE.js.map} +0 -0
  481. /package/dist/{chunk-66772WBP.js.map → chunk-NFXQJHJD.js.map} +0 -0
  482. /package/dist/{chunk-AZ5BTEKX.js.map → chunk-NQUF7XKR.js.map} +0 -0
  483. /package/dist/{chunk-W4FBGYGK.js.map → chunk-NRV4Y3PM.js.map} +0 -0
  484. /package/dist/{chunk-NHWB6HG2.js.map → chunk-NYCGIQRA.js.map} +0 -0
  485. /package/dist/{chunk-QJAQNXWI.js.map → chunk-ONHRRJZM.js.map} +0 -0
  486. /package/dist/{chunk-FDAMS4PK.js.map → chunk-PNPOWBGC.js.map} +0 -0
  487. /package/dist/{chunk-IC6CBHCA.js.map → chunk-QGENAYVS.js.map} +0 -0
  488. /package/dist/{chunk-62U4J2GN.js.map → chunk-UR77VKF7.js.map} +0 -0
  489. /package/dist/{chunk-JCBWCYEJ.js.map → chunk-VANLTS5F.js.map} +0 -0
  490. /package/dist/{chunk-RMMVQQA6.js.map → chunk-WDISJRMG.js.map} +0 -0
  491. /package/dist/{chunk-UVYI6VIX.js.map → chunk-X7Y7WX73.js.map} +0 -0
  492. /package/dist/{chunk-TH2LSRMG.js.map → chunk-XHDIB4T4.js.map} +0 -0
  493. /package/dist/{chunk-CVILPI77.js.map → chunk-XOQSEF7X.js.map} +0 -0
  494. /package/dist/{chunk-LBOD4U5B.js.map → chunk-YFOMN2II.js.map} +0 -0
  495. /package/dist/{chunk-I5NLEENJ.js.map → chunk-Z4SWV4VW.js.map} +0 -0
@@ -1,5 +1,6 @@
1
1
  import assert from "node:assert/strict";
2
2
  import { mkdtemp, rm, writeFile } from "node:fs/promises";
3
+ import { execFileSync } from "node:child_process";
3
4
  import fs from "node:fs";
4
5
  import os from "node:os";
5
6
  import path from "node:path";
@@ -523,6 +524,98 @@ test("access-cli rejects adjacent option-looking values", async () => {
523
524
  assert.match(output, /missing required option: --content/);
524
525
  });
525
526
 
527
+ test("access-cli extraction-flush drains the requested session through the boundary", async () => {
528
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "remnic-access-cli-"));
529
+ let output = "";
530
+ const originalStdoutWrite = process.stdout.write;
531
+ process.stdout.write = ((chunk: string | Uint8Array) => {
532
+ output += String(chunk);
533
+ return true;
534
+ }) as typeof process.stdout.write;
535
+
536
+ try {
537
+ const configPath = path.join(tempDir, "openclaw.json");
538
+ writeOpenClawConfig(configPath, {
539
+ memoryDir: path.join(tempDir, "memory"),
540
+ defaultNamespace: "default",
541
+ });
542
+
543
+ await withPatchedEnv(
544
+ {
545
+ OPENCLAW_CONFIG_PATH: configPath,
546
+ OPENCLAW_ENGRAM_CONFIG_PATH: undefined,
547
+ },
548
+ async () => {
549
+ await main([
550
+ "extraction-flush",
551
+ "--session-key",
552
+ "cli:flush",
553
+ "--namespace",
554
+ "default",
555
+ "--deadline-ms",
556
+ String(Date.now() + 10_000),
557
+ ]);
558
+ },
559
+ );
560
+
561
+ assert.match(output, /"flushed": true/);
562
+ assert.match(output, /"sessionKey": "cli:flush"/);
563
+ assert.match(output, /"effectiveNamespace": "default"/);
564
+ } finally {
565
+ process.stdout.write = originalStdoutWrite;
566
+ fs.rmSync(tempDir, { recursive: true, force: true });
567
+ }
568
+ });
569
+
570
+ test("access-cli extraction-flush expands tilde in cwd before resolving project scope", async () => {
571
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "remnic-access-cli-"));
572
+ const repoDir = path.join(tempDir, "repo");
573
+ fs.mkdirSync(repoDir);
574
+ execFileSync("git", ["init", "-q"], { cwd: repoDir });
575
+ let output = "";
576
+ const originalStdoutWrite = process.stdout.write;
577
+ process.stdout.write = ((chunk: string | Uint8Array) => {
578
+ output += String(chunk);
579
+ return true;
580
+ }) as typeof process.stdout.write;
581
+
582
+ try {
583
+ const configPath = path.join(tempDir, "openclaw.json");
584
+ writeOpenClawConfig(configPath, {
585
+ namespacesEnabled: true,
586
+ defaultNamespace: "default",
587
+ agentAccessHttp: { principal: "pi-geek" },
588
+ principalFromSessionKeyMode: "prefix",
589
+ principalFromSessionKeyRules: [{ match: "cli:", principal: "pi-geek" }],
590
+ codingMode: { projectScope: true },
591
+ });
592
+
593
+ await withPatchedEnv(
594
+ {
595
+ HOME: tempDir,
596
+ OPENCLAW_CONFIG_PATH: configPath,
597
+ OPENCLAW_ENGRAM_CONFIG_PATH: undefined,
598
+ },
599
+ async () => {
600
+ await main([
601
+ "extraction-flush",
602
+ "--session-key",
603
+ "cli:tilde-cwd",
604
+ "--cwd",
605
+ "~/repo",
606
+ "--deadline-ms",
607
+ String(Date.now() + 10_000),
608
+ ]);
609
+ },
610
+ );
611
+
612
+ assert.match(output, /"effectiveNamespace": "default-project-/);
613
+ } finally {
614
+ process.stdout.write = originalStdoutWrite;
615
+ fs.rmSync(tempDir, { recursive: true, force: true });
616
+ }
617
+ });
618
+
526
619
  // ──────────────────────────────────────────────────────────────────────────
527
620
  // architecture command — wired through the boundary operation (#1548 PR3)
528
621
  // ──────────────────────────────────────────────────────────────────────────
package/src/access-cli.ts CHANGED
@@ -15,7 +15,14 @@ import { projectTagProjectId } from "./coding/coding-namespace.js";
15
15
 
16
16
  const OPENCLAW_REMNIC_PLUGIN_IDS = ["openclaw-remnic", "openclaw-engram"] as const;
17
17
 
18
- type CommandName = "browse" | "store" | "decision" | "architecture" | "delta" | "correct";
18
+ type CommandName =
19
+ | "browse"
20
+ | "store"
21
+ | "extraction-flush"
22
+ | "decision"
23
+ | "architecture"
24
+ | "delta"
25
+ | "correct";
19
26
 
20
27
  type ParsedArgs = {
21
28
  command: CommandName;
@@ -136,6 +143,7 @@ function usage(): string {
136
143
  return [
137
144
  " engram-access browse [options]",
138
145
  " engram-access store [options]",
146
+ " engram-access extraction-flush [options]",
139
147
  " engram-access decision [options]",
140
148
  " engram-access architecture [options]",
141
149
  " engram-access delta [options]",
@@ -165,6 +173,14 @@ function usage(): string {
165
173
  " --idempotency-key <key>",
166
174
  " --dry-run",
167
175
  "",
176
+ "Extraction flush options:",
177
+ " --session-key <key>",
178
+ " --namespace <name>",
179
+ " --principal <principal>",
180
+ " --cwd <path>",
181
+ " --project-tag <tag>",
182
+ " --deadline-ms <timestamp>",
183
+ "",
168
184
  "Decision options:",
169
185
  " --subcommand <list|get|record|supersede>",
170
186
  " --namespace <name>",
@@ -233,6 +249,10 @@ const COMMAND_SPECS: Record<CommandName, CommandSpec> = {
233
249
  ]),
234
250
  flagOptions: new Set(["dry-run"]),
235
251
  },
252
+ "extraction-flush": {
253
+ valueOptions: new Set(["session-key", "namespace", "principal", "cwd", "project-tag", "deadline-ms"]),
254
+ flagOptions: new Set(),
255
+ },
236
256
  decision: {
237
257
  valueOptions: new Set([
238
258
  "subcommand",
@@ -301,7 +321,15 @@ type BrowseSort = (typeof BROWSE_SORT_VALUES)[number];
301
321
  * `command: commandRaw` assignment below (codex review P2).
302
322
  */
303
323
  function isCommandName(value: string): value is CommandName {
304
- return value === "browse" || value === "store" || value === "decision" || value === "architecture" || value === "delta" || value === "correct";
324
+ return (
325
+ value === "browse" ||
326
+ value === "store" ||
327
+ value === "extraction-flush" ||
328
+ value === "decision" ||
329
+ value === "architecture" ||
330
+ value === "delta" ||
331
+ value === "correct"
332
+ );
305
333
  }
306
334
 
307
335
  function parseArgs(argv: string[]): ParsedArgs {
@@ -561,6 +589,28 @@ async function runStore(args: ParsedArgs, preferredId?: string): Promise<void> {
561
589
  console.log(JSON.stringify(output.result, null, 2));
562
590
  }
563
591
 
592
+ async function runExtractionFlush(args: ParsedArgs, preferredId?: string): Promise<void> {
593
+ const { config, service } = buildRuntime(preferredId);
594
+ const op = getOperation("extraction_force_flush");
595
+ if (!op) {
596
+ throw new Error("access-boundary: operation not registered: extraction_force_flush");
597
+ }
598
+ const output = (await op.run(
599
+ {
600
+ sessionKey: requireOption(args, "session-key"),
601
+ namespace: getLastOption(args, "namespace"),
602
+ cwd: expandOptionalPath(getLastOption(args, "cwd")),
603
+ projectTag: getLastOption(args, "project-tag"),
604
+ deadlineMs: parseIntegerOption(args, "deadline-ms", { min: 0 }),
605
+ },
606
+ {
607
+ service,
608
+ authenticatedPrincipal: getLastOption(args, "principal") ?? config.agentAccessHttp.principal,
609
+ },
610
+ )) as { result: unknown };
611
+ console.log(JSON.stringify(output.result, null, 2));
612
+ }
613
+
564
614
  function expandOptionalPath(value: string | undefined): string | undefined {
565
615
  return value === undefined ? undefined : expandTildePath(value);
566
616
  }
@@ -805,6 +855,10 @@ export async function main(
805
855
  await runBrowse(args, options.preferredId);
806
856
  return;
807
857
  }
858
+ if (args.command === "extraction-flush") {
859
+ await runExtractionFlush(args, options.preferredId);
860
+ return;
861
+ }
808
862
  if (args.command === "decision") {
809
863
  await runDecision(args, options.preferredId);
810
864
  return;
@@ -0,0 +1,177 @@
1
+ import { isAbortError, throwIfAborted } from "./abort-error.js";
2
+ import { EngramAccessForbiddenError } from "./access-errors.js";
3
+ import type { AccessObserveWriteSurfaceDeps } from "./access-observe-write-surface.js";
4
+ import {
5
+ type EngramAccessExtractionForceFlushRequest,
6
+ type EngramAccessExtractionForceFlushResponse,
7
+ EngramAccessInputError,
8
+ } from "./access-service.js";
9
+ import { resolveNamespaceCapabilities } from "./capabilities.js";
10
+ import { log } from "./logger.js";
11
+ import { resolvePrincipal } from "./namespaces/principal.js";
12
+ import { ExtractionDeadlineError } from "./orchestration/extraction-run.js";
13
+ import { SessionOwnershipError, awaitSessionFlushPhase } from "./orchestration/session-context.js";
14
+ import { pendingObserveScopeHint } from "./access-observe-helpers.js";
15
+
16
+ type PendingObserveExtractionWaiter = (
17
+ sessionKey: string,
18
+ principal: string | undefined,
19
+ namespace: string | undefined,
20
+ abortSignal?: AbortSignal,
21
+ registerCancellation?: (cancel: () => void) => void,
22
+ scopeHint?: string,
23
+ ) => Promise<void>;
24
+
25
+ export async function extractionForceFlush(
26
+ deps: AccessObserveWriteSurfaceDeps,
27
+ request: EngramAccessExtractionForceFlushRequest,
28
+ waitForPendingObserveExtraction?: PendingObserveExtractionWaiter
29
+ ): Promise<EngramAccessExtractionForceFlushResponse> {
30
+ if (!request.sessionKey || typeof request.sessionKey !== "string" || request.sessionKey.trim().length === 0) {
31
+ throw new EngramAccessInputError("sessionKey is required and must be a non-empty string");
32
+ }
33
+ if (request.deadlineMs !== undefined && (!Number.isFinite(request.deadlineMs) || request.deadlineMs < 0)) {
34
+ throw new EngramAccessInputError("deadlineMs must be a finite non-negative number");
35
+ }
36
+
37
+ const authenticatedPrincipal = request.authenticatedPrincipal?.trim();
38
+ throwIfAborted(request.abortSignal, "extraction force-flush aborted");
39
+
40
+ const namespacesEnabled = resolveNamespaceCapabilities(deps.orchestrator.config).namespaces === true;
41
+ const sessionPrincipal = namespacesEnabled
42
+ ? resolvePrincipal(request.sessionKey, deps.orchestrator.config)
43
+ : undefined;
44
+ if (namespacesEnabled) {
45
+ if (
46
+ !authenticatedPrincipal ||
47
+ (sessionPrincipal !== undefined && sessionPrincipal !== "default" && sessionPrincipal !== authenticatedPrincipal)
48
+ ) {
49
+ throw new EngramAccessInputError("sessionKey is not owned by authenticated principal");
50
+ }
51
+ }
52
+
53
+ let committed = false;
54
+ const markCommitted = (): void => {
55
+ if (committed) return;
56
+ committed = true;
57
+ request.onCommitted?.();
58
+ };
59
+ let abortHandler: (() => void) | undefined;
60
+
61
+ try {
62
+ const scope = await deps.resolveMemoryScopePlan(request);
63
+ const reservationScopeHint = pendingObserveScopeHint(request);
64
+ const cancelScopedPendingObserveExtractions = (): void => {
65
+ deps.cancelPendingObserveExtractions?.(
66
+ request.sessionKey,
67
+ scope.principal,
68
+ scope.writeNamespace,
69
+ reservationScopeHint,
70
+ );
71
+ };
72
+ if (request.abortSignal?.aborted) cancelScopedPendingObserveExtractions();
73
+ throwIfAborted(request.abortSignal, "extraction force-flush aborted");
74
+ if (typeof request.deadlineMs === "number" && request.deadlineMs <= Date.now()) {
75
+ cancelScopedPendingObserveExtractions();
76
+ throw new EngramAccessInputError("extraction force-flush deadline exceeded before buffer drain");
77
+ }
78
+ abortHandler = cancelScopedPendingObserveExtractions;
79
+ request.abortSignal?.addEventListener("abort", abortHandler, { once: true });
80
+ await awaitSessionFlushPhase(
81
+ () =>
82
+ deps.orchestrator.flushSession(request.sessionKey, {
83
+ reason: "access_force_flush",
84
+ abortSignal: request.abortSignal,
85
+ failOnExtractionFailure: true,
86
+ extractionDeadlineMs: request.deadlineMs,
87
+ writeNamespaceOverride: scope.writeNamespace,
88
+ principalOverride:
89
+ typeof scope.principal === "string" && scope.principal.length > 0 ? scope.principal : undefined,
90
+ scopeProfileWritePlan: scope.scopeProfilePlan,
91
+ onCommitted: markCommitted,
92
+ }),
93
+ {
94
+ abortSignal: request.abortSignal,
95
+ extractionDeadlineMs: request.deadlineMs,
96
+ reason: "access_force_flush",
97
+ deadlineStage: "buffer_drain",
98
+ onDeadline: cancelScopedPendingObserveExtractions,
99
+ }
100
+ );
101
+ // A flush with no buffered turns still consumes the lifecycle write;
102
+ // durable drains already invoked this idempotent callback.
103
+ markCommitted();
104
+
105
+ if (waitForPendingObserveExtraction) {
106
+ let cancelPendingObserveExtraction: (() => void) | undefined;
107
+ await awaitSessionFlushPhase(
108
+ () =>
109
+ waitForPendingObserveExtraction(
110
+ request.sessionKey,
111
+ scope.principal,
112
+ scope.writeNamespace,
113
+ request.abortSignal,
114
+ (cancel) => {
115
+ cancelPendingObserveExtraction = cancel;
116
+ },
117
+ reservationScopeHint,
118
+ ),
119
+ {
120
+ abortSignal: request.abortSignal,
121
+ extractionDeadlineMs: request.deadlineMs,
122
+ reason: "access_force_flush",
123
+ deadlineStage: "pending_observe_extraction",
124
+ onDeadline: () => {
125
+ cancelScopedPendingObserveExtractions();
126
+ cancelPendingObserveExtraction?.();
127
+ },
128
+ }
129
+ );
130
+ }
131
+
132
+ const buffer = deps.orchestrator.buffer;
133
+ if (buffer && typeof buffer.clearRetainedTurnsForSession === "function") {
134
+ try {
135
+ await awaitSessionFlushPhase(
136
+ () =>
137
+ buffer.clearRetainedTurnsForSession(request.sessionKey, namespacesEnabled ? scope.principal : undefined, {
138
+ abortSignal: request.abortSignal,
139
+ deadlineMs: request.deadlineMs,
140
+ }),
141
+ {
142
+ abortSignal: request.abortSignal,
143
+ extractionDeadlineMs: request.deadlineMs,
144
+ reason: "access_force_flush",
145
+ deadlineStage: "retained_turn_cleanup",
146
+ }
147
+ );
148
+ } catch (cleanupError) {
149
+ if (isAbortError(cleanupError) || cleanupError instanceof ExtractionDeadlineError) {
150
+ throw cleanupError;
151
+ }
152
+ log.warn(
153
+ `extractionForceFlush: retained-turn cleanup failed after a successful flush, continuing: ${
154
+ cleanupError instanceof Error ? cleanupError.message : String(cleanupError)
155
+ }`
156
+ );
157
+ }
158
+ }
159
+
160
+ return {
161
+ flushed: true,
162
+ sessionKey: request.sessionKey,
163
+ namespace: deps.legacyResponseNamespaceForScope(scope),
164
+ effectiveNamespace: scope.writeNamespace,
165
+ };
166
+ } catch (error) {
167
+ if (error instanceof SessionOwnershipError) {
168
+ throw new EngramAccessForbiddenError(error.message);
169
+ }
170
+ if (error instanceof ExtractionDeadlineError) {
171
+ throw new EngramAccessInputError(error.message);
172
+ }
173
+ throw error;
174
+ } finally {
175
+ if (abortHandler) request.abortSignal?.removeEventListener("abort", abortHandler);
176
+ }
177
+ }
@@ -0,0 +1,132 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+
4
+ import { EngramAccessHttpServer } from "./access-http.js";
5
+ import type {
6
+ EngramAccessExtractionForceFlushRequest,
7
+ EngramAccessLcmCompactionFlushRequest,
8
+ EngramAccessService,
9
+ } from "./access-service.js";
10
+
11
+ test("HTTP extraction force-flush forwards validated scope and deadline to the access service", async () => {
12
+ const requests: EngramAccessExtractionForceFlushRequest[] = [];
13
+ const service = {
14
+ extractionForceFlush: async (request: EngramAccessExtractionForceFlushRequest) => {
15
+ requests.push(request);
16
+ return {
17
+ flushed: true,
18
+ sessionKey: request.sessionKey,
19
+ namespace: request.namespace ?? "default",
20
+ effectiveNamespace: request.namespace ?? "default",
21
+ };
22
+ },
23
+ } as unknown as EngramAccessService;
24
+ const server = new EngramAccessHttpServer({
25
+ service,
26
+ port: 0,
27
+ authToken: "test-token",
28
+ adminConsoleEnabled: false,
29
+ });
30
+
31
+ const status = await server.start();
32
+ try {
33
+ const response = await fetch(`http://127.0.0.1:${status.port}/engram/v1/extraction/flush`, {
34
+ method: "POST",
35
+ headers: {
36
+ authorization: "Bearer test-token",
37
+ "content-type": "application/json",
38
+ },
39
+ body: JSON.stringify({
40
+ sessionKey: "pi:session-1",
41
+ namespace: "team-project",
42
+ cwd: "/workspace/project",
43
+ projectTag: "Acme/Webshop",
44
+ deadlineMs: 1_900_000_000_000,
45
+ }),
46
+ });
47
+
48
+ assert.equal(response.status, 200);
49
+ assert.deepEqual(await response.json(), {
50
+ flushed: true,
51
+ sessionKey: "pi:session-1",
52
+ namespace: "team-project",
53
+ effectiveNamespace: "team-project",
54
+ });
55
+ assert.equal(requests.length, 1);
56
+ const [request] = requests;
57
+ assert.equal(request.sessionKey, "pi:session-1");
58
+ assert.equal(request.namespace, "team-project");
59
+ assert.equal(request.cwd, "/workspace/project");
60
+ assert.equal(request.projectTag, "Acme/Webshop");
61
+ assert.equal(request.deadlineMs, 1_900_000_000_000);
62
+ assert.ok(request.abortSignal instanceof AbortSignal);
63
+
64
+ const invalid = await fetch(`http://127.0.0.1:${status.port}/engram/v1/extraction/flush`, {
65
+ method: "POST",
66
+ headers: {
67
+ authorization: "Bearer test-token",
68
+ "content-type": "application/json",
69
+ },
70
+ body: JSON.stringify({ sessionKey: "pi:session-1", deadlineMs: -1 }),
71
+ });
72
+ assert.equal(invalid.status, 400);
73
+ assert.equal(requests.length, 1, "invalid requests must not reach the access service");
74
+ } finally {
75
+ await server.stop();
76
+ }
77
+ });
78
+
79
+ test("HTTP lifecycle flush preserves the scoped LCM compaction route", async () => {
80
+ const requests: EngramAccessLcmCompactionFlushRequest[] = [];
81
+ const service = {
82
+ lcmCompactionFlush: async (request: EngramAccessLcmCompactionFlushRequest) => {
83
+ requests.push(request);
84
+ return {
85
+ enabled: true,
86
+ flushed: true,
87
+ sessionKey: request.sessionKey,
88
+ namespace: request.namespace ?? "default",
89
+ };
90
+ },
91
+ } as unknown as EngramAccessService;
92
+ const server = new EngramAccessHttpServer({
93
+ service,
94
+ port: 0,
95
+ authToken: "test-token",
96
+ adminConsoleEnabled: false,
97
+ });
98
+
99
+ const status = await server.start();
100
+ try {
101
+ const response = await fetch(`http://127.0.0.1:${status.port}/remnic/v1/lcm/compaction/flush`, {
102
+ method: "POST",
103
+ headers: {
104
+ authorization: "Bearer test-token",
105
+ "content-type": "application/json",
106
+ },
107
+ body: JSON.stringify({
108
+ sessionKey: "pi:session-1",
109
+ namespace: "team-project",
110
+ cwd: "/workspace/project",
111
+ projectTag: "Acme/Webshop",
112
+ }),
113
+ });
114
+
115
+ assert.equal(response.status, 200);
116
+ assert.deepEqual(await response.json(), {
117
+ enabled: true,
118
+ flushed: true,
119
+ sessionKey: "pi:session-1",
120
+ namespace: "team-project",
121
+ });
122
+ assert.deepEqual(requests, [{
123
+ sessionKey: "pi:session-1",
124
+ namespace: "team-project",
125
+ cwd: "/workspace/project",
126
+ projectTag: "Acme/Webshop",
127
+ authenticatedPrincipal: undefined,
128
+ }]);
129
+ } finally {
130
+ await server.stop();
131
+ }
132
+ });
@@ -1,9 +1,13 @@
1
1
  import type { ServerResponse } from "node:http";
2
2
 
3
- import type { LcmCompactionFlushRequest } from "./access-schema.js";
4
- import type { EngramAccessLcmCompactionFlushResponse, EngramAccessService } from "./access-service.js";
3
+ import type { LcmCompactionFlushRequest, LcmCompactionRecordRequest } from "./access-schema.js";
4
+ import type {
5
+ EngramAccessLcmCompactionFlushResponse,
6
+ EngramAccessLcmCompactionRecordResponse,
7
+ EngramAccessService,
8
+ } from "./access-service.js";
5
9
 
6
- type LcmCompactionService = Pick<EngramAccessService, "lcmCompactionFlush">;
10
+ type LcmCompactionService = Pick<EngramAccessService, "lcmCompactionFlush" | "lcmCompactionRecord">;
7
11
  type JsonResponder = (res: ServerResponse, status: number, payload: unknown) => void;
8
12
 
9
13
  export interface LcmCompactionFlushHttpOptions {
@@ -24,28 +28,55 @@ export function respondLcmCompactionCapabilitiesHttp(response: ServerResponse):
24
28
  response.end(JSON.stringify({ lcmCompactionFlushBatch: true }, null, 2));
25
29
  }
26
30
 
27
- export async function handleLcmCompactionFlushHttp({
31
+ export interface LcmCompactionFlushRunnerOptions {
32
+ body: LcmCompactionFlushRequest;
33
+ service: LcmCompactionService;
34
+ ensureWriteRateLimitAvailable: () => void;
35
+ recordWriteRateLimitHit: () => void;
36
+ resolveNamespace: (namespace?: string) => string | undefined;
37
+ defaultNamespace?: string;
38
+ resolveRequestPrincipal: () => string | undefined;
39
+ }
40
+
41
+ type LcmCompactionFlushBatchResult =
42
+ | {
43
+ namespace: string;
44
+ status: "fulfilled";
45
+ result: EngramAccessLcmCompactionFlushResponse;
46
+ }
47
+ | { namespace: string; status: "rejected" };
48
+
49
+ type LcmCompactionFlushHttpResult =
50
+ | EngramAccessLcmCompactionFlushResponse
51
+ | {
52
+ enabled: boolean;
53
+ flushed: boolean;
54
+ sessionKey: string;
55
+ namespaces: string[];
56
+ results: LcmCompactionFlushBatchResult[];
57
+ };
58
+
59
+ export async function runLcmCompactionFlushHttp({
28
60
  body,
29
61
  service,
30
- response,
31
62
  ensureWriteRateLimitAvailable,
32
63
  recordWriteRateLimitHit,
33
64
  resolveNamespace,
34
65
  defaultNamespace,
35
66
  resolveRequestPrincipal,
36
- respondJson,
37
- }: LcmCompactionFlushHttpOptions): Promise<void> {
67
+ }: LcmCompactionFlushRunnerOptions): Promise<LcmCompactionFlushHttpResult> {
38
68
  ensureWriteRateLimitAvailable();
39
69
  const requestedNamespaces = body.namespaces;
40
70
  if (requestedNamespaces === undefined) {
41
71
  const result = await service.lcmCompactionFlush({
42
72
  sessionKey: body.sessionKey,
43
73
  namespace: resolveNamespace(body.namespace),
74
+ ...(body.cwd !== undefined ? { cwd: body.cwd } : {}),
75
+ ...(body.projectTag !== undefined ? { projectTag: body.projectTag } : {}),
44
76
  authenticatedPrincipal: resolveRequestPrincipal(),
45
77
  });
46
78
  recordWriteRateLimitHit();
47
- respondJson(response, 200, result);
48
- return;
79
+ return result;
49
80
  }
50
81
  const resolutionOutcomes = await Promise.allSettled(
51
82
  requestedNamespaces.map(async (requestedNamespace) => {
@@ -74,6 +105,8 @@ export async function handleLcmCompactionFlushHttp({
74
105
  service.lcmCompactionFlush({
75
106
  sessionKey: body.sessionKey,
76
107
  namespace,
108
+ ...(body.cwd !== undefined ? { cwd: body.cwd } : {}),
109
+ ...(body.projectTag !== undefined ? { projectTag: body.projectTag } : {}),
77
110
  authenticatedPrincipal: resolveRequestPrincipal(),
78
111
  })
79
112
  )
@@ -88,29 +121,73 @@ export async function handleLcmCompactionFlushHttp({
88
121
  serviceOutcomesByEffectiveNamespace.set(resolved.effectiveNamespace, serviceOutcome);
89
122
  }
90
123
  }
91
- type BatchResult =
92
- | {
93
- requestedNamespace: string;
94
- status: "fulfilled";
95
- result: EngramAccessLcmCompactionFlushResponse;
96
- }
97
- | { requestedNamespace: string; status: "rejected" };
98
- const results: BatchResult[] = resolutionOutcomes.map((outcome, index) => {
124
+ const results = resolutionOutcomes.map((outcome, index): LcmCompactionFlushBatchResult => {
99
125
  const requestedNamespace = requestedNamespaces[index] ?? "";
100
126
  if (outcome.status === "rejected") {
101
- return { status: "rejected", requestedNamespace };
127
+ return { status: "rejected", namespace: requestedNamespace };
102
128
  }
103
129
  const serviceOutcome = serviceOutcomesByEffectiveNamespace.get(outcome.value.effectiveNamespace);
104
130
  return serviceOutcome?.status === "fulfilled"
105
- ? { status: "fulfilled", requestedNamespace, result: serviceOutcome.value }
106
- : { status: "rejected", requestedNamespace };
131
+ ? { status: "fulfilled", namespace: requestedNamespace, result: serviceOutcome.value }
132
+ : { status: "rejected", namespace: requestedNamespace };
107
133
  });
108
134
  recordWriteRateLimitHit();
109
- respondJson(response, 200, {
135
+ return {
110
136
  enabled: results.every((result) => result.status === "fulfilled" && result.result.enabled !== false),
111
137
  flushed: results.every((result) => result.status === "fulfilled" && result.result.flushed !== false),
112
138
  sessionKey: body.sessionKey,
113
139
  namespaces: requestedNamespaces,
114
- results: results.map(({ requestedNamespace, ...result }) => ({ ...result, namespace: requestedNamespace })),
140
+ results,
141
+ };
142
+ }
143
+ export async function handleLcmCompactionFlushHttp({
144
+ body,
145
+ service,
146
+ response,
147
+ ensureWriteRateLimitAvailable,
148
+ recordWriteRateLimitHit,
149
+ resolveNamespace,
150
+ defaultNamespace,
151
+ resolveRequestPrincipal,
152
+ respondJson,
153
+ }: LcmCompactionFlushHttpOptions): Promise<void> {
154
+ const result = await runLcmCompactionFlushHttp({
155
+ body,
156
+ service,
157
+ ensureWriteRateLimitAvailable,
158
+ recordWriteRateLimitHit,
159
+ resolveNamespace,
160
+ defaultNamespace,
161
+ resolveRequestPrincipal,
115
162
  });
163
+ respondJson(response, 200, result);
164
+ }
165
+
166
+ export interface LcmCompactionRecordHttpOptions {
167
+ body: LcmCompactionRecordRequest;
168
+ service: LcmCompactionService;
169
+ ensureWriteRateLimitAvailable: () => void;
170
+ recordWriteRateLimitHit: () => void;
171
+ resolveNamespace: (namespace?: string) => string | undefined;
172
+ resolveRequestPrincipal: () => string | undefined;
173
+ }
174
+
175
+ export async function runLcmCompactionRecordHttp({
176
+ body,
177
+ service,
178
+ ensureWriteRateLimitAvailable,
179
+ recordWriteRateLimitHit,
180
+ resolveNamespace,
181
+ resolveRequestPrincipal,
182
+ }: LcmCompactionRecordHttpOptions): Promise<EngramAccessLcmCompactionRecordResponse> {
183
+ ensureWriteRateLimitAvailable();
184
+ const response = await service.lcmCompactionRecord({
185
+ sessionKey: body.sessionKey,
186
+ namespace: resolveNamespace(body.namespace),
187
+ tokensBefore: body.tokensBefore,
188
+ tokensAfter: body.tokensAfter,
189
+ authenticatedPrincipal: resolveRequestPrincipal(),
190
+ });
191
+ recordWriteRateLimitHit();
192
+ return response;
116
193
  }