@remnic/core 10.0.84 → 10.0.86

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 (545) hide show
  1. package/dist/access-admin-ops-surface.js +90 -88
  2. package/dist/access-authorization-probe.js +91 -89
  3. package/dist/access-boundary.d.ts.map +1 -1
  4. package/dist/access-boundary.js +90 -88
  5. package/dist/access-cli.js +198 -194
  6. package/dist/access-cli.js.map +1 -1
  7. package/dist/access-errors.d.ts +14 -0
  8. package/dist/access-errors.d.ts.map +1 -1
  9. package/dist/access-errors.js +5 -1
  10. package/dist/access-extraction-force-flush.js +90 -88
  11. package/dist/access-http-briefing.js +91 -89
  12. package/dist/access-http-query.js +92 -90
  13. package/dist/access-http.d.ts +12 -0
  14. package/dist/access-http.d.ts.map +1 -1
  15. package/dist/access-http.js +119 -116
  16. package/dist/access-identity-continuity-surface.js +90 -88
  17. package/dist/access-lcm-surface.js +90 -88
  18. package/dist/access-mcp-frames.d.ts +29 -0
  19. package/dist/access-mcp-frames.d.ts.map +1 -0
  20. package/dist/access-mcp-frames.js +10 -0
  21. package/dist/access-mcp.d.ts +1 -1
  22. package/dist/access-mcp.d.ts.map +1 -1
  23. package/dist/access-mcp.js +105 -102
  24. package/dist/access-memory-search-fanout.js +2 -2
  25. package/dist/access-namespace-preflight.js +90 -88
  26. package/dist/access-observe-write-category.js +15 -14
  27. package/dist/access-observe-write-surface.d.ts.map +1 -1
  28. package/dist/access-observe-write-surface.js +90 -88
  29. package/dist/access-offline-manifest.js +10 -10
  30. package/dist/access-operations-batch.js +94 -92
  31. package/dist/access-operations.js +101 -99
  32. package/dist/access-recall-concurrency.js +90 -88
  33. package/dist/access-recall-diagnostics.js +2 -2
  34. package/dist/access-recall-response.js +90 -88
  35. package/dist/access-recall-surface.js +90 -88
  36. package/dist/access-schema.d.ts.map +1 -1
  37. package/dist/access-schema.js +10 -9
  38. package/dist/access-service.d.ts +3 -3
  39. package/dist/access-service.d.ts.map +1 -1
  40. package/dist/access-service.js +90 -88
  41. package/dist/access-surface-catalog.js +92 -90
  42. package/dist/access-surface-catalog.js.map +1 -1
  43. package/dist/access-token-capabilities.js +2 -2
  44. package/dist/active-recall.js +38 -38
  45. package/dist/adapters/index.js +7 -7
  46. package/dist/adapters/registry.js +3 -3
  47. package/dist/{auto-sync-C7E6G7Y2.js → auto-sync-3AZW7MXI.js} +6 -6
  48. package/dist/briefing-deadline.d.ts +2 -2
  49. package/dist/briefing-deadline.d.ts.map +1 -1
  50. package/dist/briefing-deadline.js +1 -1
  51. package/dist/briefing.js +25 -25
  52. package/dist/buffer-admission.d.ts +22 -0
  53. package/dist/buffer-admission.d.ts.map +1 -0
  54. package/dist/buffer-admission.js +13 -0
  55. package/dist/buffer-eviction.d.ts +4 -5
  56. package/dist/buffer-eviction.d.ts.map +1 -1
  57. package/dist/buffer-eviction.js +1 -1
  58. package/dist/buffer-persistence.d.ts +8 -4
  59. package/dist/buffer-persistence.d.ts.map +1 -1
  60. package/dist/buffer-persistence.js +1 -1
  61. package/dist/buffer-turn-helpers.d.ts +12 -0
  62. package/dist/buffer-turn-helpers.d.ts.map +1 -1
  63. package/dist/buffer-turn-helpers.js +9 -1
  64. package/dist/buffer-types.d.ts +24 -1
  65. package/dist/buffer-types.d.ts.map +1 -1
  66. package/dist/buffer.d.ts +21 -19
  67. package/dist/buffer.d.ts.map +1 -1
  68. package/dist/buffer.js +17 -13
  69. package/dist/calibration.js +3 -3
  70. package/dist/{capsule-crypto-YO5QJ6L3.js → capsule-crypto-7FJQINUR.js} +2 -2
  71. package/dist/capsule-gunzip-KGBDGF7P.js +11 -0
  72. package/dist/capsule-gunzip-KGBDGF7P.js.map +1 -0
  73. package/dist/capsule-import-gate.d.ts +11 -0
  74. package/dist/capsule-import-gate.d.ts.map +1 -0
  75. package/dist/capsule-import-gate.js +12 -0
  76. package/dist/capsule-import-gate.js.map +1 -0
  77. package/dist/{capsule-merge-XVTQJJ6R.js → capsule-merge-2IIXFXN5.js} +5 -11
  78. package/dist/capsule-merge-2IIXFXN5.js.map +1 -0
  79. package/dist/causal-behavior.js +2 -2
  80. package/dist/causal-chain.js +2 -2
  81. package/dist/causal-consolidation.js +27 -27
  82. package/dist/causal-retrieval.js +2 -2
  83. package/dist/causal-trajectory-graph.js +2 -2
  84. package/dist/causal-trajectory.js +1 -1
  85. package/dist/{chunk-MSIRVXQ3.js → chunk-2G4TV2ML.js} +12 -12
  86. package/dist/{chunk-B74NPUHT.js → chunk-2JG2NI7C.js} +54 -54
  87. package/dist/chunk-2JG2NI7C.js.map +1 -0
  88. package/dist/{chunk-IR4C3DP2.js → chunk-2K3AUDH7.js} +2 -2
  89. package/dist/{chunk-2IW5PT7U.js → chunk-2N4OUSIA.js} +2 -2
  90. package/dist/{chunk-BXLOS5AJ.js → chunk-2NLLXCJG.js} +2 -2
  91. package/dist/{chunk-QZSIDSB2.js → chunk-2NUDHVYM.js} +2 -2
  92. package/dist/{chunk-HPFVZPRH.js → chunk-2U4LMSEX.js} +3 -3
  93. package/dist/{chunk-WHQXWFH7.js → chunk-2XOFVTTT.js} +2 -2
  94. package/dist/{chunk-I6ORDT54.js → chunk-32CA7B6L.js} +2 -2
  95. package/dist/{chunk-T77AX6DG.js → chunk-32YX7EJ3.js} +4 -4
  96. package/dist/{chunk-HLKUZW42.js → chunk-3CTKEXXF.js} +144 -156
  97. package/dist/chunk-3CTKEXXF.js.map +1 -0
  98. package/dist/{chunk-HLWXCDUQ.js → chunk-3DAWHP5K.js} +5 -5
  99. package/dist/{chunk-ZJJFUEPO.js → chunk-3PJEDHLD.js} +2 -2
  100. package/dist/{chunk-PJYK7HH2.js → chunk-3UZ2VMKD.js} +2 -2
  101. package/dist/{chunk-IN4OFAHX.js → chunk-3Y5X6YFH.js} +2 -2
  102. package/dist/{chunk-YUTT4ZTI.js → chunk-45VUHDV2.js} +2 -2
  103. package/dist/{chunk-T6T2RMWW.js → chunk-4GMI5HFH.js} +12 -12
  104. package/dist/{chunk-YOEYL6CH.js → chunk-4LCVA2LW.js} +3 -3
  105. package/dist/{chunk-66JOLMWS.js → chunk-4X7HQKAG.js} +2 -2
  106. package/dist/{chunk-65SKM4BF.js → chunk-4XYAWK5H.js} +2 -2
  107. package/dist/{chunk-H7BZBSP6.js → chunk-52II7PB6.js} +4 -4
  108. package/dist/{chunk-TPX7XXY4.js → chunk-5SOSQTVE.js} +2 -2
  109. package/dist/{chunk-G3T6YMBO.js → chunk-64S6X4IU.js} +7 -7
  110. package/dist/{chunk-BK7AJUWB.js → chunk-6BCWFCDG.js} +7 -7
  111. package/dist/{chunk-V27FK6D6.js → chunk-6XTUZKCZ.js} +2 -2
  112. package/dist/{chunk-KASJJGRG.js → chunk-6ZELOK6O.js} +3 -8
  113. package/dist/chunk-6ZELOK6O.js.map +1 -0
  114. package/dist/{chunk-LECSS7EE.js → chunk-73UZZFJC.js} +3 -3
  115. package/dist/{chunk-4EACCIPO.js → chunk-77PDJ4OE.js} +3 -3
  116. package/dist/{chunk-GQZSGXR6.js → chunk-7GSL4LBG.js} +2 -2
  117. package/dist/{chunk-B6SPPYGJ.js → chunk-7IWRLYFJ.js} +2 -2
  118. package/dist/{chunk-R45L4TV6.js → chunk-7LCGFUMB.js} +6 -6
  119. package/dist/{chunk-A7BM2JTH.js → chunk-AJHNXIQU.js} +2 -2
  120. package/dist/{chunk-2D7BTSDW.js → chunk-ANZZLRUX.js} +2 -2
  121. package/dist/{chunk-ZXF3O7P4.js → chunk-ARRTLPRC.js} +2 -2
  122. package/dist/{chunk-S5CQI2KF.js → chunk-B3GKQ6DU.js} +2 -2
  123. package/dist/{chunk-XRBHIR7Q.js → chunk-B56LORLY.js} +2 -2
  124. package/dist/{chunk-KO3YBHOV.js → chunk-BIVKPQ6Q.js} +3 -3
  125. package/dist/{chunk-QZBTIYKD.js → chunk-BLSHFIR6.js} +7 -6
  126. package/dist/chunk-BLSHFIR6.js.map +1 -0
  127. package/dist/{chunk-54FDG7K7.js → chunk-C2HORX76.js} +3 -3
  128. package/dist/{chunk-WAD32CZG.js → chunk-CC4V7HNP.js} +43 -30
  129. package/dist/chunk-CC4V7HNP.js.map +1 -0
  130. package/dist/{chunk-LGEH473S.js → chunk-CJCTKL6Y.js} +9 -1
  131. package/dist/chunk-CJCTKL6Y.js.map +1 -0
  132. package/dist/{chunk-E33UJHY3.js → chunk-CN7Q3T2J.js} +4 -4
  133. package/dist/{chunk-YUTG35M4.js → chunk-CYCEROPR.js} +3 -3
  134. package/dist/{chunk-TFLPDNQV.js → chunk-D5EV6Y2L.js} +3 -3
  135. package/dist/{chunk-BFBS7OFQ.js → chunk-DC55RIEZ.js} +4 -4
  136. package/dist/{chunk-B4ZU34JQ.js → chunk-DT7SNJH6.js} +3 -3
  137. package/dist/{chunk-VLMBSGQF.js → chunk-DZ7DPDVW.js} +10 -8
  138. package/dist/chunk-DZ7DPDVW.js.map +1 -0
  139. package/dist/{chunk-FVRTCYZ3.js → chunk-EA2LA5RI.js} +2 -2
  140. package/dist/{chunk-WBN66HPI.js → chunk-ELHJK7LM.js} +6 -6
  141. package/dist/{chunk-77R7BQZ2.js → chunk-EQ4U73UH.js} +77 -24
  142. package/dist/chunk-EQ4U73UH.js.map +1 -0
  143. package/dist/{chunk-3JPTUCD7.js → chunk-EUBDYOLD.js} +32 -23
  144. package/dist/chunk-EUBDYOLD.js.map +1 -0
  145. package/dist/{chunk-YNDLCWXS.js → chunk-EZ25VE3G.js} +4 -4
  146. package/dist/{chunk-YAUHSNPB.js → chunk-F74G4KIH.js} +2 -2
  147. package/dist/{chunk-MPGLM2VU.js → chunk-FF3EFLUT.js} +7 -5
  148. package/dist/chunk-FF3EFLUT.js.map +1 -0
  149. package/dist/{chunk-BV2BRHD4.js → chunk-FHGWKODN.js} +2 -2
  150. package/dist/chunk-FKBGK3NC.js +62 -0
  151. package/dist/chunk-FKBGK3NC.js.map +1 -0
  152. package/dist/{chunk-X2KO4FK5.js → chunk-FNFURZBZ.js} +5 -5
  153. package/dist/chunk-FNFURZBZ.js.map +1 -0
  154. package/dist/{chunk-KESJ5XX3.js → chunk-G54BOKZ6.js} +2 -2
  155. package/dist/{chunk-YK7GOPIE.js → chunk-G67EUQAB.js} +9 -7
  156. package/dist/chunk-G67EUQAB.js.map +1 -0
  157. package/dist/{chunk-K36RMINQ.js → chunk-GOZXQNIM.js} +3 -3
  158. package/dist/{chunk-OQSSQOKQ.js → chunk-GULUWOA5.js} +2 -2
  159. package/dist/{chunk-K6RTQZA4.js → chunk-HFUKXOUW.js} +2 -2
  160. package/dist/{chunk-WV254W4V.js → chunk-HLN2HOXX.js} +2 -2
  161. package/dist/{chunk-FUOAIJKQ.js → chunk-IBDWYRDR.js} +3 -3
  162. package/dist/{chunk-Z3DDQXM4.js → chunk-IBGU6AN6.js} +45 -45
  163. package/dist/chunk-IBGU6AN6.js.map +1 -0
  164. package/dist/{chunk-AJG2TAMR.js → chunk-IEEV27BC.js} +2 -2
  165. package/dist/chunk-IGLJNHOX.js +62 -0
  166. package/dist/chunk-IGLJNHOX.js.map +1 -0
  167. package/dist/{chunk-LTDLJCMQ.js → chunk-IJ3OEECW.js} +4 -4
  168. package/dist/{chunk-BK4FBHZ3.js → chunk-IPD5GC7C.js} +3 -3
  169. package/dist/{chunk-KFLD7ZZG.js → chunk-IUKYFTGW.js} +3 -3
  170. package/dist/{chunk-GCAQ3VUJ.js → chunk-JM2YZKCQ.js} +2 -2
  171. package/dist/{chunk-BNQJKWWZ.js → chunk-K3FH3LAQ.js} +4 -4
  172. package/dist/{chunk-LU66I56Q.js → chunk-KVSOEVAF.js} +61 -12
  173. package/dist/chunk-KVSOEVAF.js.map +1 -0
  174. package/dist/chunk-M3BEJJNV.js +31 -0
  175. package/dist/chunk-M3BEJJNV.js.map +1 -0
  176. package/dist/{chunk-RZH5RVJC.js → chunk-MTTYIXSU.js} +2 -2
  177. package/dist/{chunk-XHGYZRVW.js → chunk-NIVKG3DS.js} +5 -5
  178. package/dist/{chunk-VZELUMKK.js → chunk-NQP4ZYGG.js} +2 -2
  179. package/dist/{chunk-7PMOCQOL.js → chunk-NT7F7WJQ.js} +192 -63
  180. package/dist/chunk-NT7F7WJQ.js.map +1 -0
  181. package/dist/{chunk-YO2JEX2Z.js → chunk-OGBQMY46.js} +2 -2
  182. package/dist/{chunk-TLHF75OR.js → chunk-OL553AWT.js} +12 -12
  183. package/dist/{chunk-CLVILSBR.js → chunk-OZNBZJ3S.js} +22 -22
  184. package/dist/{chunk-VUROWXFL.js → chunk-P452SEKO.js} +2 -2
  185. package/dist/{chunk-JX3E4XCW.js → chunk-PDOOUXCS.js} +2 -2
  186. package/dist/{chunk-6QYPL6NI.js → chunk-PKZ274PI.js} +3 -3
  187. package/dist/{chunk-KJCL2FZO.js → chunk-QD5R6U5J.js} +2 -2
  188. package/dist/{chunk-JRVMCZE3.js → chunk-QEYTRFR3.js} +2 -2
  189. package/dist/{chunk-VKDAJJQP.js → chunk-QEZ3DW5O.js} +11 -11
  190. package/dist/{chunk-WYPCJK6K.js → chunk-QKERFEJS.js} +2 -2
  191. package/dist/{chunk-BDN3TDGV.js → chunk-QKES7GU6.js} +2 -2
  192. package/dist/{chunk-PCQWKMOL.js → chunk-QNSZYTSG.js} +2 -2
  193. package/dist/chunk-QV2VZKD5.js +31 -0
  194. package/dist/chunk-QV2VZKD5.js.map +1 -0
  195. package/dist/{chunk-IZJQNDGI.js → chunk-R6HMAIKM.js} +2 -2
  196. package/dist/{chunk-CIIHIAJ2.js → chunk-ROGO7FRA.js} +6 -5
  197. package/dist/{chunk-CIIHIAJ2.js.map → chunk-ROGO7FRA.js.map} +1 -1
  198. package/dist/{chunk-NUSAAN75.js → chunk-ROKDHO74.js} +2 -2
  199. package/dist/{chunk-D5SSBCYY.js → chunk-RWGRSKN5.js} +7 -5
  200. package/dist/chunk-RWGRSKN5.js.map +1 -0
  201. package/dist/{chunk-FF6N7BXC.js → chunk-S45INSV3.js} +4 -4
  202. package/dist/{chunk-2RUTN7PR.js → chunk-S7GJNA3K.js} +2 -2
  203. package/dist/{chunk-XT45WCKX.js → chunk-SYKJBS7S.js} +10 -10
  204. package/dist/{chunk-5BE3FLKL.js → chunk-TAUHAP5J.js} +4 -4
  205. package/dist/{chunk-RJWL3RHB.js → chunk-TFEHSPGQ.js} +2 -2
  206. package/dist/{chunk-XYP5WBDO.js → chunk-TQ4SCPGQ.js} +76 -60
  207. package/dist/chunk-TQ4SCPGQ.js.map +1 -0
  208. package/dist/{chunk-K3B72DKJ.js → chunk-TRMZHGIX.js} +8 -8
  209. package/dist/{chunk-WBDIZWJQ.js → chunk-TSS3D7ZY.js} +2 -2
  210. package/dist/{chunk-6LCWKS62.js → chunk-UAUV3BWS.js} +104 -121
  211. package/dist/chunk-UAUV3BWS.js.map +1 -0
  212. package/dist/{chunk-KQUSP6LB.js → chunk-UDKWFDV2.js} +1 -1
  213. package/dist/chunk-UDKWFDV2.js.map +1 -0
  214. package/dist/{chunk-HQPFACXO.js → chunk-UH3FPX3L.js} +2 -2
  215. package/dist/{chunk-GGJFRVRD.js → chunk-US7KPQA5.js} +2 -2
  216. package/dist/{chunk-FJ2VJTGA.js → chunk-UWRHHRDK.js} +3 -3
  217. package/dist/{chunk-4KLQI3L2.js → chunk-UXXK523X.js} +40 -2
  218. package/dist/chunk-UXXK523X.js.map +1 -0
  219. package/dist/{chunk-SDESKFKT.js → chunk-UYHDMCY2.js} +2 -2
  220. package/dist/{chunk-3T3VHXUH.js → chunk-VKILERSL.js} +2 -2
  221. package/dist/{chunk-2TGIKMMZ.js → chunk-WXDTOE6F.js} +2 -2
  222. package/dist/{chunk-KQLBXUUQ.js → chunk-WYG5UNDY.js} +2 -2
  223. package/dist/{chunk-DQEMWVMT.js → chunk-X7Y7WX73.js} +1 -1
  224. package/dist/{chunk-MPDLLLOG.js → chunk-XO23OKMK.js} +9 -5
  225. package/dist/chunk-XO23OKMK.js.map +1 -0
  226. package/dist/{chunk-WC475JOG.js → chunk-XU37EJTW.js} +24 -24
  227. package/dist/chunk-XU37EJTW.js.map +1 -0
  228. package/dist/{chunk-FZVROZKC.js → chunk-XVZA6VXC.js} +4 -4
  229. package/dist/{chunk-QA3Y2O6H.js → chunk-YAVIBVCU.js} +2 -2
  230. package/dist/{chunk-2XJZLSXE.js → chunk-YL4UKMD7.js} +124 -58
  231. package/dist/chunk-YL4UKMD7.js.map +1 -0
  232. package/dist/{chunk-VPEIWMUT.js → chunk-YLTU2DC4.js} +2 -2
  233. package/dist/{chunk-HWHNQVRV.js → chunk-YMJRLT7S.js} +28 -8
  234. package/dist/chunk-YMJRLT7S.js.map +1 -0
  235. package/dist/{chunk-EBOHFZI4.js → chunk-YRZPBN46.js} +3 -3
  236. package/dist/{chunk-FMFCQRDM.js → chunk-ZANNIXXE.js} +3 -3
  237. package/dist/{chunk-HQGATKG2.js → chunk-ZBFLV657.js} +3 -3
  238. package/dist/{chunk-6L63IN3M.js → chunk-ZOJUWVAU.js} +1 -1
  239. package/dist/cli.js +144 -141
  240. package/dist/coding/export-okf-codegraph.js +24 -24
  241. package/dist/coding/pre-action-gate.js +2 -2
  242. package/dist/compounding/engine.js +26 -26
  243. package/dist/config.js +35 -35
  244. package/dist/connectors/codex-materialize-runner.js +24 -24
  245. package/dist/connectors/index.js +28 -28
  246. package/dist/contradiction/index.js +4 -4
  247. package/dist/convergence-refresh.js +26 -26
  248. package/dist/corpus-watermark.js +28 -28
  249. package/dist/dashboard-runtime.js +2 -2
  250. package/dist/deep-recall-config.js +2 -2
  251. package/dist/deep-recall-http-glue.js +12 -12
  252. package/dist/entity-retrieval.js +25 -25
  253. package/dist/event-order-recall.js +2 -2
  254. package/dist/explicit-capture.js +6 -6
  255. package/dist/external-wiki-access.js +91 -89
  256. package/dist/extraction-evidence-class.js +2 -2
  257. package/dist/extraction-quote-grounding.d.ts +5 -1
  258. package/dist/extraction-quote-grounding.d.ts.map +1 -1
  259. package/dist/extraction-quote-grounding.js +1 -1
  260. package/dist/extraction-source-grounding-rules.d.ts +3 -1
  261. package/dist/extraction-source-grounding-rules.d.ts.map +1 -1
  262. package/dist/extraction-source-grounding-rules.js +2 -2
  263. package/dist/extraction-source-grounding.d.ts +1 -1
  264. package/dist/extraction-source-grounding.d.ts.map +1 -1
  265. package/dist/extraction-source-grounding.js +5 -5
  266. package/dist/extraction-span-materialize.js +2 -2
  267. package/dist/extraction.d.ts.map +1 -1
  268. package/dist/extraction.js +43 -43
  269. package/dist/{first-start-migration-QVD22WWS.js → first-start-migration-A6PHIBUQ.js} +4 -4
  270. package/dist/{graph-edge-decay-CXTNJ7IQ.js → graph-edge-decay-EKWXRBWF.js} +5 -5
  271. package/dist/graph-edge-decay-EKWXRBWF.js.map +1 -0
  272. package/dist/graph-jsonl.js +3 -3
  273. package/dist/graph-snapshot.js +3 -3
  274. package/dist/graph.js +2 -2
  275. package/dist/harmonic-retrieval.js +24 -24
  276. package/dist/index.js +255 -251
  277. package/dist/lcm/engine.js +2 -2
  278. package/dist/lcm/index.js +5 -5
  279. package/dist/local-llm.js +3 -3
  280. package/dist/location/index.js +28 -28
  281. package/dist/maintenance/memory-governance.js +24 -24
  282. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +24 -24
  283. package/dist/maintenance/rebuild-memory-projection-runner.js +26 -26
  284. package/dist/maintenance/rebuild-memory-projection.js +25 -25
  285. package/dist/memory-browse-http-glue.js +2 -2
  286. package/dist/memory-browse-operations.js +91 -89
  287. package/dist/memory-browse.js +5 -5
  288. package/dist/memory-subject.js +2 -2
  289. package/dist/namespaces/migrate.js +25 -25
  290. package/dist/namespaces/search.d.ts +9 -0
  291. package/dist/namespaces/search.d.ts.map +1 -1
  292. package/dist/namespaces/search.js +13 -7
  293. package/dist/namespaces/storage.js +24 -24
  294. package/dist/offline-sync-changeset-generations.js +3 -3
  295. package/dist/offline-sync-embedding-generation.js +2 -2
  296. package/dist/offline-sync-impression-drain.js +2 -2
  297. package/dist/offline-sync-snapshot-stream.js +6 -6
  298. package/dist/offline-sync.js +5 -5
  299. package/dist/operator-doctor-corpus.js +31 -31
  300. package/dist/operator-doctor-replica.js +4 -4
  301. package/dist/operator-toolkit.js +49 -49
  302. package/dist/orchestration/backlog-scheduler.d.ts +3 -2
  303. package/dist/orchestration/backlog-scheduler.d.ts.map +1 -1
  304. package/dist/orchestration/backlog-scheduler.js +209 -205
  305. package/dist/orchestration/backlog-scheduler.js.map +1 -1
  306. package/dist/orchestration/buffer-drain-runner.d.ts +6 -1
  307. package/dist/orchestration/buffer-drain-runner.d.ts.map +1 -1
  308. package/dist/orchestration/buffer-drain-runner.js +199 -195
  309. package/dist/orchestration/extraction-persist.d.ts.map +1 -1
  310. package/dist/orchestration/fact-dedup-window.d.ts +1 -4
  311. package/dist/orchestration/fact-dedup-window.d.ts.map +1 -1
  312. package/dist/orchestration/maintenance.js +41 -41
  313. package/dist/orchestration/turn-ingestion.d.ts +2 -9
  314. package/dist/orchestration/turn-ingestion.d.ts.map +1 -1
  315. package/dist/orchestrator.js +198 -194
  316. package/dist/provenance.js +2 -2
  317. package/dist/qmd.js +4 -4
  318. package/dist/recall-navigation-http-glue.js +2 -2
  319. package/dist/recall-navigation-operations.js +91 -89
  320. package/dist/recall-navigation.js +90 -88
  321. package/dist/recall-state-view-admission.js +5 -5
  322. package/dist/recall-why-service.js +5 -5
  323. package/dist/reconcile/manifest.js +2 -2
  324. package/dist/replica-divergence.js +3 -3
  325. package/dist/{resolution-BNWE5Y25.js → resolution-23ZBDM6A.js} +5 -5
  326. package/dist/resolution-23ZBDM6A.js.map +1 -0
  327. package/dist/resume-bundles.js +36 -36
  328. package/dist/salvage-envelope.js +4 -4
  329. package/dist/search/factory.js +6 -6
  330. package/dist/search/index.js +12 -12
  331. package/dist/semantic-consolidation.js +25 -25
  332. package/dist/semantic-rule-promotion.js +24 -24
  333. package/dist/semantic-rule-verifier.js +24 -24
  334. package/dist/source-agent-qualifier.d.ts +2 -0
  335. package/dist/source-agent-qualifier.d.ts.map +1 -1
  336. package/dist/source-agent-qualifier.js +36 -36
  337. package/dist/standup/build.js +25 -25
  338. package/dist/storage/buffer-drain-claims.d.ts +18 -6
  339. package/dist/storage/buffer-drain-claims.d.ts.map +1 -1
  340. package/dist/storage/buffer-drain-claims.js +2 -2
  341. package/dist/storage/buffer-session-files.js +2 -2
  342. package/dist/storage/content-hash-index.d.ts +8 -0
  343. package/dist/storage/content-hash-index.d.ts.map +1 -1
  344. package/dist/storage.d.ts +10 -1
  345. package/dist/storage.d.ts.map +1 -1
  346. package/dist/storage.js +23 -23
  347. package/dist/subject-config.js +3 -3
  348. package/dist/summarizer.js +4 -4
  349. package/dist/support-passport/index.js +93 -91
  350. package/dist/tokens.js +3 -3
  351. package/dist/transfer/autodetect.js +1 -1
  352. package/dist/transfer/backup.js +2 -2
  353. package/dist/transfer/capsule-export.js +3 -3
  354. package/dist/transfer/capsule-gunzip.d.ts +14 -0
  355. package/dist/transfer/capsule-gunzip.d.ts.map +1 -0
  356. package/dist/transfer/capsule-import.d.ts.map +1 -1
  357. package/dist/transfer/capsule-import.js +3 -2
  358. package/dist/transfer/capsule-merge.d.ts.map +1 -1
  359. package/dist/transfer/export-okf.js +24 -24
  360. package/dist/verified-recall.js +24 -24
  361. package/dist/who-knows-cli.js +26 -26
  362. package/dist/who-knows.js +25 -25
  363. package/dist/write-envelope.js +3 -3
  364. package/package.json +2 -2
  365. package/src/access-boundary.ts +15 -0
  366. package/src/access-errors.ts +22 -0
  367. package/src/access-fleet-wide-work-peer.test.ts +236 -0
  368. package/src/access-http-peer-fleet-wide.test.ts +192 -0
  369. package/src/access-http.test.ts +249 -4
  370. package/src/access-http.ts +114 -39
  371. package/src/access-mcp-frames.test.ts +47 -0
  372. package/src/access-mcp-frames.ts +74 -0
  373. package/src/access-mcp.test.ts +210 -0
  374. package/src/access-mcp.ts +47 -37
  375. package/src/access-observe-replay-durability.test.ts +40 -4
  376. package/src/access-observe-write-surface.ts +4 -4
  377. package/src/access-operations-batch.ts +23 -12
  378. package/src/access-proto-injection.test.ts +340 -0
  379. package/src/access-schema.ts +31 -5
  380. package/src/access-service-capsule-import.test.ts +235 -0
  381. package/src/access-service.ts +6 -45
  382. package/src/backlog-scheduler.test.ts +443 -3
  383. package/src/briefing-deadline.ts +5 -4
  384. package/src/buffer-admission.ts +45 -0
  385. package/src/buffer-eviction-backpressure.test.ts +211 -0
  386. package/src/buffer-eviction.ts +8 -14
  387. package/src/buffer-incremental-persistence.test.ts +25 -37
  388. package/src/buffer-persistence.ts +15 -6
  389. package/src/buffer-session.test.ts +32 -16
  390. package/src/buffer-turn-helpers.ts +47 -0
  391. package/src/buffer-types.ts +28 -1
  392. package/src/buffer.ts +83 -91
  393. package/src/capsule-import-gate.ts +109 -0
  394. package/src/cli.ts +4 -4
  395. package/src/extraction-quote-grounding.test.ts +125 -0
  396. package/src/extraction-quote-grounding.ts +99 -25
  397. package/src/extraction-source-grounding-rules.ts +6 -1
  398. package/src/extraction-source-grounding.ts +2 -0
  399. package/src/extraction.ts +3 -4
  400. package/src/fact-dedup-window.test.ts +103 -20
  401. package/src/namespaces/search.test.ts +480 -1
  402. package/src/namespaces/search.ts +93 -10
  403. package/src/orchestration/backlog-scheduler.ts +13 -12
  404. package/src/orchestration/buffer-drain-runner.ts +40 -16
  405. package/src/orchestration/extraction-persist.ts +2 -10
  406. package/src/orchestration/fact-dedup-window.ts +5 -12
  407. package/src/orchestration/turn-ingestion.ts +38 -39
  408. package/src/recall-navigation-operations.ts +9 -2
  409. package/src/source-agent-qualifier.ts +3 -0
  410. package/src/storage/buffer-drain-claims.test.ts +330 -6
  411. package/src/storage/buffer-drain-claims.ts +226 -80
  412. package/src/storage/buffer-session-files.ts +2 -2
  413. package/src/storage/content-hash-index.ts +9 -0
  414. package/src/storage.ts +15 -0
  415. package/src/transfer/capsule-gunzip.ts +39 -0
  416. package/src/transfer/capsule-import.test.ts +73 -0
  417. package/src/transfer/capsule-import.ts +2 -2
  418. package/src/transfer/capsule-merge.test.ts +34 -0
  419. package/src/transfer/capsule-merge.ts +2 -10
  420. package/dist/capsule-merge-XVTQJJ6R.js.map +0 -1
  421. package/dist/chunk-2XJZLSXE.js.map +0 -1
  422. package/dist/chunk-3JPTUCD7.js.map +0 -1
  423. package/dist/chunk-4KLQI3L2.js.map +0 -1
  424. package/dist/chunk-6LCWKS62.js.map +0 -1
  425. package/dist/chunk-77R7BQZ2.js.map +0 -1
  426. package/dist/chunk-7PMOCQOL.js.map +0 -1
  427. package/dist/chunk-B74NPUHT.js.map +0 -1
  428. package/dist/chunk-D5SSBCYY.js.map +0 -1
  429. package/dist/chunk-HLKUZW42.js.map +0 -1
  430. package/dist/chunk-HWHNQVRV.js.map +0 -1
  431. package/dist/chunk-KASJJGRG.js.map +0 -1
  432. package/dist/chunk-KQUSP6LB.js.map +0 -1
  433. package/dist/chunk-LGEH473S.js.map +0 -1
  434. package/dist/chunk-LU66I56Q.js.map +0 -1
  435. package/dist/chunk-MPDLLLOG.js.map +0 -1
  436. package/dist/chunk-MPGLM2VU.js.map +0 -1
  437. package/dist/chunk-QZBTIYKD.js.map +0 -1
  438. package/dist/chunk-VLMBSGQF.js.map +0 -1
  439. package/dist/chunk-WAD32CZG.js.map +0 -1
  440. package/dist/chunk-WC475JOG.js.map +0 -1
  441. package/dist/chunk-X2KO4FK5.js.map +0 -1
  442. package/dist/chunk-XYP5WBDO.js.map +0 -1
  443. package/dist/chunk-YK7GOPIE.js.map +0 -1
  444. package/dist/chunk-Z3DDQXM4.js.map +0 -1
  445. /package/dist/{capsule-crypto-YO5QJ6L3.js.map → access-mcp-frames.js.map} +0 -0
  446. /package/dist/{auto-sync-C7E6G7Y2.js.map → auto-sync-3AZW7MXI.js.map} +0 -0
  447. /package/dist/{graph-edge-decay-CXTNJ7IQ.js.map → buffer-admission.js.map} +0 -0
  448. /package/dist/{resolution-BNWE5Y25.js.map → capsule-crypto-7FJQINUR.js.map} +0 -0
  449. /package/dist/{chunk-MSIRVXQ3.js.map → chunk-2G4TV2ML.js.map} +0 -0
  450. /package/dist/{chunk-IR4C3DP2.js.map → chunk-2K3AUDH7.js.map} +0 -0
  451. /package/dist/{chunk-2IW5PT7U.js.map → chunk-2N4OUSIA.js.map} +0 -0
  452. /package/dist/{chunk-BXLOS5AJ.js.map → chunk-2NLLXCJG.js.map} +0 -0
  453. /package/dist/{chunk-QZSIDSB2.js.map → chunk-2NUDHVYM.js.map} +0 -0
  454. /package/dist/{chunk-HPFVZPRH.js.map → chunk-2U4LMSEX.js.map} +0 -0
  455. /package/dist/{chunk-WHQXWFH7.js.map → chunk-2XOFVTTT.js.map} +0 -0
  456. /package/dist/{chunk-I6ORDT54.js.map → chunk-32CA7B6L.js.map} +0 -0
  457. /package/dist/{chunk-T77AX6DG.js.map → chunk-32YX7EJ3.js.map} +0 -0
  458. /package/dist/{chunk-HLWXCDUQ.js.map → chunk-3DAWHP5K.js.map} +0 -0
  459. /package/dist/{chunk-ZJJFUEPO.js.map → chunk-3PJEDHLD.js.map} +0 -0
  460. /package/dist/{chunk-PJYK7HH2.js.map → chunk-3UZ2VMKD.js.map} +0 -0
  461. /package/dist/{chunk-IN4OFAHX.js.map → chunk-3Y5X6YFH.js.map} +0 -0
  462. /package/dist/{chunk-YUTT4ZTI.js.map → chunk-45VUHDV2.js.map} +0 -0
  463. /package/dist/{chunk-T6T2RMWW.js.map → chunk-4GMI5HFH.js.map} +0 -0
  464. /package/dist/{chunk-YOEYL6CH.js.map → chunk-4LCVA2LW.js.map} +0 -0
  465. /package/dist/{chunk-66JOLMWS.js.map → chunk-4X7HQKAG.js.map} +0 -0
  466. /package/dist/{chunk-65SKM4BF.js.map → chunk-4XYAWK5H.js.map} +0 -0
  467. /package/dist/{chunk-H7BZBSP6.js.map → chunk-52II7PB6.js.map} +0 -0
  468. /package/dist/{chunk-TPX7XXY4.js.map → chunk-5SOSQTVE.js.map} +0 -0
  469. /package/dist/{chunk-G3T6YMBO.js.map → chunk-64S6X4IU.js.map} +0 -0
  470. /package/dist/{chunk-BK7AJUWB.js.map → chunk-6BCWFCDG.js.map} +0 -0
  471. /package/dist/{chunk-V27FK6D6.js.map → chunk-6XTUZKCZ.js.map} +0 -0
  472. /package/dist/{chunk-LECSS7EE.js.map → chunk-73UZZFJC.js.map} +0 -0
  473. /package/dist/{chunk-4EACCIPO.js.map → chunk-77PDJ4OE.js.map} +0 -0
  474. /package/dist/{chunk-GQZSGXR6.js.map → chunk-7GSL4LBG.js.map} +0 -0
  475. /package/dist/{chunk-B6SPPYGJ.js.map → chunk-7IWRLYFJ.js.map} +0 -0
  476. /package/dist/{chunk-R45L4TV6.js.map → chunk-7LCGFUMB.js.map} +0 -0
  477. /package/dist/{chunk-A7BM2JTH.js.map → chunk-AJHNXIQU.js.map} +0 -0
  478. /package/dist/{chunk-2D7BTSDW.js.map → chunk-ANZZLRUX.js.map} +0 -0
  479. /package/dist/{chunk-ZXF3O7P4.js.map → chunk-ARRTLPRC.js.map} +0 -0
  480. /package/dist/{chunk-S5CQI2KF.js.map → chunk-B3GKQ6DU.js.map} +0 -0
  481. /package/dist/{chunk-XRBHIR7Q.js.map → chunk-B56LORLY.js.map} +0 -0
  482. /package/dist/{chunk-KO3YBHOV.js.map → chunk-BIVKPQ6Q.js.map} +0 -0
  483. /package/dist/{chunk-54FDG7K7.js.map → chunk-C2HORX76.js.map} +0 -0
  484. /package/dist/{chunk-E33UJHY3.js.map → chunk-CN7Q3T2J.js.map} +0 -0
  485. /package/dist/{chunk-YUTG35M4.js.map → chunk-CYCEROPR.js.map} +0 -0
  486. /package/dist/{chunk-TFLPDNQV.js.map → chunk-D5EV6Y2L.js.map} +0 -0
  487. /package/dist/{chunk-BFBS7OFQ.js.map → chunk-DC55RIEZ.js.map} +0 -0
  488. /package/dist/{chunk-B4ZU34JQ.js.map → chunk-DT7SNJH6.js.map} +0 -0
  489. /package/dist/{chunk-FVRTCYZ3.js.map → chunk-EA2LA5RI.js.map} +0 -0
  490. /package/dist/{chunk-WBN66HPI.js.map → chunk-ELHJK7LM.js.map} +0 -0
  491. /package/dist/{chunk-YNDLCWXS.js.map → chunk-EZ25VE3G.js.map} +0 -0
  492. /package/dist/{chunk-YAUHSNPB.js.map → chunk-F74G4KIH.js.map} +0 -0
  493. /package/dist/{chunk-BV2BRHD4.js.map → chunk-FHGWKODN.js.map} +0 -0
  494. /package/dist/{chunk-KESJ5XX3.js.map → chunk-G54BOKZ6.js.map} +0 -0
  495. /package/dist/{chunk-K36RMINQ.js.map → chunk-GOZXQNIM.js.map} +0 -0
  496. /package/dist/{chunk-OQSSQOKQ.js.map → chunk-GULUWOA5.js.map} +0 -0
  497. /package/dist/{chunk-K6RTQZA4.js.map → chunk-HFUKXOUW.js.map} +0 -0
  498. /package/dist/{chunk-WV254W4V.js.map → chunk-HLN2HOXX.js.map} +0 -0
  499. /package/dist/{chunk-FUOAIJKQ.js.map → chunk-IBDWYRDR.js.map} +0 -0
  500. /package/dist/{chunk-AJG2TAMR.js.map → chunk-IEEV27BC.js.map} +0 -0
  501. /package/dist/{chunk-LTDLJCMQ.js.map → chunk-IJ3OEECW.js.map} +0 -0
  502. /package/dist/{chunk-BK4FBHZ3.js.map → chunk-IPD5GC7C.js.map} +0 -0
  503. /package/dist/{chunk-KFLD7ZZG.js.map → chunk-IUKYFTGW.js.map} +0 -0
  504. /package/dist/{chunk-GCAQ3VUJ.js.map → chunk-JM2YZKCQ.js.map} +0 -0
  505. /package/dist/{chunk-BNQJKWWZ.js.map → chunk-K3FH3LAQ.js.map} +0 -0
  506. /package/dist/{chunk-RZH5RVJC.js.map → chunk-MTTYIXSU.js.map} +0 -0
  507. /package/dist/{chunk-XHGYZRVW.js.map → chunk-NIVKG3DS.js.map} +0 -0
  508. /package/dist/{chunk-VZELUMKK.js.map → chunk-NQP4ZYGG.js.map} +0 -0
  509. /package/dist/{chunk-YO2JEX2Z.js.map → chunk-OGBQMY46.js.map} +0 -0
  510. /package/dist/{chunk-TLHF75OR.js.map → chunk-OL553AWT.js.map} +0 -0
  511. /package/dist/{chunk-CLVILSBR.js.map → chunk-OZNBZJ3S.js.map} +0 -0
  512. /package/dist/{chunk-VUROWXFL.js.map → chunk-P452SEKO.js.map} +0 -0
  513. /package/dist/{chunk-JX3E4XCW.js.map → chunk-PDOOUXCS.js.map} +0 -0
  514. /package/dist/{chunk-6QYPL6NI.js.map → chunk-PKZ274PI.js.map} +0 -0
  515. /package/dist/{chunk-KJCL2FZO.js.map → chunk-QD5R6U5J.js.map} +0 -0
  516. /package/dist/{chunk-JRVMCZE3.js.map → chunk-QEYTRFR3.js.map} +0 -0
  517. /package/dist/{chunk-VKDAJJQP.js.map → chunk-QEZ3DW5O.js.map} +0 -0
  518. /package/dist/{chunk-WYPCJK6K.js.map → chunk-QKERFEJS.js.map} +0 -0
  519. /package/dist/{chunk-BDN3TDGV.js.map → chunk-QKES7GU6.js.map} +0 -0
  520. /package/dist/{chunk-PCQWKMOL.js.map → chunk-QNSZYTSG.js.map} +0 -0
  521. /package/dist/{chunk-IZJQNDGI.js.map → chunk-R6HMAIKM.js.map} +0 -0
  522. /package/dist/{chunk-NUSAAN75.js.map → chunk-ROKDHO74.js.map} +0 -0
  523. /package/dist/{chunk-FF6N7BXC.js.map → chunk-S45INSV3.js.map} +0 -0
  524. /package/dist/{chunk-2RUTN7PR.js.map → chunk-S7GJNA3K.js.map} +0 -0
  525. /package/dist/{chunk-XT45WCKX.js.map → chunk-SYKJBS7S.js.map} +0 -0
  526. /package/dist/{chunk-5BE3FLKL.js.map → chunk-TAUHAP5J.js.map} +0 -0
  527. /package/dist/{chunk-RJWL3RHB.js.map → chunk-TFEHSPGQ.js.map} +0 -0
  528. /package/dist/{chunk-K3B72DKJ.js.map → chunk-TRMZHGIX.js.map} +0 -0
  529. /package/dist/{chunk-WBDIZWJQ.js.map → chunk-TSS3D7ZY.js.map} +0 -0
  530. /package/dist/{chunk-HQPFACXO.js.map → chunk-UH3FPX3L.js.map} +0 -0
  531. /package/dist/{chunk-GGJFRVRD.js.map → chunk-US7KPQA5.js.map} +0 -0
  532. /package/dist/{chunk-FJ2VJTGA.js.map → chunk-UWRHHRDK.js.map} +0 -0
  533. /package/dist/{chunk-SDESKFKT.js.map → chunk-UYHDMCY2.js.map} +0 -0
  534. /package/dist/{chunk-3T3VHXUH.js.map → chunk-VKILERSL.js.map} +0 -0
  535. /package/dist/{chunk-2TGIKMMZ.js.map → chunk-WXDTOE6F.js.map} +0 -0
  536. /package/dist/{chunk-KQLBXUUQ.js.map → chunk-WYG5UNDY.js.map} +0 -0
  537. /package/dist/{chunk-DQEMWVMT.js.map → chunk-X7Y7WX73.js.map} +0 -0
  538. /package/dist/{chunk-FZVROZKC.js.map → chunk-XVZA6VXC.js.map} +0 -0
  539. /package/dist/{chunk-QA3Y2O6H.js.map → chunk-YAVIBVCU.js.map} +0 -0
  540. /package/dist/{chunk-VPEIWMUT.js.map → chunk-YLTU2DC4.js.map} +0 -0
  541. /package/dist/{chunk-EBOHFZI4.js.map → chunk-YRZPBN46.js.map} +0 -0
  542. /package/dist/{chunk-FMFCQRDM.js.map → chunk-ZANNIXXE.js.map} +0 -0
  543. /package/dist/{chunk-HQGATKG2.js.map → chunk-ZBFLV657.js.map} +0 -0
  544. /package/dist/{chunk-6L63IN3M.js.map → chunk-ZOJUWVAU.js.map} +0 -0
  545. /package/dist/{first-start-migration-QVD22WWS.js.map → first-start-migration-A6PHIBUQ.js.map} +0 -0
