@remnic/core 9.30.1 → 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 (493) 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-YNQBRLC5.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/session-context.ts +193 -18
  427. package/src/orchestration/turn-ingestion.ts +61 -11
  428. package/src/orchestrator-flush.test.ts +511 -5
  429. package/src/orchestrator.ts +8 -6
  430. package/src/types.ts +2 -2
  431. package/dist/chunk-4A6YGWQN.js.map +0 -1
  432. package/dist/chunk-4WKA6I65.js.map +0 -1
  433. package/dist/chunk-4Z4XNEWZ.js.map +0 -1
  434. package/dist/chunk-6FUPCJUL.js.map +0 -1
  435. package/dist/chunk-B6JDYXL7.js.map +0 -1
  436. package/dist/chunk-GBJ4RDFR.js.map +0 -1
  437. package/dist/chunk-HUHX2OCX.js.map +0 -1
  438. package/dist/chunk-IYZ5K7MU.js.map +0 -1
  439. package/dist/chunk-LGHKJABJ.js.map +0 -1
  440. package/dist/chunk-PHWUFPCO.js.map +0 -1
  441. package/dist/chunk-RPW2NOU6.js.map +0 -1
  442. package/dist/chunk-SPJXKAVF.js.map +0 -1
  443. package/dist/chunk-YNQBRLC5.js.map +0 -1
  444. package/dist/chunk-YTSNAUXN.js.map +0 -1
  445. /package/dist/{capsule-crypto-GWVG7LGC.js.map → access-extraction-force-flush.js.map} +0 -0
  446. /package/dist/{capsule-merge-5KKJQBWQ.js.map → capsule-merge-2H2IUTBT.js.map} +0 -0
  447. /package/dist/{chunk-LEPOP46W.js.map → chunk-227UFSEQ.js.map} +0 -0
  448. /package/dist/{chunk-GIBMDSJ2.js.map → chunk-27P5YVDU.js.map} +0 -0
  449. /package/dist/{chunk-2SA56WMI.js.map → chunk-2LTDWSR6.js.map} +0 -0
  450. /package/dist/{chunk-OWHERGF2.js.map → chunk-2NLLXCJG.js.map} +0 -0
  451. /package/dist/{chunk-6U7F52DE.js.map → chunk-4XHR3I67.js.map} +0 -0
  452. /package/dist/{chunk-2EUVEDF5.js.map → chunk-5XA7PQ5I.js.map} +0 -0
  453. /package/dist/{chunk-ALSGMEJR.js.map → chunk-65ZPVYTA.js.map} +0 -0
  454. /package/dist/{chunk-5VQJBH2G.js.map → chunk-6TAUHL33.js.map} +0 -0
  455. /package/dist/{chunk-RGIWINDN.js.map → chunk-7G5MH4NT.js.map} +0 -0
  456. /package/dist/{chunk-WVO4G37W.js.map → chunk-7TEZUUGM.js.map} +0 -0
  457. /package/dist/{chunk-MJCGLM25.js.map → chunk-7VUAG236.js.map} +0 -0
  458. /package/dist/{chunk-M3C2V3PV.js.map → chunk-AJEMDQNA.js.map} +0 -0
  459. /package/dist/{chunk-RKNJBZ55.js.map → chunk-AU7Q3LSC.js.map} +0 -0
  460. /package/dist/{chunk-ACXPX4AG.js.map → chunk-BR2K43MK.js.map} +0 -0
  461. /package/dist/{chunk-CZRYLSSW.js.map → chunk-BUGVGH4N.js.map} +0 -0
  462. /package/dist/{chunk-YTQNQ4KB.js.map → chunk-C4VQMFVM.js.map} +0 -0
  463. /package/dist/{chunk-ZPSVBSOF.js.map → chunk-CIVDJD6P.js.map} +0 -0
  464. /package/dist/{chunk-K5GB36ME.js.map → chunk-CZDOT5I2.js.map} +0 -0
  465. /package/dist/{chunk-VI2JQPNQ.js.map → chunk-E4PWACUN.js.map} +0 -0
  466. /package/dist/{chunk-D2ANTDGO.js.map → chunk-E6BMSH7U.js.map} +0 -0
  467. /package/dist/{chunk-P5PXWTW7.js.map → chunk-EJCAV3QZ.js.map} +0 -0
  468. /package/dist/{chunk-CKMO4RDY.js.map → chunk-EMDLM3LW.js.map} +0 -0
  469. /package/dist/{chunk-G5R3D5UP.js.map → chunk-GTTAHHD3.js.map} +0 -0
  470. /package/dist/{chunk-H5CPS5JP.js.map → chunk-H36LJIPD.js.map} +0 -0
  471. /package/dist/{chunk-AITCS2RC.js.map → chunk-IJ7HK452.js.map} +0 -0
  472. /package/dist/{chunk-D3LMYTBV.js.map → chunk-J7WZUL2K.js.map} +0 -0
  473. /package/dist/{chunk-5W4ZLBEZ.js.map → chunk-JCFTIQBR.js.map} +0 -0
  474. /package/dist/{chunk-XOZ4ALGB.js.map → chunk-KE353EWI.js.map} +0 -0
  475. /package/dist/{chunk-W5EG6LE3.js.map → chunk-KIT6M7EB.js.map} +0 -0
  476. /package/dist/{chunk-5W7CTZ2E.js.map → chunk-KQAFEZQX.js.map} +0 -0
  477. /package/dist/{chunk-Z54EM5YZ.js.map → chunk-MAXVH44E.js.map} +0 -0
  478. /package/dist/{chunk-WZFAPHIK.js.map → chunk-MU7ZHSZE.js.map} +0 -0
  479. /package/dist/{chunk-66772WBP.js.map → chunk-NFXQJHJD.js.map} +0 -0
  480. /package/dist/{chunk-AZ5BTEKX.js.map → chunk-NQUF7XKR.js.map} +0 -0
  481. /package/dist/{chunk-W4FBGYGK.js.map → chunk-NRV4Y3PM.js.map} +0 -0
  482. /package/dist/{chunk-NHWB6HG2.js.map → chunk-NYCGIQRA.js.map} +0 -0
  483. /package/dist/{chunk-QJAQNXWI.js.map → chunk-ONHRRJZM.js.map} +0 -0
  484. /package/dist/{chunk-FDAMS4PK.js.map → chunk-PNPOWBGC.js.map} +0 -0
  485. /package/dist/{chunk-IC6CBHCA.js.map → chunk-QGENAYVS.js.map} +0 -0
  486. /package/dist/{chunk-62U4J2GN.js.map → chunk-UR77VKF7.js.map} +0 -0
  487. /package/dist/{chunk-JCBWCYEJ.js.map → chunk-VANLTS5F.js.map} +0 -0
  488. /package/dist/{chunk-RMMVQQA6.js.map → chunk-WDISJRMG.js.map} +0 -0
  489. /package/dist/{chunk-UVYI6VIX.js.map → chunk-X7Y7WX73.js.map} +0 -0
  490. /package/dist/{chunk-TH2LSRMG.js.map → chunk-XHDIB4T4.js.map} +0 -0
  491. /package/dist/{chunk-CVILPI77.js.map → chunk-XOQSEF7X.js.map} +0 -0
  492. /package/dist/{chunk-LBOD4U5B.js.map → chunk-YFOMN2II.js.map} +0 -0
  493. /package/dist/{chunk-I5NLEENJ.js.map → chunk-Z4SWV4VW.js.map} +0 -0