package/src/buffer.ts CHANGED
@@ -23,39 +23,32 @@ import {
23
23
  bufferTurnsEqual,
24
24
  copyBufferTurn,
25
25
  describeError,
26
+ entryActivityAt,
27
+ entryHoldsAcceptedCapture,
26
28
  hasPinnedCaptureScope,
27
29
  liveTurnsFromExtractionSnapshot,
28
30
  matchingQueuedExtractionPrefixLength,
31
+ normalizeBufferState,
29
32
  probeWithTimeout,
30
33
  selectRetainedDeferredTurns,
31
34
  type BufferEntryCounts,
32
35
  } from "./buffer-turn-helpers.js";
36
+ import { BufferAdmissionRefusedError, canAdmitNewEntryUnlocked } from "./buffer-admission.js";
37
+ export { BufferAdmissionRefusedError } from "./buffer-admission.js";
38
+ import type { AddTurnMutationResult, AddTurnOutcome, RetainedTurnCleanupOptions, TriggerDecision } from "./buffer-types.js";
33
39
 
34
- export type TriggerDecision = "extract_now" | "extract_batch" | "keep_buffering";
40
+ export type { TriggerDecision, AddTurnOutcome, RetainedTurnCleanupOptions } from "./buffer-types.js";
41
+
42
+ // Eviction hooks are pure functions of an entry; one shared instance serves
43
+ // pruneEntries, the admission probe and the batch preflight.
44
+ const EVICTION_HOOKS = { activityAt: entryActivityAt, holdsAcceptedCapture: entryHoldsAcceptedCapture };
35
45
 