@@ -0,0 +1,81 @@
1
+ import type { OperationName } from "./access-boundary.js";
2
+ import { runLcmCompactionFlushHttp, runLcmCompactionRecordHttp } from "./access-http-lcm-compaction.js";
3
+ import type { LcmCompactionFlushRequest, LcmCompactionRecordRequest } from "./access-schema.js";
4
+ import type { EngramAccessExtractionForceFlushRequest, EngramAccessService } from "./access-service.js";
5
+
6
+ export interface LifecycleFlushHttpDeps {
7
+ service: Pick<EngramAccessService, "extractionForceFlush" | "lcmCompactionFlush" | "lcmCompactionRecord">;
8
+ enforceTokenOp(op: OperationName): void;
9
+ defaultNamespace?: string;
10
+ readValidatedBody(schemaName: "lcmCompactionFlush"): Promise<LcmCompactionFlushRequest>;
11
+ readValidatedBody(schemaName: "lcmCompactionRecord"): Promise<LcmCompactionRecordRequest>;
12
+ readValidatedBody(schemaName: "extractionForceFlush"): Promise<EngramAccessExtractionForceFlushRequest>;
13
+ ensureWriteRateLimitAvailable(): void;
14
+ resolveNamespace(namespace: string | undefined): string | undefined;
15
+ resolveRequestPrincipal(): string | undefined;
16
+ recordWriteRateLimitHit(): void;
17
+ respondJson(payload: unknown): void;
18
+ }
19
+
20
+ export async function maybeHandleLifecycleFlush(
21
+ deps: LifecycleFlushHttpDeps,
22
+ method: string | undefined,
23
+ pathname: string,
24
+ abortSignal: AbortSignal
25
+ ): Promise<boolean> {
26
+ if (method !== "POST") return false;
27
+ if (pathname === "/engram/v1/lcm/compaction/flush" || pathname === "/remnic/v1/lcm/compaction/flush") {
28
+ deps.enforceTokenOp("lcm_compaction_flush");
29
+ const body = await deps.readValidatedBody("lcmCompactionFlush");
30
+ const response = await runLcmCompactionFlushHttp({
31
+ body,
32
+ service: deps.service,
33
+ ensureWriteRateLimitAvailable: deps.ensureWriteRateLimitAvailable,
34
+ recordWriteRateLimitHit: deps.recordWriteRateLimitHit,
35
+ resolveNamespace: deps.resolveNamespace,
36
+ defaultNamespace: deps.defaultNamespace,
37
+ resolveRequestPrincipal: deps.resolveRequestPrincipal,
38
+ });
39
+ deps.respondJson(response);
40
+ return true;
41
+ }
42
+
43
+ if (pathname === "/engram/v1/lcm/compaction/record" || pathname === "/remnic/v1/lcm/compaction/record") {
44
+ deps.enforceTokenOp("lcm_compaction_record");
45
+ const body = await deps.readValidatedBody("lcmCompactionRecord");
46
+ const response = await runLcmCompactionRecordHttp({
47
+ body,
48
+ service: deps.service,
49
+ ensureWriteRateLimitAvailable: deps.ensureWriteRateLimitAvailable,
50
+ recordWriteRateLimitHit: deps.recordWriteRateLimitHit,
51
+ resolveNamespace: deps.resolveNamespace,
52
+ resolveRequestPrincipal: deps.resolveRequestPrincipal,
53
+ });
54
+ deps.respondJson(response);
55
+ return true;
56
+ }
57
+
58
+ if (pathname === "/engram/v1/extraction/flush" || pathname === "/remnic/v1/extraction/flush") {
59
+ deps.enforceTokenOp("extraction_force_flush");
60
+ const body = await deps.readValidatedBody("extractionForceFlush");
61
+ deps.ensureWriteRateLimitAvailable();
62
+ let writeRateLimitRecorded = false;
63
+ const recordCommittedWrite = (): void => {
64
+ if (writeRateLimitRecorded) return;
65
+ writeRateLimitRecorded = true;
66
+ deps.recordWriteRateLimitHit();
67
+ };
68
+ const response = await deps.service.extractionForceFlush({
69
+ ...body,
70
+ namespace: deps.resolveNamespace(body.namespace),
71
+ authenticatedPrincipal: deps.resolveRequestPrincipal(),
72
+ abortSignal,
73
+ onCommitted: recordCommittedWrite,
74
+ });
75
+ recordCommittedWrite();
76
+ deps.respondJson(response);
77
+ return true;
78
+ }
79
+
80
+ return false;
81
+ }
@@ -203,6 +203,72 @@ test("HTTP batch LCM flush isolates namespace failures and charges one write quo
203
203
  }