36
46
  export type { BufferSurpriseProbe } from "./buffer-types.js";
37
47
  import type { BufferSurpriseProbe, SurpriseTelemetryQueueEntry } from "./buffer-types.js";
38
48
 
39
- export interface AddTurnOutcome {
40
- decision: TriggerDecision;
41
- extractionTurns?: BufferTurn[];
42
- }
43
-
44
- export interface RetainedTurnCleanupOptions {
45
- abortSignal?: AbortSignal;
46
- deadlineMs?: number;
47
- /** Keep cleanup within the accepted namespace. */
48
- writeNamespaceOverride?: string;
49
- /** Match the original profile and project binding, not just its write namespace. */
50
- scopeProfileWritePlan?: import("./namespaces/scope-profiles.js").ResolvedScopeProfilePlan | null;
51
- codingContext?: import("./types.js").CodingContext;
52
- }
53
-
54
49
  // Raised from 200 in #3303: live captures were being dropped at busy hours
55
50
  // while the single extraction worker drained a backlog.
56
51
  const FALLBACK_MAX_BUFFER_SESSIONS = 1000;
57
- const isAcceptedTurn = (t: { acceptedCapture?: boolean; writeNamespaceOverride?: string }): boolean =>
58
- t.acceptedCapture === true || t.writeNamespaceOverride !== undefined;
59
52
 