204
204
  });
205
205
 
206
+ test("HTTP LCM compaction record uses the lifecycle route and write quota", async () => {
207
+ const calls: unknown[] = [];
208
+ const service = {
209
+ lcmCompactionRecord: async (request: unknown) => {
210
+ calls.push(request);
211
+ return { enabled: true, recorded: true, sessionKey: "record-session" };
212
+ },
213
+ } as unknown as EngramAccessService;
214
+ const server = new EngramAccessHttpServer({
215
+ service,
216
+ port: 0,
217
+ authToken: "test-token",
218
+ adminConsoleEnabled: false,
219
+ writeRateLimitMaxRequests: 1,
220
+ });
221
+
222
+ const status = await server.start();
223
+ try {
224
+ const response = await fetch(`http://127.0.0.1:${status.port}/engram/v1/lcm/compaction/record`, {
225
+ method: "POST",
226
+ headers: {
227
+ authorization: "Bearer test-token",
228
+ "content-type": "application/json",
229
+ },
230
+ body: JSON.stringify({
231
+ sessionKey: "record-session",
232
+ namespace: "team-a",
233
+ tokensBefore: 100,
234
+ tokensAfter: 40,
235
+ }),
236
+ });
237
+ assert.equal(response.status, 200);
238
+ assert.deepEqual(await response.json(), {
239
+ enabled: true,
240
+ recorded: true,
241
+ sessionKey: "record-session",
242
+ });
243
+ assert.deepEqual(calls, [
244
+ {
245
+ sessionKey: "record-session",
246
+ namespace: "team-a",
247
+ tokensBefore: 100,
248
+ tokensAfter: 40,
249
+ authenticatedPrincipal: undefined,
250
+ },
251
+ ]);
252
+
253
+ const rateLimited = await fetch(`http://127.0.0.1:${status.port}/engram/v1/lcm/compaction/record`, {
254
+ method: "POST",
255
+ headers: {
256
+ authorization: "Bearer test-token",
257
+ "content-type": "application/json",
258
+ },
259
+ body: JSON.stringify({
260
+ sessionKey: "record-session",
261
+ tokensBefore: 120,
262
+ tokensAfter: 60,
263
+ }),
264
+ });
265
+ assert.equal(rateLimited.status, 429);
266
+ assert.equal(calls.length, 1);
267
+ } finally {
268
+ await server.stop();
269
+ }
270
+ });
271
+
206
272
  test("HTTP batch LCM flush deduplicates aliases after effective namespace resolution", async () => {
207
273
  const calls: Array<{ namespace?: string; sessionKey: string; authenticatedPrincipal?: string }> = [];
208
274
  const service = {
@@ -3172,6 +3238,167 @@ test("HTTP meetings build enforces the per-principal write rate limit (issue #19
3172
3238
  await server.stop();
3173
3239
  }
3174
3240
  });
3241
+ test("HTTP-MCP extraction force-flush aliases consume the write quota", async () => {
3242
+ let flushes = 0;
3243
+ const service = {
3244
+ extractionForceFlush: async () => {
3245
+ flushes += 1;
3246
+ return {
3247
+ flushed: true,
3248
+ sessionKey: "session-1",
3249
+ namespace: "default",
3250
+ effectiveNamespace: "default",
3251
+ };
3252
+ },
3253
+ } as unknown as EngramAccessService;
3254
+ const server = new EngramAccessHttpServer({
3255
+ service,
3256
+ port: 0,
3257
+ authToken: "test-token",
3258
+ adminConsoleEnabled: false,
3259
+ writeRateLimitMaxRequests: 1,
3260
+ });
3261
+ const status = await server.start();
3262
+ try {
3263
+ const responses: Response[] = [];
3264
+ for (const name of ["remnic.extraction_force_flush", "engram.extraction_force_flush"]) {
3265
+ responses.push(
3266
+ await fetch(`http://127.0.0.1:${status.port}/mcp`, {
3267
+ method: "POST",
3268
+ headers: {
3269
+ authorization: "Bearer test-token",
3270
+ "content-type": "application/json",
3271
+ },
3272
+ body: JSON.stringify({
3273
+ jsonrpc: "2.0",
3274
+ id: name,
3275
+ method: "tools/call",
3276
+ params: {
3277
+ name,
3278
+ arguments: {
3279
+ sessionKey: "session-1",
3280
+ namespace: "default",
3281
+ cwd: "/workspace/project",
3282
+ projectTag: "Acme/Webshop",
3283
+ deadlineMs: Date.now() + 60_000,
3284
+ },
3285
+ },
3286
+ }),
3287
+ }),
3288
+ );
3289
+ }
3290
+ const [first, second] = responses;
3291
+ assert.equal(first.status, 200);
3292
+ await first.text();
3293
+ assert.equal(second.status, 429);
3294
+ const rateLimited = await second.json() as { code?: string };
3295
+ assert.equal(rateLimited.code, "write_rate_limited");
3296
+ assert.equal(flushes, 1, "the rate-limited alias must not reach the service");
3297
+ } finally {
3298
+ await server.stop();
3299
+ }
3300
+ });
3301
+
3302
+ test("HTTP extraction force-flush records quota after commit when cleanup fails", async () => {
3303
+ let flushes = 0;
3304
+ let committed = 0;
3305
+ const service = {
3306
+ extractionForceFlush: async (request: {
3307
+ onCommitted?: () => void;
3308
+ }) => {
3309
+ flushes += 1;
3310
+ request.onCommitted?.();
3311
+ committed += 1;
3312
+ throw new Error("retained cleanup deadline");
3313
+ },
3314
+ } as unknown as EngramAccessService;
3315
+ const server = new EngramAccessHttpServer({
3316
+ service,
3317
+ port: 0,
3318
+ authToken: "test-token",
3319
+ adminConsoleEnabled: false,
3320
+ writeRateLimitMaxRequests: 1,
3321
+ });
3322
+ const status = await server.start();
3323
+ const flush = () =>
3324
+ fetch(`http://127.0.0.1:${status.port}/engram/v1/extraction/flush`, {
3325
+ method: "POST",
3326
+ headers: {
3327
+ authorization: "Bearer test-token",
3328
+ "content-type": "application/json",
3329
+ },
3330
+ body: JSON.stringify({ sessionKey: "session-1" }),
3331
+ });
3332
+ try {
3333
+ const first = await flush();
3334
+ assert.equal(first.status, 500);
3335
+ await first.text();
3336
+ const second = await flush();
3337
+ assert.equal(second.status, 429);
3338
+ const rateLimited = await second.json() as { code?: string };
3339
+ assert.equal(rateLimited.code, "write_rate_limited");
3340
+ assert.equal(flushes, 1);
3341
+ assert.equal(committed, 1);
3342
+ } finally {
3343
+ await server.stop();
3344
+ }
3345
+ });
3346
+
3347
+ test("HTTP-MCP extraction force-flush records quota at the commit boundary", async () => {
3348
+ let flushes = 0;
3349
+ let committed = 0;
3350
+ const service = {
3351
+ extractionForceFlush: async (request: { onCommitted?: () => void }) => {
3352
+ flushes += 1;
3353
+ if (request.onCommitted) {
3354
+ committed += 1;
3355
+ request.onCommitted();
3356
+ }
3357
+ throw new Error("retained cleanup deadline");
3358
+ },
3359
+ } as unknown as EngramAccessService;
3360
+ const server = new EngramAccessHttpServer({
3361
+ service,
3362
+ port: 0,
3363
+ authToken: "test-token",
3364
+ adminConsoleEnabled: false,
3365
+ writeRateLimitMaxRequests: 1,
3366
+ });
3367
+ const status = await server.start();
3368
+ const flush = () =>
3369
+ fetch(`http://127.0.0.1:${status.port}/mcp`, {
3370
+ method: "POST",
3371
+ headers: {
3372
+ authorization: "Bearer test-token",
3373
+ "content-type": "application/json",
3374
+ },
3375
+ body: JSON.stringify({
3376
+ jsonrpc: "2.0",
3377
+ id: "extraction-force-flush",
3378
+ method: "tools/call",
3379
+ params: {
3380
+ name: "remnic.extraction_force_flush",
3381
+ arguments: { sessionKey: "session-1" },
3382
+ },
3383
+ }),
3384
+ });
3385
+ try {
3386
+ const first = await flush();
3387
+ assert.equal(first.status, 200);
3388
+ const firstBody = (await first.json()) as {
3389
+ result?: { isError?: boolean; content?: Array<{ text?: string }> };
3390
+ };
3391
+ assert.equal(firstBody.result?.isError, true);
3392
+ const second = await flush();
3393
+ assert.equal(second.status, 429);
3394
+ const rateLimited = (await second.json()) as { code?: string };
3395
+ assert.equal(rateLimited.code, "write_rate_limited");
3396
+ assert.equal(flushes, 1, "the rate-limited MCP flush must not reach the service");
3397
+ assert.equal(committed, 1);
3398
+ } finally {
3399
+ await server.stop();
3400
+ }
3401
+ });
3175
3402
 
3176
3403
  test("HTTP meetings get returns 400 (not 500) for a malformed percent-encoded id (issue #1900)", async () => {
3177
3404
  let called = 0;
@@ -17,6 +17,7 @@ import {
17
17
  type EngramAccessMemoryResponse,
18
18
  type EngramAccessWriteResponse,
19
19
  } from "./access-service.js";
20
+ import { maybeHandleLifecycleFlush, type LifecycleFlushHttpDeps } from "./access-http-lifecycle-flush.js";
20
21
  import { CorrectionContractError } from "./correction/correction-contract.js";
21
22
  import { WearablesInputError } from "./wearables/errors.js"; import { respondMeetingsList, respondMeetingsGet, respondMeetingsBuild } from "./meetings/http-glue.js";
22
23
  import { EngramMcpServer, MCP_SUPPORTED_PROTOCOL_VERSIONS } from "./access-mcp.js";
@@ -40,7 +41,7 @@ import { projectTagProjectId } from "./coding/coding-namespace.js";
40
41
  import { getOperation, type OperationName } from "./access-boundary.js";
41
42
  import { authorizationProbeNamespaces, probeOperationAuthorization } from "./access-authorization-probe.js";
42
43
  import { resolveQueryNamespaceWritablePreflight } from "./access-namespace-preflight.js";
43
- import * as lcm from "./access-http-lcm-compaction.js";
44
+ import { respondLcmCompactionCapabilitiesHttp } from "./access-http-lcm-compaction.js";
44
45
  import {
45
46
  assertOperationAllowed,
46
47
  capabilityAllowsOp,
@@ -890,7 +891,7 @@ export class EngramAccessHttpServer {
890
891
  this.respondJson(res, 200, await this.service.health());
891
892
  return;
892
893
  }
893
- if (req.method === "GET" && pathname === "/engram/v1/capabilities") return lcm.respondLcmCompactionCapabilitiesHttp(res);
894
+ if (req.method === "GET" && pathname === "/engram/v1/capabilities") return respondLcmCompactionCapabilitiesHttp(res);
894
895
  if (req.method === "GET" && pathname === "/engram/v1/authorization") {
895
896
  res.setHeader("cache-control", "no-store");
896
897
  const probe = probeOperationAuthorization(tokenCapabilityStore.getStore(), parsed.searchParams.getAll("op"));
@@ -1668,41 +1669,9 @@ export class EngramAccessHttpServer {
1668
1669
  this.respondJson(res, 200, response);
1669
1670
  return;
1670
1671
  }
1671
-
1672
- if (
1673
- req.method === "POST" &&
1674
- (pathname === "/engram/v1/lcm/compaction/flush" || pathname === "/remnic/v1/lcm/compaction/flush")
1675
- ) {
1676
- this.enforceTokenOp("lcm_compaction_flush"); // boundary dispatch (issue #1525)
1677
- const body = await this.readValidatedBody(req, "lcmCompactionFlush");
1678
- await lcm.handleLcmCompactionFlushHttp({
1679
- body, service: this.service,
1680
- response: res, ensureWriteRateLimitAvailable: () => this.ensureWriteRateLimitAvailable(req),
1681
- recordWriteRateLimitHit: () => this.recordWriteRateLimitHit(req),
1682
- resolveNamespace: (namespace) => this.resolveNamespace(req, namespace), defaultNamespace: this.service.configRef?.defaultNamespace,
1683
- resolveRequestPrincipal: () => this.resolveRequestPrincipal(req), respondJson: this.respondJson.bind(this),
1684
- });
1685
- return;
1686
- }
1687
-
1688
- if (
1689
- req.method === "POST" &&
1690
- (pathname === "/engram/v1/lcm/compaction/record" || pathname === "/remnic/v1/lcm/compaction/record")
1691
- ) {
1692
- this.enforceTokenOp("lcm_compaction_record"); // boundary dispatch (issue #1525)
1693
- const body = await this.readValidatedBody(req, "lcmCompactionRecord");
1694
- this.ensureWriteRateLimitAvailable(req);
1695
- const response = await this.service.lcmCompactionRecord({
1696
- sessionKey: body.sessionKey,
1697
- namespace: this.resolveNamespace(req, body.namespace),
1698
- tokensBefore: body.tokensBefore,
1699
- tokensAfter: body.tokensAfter,
1700
- authenticatedPrincipal: this.resolveRequestPrincipal(req),
1701
- });
1702
- this.recordWriteRateLimitHit(req);
1703
- this.respondJson(res, 200, response);
1704
- return;
1705
- }
1672
+ if (await maybeHandleLifecycleFlush(
1673
+ this.lifecycleFlushDeps(req, res), req.method, pathname, abortSignal,
1674
+ )) return;
1706
1675
 
1707
1676
  if (req.method === "GET" && pathname === "/engram/v1/lcm/status") {
1708
1677
  this.enforceTokenOp("lcm_status"); // boundary dispatch (issue #1525)
@@ -3218,6 +3187,8 @@ export class EngramAccessHttpServer {
3218
3187
  toolName === "remnic.observe" ||
3219
3188
  toolName === "engram.lcm_compaction_flush" ||
3220
3189
  toolName === "remnic.lcm_compaction_flush" ||
3190
+ toolName === "engram.extraction_force_flush" ||
3191
+ toolName === "remnic.extraction_force_flush" ||
3221
3192
  toolName === "engram.lcm_compaction_record" ||
3222
3193
  toolName === "remnic.lcm_compaction_record" ||
3223
3194
  toolName === "engram.capsule_export" ||
@@ -3254,6 +3225,16 @@ export class EngramAccessHttpServer {
3254
3225
  // the record). Other write tools keep the coarse pre-check.
3255
3226
  const observeSelfEnforcesQuota =
3256
3227
  toolName === "engram.observe" || toolName === "remnic.observe";
3228
+ const extractionForceFlushWrite =
3229
+ toolName === "engram.extraction_force_flush" || toolName === "remnic.extraction_force_flush";
3230
+ let writeRateLimitRecorded = false;
3231
+ const recordCommittedMcpWrite = extractionForceFlushWrite
3232
+ ? () => {
3233
+ if (writeRateLimitRecorded) return;
3234
+ writeRateLimitRecorded = true;
3235
+ this.recordWriteRateLimitHit(req);
3236
+ }
3237
+ : undefined;
3257
3238
  if (isMcpWrite && !observeSelfEnforcesQuota) {
3258
3239
  this.ensureWriteRateLimitAvailable(req);
3259
3240
  }
@@ -3296,6 +3277,7 @@ export class EngramAccessHttpServer {
3296
3277
  enforceWriteQuota: observeSelfEnforcesQuota
3297
3278
  ? () => this.ensureWriteRateLimitAvailable(req)
3298
3279
  : undefined,
3280
+ recordWriteCommit: recordCommittedMcpWrite,
3299
3281
  sourceConnector: this.resolveConnector(req),
3300
3282
  abortSignal,
3301
3283
  });
@@ -3317,8 +3299,9 @@ export class EngramAccessHttpServer {
3317
3299
  // consumed a write — count it. Tools WITH structuredContent use the
3318
3300
  // dryRun/idempotencyReplay guards.
3319
3301
  const counts = structured ? this.shouldCountWriteRateLimit(structured) : true;
3320
- if (!isError && !isRejectedCodegraph && counts) {
3302
+ if (!writeRateLimitRecorded && !isError && !isRejectedCodegraph && counts) {
3321
3303
  this.recordWriteRateLimitHit(req);
3304
+ writeRateLimitRecorded = true;
3322
3305
  }
3323
3306
  }
3324
3307
  // A mutating tool may have committed just before the client disconnected.
@@ -3621,7 +3604,6 @@ export class EngramAccessHttpServer {
3621
3604
  }
3622
3605
  return parsed;
3623
3606
  }
3624
-
3625
3607
  private parseOptionalBooleanHeader(
3626
3608
  req: IncomingMessage,
3627
3609
  name: string,
@@ -3633,7 +3615,18 @@ export class EngramAccessHttpServer {
3633
3615
  if (raw === "false") return false;
3634
3616
  throw new EngramAccessInputError(`${name} header must be one of: true, false`);
3635
3617
  }
3636
-
3618
+ private lifecycleFlushDeps(req: IncomingMessage, res: ServerResponse): LifecycleFlushHttpDeps {
3619
+ const readValidatedBody = ((schemaName: SchemaName) => this.readValidatedBody(req, schemaName)) as LifecycleFlushHttpDeps["readValidatedBody"];
3620
+ return { service: this.service, defaultNamespace: this.service.configRef?.defaultNamespace,
3621
+ enforceTokenOp: (op) => this.enforceTokenOp(op),
3622
+ readValidatedBody,
3623
+ ensureWriteRateLimitAvailable: () => this.ensureWriteRateLimitAvailable(req),
3624
+ resolveNamespace: (namespace) => this.resolveNamespace(req, namespace),
3625
+ resolveRequestPrincipal: () => this.resolveRequestPrincipal(req),
3626
+ recordWriteRateLimitHit: () => this.recordWriteRateLimitHit(req),
3627
+ respondJson: (payload) => this.respondJson(res, 200, payload),
3628
+ };
3629
+ }
3637
3630
  private async readValidatedBody<S extends SchemaName>(
3638
3631
  req: IncomingMessage,
3639
3632
  schemaName: S,
@@ -167,6 +167,12 @@ const TOOL_OUTPUT_SCHEMAS: Readonly<Record<string, Record<string, unknown>>> = {
167
167
  sessionKey: T_STRING,
168
168
  namespace: T_STRING,
169
169
  }),
170
+ extraction_force_flush: objectSchema({
171
+ flushed: T_BOOLEAN,
172
+ sessionKey: T_STRING,
173
+ namespace: T_STRING,
174
+ effectiveNamespace: T_STRING,
175
+ }),
170
176
  lcm_compaction_record: objectSchema({
171
177
  enabled: T_BOOLEAN,
172
178
  recorded: T_BOOLEAN,
@@ -850,17 +850,57 @@ test("MCP LCM compaction flush dispatches sanitized args to the access service",
850
850
  makeToolRequest("remnic.lcm_compaction_flush", {
851
851
  sessionKey: "pi:session",
852
852
  namespace: "work",
853
+ cwd: "/workspace/project",
854
+ projectTag: "Acme/Webshop",
853
855
  }),
854
856
  );
855
857
 
856
858
  assert.deepEqual(received, {
857
859
  sessionKey: "pi:session",
858
860
  namespace: "work",
861
+ cwd: "/workspace/project",
862
+ projectTag: "Acme/Webshop",
859
863
  authenticatedPrincipal: undefined,
860
864
  });
861
865
  assert.equal((response as Record<string, unknown> & { result?: { isError?: boolean } }).result?.isError, false);
862
866
  });
863
867
 
868
+ test("MCP extraction force-flush dispatches scope, deadline, and cancellation to the access service", async () => {
869
+ let received: Record<string, unknown> | undefined;
870
+ const service = {
871
+ ...makeMockService(),
872
+ extractionForceFlush: async (args: Record<string, unknown>) => {
873
+ received = args;
874
+ return { flushed: true, sessionKey: "pi:session", namespace: "work", effectiveNamespace: "work" };
875
+ },
876
+ } as unknown as EngramAccessService;
877
+ const server = new EngramMcpServer(service);
878
+ const abortController = new AbortController();
879
+
880
+ const response = await server.handleRequest(
881
+ makeToolRequest("remnic.extraction_force_flush", {
882
+ sessionKey: "pi:session",
883
+ namespace: "work",
884
+ cwd: "/workspace/project",
885
+ projectTag: "Acme/Webshop",
886
+ deadlineMs: 1_900_000_000_000,
887
+ }),
888
+ { abortSignal: abortController.signal },
889
+ );
890
+
891
+ assert.deepEqual(received, {
892
+ sessionKey: "pi:session",
893
+ namespace: "work",
894
+ cwd: "/workspace/project",
895
+ projectTag: "Acme/Webshop",
896
+ deadlineMs: 1_900_000_000_000,
897
+ authenticatedPrincipal: undefined,
898
+ onCommitted: undefined,
899
+ abortSignal: abortController.signal,
900
+ });
901
+ assert.equal((response as Record<string, unknown> & { result?: { isError?: boolean } }).result?.isError, false);
902
+ });
903
+
864
904
  test("MCP tools/list exposes LCM compaction tools under remnic aliases", async () => {
865
905
  const server = new EngramMcpServer(makeMockService());
866
906
 
package/src/access-mcp.ts CHANGED
@@ -72,6 +72,12 @@ type McpRequestOptions = {
72
72
  * the write-rate-limit window); the standalone MCP server has no quota.
73
73
  */
74
74
  enforceWriteQuota?: () => void | Promise<void>;
75
+ /**
76
+ * Called once when a lifecycle write reaches its durable commit boundary.
77
+ * HTTP transports use this to account writes even when post-commit work
78
+ * fails or the client disconnects before a response is available.
79
+ */
80
+ recordWriteCommit?: () => void;
75
81
  /**
76
82
  * Server-resolved connector identity (Phase 1 provenance). Set by the HTTP
77
83
  * auth boundary from the matched token entry's connector; threaded into
@@ -207,6 +213,7 @@ const MCP_MIGRATED_OPERATIONS: Readonly<Record<string, OperationName>> = {
207
213
  "engram.observe": "observe",
208
214
  "engram.lcm_search": "lcm_search",
209
215
  "engram.lcm_compaction_flush": "lcm_compaction_flush",
216
+ "engram.extraction_force_flush": "extraction_force_flush",
210
217
  "engram.lcm_compaction_record": "lcm_compaction_record",
211
218
  "engram.continuity_audit_generate": "continuity_audit_generate",
212
219
  "engram.continuity_incident_open": "continuity_incident_open",
@@ -1062,6 +1069,24 @@ export class EngramMcpServer {
1062
1069
  properties: {
1063
1070
  sessionKey: { type: "string", description: "Conversation session identifier" },
1064
1071
  namespace: { type: "string" },
1072
+ cwd: { type: "string", description: "Working directory for auto git-context resolution." },
1073
+ projectTag: { type: "string", description: "Project tag for non-git project scoping." },
1074
+ },
1075
+ required: ["sessionKey"],
1076
+ additionalProperties: false,
1077
+ },
1078
+ },
1079
+ {
1080
+ name: "engram.extraction_force_flush",
1081
+ description: "Force-drain a session extraction buffer before a lifecycle boundary.",
1082
+ inputSchema: {
1083
+ type: "object",
1084
+ properties: {
1085
+ sessionKey: { type: "string", description: "Conversation session identifier" },
1086
+ namespace: { type: "string" },
1087
+ cwd: { type: "string", description: "Working directory for auto git-context resolution." },
1088
+ projectTag: { type: "string", description: "Project tag for non-git project scoping." },
1089
+ deadlineMs: { type: "number", minimum: 0 },
1065
1090
  },
1066
1091
  required: ["sessionKey"],
1067
1092
  additionalProperties: false,
@@ -2413,6 +2438,7 @@ export class EngramMcpServer {
2413
2438
  options?.sessionId,
2414
2439
  mcpScope,
2415
2440
  options?.enforceWriteQuota,
2441
+ options?.recordWriteCommit,
2416
2442
  options?.sourceConnector,
2417
2443
  options?.abortSignal,
2418
2444
  );
@@ -2629,6 +2655,7 @@ export class EngramMcpServer {
2629
2655
  mcpSessionId?: string,
2630
2656
  scope?: { namespace?: string; sessionKey?: string },
2631
2657
  enforceWriteQuota?: () => void | Promise<void>,
2658
+ recordWriteCommit?: () => void,
2632
2659
  sourceConnector?: string,
2633
2660
  abortSignal?: AbortSignal,
2634
2661
  ): Promise<unknown> {
@@ -2659,6 +2686,8 @@ export class EngramMcpServer {
2659
2686
  envelope = parseMcpRequest("observe", args);
2660
2687
  } else if (migrated === "lcm_compaction_flush") {
2661
2688
  envelope = parseMcpRequest("lcmCompactionFlush", args);
2689
+ } else if (migrated === "extraction_force_flush") {
2690
+ envelope = parseMcpRequest("extractionForceFlush", args);
2662
2691
  } else if (migrated === "lcm_compaction_record") {
2663
2692
  envelope = parseMcpRequest("lcmCompactionRecord", args);
2664
2693
  } else if (migrated.startsWith("codegraph_")) {
@@ -2730,7 +2759,9 @@ export class EngramMcpServer {
2730
2759
  const output = (await op.run(envelope, {
2731
2760
  service: this.service,
2732
2761
  authenticatedPrincipal: effectivePrincipal,
2733
- ...(enforceWriteQuota ? { hooks: { enforceWriteQuota } } : {}),
2762
+ ...(enforceWriteQuota || recordWriteCommit
2763
+ ? { hooks: { ...(enforceWriteQuota ? { enforceWriteQuota } : {}), ...(recordWriteCommit ? { recordWriteCommit } : {}) } }
2764
+ : {}),
2734
2765
  ...(sourceConnector ? { sourceConnector } : {}),
2735
2766
  ...(abortSignal ? { abortSignal } : {}),
2736
2767
  })) as { result: unknown };