60
53
  /**
61
54
  * Upper bound on how long a debounced buffer save may be deferred under
@@ -76,15 +69,6 @@ const BUFFER_SAVE_MAX_DEFER_MULTIPLIER = 5;
76
69
  */
77
70
  const MAX_SET_TIMEOUT_MS = 2_147_483_647;
78
71
 
79
- interface AddTurnMutationResult {
80
- decision: TriggerDecision;
81
- signalLevel: SignalLevel;
82
- priorTurns: BufferTurn[];
83
- activeTurnsSnapshot: BufferTurn[];
84
- retainedTurnsSnapshot: BufferTurn[];
85
- turnCountInWindow: number;
86
- }
87
-
88
72
  export class SmartBuffer {
89
73
  private state: BufferState;
90
74
  private loaded = false;
@@ -182,61 +166,13 @@ export class SmartBuffer {
182
166
  };
183
167
  }
184
168
 
185
- private normalizeState(state: BufferState): BufferState {
186
- const entries = Object.assign(
187
- Object.create(null),
188
- state.entries ?? {},
189
- ) as NonNullable<BufferState["entries"]>;
190
- if (!entries.default) {
191
- entries.default = {
192
- turns: Array.isArray(state.turns) ? [...state.turns] : [],
193
- lastExtractionAt: state.lastExtractionAt ?? null,
194
- extractionCount:
195
- typeof state.extractionCount === "number" ? state.extractionCount : 0,
196
- };
197
- }
198
- return {
199
- turns: entries.default.turns,
200
- lastExtractionAt: entries.default.lastExtractionAt,
201
- extractionCount: entries.default.extractionCount,
202
- entries,
203
- };
204
- }
205
-
206
- private entryActivityAt(entry: BufferEntryState): number {
207
- const lastTurnAt = entry.turns.reduce((latest, turn) => {
208
- const parsed = Date.parse(turn.timestamp);
209
- return Number.isFinite(parsed) ? Math.max(latest, parsed) : latest;
210
- }, -1);
211
- const lastExtractionAt =
212
- typeof entry.lastExtractionAt === "string"
213
- ? Date.parse(entry.lastExtractionAt)
214
- : Number.NaN;
215
- return Math.max(
216
- lastTurnAt,
217
- Number.isFinite(lastExtractionAt) ? lastExtractionAt : -1,
218
- );
219
- }
220
-
221
169
  /** Evict oldest entries past this.maxSessionEntries and queue their session files for deletion. */
222
170
  private pruneEntries(retainKeys: string[], maxCount = this.maxSessionEntries): void {
223
171
  const entries = this.state.entries;
224
172
  if (!entries) return;
225
- const evicted = selectEvictedBufferKeys(entries, retainKeys, maxCount, {
226
- activityAt: (entry) => this.entryActivityAt(entry),
227
- holdsAcceptedCapture: (entry) => this.entryHoldsAcceptedCapture(entry),
228
- });
173
+ const evicted = selectEvictedBufferKeys(entries, retainKeys, maxCount, EVICTION_HOOKS);
229
174
  for (const key of evicted) delete entries[key];
230
175
  this.persistence.markEvicted(evicted);
231
- if (evicted.length > 0) {
232
- // Loud degradation (extraction hot-loop hardening, Step 7): buffer
233
- // pressure during a provider outage is bounded and expected, but must
234
- // be observable, not silent.
235
- log.warn(
236
- `buffer: pruned ${evicted.length} oldest session entr${evicted.length === 1 ? "y" : "ies"} ` +
237
- `past the session-entry cap (${this.maxSessionEntries}); buffered turn data for those sessions was dropped`,
238
- );
239
- }
240
176
  }
241
177
 
242
178
  private async loadUnlocked(): Promise<void> {
@@ -244,7 +180,7 @@ export class SmartBuffer {
244
180
  if (!this.loadPromise) {
245
181
  this.loadPromise = this.storage.loadBuffer()
246
182
  .then((state) => {
247
- this.state = this.normalizeState(state);
183
+ this.state = normalizeBufferState(state);
248
184
  this.loaded = true;
249
185
  })
250
186
  .finally(() => {
@@ -300,16 +236,16 @@ export class SmartBuffer {
300
236
  this.loaded = true;
301
237
  }
302
238
 
303
- private async saveUnlocked(): Promise<void> {
304
- const { handedOver, drainedTurns } = await this.persistence.persist(this.storage, this.state, (key) => this.peekEntry(key) ?? undefined);
239
+ private async saveUnlocked(reconcile?: { key: string; drained: import("./buffer-turn-helpers.js").DrainedTurnSets }): Promise<void> {
240
+ const { handedOver, drainedTurns } = await this.persistence.persist(this.storage, this.state, (key) => this.peekEntry(key) ?? undefined, reconcile);
305
241
  // A drain tombstone: the turns the drain extracted leave this copy too,
306
242
  // so a stale owner never extracts (or persists) them a second time.
307
243
  for (const [key, drained] of drainedTurns) {
308
244
  const entry = this.peekEntry(key);
309
245
  if (!entry) continue;
310
- entry.turns = subtractBufferTurns(entry.turns, drained);
246
+ entry.turns = subtractBufferTurns(entry.turns, drained.turns);
311
247
  if (entry.retainedTurns && entry.retainedTurns.length > 0) {
312
- entry.retainedTurns = subtractBufferTurns(entry.retainedTurns, drained);
248
+ entry.retainedTurns = subtractBufferTurns(entry.retainedTurns, drained.retainedTurns);
313
249
  if (entry.retainedTurns.length === 0) delete entry.retainedTurns;
314
250
  }
315
251
  if (key === "default") this.state.turns = entry.turns;
@@ -340,8 +276,8 @@ export class SmartBuffer {
340
276
  return bufferEntryCounts(this.state);
341
277
  }
342
278
 
343
- async save(): Promise<void> {
344
- await this.enqueueMutation(async () => this.saveUnlocked());
279
+ async save(reconcile?: { key: string; drained: import("./buffer-turn-helpers.js").DrainedTurnSets }): Promise<void> {
280
+ await this.enqueueMutation(async () => this.saveUnlocked(reconcile));
345
281
  }
346
282
 
347
283
  /**
@@ -517,24 +453,80 @@ export class SmartBuffer {
517
453
  if (mutation === null) return null;
518
454
  return this.completeAddTurnOutcome(bufferKey, turn, mutation);
519
455
  }
456
+ /**
457
+ * Admit a multi-session durable capture as one capacity transaction.
458
+ * Preflight every new key under the mutation lock before persisting any
459
+ * turn; refusal records nothing and drops nothing.
460
+ */
461
+ async addTurnsBounded(
462
+ batches: readonly { bufferKey: string; turns: readonly BufferTurn[] }[],
463
+ ): Promise<Array<{ bufferKey: string; turn: BufferTurn; outcome: AddTurnOutcome }> | null> {
464
+ const pending = await this.enqueueMutation(async () => {
465
+ await this.loadUnlocked();
466
+ const additions: Array<{ bufferKey: string; turn: BufferTurn }> = [];
467
+ for (const batch of batches) {
468
+ for (const turn of batch.turns) {
469
+ additions.push({ bufferKey: batch.bufferKey, turn });
470
+ }
471
+ }
472
+
473
+ const entries = this.state.entries ?? {};
474
+ const newKeys = [...new Set(
475
+ additions
476
+ .map(({ bufferKey }) => bufferKey)
477
+ .filter((bufferKey) => this.peekEntry(bufferKey) === null),
478
+ )];
479
+ const count = Object.keys(entries).length;
480
+ const requiredEvictions = Math.max(0, count + newKeys.length - this.maxSessionEntries);
481
+ if (requiredEvictions > 0) {
482
+ const target = Math.max(0, this.maxSessionEntries - newKeys.length);
483
+ const evicted = selectEvictedBufferKeys(entries, newKeys, target, EVICTION_HOOKS);
484
+ if (newKeys.length > 0 && evicted.length < requiredEvictions) return null;
485
+ for (const key of evicted) delete entries[key];
486
+ this.persistence.markEvicted(evicted);
487
+ }
488
+
489
+ const recorded: Array<{ bufferKey: string; turn: BufferTurn; mutation: AddTurnMutationResult }> = [];
490
+ for (const { bufferKey, turn } of additions) {
491
+ recorded.push({ bufferKey, turn, mutation: await this.recordTurnUnlocked(bufferKey, turn) });
492
+ }
493
+ return recorded;
494
+ });
495
+ if (pending === null) return null;
496
+
497
+ const outcomes: Array<{ bufferKey: string; turn: BufferTurn; outcome: AddTurnOutcome }> = [];
498
+ for (const item of pending) {
499
+ outcomes.push({
500
+ bufferKey: item.bufferKey,
501
+ turn: item.turn,
502
+ outcome: await this.completeAddTurnOutcome(item.bufferKey, item.turn, item.mutation),
503
+ });
504
+ }
505
+ return outcomes;
506
+ }
520
507
 
521
- /** Free one slot for an accepted capture via the native eviction policy (COS-244c). */
508
+ /** Free one slot only when an empty entry can be reclaimed. */
522
509
  private makeRoomForEntryUnlocked(): void {
523
510
  const entries = this.state.entries ?? {};
524
511
  const target = Math.max(0, this.maxSessionEntries - 1);
525
- const pinned = Object.keys(entries).filter((k) => k === "default" || this.entryHoldsAcceptedCapture(entries[k]));
526
- if (pinned.length <= target) this.pruneEntries([], target); // evict only if it frees a slot
527
- }
528
-
529
- private entryHoldsAcceptedCapture(entry: BufferEntryState | undefined): boolean {
530
- return (entry?.turns ?? []).some(isAcceptedTurn) || (entry?.retainedTurns ?? []).some(isAcceptedTurn);
512
+ const pinned = Object.keys(entries).filter((k) => k === "default" || entryHoldsAcceptedCapture(entries[k]));
513
+ if (pinned.length <= target) this.pruneEntries([], target);
531
514
  }
532
515
 
533
516
  async addTurnWithOutcome(
534
517
  bufferKey: string,
535
518
  turn: BufferTurn,
536
519
  ): Promise<AddTurnOutcome> {
537
- const mutation = await this.enqueueMutation(() => this.recordTurnUnlocked(bufferKey, turn));
520
+ const mutation = await this.enqueueMutation(async () => {
521
+ await this.loadUnlocked();
522
+ if (
523
+ this.peekEntry(bufferKey) === null &&
524
+ !canAdmitNewEntryUnlocked(this.state.entries ?? {}, bufferKey, this.maxSessionEntries, EVICTION_HOOKS)
525
+ ) {
526
+ throw new BufferAdmissionRefusedError(bufferKey, this.maxSessionEntries);
527
+ }
528
+ return this.recordTurnUnlocked(bufferKey, turn);
529
+ });
538
530
  return this.completeAddTurnOutcome(bufferKey, turn, mutation);
539
531
  }
540
532
 
@@ -0,0 +1,109 @@
1
+ import { constants as fsConstants } from "node:fs";
2
+ import { access, realpath, stat } from "node:fs/promises";
3
+ import path from "node:path";
4
+ import { ZodError } from "zod";
5
+ import { EngramAccessInputError } from "./access-errors.js";
6
+ import { defaultCapsulesDir } from "./capsule-cli.js";
7
+
8
+ /**
9
+ * Import-path gate for remote capsule imports (issue #3225 C1).
10
+ *
11
+ * `EngramAccessService.capsuleImport` serves the HTTP route and the
12
+ * `capsule_import` MCP operation, where the caller supplies `archivePath`.
13
+ * The destination namespace is authorized, but the source archive previously
14
+ * was not: any path the server process could read was accepted. This module
15
+ * confines the source to the namespace capsule store, `defaultCapsulesDir`
16
+ * of the destination storage dir, which is the same store `capsule export`
17
+ * writes and `capsule_list` lists.
18
+ *
19
+ * The CLI import path does not go through this gate; it is the explicit
20
+ * operator authority and keeps unrestricted local-path imports.
21
+ */
22
+
23
+ /** True when the caught error carries the given errno-style code. */
24
+ function hasFsErrorCode(cause: unknown, code: string): boolean {
25
+ return cause instanceof Object && "code" in cause && cause.code === code;
26
+ }
27
+
28
+ /** True when `cause` is a path error the gate reports as an input error instead of a server fault. */
29
+ function isInputFsError(cause: unknown): boolean {
30
+ return (
31
+ hasFsErrorCode(cause, "ENOENT") ||
32
+ hasFsErrorCode(cause, "ENOTDIR") ||
33
+ hasFsErrorCode(cause, "EACCES") ||
34
+ hasFsErrorCode(cause, "EPERM") ||
35
+ hasFsErrorCode(cause, "ELOOP") ||
36
+ hasFsErrorCode(cause, "ENAMETOOLONG") ||
37
+ hasFsErrorCode(cause, "ERR_INVALID_ARG_VALUE")
38
+ );
39
+ }
40
+
41
+ /** Matches zod-style `Z_` error codes carried on error objects. */
42
+ const ZOD_STYLE_CODE = /^Z_/;
43
+
44
+ /** True when the caught error carries a zod-style `Z_` code. */
45
+ function hasZodStyleErrorCode(cause: unknown): boolean {
46
+ return cause instanceof Object && "code" in cause && ZOD_STYLE_CODE.test(String(cause.code));
47
+ }
48
+
49
+ /** True when the importer failed on archive input (shape, gzip, checksum) rather than backend errors. */
50
+ export function isCapsuleImportArchiveInputError(cause: unknown, message: string): boolean {
51
+ if (cause instanceof ZodError) return true;
52
+ if (hasZodStyleErrorCode(cause)) return true;
53
+ return (
54
+ message.startsWith("importCapsule: archive") ||
55
+ message.startsWith("importCapsule: bundle") ||
56
+ message.startsWith("importCapsule: manifest") ||
57
+ message.startsWith("importCapsule: record") ||
58
+ /incorrect header check|invalid stored block lengths|not in gzip format|unexpected end of file/i.test(message)
59
+ );
60
+ }
61
+
62
+ /**
63
+ * One message for every refusal before confinement is proven. A caller that
64
+ * can name any server path must not learn from the error whether that path
65
+ * exists, is a directory, or is unreadable.
66
+ */
67
+ const IMPORT_SOURCE_REFUSED =
68
+ "capsule import failed: archivePath must be an existing file inside the namespace capsule store";
69
+
70
+ /** Resolve a path to its real path; a missing, looping, or unreadable path resolves to null. */
71
+ async function realpathOrNull(target: string): Promise<string | null> {
72
+ try {
73
+ return await realpath(target);
74
+ } catch (cause) {
75
+ if (!isInputFsError(cause)) throw cause;
76
+ return null;
77
+ }
78
+ }
79
+
80
+ /** True when `target` is a strict descendant of `directory` (both already resolved). */
81
+ function isInsideDirectory(directory: string, target: string): boolean {
82
+ const rel = path.relative(directory, target);
83
+ return rel !== "" && rel !== ".." && !rel.startsWith(`..${path.sep}`) && !path.isAbsolute(rel);
84
+ }
85
+
86
+ /**
87
+ * Validate a remote import source and confine it to the namespace capsule
88
+ * store. Both real paths are resolved first, so `..` segments and store
89
+ * symlinks that point outside are refused. Confinement is checked before the
90
+ * file is inspected in any other way, and every failure before it proves
91
+ * confinement raises the same message.
92
+ */
93
+ export async function validateCapsuleImportArchive(archivePath: string, storageDir: string): Promise<void> {
94
+ const storeReal = await realpathOrNull(defaultCapsulesDir(storageDir));
95
+ const archiveReal = await realpathOrNull(archivePath);
96
+ if (storeReal === null || archiveReal === null || !isInsideDirectory(storeReal, archiveReal)) {
97
+ throw new EngramAccessInputError(IMPORT_SOURCE_REFUSED);
98
+ }
99
+ // The path now names a store entry, so the checks below only describe the store.
100
+ if (!(await stat(archiveReal)).isFile()) {
101
+ throw new EngramAccessInputError("capsule import failed: archivePath must point to a file");
102
+ }
103
+ try {
104
+ await access(archiveReal, fsConstants.R_OK);
105
+ } catch (cause) {
106
+ if (!isInputFsError(cause)) throw cause;
107
+ throw new EngramAccessInputError("capsule import failed: archive is not readable");
108
+ }
109
+ }
package/src/cli.ts CHANGED
@@ -4895,7 +4895,7 @@ export function registerCli(
4895
4895
  // No sidecar — attempt in-memory decryption if the secure-store is
4896
4896
  // unlocked. decryptCapsuleFileInMemory returns the plaintext gzip
4897
4897
  // bytes; we then gunzip and parse exactly like the plaintext path.
4898
- const { gunzipSync } = await import("node:zlib");
4898
+ const { gunzipCapsuleArchive } = await import("./transfer/capsule-gunzip.js");
4899
4899
  const { parseExportBundle } = await import("./transfer/types.js");
4900
4900
  let decryptedBuf: Buffer;
4901
4901
  try {
@@ -4917,7 +4917,7 @@ export function registerCli(
4917
4917
  process.exitCode = 1;
4918
4918
  return;
4919
4919
  }
4920
- const json = gunzipSync(decryptedBuf).toString("utf-8");
4920
+ const json = gunzipCapsuleArchive(decryptedBuf, "capsule inspect", archivePath);
4921
4921
  const parsed2 = parseExportBundle(JSON.parse(json));
4922
4922
  if (parsed2.capsuleVersion !== 2) {
4923
4923
  process.stderr.write(
@@ -4929,10 +4929,10 @@ export function registerCli(
4929
4929
  manifest = (parsed2.bundle as { manifest: Record<string, unknown> }).manifest;
4930
4930
  } else {
4931
4931
  const { readFile } = await import("node:fs/promises");
4932
- const { gunzipSync } = await import("node:zlib");
4932
+ const { gunzipCapsuleArchive } = await import("./transfer/capsule-gunzip.js");
4933
4933
  const { parseExportBundle } = await import("./transfer/types.js");
4934
4934
  const buf = await readFile(archivePath);
4935
- const json = gunzipSync(buf).toString("utf-8");
4935
+ const json = gunzipCapsuleArchive(buf, "capsule inspect", archivePath);
4936
4936
  const parsed2 = parseExportBundle(JSON.parse(json));
4937
4937
  if (parsed2.capsuleVersion !== 2) {
4938
4938
  process.stderr.write(
@@ -410,6 +410,55 @@ test("a claim that inverts a negated quote is rejected, a restated exclusion is
410
410
  assert.deepEqual(keptContents(grounded), ["Alice would avoid approving the budget."]);
411
411
  });
412
412
 
413
+ test("a claim that keeps one quote negation and flips another is rejected", () => {
414
+ const source = "Notes: Alice did not approve the budget. Bob did not review the ledger.";
415
+ const quote = "Alice did not approve the budget. Bob did not review the ledger.";
416
+ const grounded = filterExtractionResultBySource(
417
+ resultOf([
418
+ { content: "Alice did not approve the budget, and Bob reviewed the ledger.", quote },
419
+ {
420
+ content: "Alice did not approve the budget, and Bob did not review the ledger.",
421
+ quote,
422
+ },
423
+ ]),
424
+ source,
425
+ source,
426
+ );
427
+ assert.deepEqual(keptContents(grounded), [
428
+ "Alice did not approve the budget, and Bob did not review the ledger.",
429
+ ]);
430
+ });
431
+
432
+ test("a claim that keeps the denial in a pronoun clause is kept", () => {
433
+ const source = "Notes: Alice did not approve the budget.";
434
+ const quote = "Alice did not approve the budget.";
435
+ const claims = [
436
+ "Alice discussed the budget; she did not approve it.",
437
+ "Alice reviewed the budget, but she did not approve it.",
438
+ ];
439
+ const grounded = filterExtractionResultBySource(
440
+ resultOf(claims.map((content) => ({ content, quote }))),
441
+ source,
442
+ source,
443
+ );
444
+ assert.deepEqual(keptContents(grounded), claims);
445
+ });
446
+
447
+ test("a negator in a claim clause that shares only the subject does not keep the denial", () => {
448
+ const source = "Notes: Alice did not approve the budget. Alice did not review the contract.";
449
+ const grounded = filterExtractionResultBySource(
450
+ resultOf([
451
+ {
452
+ content: "Alice did not review the contract. She approved the budget.",
453
+ quote: "Alice did not approve the budget.",
454
+ },
455
+ ]),
456
+ source,
457
+ source,
458
+ );
459
+ assert.equal(grounded.facts.length, 0);
460
+ });
461
+
413
462
  test("a claim that inverts a denial verb in the quote is rejected", () => {
414
463
  const source = "Notes: Alice denied approving the budget. Bob reviewed it.";
415
464
  const grounded = filterExtractionResultBySource(
@@ -544,3 +593,79 @@ test("a quote naming rewritten text is located after temporal anchoring", () =>
544
593
  );
545
594
  assert.equal(grounded.facts.length, 1);
546
595
  });
596
+
597
+ const TURN_ONE =
598
+ "The river gauges read high all week near the mill.\n\nAlso the culvert repair is scheduled for next Tuesday at the plant.";
599
+ const TURN_TWO = "A different conversation about the warehouse roof leaks and the insurance claim.";
600
+ const TURNED_SOURCE = `${TURN_ONE}\n\n${TURN_TWO}`;
601
+
602
+ test("a quote crossing a blank line inside one turn is anchored when turn boundaries are given", () => {
603
+ const quote = "near the mill. Also the culvert repair is scheduled for next Tuesday at the plant";
604
+ const anchors = quoteAnchors(quote, TURNED_SOURCE, undefined, [TURN_ONE, TURN_TWO]);
605
+ assert.equal(anchors.length, 1);
606
+ assert.equal(anchors[0]!.quote, quote);
607
+ });
608
+
609
+ test("a quote spanning two turns still yields no anchor even with turn boundaries given", () => {
610
+ const stitched = "scheduled for next Tuesday at the plant.\n\nA different conversation about the warehouse";
611
+ assert.deepEqual(quoteAnchors(stitched, TURNED_SOURCE, undefined, [TURN_ONE, TURN_TWO]), []);
612
+ });
613
+
614
+ test("the anchor window reaches past a blank line to its turn's end, never into the next turn", () => {
615
+ const [anchor] = quoteAnchors(
616
+ "The river gauges read high all week near the mill.",
617
+ TURNED_SOURCE,
618
+ undefined,
619
+ [TURN_ONE, TURN_TWO],
620
+ );
621
+ assert.ok(anchor !== undefined);
622
+ assert.ok(anchor.window.includes("culvert repair is scheduled for next Tuesday at the plant"));
623
+ assert.ok(!anchor.window.includes("warehouse"));
624
+ });
625
+
626
+ test("without turn boundaries a blank line still rejects the quote and cuts the window", () => {
627
+ const quote = "near the mill. Also the culvert repair is scheduled for next Tuesday at the plant";
628
+ assert.deepEqual(quoteAnchors(quote, TURNED_SOURCE), []);
629
+ const [anchor] = quoteAnchors("The river gauges read high all week near the mill.", TURNED_SOURCE);
630
+ assert.ok(anchor !== undefined);
631
+ assert.ok(!anchor.window.includes("culvert repair"));
632
+ });
633
+
634
+ test("turn texts that do not tile the source fall back to blank-line behavior", () => {
635
+ const quote = "near the mill. Also the culvert repair is scheduled for next Tuesday at the plant";
636
+ assert.deepEqual(quoteAnchors(quote, TURNED_SOURCE, undefined, ["a turn that is not in the source"]), []);
637
+ });
638
+
639
+ const LONG_TAIL = Array.from({ length: 60 }, (_, index) => `word${index} filler`).join(" ");
640
+ const LONG_TURN = `The river gauges read high all week near the mill. ${LONG_TAIL}`;
641
+ const LONG_SOURCE = `${LONG_TURN}\n\n${TURN_TWO}`;
642
+
643
+ test("the window cut by the turn length ends on a whole word, matching the no-turns window", () => {
644
+ const quote = "The river gauges read high all week near the mill.";
645
+ const [bounded] = quoteAnchors(quote, LONG_SOURCE, undefined, [LONG_TURN, TURN_TWO]);
646
+ const [plain] = quoteAnchors(quote, LONG_TURN);
647
+ assert.ok(bounded !== undefined && plain !== undefined);
648
+ assert.equal(bounded.window, plain.window);
649
+ });
650
+
651
+ test("the window of a quote in a non-last turn does not end with a separator newline", () => {
652
+ const [anchor] = quoteAnchors(
653
+ "The river gauges read high all week near the mill.",
654
+ TURNED_SOURCE,
655
+ undefined,
656
+ [TURN_ONE, TURN_TWO],
657
+ );
658
+ assert.ok(anchor !== undefined);
659
+ assert.ok(!anchor.window.endsWith("\n"));
660
+ });
661
+
662
+ test("a quote ending exactly at the last character of a non-last turn still anchors", () => {
663
+ const anchors = quoteAnchors(
664
+ "Also the culvert repair is scheduled for next Tuesday at the plant.",
665
+ TURNED_SOURCE,
666
+ undefined,
667
+ [TURN_ONE, TURN_TWO],
668
+ );
669
+ assert.equal(anchors.length, 1);
670
+ assert.ok(anchors[0]!.window.endsWith("at the plant."));
671
+ });