@remnic/core 9.7.15 → 9.9.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 (929) hide show
  1. package/dist/access-admin-ops-surface.d.ts +13 -6
  2. package/dist/access-admin-ops-surface.js +85 -71
  3. package/dist/access-audit.js +2 -2
  4. package/dist/access-boundary.d.ts +35 -17
  5. package/dist/access-boundary.js +86 -74
  6. package/dist/access-citation.d.ts +28 -0
  7. package/dist/access-citation.js +9 -0
  8. package/dist/access-cli.js +194 -178
  9. package/dist/access-cli.js.map +1 -1
  10. package/dist/access-errors.d.ts +16 -1
  11. package/dist/access-errors.js +7 -3
  12. package/dist/access-http.d.ts +25 -19
  13. package/dist/access-http.js +100 -87
  14. package/dist/access-identity-continuity-surface.d.ts +13 -8
  15. package/dist/access-identity-continuity-surface.js +85 -71
  16. package/dist/access-lcm-surface.d.ts +16 -9
  17. package/dist/access-lcm-surface.js +85 -71
  18. package/dist/access-mcp.d.ts +23 -16
  19. package/dist/access-mcp.js +96 -84
  20. package/dist/access-memory-search-fanout.d.ts +93 -0
  21. package/dist/access-memory-search-fanout.js +18 -0
  22. package/dist/access-observe-write-surface.d.ts +26 -8
  23. package/dist/access-observe-write-surface.js +85 -71
  24. package/dist/access-operations-batch.js +92 -80
  25. package/dist/access-operations.d.ts +29 -22
  26. package/dist/access-operations.js +94 -82
  27. package/dist/access-recall-concurrency.d.ts +250 -0
  28. package/dist/access-recall-concurrency.js +157 -0
  29. package/dist/access-recall-response.d.ts +130 -0
  30. package/dist/access-recall-response.js +147 -0
  31. package/dist/access-recall-surface.d.ts +15 -7
  32. package/dist/access-recall-surface.js +85 -71
  33. package/dist/access-schema.d.ts +98 -98
  34. package/dist/access-schema.js +8 -6
  35. package/dist/{access-service-DpcYZ9Nl.d.ts → access-service-DbZ1G3zV.d.ts} +29 -36
  36. package/dist/access-service.d.ts +13 -6
  37. package/dist/access-service.js +89 -72
  38. package/dist/access-surface-catalog.d.ts +23 -16
  39. package/dist/access-surface-catalog.js +1 -0
  40. package/dist/access-surface-catalog.js.map +1 -1
  41. package/dist/access-token-capabilities.d.ts +2 -1
  42. package/dist/access-token-capabilities.js +4 -2
  43. package/dist/action-confidence.d.ts +3 -1
  44. package/dist/active-memory-bridge.d.ts +3 -1
  45. package/dist/active-memory-bridge.js +4 -4
  46. package/dist/active-recall.d.ts +4 -1
  47. package/dist/active-recall.js +23 -13
  48. package/dist/active-recall.js.map +1 -1
  49. package/dist/adapters/index.js +4 -4
  50. package/dist/adapters/registry.js +2 -2
  51. package/dist/{auto-sync-AAMTVZMK.js → auto-sync-UZG3XQZ5.js} +14 -8
  52. package/dist/{auto-sync-AAMTVZMK.js.map → auto-sync-UZG3XQZ5.js.map} +1 -1
  53. package/dist/behavior-learner.d.ts +3 -1
  54. package/dist/behavior-signals.d.ts +3 -1
  55. package/dist/bootstrap.d.ts +12 -7
  56. package/dist/bootstrap.js +2 -2
  57. package/dist/bounded-jsonl-state.d.ts +54 -0
  58. package/dist/bounded-jsonl-state.js +10 -0
  59. package/dist/boxes.js +2 -2
  60. package/dist/briefing.d.ts +5 -2
  61. package/dist/briefing.js +34 -24
  62. package/dist/buffer-surprise-report.d.ts +3 -1
  63. package/dist/buffer.d.ts +60 -2
  64. package/dist/buffer.js +3 -3
  65. package/dist/bulk-import/index.d.ts +5 -3
  66. package/dist/calibration.d.ts +3 -1
  67. package/dist/calibration.js +6 -6
  68. package/dist/capabilities.d.ts +7 -7
  69. package/dist/capabilities.js +1 -1
  70. package/dist/{capsule-crypto-CZJSLEFG.js → capsule-crypto-YO5QJ6L3.js} +3 -3
  71. package/dist/capsule-crypto-YO5QJ6L3.js.map +1 -0
  72. package/dist/{catalog-C9444P10.d.ts → catalog-BWqHb5HT.d.ts} +1 -1
  73. package/dist/causal-behavior.d.ts +3 -1
  74. package/dist/causal-behavior.js +6 -6
  75. package/dist/causal-chain.js +4 -4
  76. package/dist/causal-consolidation.d.ts +3 -1
  77. package/dist/causal-consolidation.js +43 -34
  78. package/dist/causal-consolidation.js.map +1 -1
  79. package/dist/causal-retrieval.js +6 -6
  80. package/dist/causal-trajectory-graph.d.ts +3 -1
  81. package/dist/causal-trajectory-graph.js +1 -1
  82. package/dist/causal-trajectory.js +1 -1
  83. package/dist/{chunk-A3GOMRJG.js → chunk-23L3IXFD.js} +2 -2
  84. package/dist/chunk-2CGLBUW3.js +15 -0
  85. package/dist/chunk-2CGLBUW3.js.map +1 -0
  86. package/dist/{chunk-MRHFJV44.js → chunk-2DQ2XREU.js} +2 -2
  87. package/dist/{chunk-L2B3EE7B.js → chunk-2QMKMVHH.js} +2 -2
  88. package/dist/{chunk-VJVNLNDQ.js → chunk-2UFO7X4Q.js} +7 -7
  89. package/dist/{chunk-2MR3MFQB.js → chunk-2VEOKUPP.js} +3 -3
  90. package/dist/chunk-2Z24E5W2.js +22 -0
  91. package/dist/chunk-2Z24E5W2.js.map +1 -0
  92. package/dist/{chunk-RHOZ5LLO.js → chunk-347WD2LE.js} +2 -2
  93. package/dist/{chunk-HDTQVNWD.js → chunk-3QAH2S33.js} +3 -3
  94. package/dist/{chunk-37CTGERM.js → chunk-3WCASNQZ.js} +12 -1
  95. package/dist/chunk-3WCASNQZ.js.map +1 -0
  96. package/dist/{chunk-LRNMRXJO.js → chunk-3Y224NYC.js} +3 -3
  97. package/dist/{chunk-3IY64MV6.js → chunk-44XZ75OQ.js} +44 -10
  98. package/dist/chunk-44XZ75OQ.js.map +1 -0
  99. package/dist/{chunk-VFSP73LP.js → chunk-45GF7Y3V.js} +2 -2
  100. package/dist/{chunk-K7LOWSLU.js → chunk-4BJQODZF.js} +2479 -1520
  101. package/dist/chunk-4BJQODZF.js.map +1 -0
  102. package/dist/{chunk-JREB6UFH.js → chunk-57OWKFUQ.js} +17 -6
  103. package/dist/chunk-57OWKFUQ.js.map +1 -0
  104. package/dist/{chunk-OEHCMALU.js → chunk-5I4M26Q7.js} +5 -5
  105. package/dist/{chunk-2AZXIZEN.js → chunk-5Q7EVV4X.js} +6 -6
  106. package/dist/{chunk-LC7OODWZ.js → chunk-5SB7SC2G.js} +80 -49
  107. package/dist/chunk-5SB7SC2G.js.map +1 -0
  108. package/dist/{chunk-PUBTHW5O.js → chunk-6DRPPQEJ.js} +2 -2
  109. package/dist/{chunk-NWTGD4AN.js → chunk-6KIQT7RG.js} +10 -9
  110. package/dist/chunk-6KIQT7RG.js.map +1 -0
  111. package/dist/{chunk-FDCTQWLW.js → chunk-6O22TZSB.js} +3 -3
  112. package/dist/{chunk-ZQ7UBUZ6.js → chunk-6QYST5XN.js} +6 -6
  113. package/dist/{chunk-W4PGTAS2.js → chunk-6WAFYNVT.js} +3 -3
  114. package/dist/chunk-6ZMAMSHS.js +20 -0
  115. package/dist/chunk-6ZMAMSHS.js.map +1 -0
  116. package/dist/{chunk-R5VAVVHP.js → chunk-72A4L5JJ.js} +2 -2
  117. package/dist/{chunk-X64YLC24.js → chunk-72VAXGEI.js} +5 -13
  118. package/dist/chunk-72VAXGEI.js.map +1 -0
  119. package/dist/{chunk-IKQTFQMI.js → chunk-755Q3DGF.js} +22 -3
  120. package/dist/chunk-755Q3DGF.js.map +1 -0
  121. package/dist/{chunk-D7FOKIY5.js → chunk-7AMFUATK.js} +12 -9
  122. package/dist/{chunk-D7FOKIY5.js.map → chunk-7AMFUATK.js.map} +1 -1
  123. package/dist/{chunk-BFVEEB7W.js → chunk-7ON2JW73.js} +57 -22
  124. package/dist/chunk-7ON2JW73.js.map +1 -0
  125. package/dist/chunk-7RNBVZZO.js +270 -0
  126. package/dist/chunk-7RNBVZZO.js.map +1 -0
  127. package/dist/{chunk-3FAMU5TX.js → chunk-A6USBZTO.js} +2 -2
  128. package/dist/{chunk-ZHIVCODT.js → chunk-A72SWTWW.js} +7 -7
  129. package/dist/{chunk-FC77VUX5.js → chunk-A7Q43EUZ.js} +2 -2
  130. package/dist/{chunk-UJBESW6X.js → chunk-AE7WMV4V.js} +7 -7
  131. package/dist/{chunk-J2HSAU72.js → chunk-AIK5W3IW.js} +29 -1
  132. package/dist/chunk-AIK5W3IW.js.map +1 -0
  133. package/dist/{chunk-A5UXZRRM.js → chunk-AJ7QCSIS.js} +2 -2
  134. package/dist/{chunk-FNMFJWBY.js → chunk-ANEUPF6O.js} +5 -5
  135. package/dist/chunk-AREGMX2J.js +50 -0
  136. package/dist/chunk-AREGMX2J.js.map +1 -0
  137. package/dist/chunk-AVPXXV6J.js +448 -0
  138. package/dist/chunk-AVPXXV6J.js.map +1 -0
  139. package/dist/{chunk-2A3OXAP2.js → chunk-B7RWBZXW.js} +2 -2
  140. package/dist/{chunk-QKQYXZVS.js → chunk-BI2OJF6J.js} +1819 -1481
  141. package/dist/chunk-BI2OJF6J.js.map +1 -0
  142. package/dist/{chunk-GWTFLF2P.js → chunk-BJMBJZ2Y.js} +59 -59
  143. package/dist/chunk-BJMBJZ2Y.js.map +1 -0
  144. package/dist/{chunk-74F5STS4.js → chunk-BLAKS3CP.js} +4 -4
  145. package/dist/{chunk-M7VGG3ID.js → chunk-BV5WMSIJ.js} +9 -9
  146. package/dist/{chunk-2BFLDH5F.js → chunk-BXLOS5AJ.js} +2 -2
  147. package/dist/{chunk-UXKMMNJD.js → chunk-C23BYTJV.js} +6 -6
  148. package/dist/{chunk-JZHHREBL.js → chunk-C3AKM55W.js} +2 -2
  149. package/dist/{chunk-RP7YXA67.js → chunk-C5JF6EZ7.js} +2 -2
  150. package/dist/{chunk-T7Y5KPLN.js → chunk-C6XBRYVD.js} +16 -15
  151. package/dist/chunk-C6XBRYVD.js.map +1 -0
  152. package/dist/{chunk-FTYDWKO6.js → chunk-CEN6DW6X.js} +12 -2
  153. package/dist/chunk-CEN6DW6X.js.map +1 -0
  154. package/dist/chunk-CGASUJVP.js +421 -0
  155. package/dist/chunk-CGASUJVP.js.map +1 -0
  156. package/dist/{chunk-EHCONI6E.js → chunk-CQMEM5CC.js} +2 -2
  157. package/dist/{chunk-PBNZVPFS.js → chunk-CXZQOVIE.js} +12 -12
  158. package/dist/chunk-D3V3UMET.js +44 -0
  159. package/dist/chunk-D3V3UMET.js.map +1 -0
  160. package/dist/{chunk-7N2RUBAP.js → chunk-DDA47TES.js} +2 -2
  161. package/dist/{chunk-64SE4X5G.js → chunk-DEBHXHJR.js} +3 -3
  162. package/dist/{chunk-EHK6KZHK.js → chunk-DNHVPZOD.js} +2 -2
  163. package/dist/{chunk-437S3G37.js → chunk-DQEMWVMT.js} +2 -2
  164. package/dist/{chunk-LZZNTPLR.js → chunk-DX3XRGLH.js} +2 -2
  165. package/dist/chunk-EA2H5LML.js +72 -0
  166. package/dist/chunk-EA2H5LML.js.map +1 -0
  167. package/dist/{chunk-INELTPRG.js → chunk-EEC7UJPX.js} +103 -106
  168. package/dist/chunk-EEC7UJPX.js.map +1 -0
  169. package/dist/{chunk-KSNVDPDF.js → chunk-EKBNDKDY.js} +21 -20
  170. package/dist/chunk-EKBNDKDY.js.map +1 -0
  171. package/dist/{chunk-YF6FMLBT.js → chunk-EQWEIIKQ.js} +64 -34
  172. package/dist/chunk-EQWEIIKQ.js.map +1 -0
  173. package/dist/{chunk-DZKHSDOM.js → chunk-ES36HTSC.js} +4 -4
  174. package/dist/{chunk-TN7THW5U.js → chunk-ET356KSB.js} +2 -2
  175. package/dist/{chunk-YNDLCWXS.js → chunk-EZ25VE3G.js} +4 -4
  176. package/dist/{chunk-DMSDUGDM.js → chunk-F7GAIWFA.js} +20 -20
  177. package/dist/{chunk-G6XXLKC5.js → chunk-FFPJINJE.js} +6 -6
  178. package/dist/chunk-FMLKOL2Z.js +636 -0
  179. package/dist/chunk-FMLKOL2Z.js.map +1 -0
  180. package/dist/chunk-FQC3DHH2.js +20 -0
  181. package/dist/chunk-FQC3DHH2.js.map +1 -0
  182. package/dist/{chunk-G4CN3ZXL.js → chunk-FUTF72MJ.js} +15 -15
  183. package/dist/chunk-GCASGYIO.js +71 -0
  184. package/dist/chunk-GCASGYIO.js.map +1 -0
  185. package/dist/{chunk-HF77M34J.js → chunk-GFPZS3F5.js} +8 -8
  186. package/dist/{chunk-BCDKBDSY.js → chunk-GNVZQ5JN.js} +99 -41
  187. package/dist/chunk-GNVZQ5JN.js.map +1 -0
  188. package/dist/{chunk-G6NKALRN.js → chunk-H4WG3UQZ.js} +2 -2
  189. package/dist/{chunk-UDQUSU27.js → chunk-HNZKVLAN.js} +2 -2
  190. package/dist/{chunk-5EZXHU36.js → chunk-HYQJQGD3.js} +2 -2
  191. package/dist/{chunk-PLQE6MJA.js → chunk-IFH6LWTO.js} +50 -8
  192. package/dist/chunk-IFH6LWTO.js.map +1 -0
  193. package/dist/{chunk-RULE4VG5.js → chunk-ILGC6JH6.js} +21 -6
  194. package/dist/chunk-ILGC6JH6.js.map +1 -0
  195. package/dist/chunk-IUM3VSHI.js +113 -0
  196. package/dist/chunk-IUM3VSHI.js.map +1 -0
  197. package/dist/{chunk-TRWPCR6P.js → chunk-JECBQBEX.js} +3 -3
  198. package/dist/{chunk-E6CBU7XP.js → chunk-JYIFGGEM.js} +2 -2
  199. package/dist/{chunk-VA4WSW54.js → chunk-JYIJNNN3.js} +3 -3
  200. package/dist/{chunk-L5HJQC36.js → chunk-K2TDK7GG.js} +3 -3
  201. package/dist/{chunk-KDXVOFYY.js → chunk-KAVBJSBQ.js} +4 -4
  202. package/dist/{chunk-BS4SGLWV.js → chunk-KF5EUVKQ.js} +16 -6
  203. package/dist/chunk-KF5EUVKQ.js.map +1 -0
  204. package/dist/chunk-KFZY2OFH.js +42 -0
  205. package/dist/chunk-KFZY2OFH.js.map +1 -0
  206. package/dist/{chunk-4OKLXWDZ.js → chunk-KNB7IBBU.js} +2 -2
  207. package/dist/{chunk-QLULYKWZ.js → chunk-KSXJOC4F.js} +2 -2
  208. package/dist/{chunk-2S6QHZGJ.js → chunk-L2DPF4DF.js} +1 -1
  209. package/dist/{chunk-JI5AVXYO.js → chunk-LEPOP46W.js} +6 -6
  210. package/dist/{chunk-O7BBFJLP.js → chunk-LTAVSOZW.js} +2 -2
  211. package/dist/{chunk-E3VODCC3.js → chunk-LUDXM7MD.js} +14 -2
  212. package/dist/{chunk-E3VODCC3.js.map → chunk-LUDXM7MD.js.map} +1 -1
  213. package/dist/{chunk-2IZAGAJR.js → chunk-LULR4IUW.js} +3 -3
  214. package/dist/{chunk-QQGPUKMT.js → chunk-MC5Q3J7S.js} +398 -7
  215. package/dist/chunk-MC5Q3J7S.js.map +1 -0
  216. package/dist/{chunk-WMWVO45V.js → chunk-MC6XO7T4.js} +2 -2
  217. package/dist/chunk-MKQBXQKU.js +107 -0
  218. package/dist/chunk-MKQBXQKU.js.map +1 -0
  219. package/dist/{chunk-7PND4PUC.js → chunk-MMGGVZ4Q.js} +29 -9
  220. package/dist/{chunk-7PND4PUC.js.map → chunk-MMGGVZ4Q.js.map} +1 -1
  221. package/dist/{chunk-D6RIFG4O.js → chunk-MNB5RMAY.js} +2 -2
  222. package/dist/{chunk-Q5WG43OP.js → chunk-MYFQ3ED4.js} +7 -7
  223. package/dist/{chunk-V3UE5I5F.js → chunk-MYVPLJOO.js} +2 -2
  224. package/dist/chunk-NINSR6LX.js +83 -0
  225. package/dist/chunk-NINSR6LX.js.map +1 -0
  226. package/dist/{chunk-MTWKDOVO.js → chunk-NLE6TSLG.js} +2 -2
  227. package/dist/{chunk-OAZVR2BV.js → chunk-OGCAYLNA.js} +8 -6
  228. package/dist/{chunk-OAZVR2BV.js.map → chunk-OGCAYLNA.js.map} +1 -1
  229. package/dist/{chunk-DBRYEIGY.js → chunk-OJP3N7UK.js} +2 -2
  230. package/dist/{chunk-VDW4VU7B.js → chunk-OQJIB32H.js} +28 -23
  231. package/dist/chunk-OQJIB32H.js.map +1 -0
  232. package/dist/{chunk-SMX5267P.js → chunk-OZKOPQCM.js} +2 -2
  233. package/dist/{chunk-JCK7V6SN.js → chunk-P65YJEEL.js} +2 -2
  234. package/dist/{chunk-MTR7BZQN.js → chunk-PBGWYM3H.js} +3 -3
  235. package/dist/chunk-PIG4WJFQ.js +87 -0
  236. package/dist/chunk-PIG4WJFQ.js.map +1 -0
  237. package/dist/chunk-PJSK6OJM.js +201 -0
  238. package/dist/chunk-PJSK6OJM.js.map +1 -0
  239. package/dist/{chunk-OVJ2HIPE.js → chunk-PMUD7ERF.js} +158 -125
  240. package/dist/chunk-PMUD7ERF.js.map +1 -0
  241. package/dist/chunk-PQVCH2AE.js +76 -0
  242. package/dist/chunk-PQVCH2AE.js.map +1 -0
  243. package/dist/{chunk-AXTXN4T6.js → chunk-PWFCHOB3.js} +2 -2
  244. package/dist/{chunk-FDPZVY6D.js → chunk-QFN4U7AG.js} +2 -2
  245. package/dist/{chunk-K2ZLHESQ.js → chunk-QIEUU4UK.js} +2 -2
  246. package/dist/{chunk-DYP3YYJJ.js → chunk-QJAQNXWI.js} +39 -5
  247. package/dist/chunk-QJAQNXWI.js.map +1 -0
  248. package/dist/{chunk-3D6AFGQR.js → chunk-QVT3E4CE.js} +7 -7
  249. package/dist/{chunk-FIJUY7GG.js → chunk-R26ZMXR2.js} +23 -23
  250. package/dist/{chunk-FIJUY7GG.js.map → chunk-R26ZMXR2.js.map} +1 -1
  251. package/dist/chunk-R3DJVOSM.js +34 -0
  252. package/dist/chunk-R3DJVOSM.js.map +1 -0
  253. package/dist/{chunk-SFQ6QNL7.js → chunk-R6YJI3HE.js} +2 -1
  254. package/dist/{chunk-5CJVLG3H.js → chunk-RFDD3B7W.js} +5 -5
  255. package/dist/{chunk-JBPKEARU.js → chunk-RKNJBZ55.js} +4 -4
  256. package/dist/chunk-ROI7BK7H.js +88 -0
  257. package/dist/chunk-ROI7BK7H.js.map +1 -0
  258. package/dist/{chunk-FNZQGN76.js → chunk-S2BBISHU.js} +4 -4
  259. package/dist/{chunk-IALLX7EE.js → chunk-S2FSBU4H.js} +3 -3
  260. package/dist/{chunk-BFPETA3S.js → chunk-SCCO46KZ.js} +3 -2
  261. package/dist/chunk-SCCO46KZ.js.map +1 -0
  262. package/dist/chunk-SK7AMF2J.js +168 -0
  263. package/dist/chunk-SK7AMF2J.js.map +1 -0
  264. package/dist/{chunk-KSBEEMQF.js → chunk-TG6IHVE2.js} +151 -6
  265. package/dist/chunk-TG6IHVE2.js.map +1 -0
  266. package/dist/{chunk-7K5Q6COX.js → chunk-TVVEYCNW.js} +4 -4
  267. package/dist/{chunk-DPAENM7O.js → chunk-U3ZAVRP3.js} +2 -2
  268. package/dist/{chunk-ODPLEWB6.js → chunk-UFGFMWAD.js} +47 -17
  269. package/dist/chunk-UFGFMWAD.js.map +1 -0
  270. package/dist/{chunk-4KJLYTLS.js → chunk-V57NLO5P.js} +2 -2
  271. package/dist/{chunk-FLVL4L3L.js → chunk-VDX2J7OX.js} +2 -2
  272. package/dist/{chunk-AJLLIIML.js → chunk-W4FBGYGK.js} +1 -1
  273. package/dist/{chunk-TXLGHDHS.js → chunk-W4XJFLAL.js} +53 -32
  274. package/dist/chunk-W4XJFLAL.js.map +1 -0
  275. package/dist/{chunk-6SXVCD7W.js → chunk-W7IGLX4G.js} +2 -2
  276. package/dist/{chunk-KQDNAXOM.js → chunk-WG5HSQ4P.js} +19 -6
  277. package/dist/chunk-WG5HSQ4P.js.map +1 -0
  278. package/dist/{chunk-LTJAMRGI.js → chunk-WL5EBRDH.js} +17 -3
  279. package/dist/chunk-WL5EBRDH.js.map +1 -0
  280. package/dist/{chunk-KAWTOYAW.js → chunk-WLZYGLJ4.js} +2 -2
  281. package/dist/{chunk-RO4LQGT3.js → chunk-WON4APQY.js} +4 -4
  282. package/dist/{chunk-PQVK2S3J.js → chunk-WZFAPHIK.js} +6 -6
  283. package/dist/{chunk-KQPJLK3X.js → chunk-XL24QQ63.js} +2 -2
  284. package/dist/{chunk-LZOV7MX7.js → chunk-XQDRKZ7V.js} +6476 -5747
  285. package/dist/chunk-XQDRKZ7V.js.map +1 -0
  286. package/dist/{chunk-RVZRYUQH.js → chunk-YROFNEG5.js} +7 -7
  287. package/dist/{chunk-RAR2BSEM.js → chunk-YV32N67O.js} +1 -1
  288. package/dist/chunk-YV32N67O.js.map +1 -0
  289. package/dist/{chunk-PBSAPHHA.js → chunk-YVKF3HEW.js} +1 -1
  290. package/dist/chunk-YVKF3HEW.js.map +1 -0
  291. package/dist/{chunk-VRAD2FGO.js → chunk-Z54EM5YZ.js} +12 -12
  292. package/dist/{chunk-2VN4JAX7.js → chunk-ZOKZIR5K.js} +95 -33
  293. package/dist/chunk-ZOKZIR5K.js.map +1 -0
  294. package/dist/{chunk-DCFV7A7H.js → chunk-ZVAYK7GU.js} +101 -91
  295. package/dist/chunk-ZVAYK7GU.js.map +1 -0
  296. package/dist/{cli-Cd5fMmhq.d.ts → cli-5tNLVTvJ.d.ts} +28 -12
  297. package/dist/cli.d.ts +16 -9
  298. package/dist/cli.js +142 -127
  299. package/dist/compounding/engine.d.ts +5 -2
  300. package/dist/compounding/engine.js +36 -26
  301. package/dist/compounding/preference-consolidator.d.ts +3 -1
  302. package/dist/compounding/preference-consolidator.js +1 -1
  303. package/dist/compression-optimizer.d.ts +3 -1
  304. package/dist/config-qmd.d.ts +8 -0
  305. package/dist/config-qmd.js +20 -0
  306. package/dist/config-qmd.js.map +1 -0
  307. package/dist/config.d.ts +3 -1
  308. package/dist/config.js +15 -10
  309. package/dist/connectors/codex-materialize-runner.d.ts +3 -1
  310. package/dist/connectors/codex-materialize-runner.js +36 -26
  311. package/dist/connectors/codex-materialize.d.ts +3 -1
  312. package/dist/connectors/codex-materialize.js +2 -2
  313. package/dist/connectors/index.d.ts +3 -1
  314. package/dist/connectors/index.js +41 -32
  315. package/dist/consolidation-provenance-check.d.ts +5 -2
  316. package/dist/consolidation-undo.d.ts +5 -2
  317. package/dist/contradiction/index.d.ts +5 -2
  318. package/dist/contradiction/index.js +10 -4
  319. package/dist/{contradiction-scan-J57T5QV7.js → contradiction-scan-RJBABNRH.js} +4 -4
  320. package/dist/contradiction-scan-RJBABNRH.js.map +1 -0
  321. package/dist/conversation-index/backend.d.ts +3 -1
  322. package/dist/conversation-index/backend.js +5 -5
  323. package/dist/conversation-index/chunker.d.ts +3 -1
  324. package/dist/conversation-index/cleanup.js +2 -2
  325. package/dist/conversation-index/faiss-adapter.d.ts +3 -1
  326. package/dist/conversation-index/faiss-adapter.js +2 -2
  327. package/dist/conversation-index/indexer.d.ts +3 -1
  328. package/dist/conversation-index/indexer.js +2 -2
  329. package/dist/conversation-index/search.d.ts +3 -1
  330. package/dist/conversation-index/search.js +2 -2
  331. package/dist/cross-namespace-budget.d.ts +45 -1
  332. package/dist/cross-namespace-budget.js +5 -3
  333. package/dist/dashboard-runtime.js +2 -2
  334. package/dist/day-summary.d.ts +3 -1
  335. package/dist/day-summary.js +3 -3
  336. package/dist/delinearize.d.ts +3 -1
  337. package/dist/direct-answer-wiring.d.ts +3 -1
  338. package/dist/direct-answer.d.ts +3 -1
  339. package/dist/{dreams-ledger-6UODQOX6.js → dreams-ledger-567VKVOU.js} +4 -2
  340. package/dist/dreams-ledger-567VKVOU.js.map +1 -0
  341. package/dist/embedding-fallback.d.ts +3 -1
  342. package/dist/embedding-fallback.js +3 -3
  343. package/dist/enrichment/index.d.ts +3 -1
  344. package/dist/entity-retrieval.d.ts +5 -2
  345. package/dist/entity-retrieval.js +35 -26
  346. package/dist/entity-schema.d.ts +3 -1
  347. package/dist/explicit-capture.d.ts +13 -8
  348. package/dist/explicit-capture.js +7 -3
  349. package/dist/extraction-faithfulness.d.ts +3 -1
  350. package/dist/extraction-faithfulness.js +5 -5
  351. package/dist/extraction-judge-telemetry.d.ts +3 -1
  352. package/dist/extraction-judge-telemetry.js +2 -2
  353. package/dist/extraction-judge-training.d.ts +3 -1
  354. package/dist/extraction-judge-training.js +2 -2
  355. package/dist/extraction-judge.d.ts +3 -1
  356. package/dist/extraction-judge.js +5 -5
  357. package/dist/extraction.d.ts +3 -1
  358. package/dist/extraction.js +13 -12
  359. package/dist/faithfulness-config.js +3 -2
  360. package/dist/fallback-llm.d.ts +3 -1
  361. package/dist/fallback-llm.js +4 -4
  362. package/dist/{first-start-migration-TI67YMLG.js → first-start-migration-CSRHCJIQ.js} +2 -2
  363. package/dist/{forget-CQCLB5LB.js → forget-HRPLVB3W.js} +5 -5
  364. package/dist/graph-dashboard-diff.d.ts +3 -1
  365. package/dist/graph-dashboard-key.d.ts +3 -1
  366. package/dist/graph-dashboard-parser.d.ts +3 -1
  367. package/dist/{graph-edge-decay-IOGBBAGC.js → graph-edge-decay-Z6ENALU2.js} +3 -3
  368. package/dist/graph-edge-decay-Z6ENALU2.js.map +1 -0
  369. package/dist/graph-edge-reinforcement.d.ts +3 -1
  370. package/dist/graph-snapshot.d.ts +3 -1
  371. package/dist/graph-snapshot.js +2 -2
  372. package/dist/graph.d.ts +3 -1
  373. package/dist/graph.js +1 -1
  374. package/dist/identity-continuity.d.ts +1 -2
  375. package/dist/importance.d.ts +3 -1
  376. package/dist/importers/index.d.ts +3 -1
  377. package/dist/in-flight-reads.d.ts +3 -1
  378. package/dist/index.d.ts +473 -464
  379. package/dist/index.js +287 -239
  380. package/dist/intent.d.ts +3 -1
  381. package/dist/lcm/archive.js +2 -2
  382. package/dist/lcm/engine.d.ts +3 -1
  383. package/dist/lcm/engine.js +6 -6
  384. package/dist/lcm/index.d.ts +3 -1
  385. package/dist/lcm/index.js +13 -13
  386. package/dist/lcm/schema.js +2 -2
  387. package/dist/lcm/summarizer.js +3 -3
  388. package/dist/lcm/tools.d.ts +3 -1
  389. package/dist/lifecycle.d.ts +3 -1
  390. package/dist/live-connectors-runner.d.ts +3 -1
  391. package/dist/local-llm.d.ts +5 -2
  392. package/dist/local-llm.js +3 -3
  393. package/dist/local-model-endpoint.d.ts +3 -1
  394. package/dist/logger.d.ts +3 -1
  395. package/dist/logger.js +7 -3
  396. package/dist/maintenance/archive-observations.js +2 -2
  397. package/dist/maintenance/memory-governance.d.ts +3 -1
  398. package/dist/maintenance/memory-governance.js +35 -25
  399. package/dist/maintenance/migrate-observations.js +3 -3
  400. package/dist/maintenance/observation-ledger-utils.js +2 -2
  401. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +102 -1
  402. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +37 -25
  403. package/dist/maintenance/rebuild-memory-projection.js +38 -28
  404. package/dist/maintenance/rebuild-observations.js +3 -3
  405. package/dist/mcp-memory-inspector-app.d.ts +22 -15
  406. package/dist/memory-action-policy.d.ts +3 -1
  407. package/dist/memory-cache.d.ts +3 -1
  408. package/dist/memory-lifecycle-ledger-utils.d.ts +25 -2
  409. package/dist/memory-lifecycle-ledger-utils.js +11 -1
  410. package/dist/memory-projection-store.d.ts +3 -1
  411. package/dist/memory-projection-store.js +2 -2
  412. package/dist/memory-provenance.d.ts +3 -1
  413. package/dist/memory-worth-outcomes.d.ts +5 -2
  414. package/dist/model-registry.js +2 -2
  415. package/dist/models-json.d.ts +3 -1
  416. package/dist/models-json.js +2 -2
  417. package/dist/namespaces/migrate.d.ts +6 -3
  418. package/dist/namespaces/migrate.js +51 -42
  419. package/dist/namespaces/principal.d.ts +27 -2
  420. package/dist/namespaces/principal.js +6 -2
  421. package/dist/namespaces/search.d.ts +16 -2
  422. package/dist/namespaces/search.js +24 -20
  423. package/dist/namespaces/storage.d.ts +24 -3
  424. package/dist/namespaces/storage.js +35 -27
  425. package/dist/native-knowledge.d.ts +3 -1
  426. package/dist/native-knowledge.js +2 -2
  427. package/dist/negative.js +2 -2
  428. package/dist/offline-sync-exclude-globs.d.ts +13 -0
  429. package/dist/offline-sync-exclude-globs.js +10 -0
  430. package/dist/offline-sync-exclude-globs.js.map +1 -0
  431. package/dist/offline-sync-impression-drain.d.ts +78 -0
  432. package/dist/offline-sync-impression-drain.js +37 -0
  433. package/dist/offline-sync-impression-drain.js.map +1 -0
  434. package/dist/offline-sync.js +4 -2
  435. package/dist/operator-toolkit.d.ts +5 -2
  436. package/dist/operator-toolkit.js +69 -54
  437. package/dist/orchestration/compression-guideline-coordinator.d.ts +5 -2
  438. package/dist/orchestration/compression-guideline-coordinator.js +3 -3
  439. package/dist/orchestration/maintenance.d.ts +121 -2
  440. package/dist/orchestration/maintenance.js +44 -31
  441. package/dist/{orchestrator-Bp_jeBHK.d.ts → orchestrator-CQJ8U7En.d.ts} +85 -79
  442. package/dist/orchestrator.d.ts +13 -8
  443. package/dist/orchestrator.js +194 -177
  444. package/dist/patterns-cli.d.ts +3 -1
  445. package/dist/{pipeline-BAj5bx7g.d.ts → pipeline-Cn-kvYeV.d.ts} +1 -1
  446. package/dist/policy-runtime.d.ts +3 -1
  447. package/dist/prioritized-embed.d.ts +19 -0
  448. package/dist/prioritized-embed.js +8 -0
  449. package/dist/prioritized-embed.js.map +1 -0
  450. package/dist/proactive-contention.d.ts +28 -0
  451. package/dist/proactive-contention.js +8 -0
  452. package/dist/proactive-contention.js.map +1 -0
  453. package/dist/profiling.js +2 -2
  454. package/dist/provenance.d.ts +3 -1
  455. package/dist/provenance.js +3 -2
  456. package/dist/{purge-NDWV6WYD.js → purge-IRF47ZTX.js} +3 -3
  457. package/dist/{qmd-_MDSlj1m.d.ts → qmd-oh9VXz1d.d.ts} +11 -1
  458. package/dist/qmd-preflight.d.ts +5 -2
  459. package/dist/qmd-recall-cache.d.ts +3 -1
  460. package/dist/qmd-status.d.ts +57 -0
  461. package/dist/qmd-status.js +18 -0
  462. package/dist/qmd-status.js.map +1 -0
  463. package/dist/qmd.d.ts +5 -2
  464. package/dist/qmd.js +7 -3
  465. package/dist/recall-concurrency-config.d.ts +16 -0
  466. package/dist/recall-concurrency-config.js +10 -0
  467. package/dist/recall-concurrency-config.js.map +1 -0
  468. package/dist/recall-disclosure-escalation.d.ts +3 -1
  469. package/dist/recall-explain-renderer.d.ts +4 -1
  470. package/dist/recall-explain-renderer.js +3 -3
  471. package/dist/recall-memory-map.d.ts +26 -0
  472. package/dist/recall-memory-map.js +18 -0
  473. package/dist/recall-memory-map.js.map +1 -0
  474. package/dist/recall-planner-llm.d.ts +3 -1
  475. package/dist/recall-planner-llm.js +4 -4
  476. package/dist/recall-qos.js +2 -2
  477. package/dist/recall-state.d.ts +163 -2
  478. package/dist/recall-state.js +6 -3
  479. package/dist/recall-tag-filter.d.ts +3 -1
  480. package/dist/recall-timings.d.ts +11 -2
  481. package/dist/recall-timings.js +3 -1
  482. package/dist/recall-xray-cli.d.ts +3 -1
  483. package/dist/recall-xray-cli.js +4 -4
  484. package/dist/recall-xray-renderer.d.ts +3 -1
  485. package/dist/recall-xray-renderer.js +3 -3
  486. package/dist/recall-xray.d.ts +3 -1
  487. package/dist/recall-xray.js +2 -2
  488. package/dist/relevance.js +3 -3
  489. package/dist/replay/normalizers/chatgpt.d.ts +3 -1
  490. package/dist/replay/normalizers/claude.d.ts +3 -1
  491. package/dist/replay/normalizers/openclaw.d.ts +3 -1
  492. package/dist/replay/normalizers/shared.d.ts +3 -1
  493. package/dist/replay/runner.d.ts +3 -1
  494. package/dist/replay/types.d.ts +3 -1
  495. package/dist/rerank.d.ts +8 -1
  496. package/dist/rerank.js +3 -1
  497. package/dist/resolution-3K27T4VO.js +18 -0
  498. package/dist/resolution-3K27T4VO.js.map +1 -0
  499. package/dist/resolve-auth-token.d.ts +3 -1
  500. package/dist/resolve-provider-secret.js +2 -2
  501. package/dist/resume-bundles.js +19 -14
  502. package/dist/retrieval-agents.d.ts +19 -16
  503. package/dist/retrieval-agents.js +3 -3
  504. package/dist/retrieval-tiers.d.ts +3 -1
  505. package/dist/routing/engine.d.ts +3 -1
  506. package/dist/routing/store.d.ts +3 -1
  507. package/dist/routing/store.js +2 -2
  508. package/dist/salvage-envelope.d.ts +18 -0
  509. package/dist/salvage-envelope.js +15 -0
  510. package/dist/salvage-envelope.js.map +1 -0
  511. package/dist/schemas.d.ts +98 -98
  512. package/dist/scope-profiles-EpJG7yKP.d.ts +30 -0
  513. package/dist/search/document-scanner.js +3 -2
  514. package/dist/search/embed-helper.d.ts +3 -1
  515. package/dist/search/embed-helper.js +3 -3
  516. package/dist/search/factory.d.ts +3 -1
  517. package/dist/search/factory.js +18 -16
  518. package/dist/search/index.d.ts +3 -1
  519. package/dist/search/index.js +22 -20
  520. package/dist/search/lancedb-backend.d.ts +3 -1
  521. package/dist/search/lancedb-backend.js +6 -5
  522. package/dist/search/meilisearch-backend.d.ts +3 -1
  523. package/dist/search/meilisearch-backend.js +6 -5
  524. package/dist/search/noop-backend.d.ts +3 -1
  525. package/dist/search/orama-backend.d.ts +3 -1
  526. package/dist/search/orama-backend.js +6 -5
  527. package/dist/search/port.d.ts +16 -2
  528. package/dist/search/port.js +1 -1
  529. package/dist/search/remote-backend.d.ts +3 -1
  530. package/dist/search/remote-backend.js +3 -3
  531. package/dist/secure-store/index.d.ts +12 -1
  532. package/dist/secure-store/index.js +6 -3
  533. package/dist/{semantic-consolidation-C2m5eHHE.d.ts → semantic-consolidation-DILZEQq3.d.ts} +1 -1
  534. package/dist/semantic-consolidation.d.ts +4 -2
  535. package/dist/semantic-consolidation.js +38 -29
  536. package/dist/semantic-rule-promotion.js +34 -24
  537. package/dist/semantic-rule-verifier.d.ts +3 -1
  538. package/dist/semantic-rule-verifier.js +35 -25
  539. package/dist/session-observer-bands.d.ts +3 -1
  540. package/dist/session-observer-state.d.ts +3 -1
  541. package/dist/session-observer-state.js +2 -2
  542. package/dist/session-transcript-migration.js +2 -2
  543. package/dist/shared-context/manager.d.ts +11 -9
  544. package/dist/shared-context/manager.js +3 -3
  545. package/dist/signal.d.ts +3 -1
  546. package/dist/{storage-hr_Y2z5R.d.ts → storage-NIyKYD8g.d.ts} +489 -110
  547. package/dist/storage-guards.js +2 -2
  548. package/dist/storage.d.ts +6 -3
  549. package/dist/storage.js +38 -26
  550. package/dist/structured-attributes.d.ts +23 -1
  551. package/dist/structured-attributes.js +7 -1
  552. package/dist/summarizer.d.ts +3 -1
  553. package/dist/summarizer.js +11 -11
  554. package/dist/summary-snapshot.d.ts +3 -1
  555. package/dist/summary-snapshot.js +2 -2
  556. package/dist/temporal-index-batch.d.ts +1 -0
  557. package/dist/temporal-index-batch.js +10 -0
  558. package/dist/temporal-index-batch.js.map +1 -0
  559. package/dist/temporal-index-compat.d.ts +279 -1
  560. package/dist/temporal-index-compat.js +1 -1
  561. package/dist/temporal-index.d.ts +1 -225
  562. package/dist/temporal-index.js +35 -3
  563. package/dist/temporal-supersession.d.ts +5 -2
  564. package/dist/temporal-supersession.js +2 -2
  565. package/dist/temporal-timeline-recall.d.ts +3 -1
  566. package/dist/temporal-validity.d.ts +3 -1
  567. package/dist/threading.d.ts +3 -1
  568. package/dist/threading.js +2 -2
  569. package/dist/tier-migration.d.ts +5 -2
  570. package/dist/tier-routing.d.ts +3 -1
  571. package/dist/{tier-stats-KV7IWCJR.js → tier-stats-QEJSPFV2.js} +2 -2
  572. package/dist/tokens.js +3 -3
  573. package/dist/topics.d.ts +3 -1
  574. package/dist/transcript.d.ts +3 -1
  575. package/dist/transcript.js +2 -2
  576. package/dist/transfer/backup.js +3 -3
  577. package/dist/transfer/capsule-export.js +3 -3
  578. package/dist/transfer/capsule-import.js +3 -3
  579. package/dist/transfer/types.d.ts +90 -90
  580. package/dist/trust-score-stage.d.ts +75 -38
  581. package/dist/trust-score-stage.js +11 -3
  582. package/dist/trust-score.d.ts +3 -1
  583. package/dist/{types-Cg8q7W7_.d.ts → types-D_fG2ix8.d.ts} +39 -63
  584. package/dist/types-continuity.d.ts +52 -0
  585. package/dist/types-continuity.js +1 -0
  586. package/dist/types-continuity.js.map +1 -0
  587. package/dist/types.d.ts +3 -1
  588. package/dist/types.js +1 -1
  589. package/dist/utility-runtime.d.ts +3 -1
  590. package/dist/utils/serialize-mutations.d.ts +31 -2
  591. package/dist/utils/serialize-mutations.js +1 -1
  592. package/dist/verified-recall.js +36 -26
  593. package/dist/write-envelope.d.ts +282 -0
  594. package/dist/write-envelope.js +35 -0
  595. package/dist/write-envelope.js.map +1 -0
  596. package/dist/write-quarantine.d.ts +94 -0
  597. package/dist/write-quarantine.js +11 -0
  598. package/dist/write-quarantine.js.map +1 -0
  599. package/dist/write-rate-limiter.d.ts +45 -0
  600. package/dist/write-rate-limiter.js +9 -0
  601. package/dist/write-rate-limiter.js.map +1 -0
  602. package/package.json +37 -2
  603. package/src/access-admin-ops-surface.ts +17 -7
  604. package/src/access-boundary.test.ts +28 -0
  605. package/src/access-boundary.ts +31 -2
  606. package/src/access-citation.test.ts +72 -0
  607. package/src/access-citation.ts +139 -0
  608. package/src/access-errors.ts +21 -0
  609. package/src/access-fingerprint-parity.test.ts +211 -0
  610. package/src/access-http-cancellation.test.ts +59 -21
  611. package/src/access-http.test.ts +90 -0
  612. package/src/access-http.ts +79 -79
  613. package/src/access-mcp-cancellation.test.ts +16 -7
  614. package/src/access-memory-search-fanout.test.ts +220 -0
  615. package/src/access-memory-search-fanout.ts +168 -0
  616. package/src/access-observe-quarantine.test.ts +172 -0
  617. package/src/access-observe-write-surface.ts +137 -11
  618. package/src/access-operations-batch.ts +2 -0
  619. package/src/access-recall-concurrency.ts +773 -0
  620. package/src/access-recall-response.ts +307 -0
  621. package/src/access-recall-surface.ts +100 -252
  622. package/src/access-service-coding-write.test.ts +22 -4
  623. package/src/access-service-health.test.ts +49 -0
  624. package/src/access-service-namespace.test.ts +486 -8
  625. package/src/access-service-observe-scope.test.ts +4 -0
  626. package/src/access-service-recall-concurrency.test.ts +1990 -0
  627. package/src/access-service.ts +186 -179
  628. package/src/access-surface-catalog.ts +1 -0
  629. package/src/access-token-capabilities.ts +16 -9
  630. package/src/active-recall.test.ts +35 -0
  631. package/src/active-recall.ts +7 -0
  632. package/src/bounded-jsonl-state.ts +93 -0
  633. package/src/buffer-session.test.ts +422 -5
  634. package/src/buffer-surprise-trigger.test.ts +41 -0
  635. package/src/buffer.ts +218 -3
  636. package/src/capabilities-cluster-b.test.ts +1 -0
  637. package/src/capabilities.ts +5 -6
  638. package/src/cli.ts +21 -22
  639. package/src/coding/architecture-surfaces.test.ts +6 -3
  640. package/src/coding/architecture-surfaces.ts +36 -25
  641. package/src/coding/decision-surfaces.ts +42 -34
  642. package/src/compounding/engine.test.ts +5 -1
  643. package/src/compounding/engine.ts +7 -7
  644. package/src/config-qmd.ts +89 -0
  645. package/src/config.test.ts +136 -0
  646. package/src/config.ts +113 -118
  647. package/src/connector-provenance-lifecycle.test.ts +4 -4
  648. package/src/connectors/coerce.test.ts +131 -0
  649. package/src/connectors/coerce.ts +80 -7
  650. package/src/contradiction/contradiction.test.ts +10 -6
  651. package/src/contradiction/resolution.ts +17 -4
  652. package/src/correction/correction-access-wiring.ts +62 -18
  653. package/src/cross-namespace-budget.test.ts +35 -0
  654. package/src/cross-namespace-budget.ts +86 -19
  655. package/src/explicit-capture.ts +54 -17
  656. package/src/extraction.ts +2 -3
  657. package/src/faithfulness-graph-guard.test.ts +16 -69
  658. package/src/graph-recall.test.ts +31 -0
  659. package/src/index.ts +22 -2
  660. package/src/local-llm.ts +4 -6
  661. package/src/logger.ts +16 -0
  662. package/src/maintenance/dreams-ledger.ts +100 -49
  663. package/src/maintenance/rebuild-memory-lifecycle-ledger-cli.ts +77 -0
  664. package/src/maintenance/rebuild-memory-lifecycle-ledger.ts +373 -9
  665. package/src/memory-lifecycle-ledger-utils.ts +51 -5
  666. package/src/namespaces/principal.test.ts +37 -1
  667. package/src/namespaces/principal.ts +48 -0
  668. package/src/namespaces/search.test.ts +79 -5
  669. package/src/namespaces/search.ts +59 -6
  670. package/src/namespaces/storage.ts +43 -1
  671. package/src/offline-sync-exclude-globs.ts +58 -0
  672. package/src/offline-sync-impression-drain.test.ts +316 -0
  673. package/src/offline-sync-impression-drain.ts +260 -0
  674. package/src/offline-sync.test.ts +32 -5
  675. package/src/offline-sync.ts +1 -14
  676. package/src/operator-toolkit.ts +1 -1
  677. package/src/orchestration/batch-deindex-flush.test.ts +146 -0
  678. package/src/orchestration/consolidation-run.ts +96 -85
  679. package/src/orchestration/extraction-envelope.ts +94 -0
  680. package/src/orchestration/extraction-persist-promotion.ts +134 -0
  681. package/src/orchestration/extraction-persist.ts +325 -260
  682. package/src/orchestration/extraction-run.test.ts +1 -1
  683. package/src/orchestration/extraction-run.ts +2 -2
  684. package/src/orchestration/graph-recall-coordinator.ts +18 -7
  685. package/src/orchestration/lifecycle-policy-coordinator.ts +63 -48
  686. package/src/orchestration/maintenance.test.ts +2103 -3
  687. package/src/orchestration/maintenance.ts +574 -2
  688. package/src/orchestration/namespace-read-fanout.ts +14 -8
  689. package/src/orchestration/orchestrator-helpers.ts +8 -1
  690. package/src/orchestration/orchestrator-init.ts +22 -6
  691. package/src/orchestration/orchestrator-namespace-scope.ts +71 -0
  692. package/src/orchestration/persistence-index.ts +64 -9
  693. package/src/orchestration/qmd-result-resolver.ts +27 -0
  694. package/src/orchestration/recall-entry.ts +34 -19
  695. package/src/orchestration/recall-internal.ts +207 -79
  696. package/src/orchestration/recall-rerank-coordinator.ts +229 -82
  697. package/src/orchestration/recall-result-formatter.ts +76 -20
  698. package/src/orchestration/recall-search-pipeline.test.ts +70 -0
  699. package/src/orchestration/recall-search-pipeline.ts +102 -129
  700. package/src/orchestration/recall-section-coordinator.ts +315 -85
  701. package/src/orchestration/semantic-consolidation-coordinator.ts +69 -37
  702. package/src/orchestration/session-context.ts +21 -0
  703. package/src/orchestration/workspace-ops.test.ts +348 -0
  704. package/src/orchestration/workspace-ops.ts +168 -34
  705. package/src/orchestrator-chunked-hash-durability.test.ts +126 -0
  706. package/src/orchestrator-connector-dedup.test.ts +1061 -40
  707. package/src/orchestrator-flush.test.ts +155 -39
  708. package/src/orchestrator-nonchunked-hash-durability.test.ts +121 -0
  709. package/src/orchestrator-source-attribution.test.ts +9 -9
  710. package/src/orchestrator.ts +160 -149
  711. package/src/prioritized-embed.ts +123 -0
  712. package/src/proactive-contention.test.ts +80 -0
  713. package/src/proactive-contention.ts +39 -0
  714. package/src/procedural/procedure-miner.test.ts +19 -14
  715. package/src/procedural/procedure-miner.ts +44 -13
  716. package/src/qmd-client.test.ts +111 -1
  717. package/src/qmd-status.ts +186 -0
  718. package/src/qmd.ts +47 -47
  719. package/src/recall-budget-config.test.ts +30 -0
  720. package/src/recall-cold-deadline.test.ts +149 -0
  721. package/src/recall-concurrency-config.ts +28 -0
  722. package/src/recall-memory-map.ts +74 -0
  723. package/src/recall-rerank-coordinator.test.ts +508 -0
  724. package/src/recall-state.test.ts +825 -1
  725. package/src/recall-state.ts +406 -7
  726. package/src/recall-timings-access.test.ts +41 -0
  727. package/src/recall-timings.ts +16 -0
  728. package/src/relay/mission-access.test.ts +5 -5
  729. package/src/rerank.ts +22 -0
  730. package/src/retrieval-agents.test.ts +79 -0
  731. package/src/retrieval-agents.ts +71 -19
  732. package/src/salvage-envelope.ts +28 -0
  733. package/src/scopes/scope-plan.test.ts +42 -0
  734. package/src/scopes/scope-plan.ts +45 -0
  735. package/src/search/port.ts +13 -0
  736. package/src/secure-store/index.ts +1 -0
  737. package/src/secure-store/secure-fs.ts +48 -0
  738. package/src/secure-store/secure-store.test.ts +40 -0
  739. package/src/semantic-rule-promotion.ts +13 -4
  740. package/src/storage/content-hash-index.ts +655 -0
  741. package/src/storage/entity-timeline.ts +473 -0
  742. package/src/storage/memory-lifecycle-ledger-access.ts +603 -0
  743. package/src/storage/secure-line-reader.test.ts +197 -0
  744. package/src/storage/secure-line-reader.ts +181 -3
  745. package/src/storage-append-header-sniff.test.ts +195 -0
  746. package/src/storage-behavior-signals-cache.test.ts +237 -0
  747. package/src/storage-contract/cache-coherence.test.ts +96 -1
  748. package/src/storage-contract/content-hash.test.ts +47 -2
  749. package/src/storage-fact-hash-index-defer.test.ts +1200 -0
  750. package/src/storage-memory-lifecycle-ledger.test.ts +1146 -3
  751. package/src/storage.ts +882 -890
  752. package/src/structured-attributes.ts +52 -0
  753. package/src/temporal-index-batch.ts +112 -0
  754. package/src/temporal-index.test.ts +193 -0
  755. package/src/temporal-index.ts +49 -53
  756. package/src/testing/lifecycle-matrix.test.ts +212 -0
  757. package/src/testing/lifecycle-matrix.ts +271 -0
  758. package/src/testing/orchestrator-lite.ts +236 -0
  759. package/src/testing/subjects/dreams-ledger.test.ts +67 -0
  760. package/src/testing/subjects/extraction-lifecycle.test.ts +442 -0
  761. package/src/testing/subjects/lifecycle-ledger.test.ts +93 -0
  762. package/src/testing/subjects/recall-budget.test.ts +461 -0
  763. package/src/testing/subjects/serialized-write-chain.test.ts +224 -0
  764. package/src/trust-score-stage.test.ts +154 -0
  765. package/src/trust-score-stage.ts +216 -53
  766. package/src/types-continuity.ts +57 -0
  767. package/src/types.ts +51 -77
  768. package/src/utils/path-containment.test.ts +75 -0
  769. package/src/utils/path-containment.ts +76 -0
  770. package/src/utils/serialize-mutations.test.ts +122 -0
  771. package/src/utils/serialize-mutations.ts +68 -3
  772. package/src/wearables/memory-gen.test.ts +31 -9
  773. package/src/wearables/memory-gen.ts +95 -55
  774. package/src/wearables/pipeline.test.ts +10 -7
  775. package/src/wearables/service.test.ts +6 -8
  776. package/src/wearables/service.ts +2 -2
  777. package/src/write-envelope.extension.test.ts +111 -0
  778. package/src/write-envelope.test.ts +683 -0
  779. package/src/write-envelope.ts +902 -0
  780. package/src/write-quarantine.test.ts +245 -0
  781. package/src/write-quarantine.ts +290 -0
  782. package/src/write-rate-limiter.test.ts +105 -0
  783. package/src/write-rate-limiter.ts +135 -0
  784. package/src/write-sealed-parity.test.ts +204 -0
  785. package/dist/chunk-2VN4JAX7.js.map +0 -1
  786. package/dist/chunk-37CTGERM.js.map +0 -1
  787. package/dist/chunk-3IY64MV6.js.map +0 -1
  788. package/dist/chunk-BCDKBDSY.js.map +0 -1
  789. package/dist/chunk-BFPETA3S.js.map +0 -1
  790. package/dist/chunk-BFVEEB7W.js.map +0 -1
  791. package/dist/chunk-BS4SGLWV.js.map +0 -1
  792. package/dist/chunk-DCFV7A7H.js.map +0 -1
  793. package/dist/chunk-DYP3YYJJ.js.map +0 -1
  794. package/dist/chunk-E5BK6CGV.js +0 -335
  795. package/dist/chunk-E5BK6CGV.js.map +0 -1
  796. package/dist/chunk-FTYDWKO6.js.map +0 -1
  797. package/dist/chunk-GWTFLF2P.js.map +0 -1
  798. package/dist/chunk-IKQTFQMI.js.map +0 -1
  799. package/dist/chunk-INELTPRG.js.map +0 -1
  800. package/dist/chunk-J2HSAU72.js.map +0 -1
  801. package/dist/chunk-JREB6UFH.js.map +0 -1
  802. package/dist/chunk-K7LOWSLU.js.map +0 -1
  803. package/dist/chunk-KQDNAXOM.js.map +0 -1
  804. package/dist/chunk-KSBEEMQF.js.map +0 -1
  805. package/dist/chunk-KSNVDPDF.js.map +0 -1
  806. package/dist/chunk-LC7OODWZ.js.map +0 -1
  807. package/dist/chunk-LTJAMRGI.js.map +0 -1
  808. package/dist/chunk-LZOV7MX7.js.map +0 -1
  809. package/dist/chunk-NWTGD4AN.js.map +0 -1
  810. package/dist/chunk-ODPLEWB6.js.map +0 -1
  811. package/dist/chunk-OVJ2HIPE.js.map +0 -1
  812. package/dist/chunk-PBSAPHHA.js.map +0 -1
  813. package/dist/chunk-PHK3HARR.js +0 -32
  814. package/dist/chunk-PHK3HARR.js.map +0 -1
  815. package/dist/chunk-PLQE6MJA.js.map +0 -1
  816. package/dist/chunk-QKQYXZVS.js.map +0 -1
  817. package/dist/chunk-QQGPUKMT.js.map +0 -1
  818. package/dist/chunk-RANHFI3P.js +0 -8
  819. package/dist/chunk-RANHFI3P.js.map +0 -1
  820. package/dist/chunk-RAR2BSEM.js.map +0 -1
  821. package/dist/chunk-RULE4VG5.js.map +0 -1
  822. package/dist/chunk-SVOZFLIQ.js +0 -16
  823. package/dist/chunk-SVOZFLIQ.js.map +0 -1
  824. package/dist/chunk-T7Y5KPLN.js.map +0 -1
  825. package/dist/chunk-TXLGHDHS.js.map +0 -1
  826. package/dist/chunk-VDW4VU7B.js.map +0 -1
  827. package/dist/chunk-VSMRDBFT.js +0 -17
  828. package/dist/chunk-VSMRDBFT.js.map +0 -1
  829. package/dist/chunk-X64YLC24.js.map +0 -1
  830. package/dist/chunk-XDSXEKYK.js +0 -118
  831. package/dist/chunk-XDSXEKYK.js.map +0 -1
  832. package/dist/chunk-YF6FMLBT.js.map +0 -1
  833. package/dist/resolution-VH4NGENZ.js +0 -12
  834. /package/dist/{capsule-crypto-CZJSLEFG.js.map → access-citation.js.map} +0 -0
  835. /package/dist/{contradiction-scan-J57T5QV7.js.map → access-memory-search-fanout.js.map} +0 -0
  836. /package/dist/{dreams-ledger-6UODQOX6.js.map → access-recall-concurrency.js.map} +0 -0
  837. /package/dist/{graph-edge-decay-IOGBBAGC.js.map → access-recall-response.js.map} +0 -0
  838. /package/dist/{resolution-VH4NGENZ.js.map → bounded-jsonl-state.js.map} +0 -0
  839. /package/dist/{chunk-A3GOMRJG.js.map → chunk-23L3IXFD.js.map} +0 -0
  840. /package/dist/{chunk-MRHFJV44.js.map → chunk-2DQ2XREU.js.map} +0 -0
  841. /package/dist/{chunk-L2B3EE7B.js.map → chunk-2QMKMVHH.js.map} +0 -0
  842. /package/dist/{chunk-VJVNLNDQ.js.map → chunk-2UFO7X4Q.js.map} +0 -0
  843. /package/dist/{chunk-2MR3MFQB.js.map → chunk-2VEOKUPP.js.map} +0 -0
  844. /package/dist/{chunk-RHOZ5LLO.js.map → chunk-347WD2LE.js.map} +0 -0
  845. /package/dist/{chunk-HDTQVNWD.js.map → chunk-3QAH2S33.js.map} +0 -0
  846. /package/dist/{chunk-LRNMRXJO.js.map → chunk-3Y224NYC.js.map} +0 -0
  847. /package/dist/{chunk-VFSP73LP.js.map → chunk-45GF7Y3V.js.map} +0 -0
  848. /package/dist/{chunk-OEHCMALU.js.map → chunk-5I4M26Q7.js.map} +0 -0
  849. /package/dist/{chunk-2AZXIZEN.js.map → chunk-5Q7EVV4X.js.map} +0 -0
  850. /package/dist/{chunk-PUBTHW5O.js.map → chunk-6DRPPQEJ.js.map} +0 -0
  851. /package/dist/{chunk-FDCTQWLW.js.map → chunk-6O22TZSB.js.map} +0 -0
  852. /package/dist/{chunk-ZQ7UBUZ6.js.map → chunk-6QYST5XN.js.map} +0 -0
  853. /package/dist/{chunk-W4PGTAS2.js.map → chunk-6WAFYNVT.js.map} +0 -0
  854. /package/dist/{chunk-R5VAVVHP.js.map → chunk-72A4L5JJ.js.map} +0 -0
  855. /package/dist/{chunk-3FAMU5TX.js.map → chunk-A6USBZTO.js.map} +0 -0
  856. /package/dist/{chunk-ZHIVCODT.js.map → chunk-A72SWTWW.js.map} +0 -0
  857. /package/dist/{chunk-FC77VUX5.js.map → chunk-A7Q43EUZ.js.map} +0 -0
  858. /package/dist/{chunk-UJBESW6X.js.map → chunk-AE7WMV4V.js.map} +0 -0
  859. /package/dist/{chunk-A5UXZRRM.js.map → chunk-AJ7QCSIS.js.map} +0 -0
  860. /package/dist/{chunk-FNMFJWBY.js.map → chunk-ANEUPF6O.js.map} +0 -0
  861. /package/dist/{chunk-2A3OXAP2.js.map → chunk-B7RWBZXW.js.map} +0 -0
  862. /package/dist/{chunk-74F5STS4.js.map → chunk-BLAKS3CP.js.map} +0 -0
  863. /package/dist/{chunk-M7VGG3ID.js.map → chunk-BV5WMSIJ.js.map} +0 -0
  864. /package/dist/{chunk-2BFLDH5F.js.map → chunk-BXLOS5AJ.js.map} +0 -0
  865. /package/dist/{chunk-UXKMMNJD.js.map → chunk-C23BYTJV.js.map} +0 -0
  866. /package/dist/{chunk-JZHHREBL.js.map → chunk-C3AKM55W.js.map} +0 -0
  867. /package/dist/{chunk-RP7YXA67.js.map → chunk-C5JF6EZ7.js.map} +0 -0
  868. /package/dist/{chunk-EHCONI6E.js.map → chunk-CQMEM5CC.js.map} +0 -0
  869. /package/dist/{chunk-PBNZVPFS.js.map → chunk-CXZQOVIE.js.map} +0 -0
  870. /package/dist/{chunk-7N2RUBAP.js.map → chunk-DDA47TES.js.map} +0 -0
  871. /package/dist/{chunk-64SE4X5G.js.map → chunk-DEBHXHJR.js.map} +0 -0
  872. /package/dist/{chunk-EHK6KZHK.js.map → chunk-DNHVPZOD.js.map} +0 -0
  873. /package/dist/{chunk-437S3G37.js.map → chunk-DQEMWVMT.js.map} +0 -0
  874. /package/dist/{chunk-LZZNTPLR.js.map → chunk-DX3XRGLH.js.map} +0 -0
  875. /package/dist/{chunk-DZKHSDOM.js.map → chunk-ES36HTSC.js.map} +0 -0
  876. /package/dist/{chunk-TN7THW5U.js.map → chunk-ET356KSB.js.map} +0 -0
  877. /package/dist/{chunk-YNDLCWXS.js.map → chunk-EZ25VE3G.js.map} +0 -0
  878. /package/dist/{chunk-DMSDUGDM.js.map → chunk-F7GAIWFA.js.map} +0 -0
  879. /package/dist/{chunk-G6XXLKC5.js.map → chunk-FFPJINJE.js.map} +0 -0
  880. /package/dist/{chunk-G4CN3ZXL.js.map → chunk-FUTF72MJ.js.map} +0 -0
  881. /package/dist/{chunk-HF77M34J.js.map → chunk-GFPZS3F5.js.map} +0 -0
  882. /package/dist/{chunk-G6NKALRN.js.map → chunk-H4WG3UQZ.js.map} +0 -0
  883. /package/dist/{chunk-UDQUSU27.js.map → chunk-HNZKVLAN.js.map} +0 -0
  884. /package/dist/{chunk-5EZXHU36.js.map → chunk-HYQJQGD3.js.map} +0 -0
  885. /package/dist/{chunk-TRWPCR6P.js.map → chunk-JECBQBEX.js.map} +0 -0
  886. /package/dist/{chunk-E6CBU7XP.js.map → chunk-JYIFGGEM.js.map} +0 -0
  887. /package/dist/{chunk-VA4WSW54.js.map → chunk-JYIJNNN3.js.map} +0 -0
  888. /package/dist/{chunk-L5HJQC36.js.map → chunk-K2TDK7GG.js.map} +0 -0
  889. /package/dist/{chunk-KDXVOFYY.js.map → chunk-KAVBJSBQ.js.map} +0 -0
  890. /package/dist/{chunk-4OKLXWDZ.js.map → chunk-KNB7IBBU.js.map} +0 -0
  891. /package/dist/{chunk-QLULYKWZ.js.map → chunk-KSXJOC4F.js.map} +0 -0
  892. /package/dist/{chunk-2S6QHZGJ.js.map → chunk-L2DPF4DF.js.map} +0 -0
  893. /package/dist/{chunk-JI5AVXYO.js.map → chunk-LEPOP46W.js.map} +0 -0
  894. /package/dist/{chunk-O7BBFJLP.js.map → chunk-LTAVSOZW.js.map} +0 -0
  895. /package/dist/{chunk-2IZAGAJR.js.map → chunk-LULR4IUW.js.map} +0 -0
  896. /package/dist/{chunk-WMWVO45V.js.map → chunk-MC6XO7T4.js.map} +0 -0
  897. /package/dist/{chunk-D6RIFG4O.js.map → chunk-MNB5RMAY.js.map} +0 -0
  898. /package/dist/{chunk-Q5WG43OP.js.map → chunk-MYFQ3ED4.js.map} +0 -0
  899. /package/dist/{chunk-V3UE5I5F.js.map → chunk-MYVPLJOO.js.map} +0 -0
  900. /package/dist/{chunk-MTWKDOVO.js.map → chunk-NLE6TSLG.js.map} +0 -0
  901. /package/dist/{chunk-DBRYEIGY.js.map → chunk-OJP3N7UK.js.map} +0 -0
  902. /package/dist/{chunk-SMX5267P.js.map → chunk-OZKOPQCM.js.map} +0 -0
  903. /package/dist/{chunk-JCK7V6SN.js.map → chunk-P65YJEEL.js.map} +0 -0
  904. /package/dist/{chunk-MTR7BZQN.js.map → chunk-PBGWYM3H.js.map} +0 -0
  905. /package/dist/{chunk-AXTXN4T6.js.map → chunk-PWFCHOB3.js.map} +0 -0
  906. /package/dist/{chunk-FDPZVY6D.js.map → chunk-QFN4U7AG.js.map} +0 -0
  907. /package/dist/{chunk-K2ZLHESQ.js.map → chunk-QIEUU4UK.js.map} +0 -0
  908. /package/dist/{chunk-3D6AFGQR.js.map → chunk-QVT3E4CE.js.map} +0 -0
  909. /package/dist/{chunk-SFQ6QNL7.js.map → chunk-R6YJI3HE.js.map} +0 -0
  910. /package/dist/{chunk-5CJVLG3H.js.map → chunk-RFDD3B7W.js.map} +0 -0
  911. /package/dist/{chunk-JBPKEARU.js.map → chunk-RKNJBZ55.js.map} +0 -0
  912. /package/dist/{chunk-FNZQGN76.js.map → chunk-S2BBISHU.js.map} +0 -0
  913. /package/dist/{chunk-IALLX7EE.js.map → chunk-S2FSBU4H.js.map} +0 -0
  914. /package/dist/{chunk-7K5Q6COX.js.map → chunk-TVVEYCNW.js.map} +0 -0
  915. /package/dist/{chunk-DPAENM7O.js.map → chunk-U3ZAVRP3.js.map} +0 -0
  916. /package/dist/{chunk-4KJLYTLS.js.map → chunk-V57NLO5P.js.map} +0 -0
  917. /package/dist/{chunk-FLVL4L3L.js.map → chunk-VDX2J7OX.js.map} +0 -0
  918. /package/dist/{chunk-AJLLIIML.js.map → chunk-W4FBGYGK.js.map} +0 -0
  919. /package/dist/{chunk-6SXVCD7W.js.map → chunk-W7IGLX4G.js.map} +0 -0
  920. /package/dist/{chunk-KAWTOYAW.js.map → chunk-WLZYGLJ4.js.map} +0 -0
  921. /package/dist/{chunk-RO4LQGT3.js.map → chunk-WON4APQY.js.map} +0 -0
  922. /package/dist/{chunk-PQVK2S3J.js.map → chunk-WZFAPHIK.js.map} +0 -0
  923. /package/dist/{chunk-KQPJLK3X.js.map → chunk-XL24QQ63.js.map} +0 -0
  924. /package/dist/{chunk-RVZRYUQH.js.map → chunk-YROFNEG5.js.map} +0 -0
  925. /package/dist/{chunk-VRAD2FGO.js.map → chunk-Z54EM5YZ.js.map} +0 -0
  926. /package/dist/{first-start-migration-TI67YMLG.js.map → first-start-migration-CSRHCJIQ.js.map} +0 -0
  927. /package/dist/{forget-CQCLB5LB.js.map → forget-HRPLVB3W.js.map} +0 -0
  928. /package/dist/{purge-NDWV6WYD.js.map → purge-IRF47ZTX.js.map} +0 -0
  929. /package/dist/{tier-stats-KV7IWCJR.js.map → tier-stats-QEJSPFV2.js.map} +0 -0
@@ -0,0 +1,316 @@
1
+ import assert from "node:assert/strict";
2
+ import { randomUUID } from "node:crypto";
3
+ import { mkdir, mkdtemp, readdir, readFile, rm, symlink, writeFile } from "node:fs/promises";
4
+ import os from "node:os";
5
+ import path from "node:path";
6
+ import test from "node:test";
7
+ import {
8
+ drainPendingImpressionsForOfflineSync,
9
+ drainPendingLifecycleForOfflineSync,
10
+ getOfflineSyncStorage,
11
+ } from "./offline-sync-impression-drain.js";
12
+ import { isEncryptedFile } from "./secure-store/secure-fs.js";
13
+ import { StorageManager } from "./storage.js";
14
+
15
+ test("retries deferred drains and succeeds when the lock is released", async () => {
16
+ let calls = 0;
17
+ await drainPendingImpressionsForOfflineSync(async () => {
18
+ calls += 1;
19
+ return { pendingDeferred: calls < 2 };
20
+ });
21
+ assert.equal(calls, 2);
22
+ });
23
+
24
+ test("retries a transient drain error before succeeding", async () => {
25
+ let calls = 0;
26
+ await drainPendingImpressionsForOfflineSync(async () => {
27
+ calls += 1;
28
+ if (calls === 1) throw new Error("temporary lock failure");
29
+ return { pendingDeferred: false };
30
+ });
31
+ assert.equal(calls, 2);
32
+ });
33
+
34
+ test("aborts after repeated deferrals instead of producing an incomplete snapshot", async () => {
35
+ let calls = 0;
36
+ await assert.rejects(
37
+ drainPendingImpressionsForOfflineSync(async () => {
38
+ calls += 1;
39
+ return { pendingDeferred: true };
40
+ }),
41
+ /could not fold pending recall impressions after 3 attempts/,
42
+ );
43
+ assert.equal(calls, 3);
44
+ });
45
+
46
+ const LIFECYCLE_LEDGER_REL = "state/memory-lifecycle-ledger.jsonl";
47
+ const LIFECYCLE_PENDING_REL = `${LIFECYCLE_LEDGER_REL}.pending.d`;
48
+
49
+ // Seed one durable pending lifecycle spill exactly as appendLifecycleEventsSerialized
50
+ // does when the ledger lock is held (#2033): a `<uuid>.jsonl` file inside the
51
+ // offline-sync-EXCLUDED pending dir under `stateRel`. The nonce proves this row
52
+ // was folded rather than dropped by the sync exclude glob.
53
+ async function seedPendingLifecycle(root: string, stateRel: string): Promise<string> {
54
+ const nonce = randomUUID();
55
+ const pendingDir = path.join(root, stateRel, "memory-lifecycle-ledger.jsonl.pending.d");
56
+ await mkdir(pendingDir, { recursive: true });
57
+ const line = `${JSON.stringify({ type: "promotion", memoryId: "mem-1", timestamp: "2026-01-01T00:00:00.000Z", nonce })}\n`;
58
+ await writeFile(path.join(pendingDir, `${randomUUID()}.jsonl`), line, "utf-8");
59
+ return nonce;
60
+ }
61
+
62
+ test("drainPendingLifecycleForOfflineSync folds root and per-namespace pending spills (#2033)", async () => {
63
+ const root = await mkdtemp(path.join(os.tmpdir(), "remnic-lifecycle-drain-"));
64
+ try {
65
+ const rootNonce = await seedPendingLifecycle(root, "state");
66
+ const nsNonce = await seedPendingLifecycle(root, "namespaces/team/state");
67
+
68
+ await drainPendingLifecycleForOfflineSync(root);
69
+
70
+ const rootPending = await readdir(path.join(root, LIFECYCLE_PENDING_REL)).catch(() => [] as string[]);
71
+ assert.deepEqual(rootPending, [], "root pending spills must be folded and finalized");
72
+ const rootActive = await readFile(path.join(root, LIFECYCLE_LEDGER_REL), "utf-8");
73
+ assert.ok(rootActive.includes(rootNonce), "root lifecycle row must land in the synced active ledger");
74
+
75
+ const nsPending = await readdir(
76
+ path.join(root, "namespaces/team", LIFECYCLE_PENDING_REL),
77
+ ).catch(() => [] as string[]);
78
+ assert.deepEqual(nsPending, [], "per-namespace pending spills must be folded and finalized");
79
+ const nsActive = await readFile(
80
+ path.join(root, "namespaces/team", LIFECYCLE_LEDGER_REL),
81
+ "utf-8",
82
+ );
83
+ assert.ok(nsActive.includes(nsNonce), "per-namespace lifecycle row must land in its active ledger");
84
+ } finally {
85
+ await rm(root, { recursive: true, force: true });
86
+ }
87
+ });
88
+
89
+ test("drains encrypted lifecycle spills through secure storage (#2033)", async () => {
90
+ const root = await mkdtemp(path.join(os.tmpdir(), "remnic-lifecycle-drain-secure-"));
91
+ const key = Buffer.alloc(32, 17);
92
+ const storage = new StorageManager(root);
93
+ storage.setSecureStoreRequired(true);
94
+ storage.setSecureStoreKey(key);
95
+ try {
96
+ const nonce = randomUUID();
97
+ const pendingDir = path.join(root, LIFECYCLE_PENDING_REL);
98
+ const pendingPath = path.join(pendingDir, `${randomUUID()}.jsonl`);
99
+ await mkdir(pendingDir, { recursive: true });
100
+ await storage.writeMemoryLifecycleLedgerContent(
101
+ `${JSON.stringify({
102
+ type: "promotion",
103
+ memoryId: "mem-secure",
104
+ timestamp: "2026-01-01T00:00:00.000Z",
105
+ nonce,
106
+ })}\n`,
107
+ pendingPath,
108
+ );
109
+
110
+ await drainPendingLifecycleForOfflineSync(
111
+ root,
112
+ (ledgerPath) => storage.drainPendingMemoryLifecycleEventsForSyncAt(ledgerPath),
113
+ );
114
+
115
+ assert.deepEqual(await readdir(pendingDir), []);
116
+ assert.ok(
117
+ isEncryptedFile(await readFile(path.join(root, LIFECYCLE_LEDGER_REL))),
118
+ "the active ledger must remain encrypted",
119
+ );
120
+ const activePlaintext = await storage.readMemoryLifecycleLedgerRawBufferForCompaction();
121
+ assert.ok(activePlaintext.toString("utf-8").includes(nonce));
122
+ } finally {
123
+ await rm(root, { recursive: true, force: true });
124
+ }
125
+ });
126
+
127
+ test("drainPendingLifecycleForOfflineSync aborts when pending rows cannot be folded (#2033)", async () => {
128
+ const root = await mkdtemp(path.join(os.tmpdir(), "remnic-lifecycle-drain-abort-"));
129
+ try {
130
+ await seedPendingLifecycle(root, "state");
131
+ // The active ledger path is a DIRECTORY, so the fold's append fails on every
132
+ // attempt: the durable spill can never be committed, so the drain aborts
133
+ // rather than let a caller build a snapshot that silently omits it.
134
+ await mkdir(path.join(root, LIFECYCLE_LEDGER_REL), { recursive: true });
135
+
136
+ await assert.rejects(
137
+ drainPendingLifecycleForOfflineSync(root),
138
+ (err: unknown) => {
139
+ assert.ok(err instanceof Error);
140
+ assert.match(
141
+ err.message,
142
+ /lifecycle drain could not fold pending memory-lifecycle events after 3 attempts.*aborting snapshot/s,
143
+ );
144
+ assert.ok(
145
+ !err.message.includes(root),
146
+ "abort error must not leak the ledger's absolute path (#2033)",
147
+ );
148
+ return true;
149
+ },
150
+ );
151
+ } finally {
152
+ await rm(root, { recursive: true, force: true });
153
+ }
154
+ });
155
+
156
+ test("aborted impression drain redacts the underlying error path (#2033)", async () => {
157
+ // A persona path standing in for a real operator's memory dir. displayErrorDetail
158
+ // must reduce the thrown fs error to its class + errno code so the absolute path
159
+ // never reaches CLI stderr / the offline snapshot failure.
160
+ const secretPath = "/home/user/.remnic/state/recall_impressions.jsonl";
161
+ await assert.rejects(
162
+ drainPendingImpressionsForOfflineSync(async () => {
163
+ const err = new Error(`EACCES: permission denied, open '${secretPath}'`);
164
+ (err as NodeJS.ErrnoException).code = "EACCES";
165
+ throw err;
166
+ }),
167
+ (err: unknown) => {
168
+ assert.ok(err instanceof Error);
169
+ assert.ok(!err.message.includes(secretPath), "raw fs path must not leak into the abort error");
170
+ assert.match(err.message, /could not fold pending recall impressions after 3 attempts/);
171
+ assert.match(err.message, /EACCES/, "the path-free error class + code still surfaces");
172
+ return true;
173
+ },
174
+ );
175
+ });
176
+
177
+ test("drainPendingLifecycleForOfflineSync skips a symlinked namespace child (#2033 containment)", async () => {
178
+ const root = await mkdtemp(path.join(os.tmpdir(), "remnic-lifecycle-drain-symlink-child-"));
179
+ const outside = await mkdtemp(path.join(os.tmpdir(), "remnic-lifecycle-drain-outside-"));
180
+ try {
181
+ const rootNonce = await seedPendingLifecycle(root, "state");
182
+ const teamNonce = await seedPendingLifecycle(root, "namespaces/team/state");
183
+ // A poisoned namespace child symlinked outside the memory root, carrying its
184
+ // own pending spill. The drain must NOT fold through it (no ledger appended
185
+ // outside memoryDir) yet still fold the root and the legit namespace.
186
+ await seedPendingLifecycle(outside, "state");
187
+ await mkdir(path.join(root, "namespaces"), { recursive: true });
188
+ await symlink(outside, path.join(root, "namespaces", "evil"));
189
+
190
+ await drainPendingLifecycleForOfflineSync(root);
191
+
192
+ assert.deepEqual(await readdir(path.join(root, LIFECYCLE_PENDING_REL)).catch(() => [] as string[]), []);
193
+ assert.ok((await readFile(path.join(root, LIFECYCLE_LEDGER_REL), "utf-8")).includes(rootNonce));
194
+ assert.ok(
195
+ (await readFile(path.join(root, "namespaces/team", LIFECYCLE_LEDGER_REL), "utf-8")).includes(teamNonce),
196
+ );
197
+ // The escaping child's spill is left untouched and no ledger was written
198
+ // through the link.
199
+ assert.equal(
200
+ (await readdir(path.join(outside, LIFECYCLE_PENDING_REL))).length,
201
+ 1,
202
+ "escaping namespace spill must be left untouched",
203
+ );
204
+ await assert.rejects(
205
+ () => readFile(path.join(outside, LIFECYCLE_LEDGER_REL), "utf-8"),
206
+ /ENOENT/,
207
+ );
208
+ } finally {
209
+ await rm(root, { recursive: true, force: true });
210
+ await rm(outside, { recursive: true, force: true });
211
+ }
212
+ });
213
+
214
+ test("drainPendingLifecycleForOfflineSync refuses a symlinked namespaces base (#2033 containment)", async () => {
215
+ const root = await mkdtemp(path.join(os.tmpdir(), "remnic-lifecycle-drain-symlink-base-"));
216
+ const outside = await mkdtemp(path.join(os.tmpdir(), "remnic-lifecycle-drain-base-outside-"));
217
+ try {
218
+ const rootNonce = await seedPendingLifecycle(root, "state");
219
+ // A legit-looking namespace living under the symlinked base target.
220
+ await seedPendingLifecycle(outside, "team/state");
221
+ await symlink(outside, path.join(root, "namespaces"));
222
+
223
+ await drainPendingLifecycleForOfflineSync(root);
224
+
225
+ // The root ledger is still folded through the real state dir.
226
+ assert.ok((await readFile(path.join(root, LIFECYCLE_LEDGER_REL), "utf-8")).includes(rootNonce));
227
+ // The symlinked base is refused wholesale: nothing under it is drained.
228
+ assert.equal(
229
+ (await readdir(path.join(outside, "team", "state", "memory-lifecycle-ledger.jsonl.pending.d"))).length,
230
+ 1,
231
+ "namespaces base symlink must be refused, leaving its spills untouched",
232
+ );
233
+ await assert.rejects(
234
+ () => readFile(path.join(outside, "team", LIFECYCLE_LEDGER_REL), "utf-8"),
235
+ /ENOENT/,
236
+ );
237
+ } finally {
238
+ await rm(root, { recursive: true, force: true });
239
+ await rm(outside, { recursive: true, force: true });
240
+ }
241
+ });
242
+
243
+ type FakeLifecycleStorage = {
244
+ dir: string;
245
+ drainPendingMemoryLifecycleEventsForSync(): Promise<{ folded: boolean; pendingDeferred: boolean }>;
246
+ };
247
+
248
+ function fakeOfflineOrchestrator(memoryRoot: string, namespaceDirs: Record<string, string>) {
249
+ const lifecycleDrains: string[] = [];
250
+ let impressionDrains = 0;
251
+ const storages: Record<string, FakeLifecycleStorage> = {};
252
+ for (const [name, dir] of Object.entries(namespaceDirs)) {
253
+ storages[name] = {
254
+ dir,
255
+ drainPendingMemoryLifecycleEventsForSync: async () => {
256
+ lifecycleDrains.push(name);
257
+ return { folded: false, pendingDeferred: false };
258
+ },
259
+ };
260
+ }
261
+ const orchestrator = {
262
+ config: { memoryDir: memoryRoot },
263
+ drainPendingRecallImpressions: async () => {
264
+ impressionDrains += 1;
265
+ return { pendingDeferred: false };
266
+ },
267
+ getStorage: async (ns: string) => {
268
+ const storage = storages[ns];
269
+ if (!storage) throw new Error(`no fake storage for namespace ${ns}`);
270
+ return storage;
271
+ },
272
+ listOfflineSyncNamespaces: async () => Object.keys(namespaceDirs).filter((n) => n !== "root"),
273
+ };
274
+ return { orchestrator, lifecycleDrains, impressions: () => impressionDrains };
275
+ }
276
+
277
+ test("getOfflineSyncStorage drains every namespace ledger for a root snapshot (#2033)", async () => {
278
+ const memoryRoot = path.join(os.tmpdir(), "remnic-root-drain-fanout");
279
+ const { orchestrator, lifecycleDrains, impressions } = fakeOfflineOrchestrator(memoryRoot, {
280
+ root: memoryRoot,
281
+ team: path.join(memoryRoot, "namespaces", "team"),
282
+ ops: path.join(memoryRoot, "namespaces", "ops"),
283
+ });
284
+
285
+ await getOfflineSyncStorage(orchestrator, "root");
286
+
287
+ assert.deepEqual(lifecycleDrains, ["root", "team", "ops"], "root snapshot folds root + every namespace ledger");
288
+ assert.equal(impressions(), 1, "global impressions are folded for a root snapshot");
289
+ });
290
+
291
+ test("getOfflineSyncStorage folds only the namespace's own ledger for a namespace snapshot (#2033)", async () => {
292
+ const memoryRoot = path.join(os.tmpdir(), "remnic-ns-drain-scope");
293
+ const { orchestrator, lifecycleDrains, impressions } = fakeOfflineOrchestrator(memoryRoot, {
294
+ root: memoryRoot,
295
+ team: path.join(memoryRoot, "namespaces", "team"),
296
+ });
297
+
298
+ await getOfflineSyncStorage(orchestrator, "team");
299
+
300
+ assert.deepEqual(lifecycleDrains, ["team"], "namespace snapshot folds only its own ledger");
301
+ assert.equal(impressions(), 0, "global impressions are left pending for the root sync");
302
+ });
303
+
304
+ test("getOfflineSyncStorage never double-folds the root ledger when it is listed as a namespace (#2033)", async () => {
305
+ const memoryRoot = path.join(os.tmpdir(), "remnic-root-drain-dedup");
306
+ const { orchestrator, lifecycleDrains } = fakeOfflineOrchestrator(memoryRoot, {
307
+ root: memoryRoot,
308
+ // A listing that also surfaces the default namespace pointing back at root.
309
+ default: memoryRoot,
310
+ team: path.join(memoryRoot, "namespaces", "team"),
311
+ });
312
+
313
+ await getOfflineSyncStorage(orchestrator, "root");
314
+
315
+ assert.deepEqual(lifecycleDrains, ["root", "team"], "root ledger is folded exactly once");
316
+ });
@@ -0,0 +1,260 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { lstat, realpath } from "node:fs/promises";
4
+ import {
5
+ drainPendingLifecycleForSyncOrThrow,
6
+ drainPendingLifecycleLedgerForSync,
7
+ type LifecyclePendingIo,
8
+ } from "./storage/memory-lifecycle-ledger-access.js";
9
+ import { writeFileAtomically } from "./maintenance/atomic-file.js";
10
+ import { log } from "./logger.js";
11
+ import { isErrnoCode } from "./utils/errno.js";
12
+ import { assertPathInsideRoot, pathIsInside } from "./utils/path-containment.js";
13
+ import { displayErrorDetail } from "./runtime/better-sqlite.js";
14
+ import { getConfiguredNamespaces } from "./scopes/scope-plan.js";
15
+ import type { PluginConfig } from "./types.js";
16
+
17
+ type PendingImpressionDrain = () => Promise<{ pendingDeferred: boolean }>;
18
+
19
+ type PendingLifecycleDrain = {
20
+ drainPendingMemoryLifecycleEventsForSync(): Promise<{ folded: boolean; pendingDeferred: boolean }>;
21
+ };
22
+
23
+ type LifecycleDrainAtPath = (
24
+ ledgerPath: string,
25
+ ) => Promise<{ folded: boolean; pendingDeferred: boolean }>;
26
+
27
+ type PendingImpressionHost = {
28
+ drainPendingRecallImpressions(): Promise<{ pendingDeferred: boolean }>;
29
+ };
30
+ /**
31
+ * Fold pending recall-impression spills before building an offline-sync snapshot.
32
+ * A deferred or failed drain must abort the snapshot rather than silently omit
33
+ * durable rows from the sync payload.
34
+ */
35
+ export async function drainPendingImpressionsForOfflineSync(
36
+ host: PendingImpressionDrain,
37
+ ): Promise<void> {
38
+ const maxAttempts = 3;
39
+ let lastError: unknown;
40
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
41
+ try {
42
+ const result = await host();
43
+ if (!result.pendingDeferred) return;
44
+ lastError = undefined;
45
+ } catch (error) {
46
+ lastError = error;
47
+ }
48
+ }
49
+ const detail = lastError
50
+ ? `: ${displayErrorDetail(lastError) || "unknown error"}`
51
+ : " (rotation lock held by a peer)";
52
+ throw new Error(
53
+ `offline-sync impression drain could not fold pending recall impressions after ${maxAttempts} attempts${detail}; aborting snapshot so the pending rows are not silently excluded (#2033)`,
54
+ );
55
+ }
56
+
57
+
58
+ export async function getOfflineSyncStorage<T extends PendingLifecycleDrain & { dir: string }>(
59
+ orchestrator: PendingImpressionHost & {
60
+ config: { memoryDir: string };
61
+ getStorage(namespace: string): Promise<T>;
62
+ listOfflineSyncNamespaces?(): Promise<string[]>;
63
+ },
64
+ namespace: string,
65
+ ): Promise<T> {
66
+ const storage = await orchestrator.getStorage(namespace);
67
+ const memoryRoot = path.resolve(orchestrator.config.memoryDir);
68
+ // Recall impressions are global: the orchestrator's single LastRecallStore
69
+ // roots at config.memoryDir, so the active recall_impressions.jsonl lives at
70
+ // <memoryDir>/state/. Fold the global pending queue ONLY when THIS snapshot's
71
+ // root actually contains that active file - a root snapshot. A namespace
72
+ // snapshot (storage.dir under namespaces/<token>/) cannot carry it, so
73
+ // draining there would empty the durable pending queue into a file this
74
+ // snapshot omits and strand the row until a root sync; leave it pending for
75
+ // the root sync instead (#2033).
76
+ const impressionsFile = path.join(memoryRoot, "state", "recall_impressions.jsonl");
77
+ if (pathIsInside(path.resolve(storage.dir), impressionsFile)) {
78
+ await drainPendingImpressionsForOfflineSync(() => orchestrator.drainPendingRecallImpressions());
79
+ }
80
+ await drainPendingLifecycleForSyncOrThrow(() => storage.drainPendingMemoryLifecycleEventsForSync());
81
+ // Root snapshot: buildOfflineSyncSnapshot walks `namespaces/<ns>/state/` for
82
+ // every namespace under the memory root and INCLUDES each namespace's active
83
+ // lifecycle ledger, but the per-namespace pending spill dirs are offline-sync
84
+ // EXCLUDED. Draining only the root ledger above would let a root snapshot omit
85
+ // append-only rows still sitting in a namespace's spill queue, so fold every
86
+ // namespace ledger too - each through its OWN namespace storage so secure-store
87
+ // AAD stays namespace-scoped (#2033, matching the CLI all-ledger drain). A
88
+ // namespace snapshot folds only its own ledger, already done above.
89
+ if (path.resolve(storage.dir) === memoryRoot && orchestrator.listOfflineSyncNamespaces) {
90
+ const drained = new Set<string>([memoryRoot]);
91
+ for (const ns of await orchestrator.listOfflineSyncNamespaces()) {
92
+ const nsStorage = await orchestrator.getStorage(ns);
93
+ const nsDir = path.resolve(nsStorage.dir);
94
+ if (drained.has(nsDir)) continue;
95
+ drained.add(nsDir);
96
+ await drainPendingLifecycleForSyncOrThrow(() => nsStorage.drainPendingMemoryLifecycleEventsForSync());
97
+ }
98
+ }
99
+ return storage;
100
+ }
101
+
102
+ type OfflineSyncNamespaceHost = {
103
+ config: PluginConfig;
104
+ namespaceCatalog: { listNamespaces(): Promise<Array<{ namespace: string }>> };
105
+ };
106
+
107
+ /**
108
+ * Every namespace whose lifecycle ledger a ROOT offline snapshot enumerates.
109
+ * Configured namespaces plus catalog-discovered ones; the catalog is queried
110
+ * best-effort so a catalog read failure still drains the configured set (#2033).
111
+ */
112
+ export async function listOfflineSyncNamespaces(host: OfflineSyncNamespaceHost): Promise<string[]> {
113
+ const names = new Set<string>(getConfiguredNamespaces(host.config));
114
+ try {
115
+ for (const ledgerPath of await offlineSyncLifecycleLedgerPaths(host.config.memoryDir)) {
116
+ const namespaceDir = path.dirname(path.dirname(ledgerPath));
117
+ if (path.basename(path.dirname(namespaceDir)) === "namespaces") {
118
+ names.add(path.basename(namespaceDir));
119
+ }
120
+ }
121
+ } catch {
122
+ // best-effort: a filesystem scan failure must not block configured/catalog namespaces
123
+ }
124
+ try {
125
+ for (const record of await host.namespaceCatalog.listNamespaces()) {
126
+ names.add(record.namespace);
127
+ }
128
+ } catch {
129
+ // best-effort: fall back to the configured and filesystem namespace sets
130
+ }
131
+ return [...names];
132
+ }
133
+
134
+ /**
135
+ * Resolve the offline-sync storage for a snapshot, folding pending spills first.
136
+ * For a root snapshot this also folds every namespace lifecycle ledger the
137
+ * snapshot will enumerate, so append-only rows in a namespace spill queue are
138
+ * never omitted (#2033).
139
+ */
140
+ export function offlineSyncStorageForSnapshot<T extends PendingLifecycleDrain & { dir: string }>(
141
+ host: PendingImpressionHost &
142
+ OfflineSyncNamespaceHost & {
143
+ getStorage(namespace: string): Promise<T>;
144
+ },
145
+ namespace: string,
146
+ ): Promise<T> {
147
+ return getOfflineSyncStorage(
148
+ {
149
+ config: { memoryDir: host.config.memoryDir },
150
+ drainPendingRecallImpressions: () => host.drainPendingRecallImpressions(),
151
+ getStorage: (ns: string) => host.getStorage(ns),
152
+ listOfflineSyncNamespaces: () => listOfflineSyncNamespaces(host),
153
+ },
154
+ namespace,
155
+ );
156
+ }
157
+
158
+ const LIFECYCLE_LEDGER_FILE = "memory-lifecycle-ledger.jsonl";
159
+
160
+ /**
161
+ * Plaintext filesystem IO for a standalone (CLI) offline-sync lifecycle drain.
162
+ * A standalone offline cache is plaintext - exactly like its LastRecallStore
163
+ * impression drain - so spills read/append as UTF-8. `writeSecure` keeps the
164
+ * atomic temp+rename the pending contract requires (#2033); a pure drain never
165
+ * spills a new event, but the interface demands an atomic writer.
166
+ */
167
+ function plaintextLifecyclePendingIo(): LifecyclePendingIo {
168
+ return {
169
+ writeSecure: async (filePath, payload) => {
170
+ await writeFileAtomically(filePath, payload);
171
+ },
172
+ readSecure: (filePath) => fs.promises.readFile(filePath, "utf8"),
173
+ };
174
+ }
175
+
176
+ /**
177
+ * Lifecycle ledger paths under a standalone memory dir: the root `state/` ledger
178
+ * plus every per-namespace `namespaces/<ns>/state/` ledger (#2033). Offline sync
179
+ * pushes the whole memory dir, so every namespace's ledger can carry pending
180
+ * spills that must be folded first.
181
+ */
182
+ async function offlineSyncLifecycleLedgerPaths(memoryDir: string): Promise<string[]> {
183
+ const paths = [path.join(memoryDir, "state", LIFECYCLE_LEDGER_FILE)];
184
+ const namespacesBase = path.join(memoryDir, "namespaces");
185
+ // Symlink/traversal containment (#2033): a symlinked <memoryDir>/namespaces
186
+ // (or a symlinked child) must not redirect the pre-sync drain - and the
187
+ // ledger appends/mkdirs it drives - outside memoryDir. Resolve the memory
188
+ // root and the scan base through realpath, reject a symlinked/escaping/
189
+ // non-directory base, and skip any symlinked/escaping child, mirroring the
190
+ // lifecycle-compaction scanner (orchestration/maintenance.ts) and the
191
+ // memory-store walkers (utils/path-containment). A rejected base is
192
+ // non-fatal: drain the root ledger only, never through the poisoned link.
193
+ let memoryDirReal: string;
194
+ try {
195
+ memoryDirReal = await realpath(memoryDir);
196
+ const baseStat = await lstat(namespacesBase);
197
+ if (baseStat.isSymbolicLink() || !baseStat.isDirectory()) {
198
+ throw new Error("namespaces base is a symlink or not a directory");
199
+ }
200
+ assertPathInsideRoot(memoryDirReal, await realpath(namespacesBase), namespacesBase);
201
+ } catch (err) {
202
+ if (!isErrnoCode(err, "ENOENT")) {
203
+ log.debug(`offline-sync lifecycle drain: namespaces base rejected (non-fatal): ${err}`);
204
+ }
205
+ return paths;
206
+ }
207
+ let entries: fs.Dirent[];
208
+ try {
209
+ entries = fs.readdirSync(namespacesBase, { withFileTypes: true });
210
+ } catch (err) {
211
+ if (!isErrnoCode(err, "ENOENT")) {
212
+ log.debug(`offline-sync lifecycle drain: namespaces dir scan failed (non-fatal): ${err}`);
213
+ }
214
+ return paths;
215
+ }
216
+ for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
217
+ if (!entry.isDirectory() || entry.isSymbolicLink()) continue;
218
+ const childPath = path.join(namespacesBase, entry.name);
219
+ try {
220
+ assertPathInsideRoot(memoryDirReal, await realpath(childPath), childPath);
221
+ } catch (err) {
222
+ log.debug(`offline-sync lifecycle drain: skipping out-of-root namespace dir ${childPath}: ${err}`);
223
+ continue;
224
+ }
225
+ paths.push(path.join(childPath, "state", LIFECYCLE_LEDGER_FILE));
226
+ }
227
+ return paths;
228
+ }
229
+
230
+ /**
231
+ * Fold pending memory-lifecycle spills into each active ledger under `memoryDir`
232
+ * before a standalone (CLI) offline-sync snapshot (#2033). Mirrors the
233
+ * access-service snapshot entrypoints, which drain lifecycle pending first: the
234
+ * default sync exclude globs keep `memory-lifecycle-ledger.jsonl.pending.d` out
235
+ * of the push, so an append-only row (promotion/import/explicit capture) that
236
+ * spilled while the ledger lock was held would be silently dropped if the local
237
+ * node were discarded before maintenance folds it. A deferred drain (lock held
238
+ * by a peer) or a repeatedly failing fold ABORTS via
239
+ * {@link drainPendingLifecycleForSyncOrThrow} rather than building/pushing a
240
+ * snapshot that omits durable rows. Fast no-op per ledger with no pending dir.
241
+ */
242
+ export async function drainPendingLifecycleForOfflineSync(
243
+ memoryDir: string,
244
+ drainAtPath: LifecycleDrainAtPath = (ledgerPath) => {
245
+ const io = plaintextLifecyclePendingIo();
246
+ const stateDir = path.dirname(ledgerPath);
247
+ return drainPendingLifecycleLedgerForSync(
248
+ ledgerPath,
249
+ io,
250
+ (payload) => fs.promises.appendFile(ledgerPath, payload),
251
+ async () => {
252
+ await fs.promises.mkdir(stateDir, { recursive: true });
253
+ },
254
+ );
255
+ },
256
+ ): Promise<void> {
257
+ for (const ledgerPath of await offlineSyncLifecycleLedgerPaths(memoryDir)) {
258
+ await drainPendingLifecycleForSyncOrThrow(() => drainAtPath(ledgerPath));
259
+ }
260
+ }
@@ -297,6 +297,16 @@ test("offline sync includes durable runtime state and excludes only transient sy
297
297
  await write(root, "state/memory-projection.sqlite-shm", "projection-shm");
298
298
  await write(root, "state/memory-projection.sqlite-wal", "projection-wal");
299
299
  await write(root, "state/recall_impressions.jsonl", "impressions");
300
+ // Rotated archive (issue #1910) must be excluded from the push snapshot
301
+ // while the active file stays remote-authoritative.
302
+ await write(root, "state/recall_impressions.jsonl.1", "rotated-impressions");
303
+ // Node-local lifecycle coordination files must never cross offline sync.
304
+ await write(root, "state/memory-lifecycle-ledger.jsonl.lock", "lock");
305
+ await write(
306
+ root,
307
+ "state/memory-lifecycle-ledger.jsonl.pending.d/event-1.json",
308
+ "pending",
309
+ );
300
310
  await write(root, "namespaces/generalist-project-origin-6ebeaa54/state/last_intent.json", "intent");
301
311
  await write(root, "namespaces/generalist-project-origin-6ebeaa54/state/entity-mention-index.json", "entities");
302
312
  await write(root, "namespaces/generalist-project-origin-6ebeaa54/state/.memory-status-version.log", "version");
@@ -341,6 +351,22 @@ test("offline sync includes durable runtime state and excludes only transient sy
341
351
  }),
342
352
  /offline sync file content path is excluded: state\/buffer\.json\.tmp-123-456/,
343
353
  );
354
+ await assert.rejects(
355
+ () =>
356
+ readOfflineSyncFileContentChunk({
357
+ root,
358
+ path: "state/memory-lifecycle-ledger.jsonl.lock",
359
+ }),
360
+ /offline sync file content path is excluded: state\/memory-lifecycle-ledger\.jsonl\.lock/,
361
+ );
362
+ await assert.rejects(
363
+ () =>
364
+ readOfflineSyncFileContentChunk({
365
+ root,
366
+ path: "state/memory-lifecycle-ledger.jsonl.pending.d/event-1.json",
367
+ }),
368
+ /offline sync file content path is excluded: state\/memory-lifecycle-ledger\.jsonl\.pending\.d\/event-1\.json/,
369
+ );
344
370
  const namespaced = await buildOfflineSyncSnapshotForPaths({
345
371
  root,
346
372
  sourceId: "remote",
@@ -363,11 +389,12 @@ test("offline sync includes durable runtime state and excludes only transient sy
363
389
  }],
364
390
  });
365
391
 
366
- // 18 = the 13 durable local-only files plus the 5 node-local excluded
367
- // artifacts, which the corrected apply-side view (#1793 review) now
368
- // SEES and deliberately leaves untouched (counted as skipped) instead
369
- // of hiding from enumeration entirely.
370
- assert.equal(pull.skipped, 18);
392
+ // 21 = the 13 durable local-only files plus the 8 node-local excluded
393
+ // artifacts (the 6 prior ones plus the lifecycle lock and pending spill
394
+ // file), which the corrected apply-side view (#1793 review) now SEES and
395
+ // deliberately leaves untouched (counted as skipped) instead of hiding
396
+ // from enumeration entirely.
397
+ assert.equal(pull.skipped, 21);
371
398
  assert.equal(await readUtf8(root, "state/memory-lifecycle-ledger.jsonl"), "ledger");
372
399
  } finally {
373
400
  await rm(root, { recursive: true, force: true });
@@ -26,6 +26,7 @@ import {
26
26
  type SafeArchiveRoot,
27
27
  } from "./transfer/fs-utils.js";
28
28
  import { parseFlexibleIsoTimestamp } from "./utils/iso-timestamp.js";
29
+ import { DEFAULT_OFFLINE_SYNC_EXCLUDE_GLOBS } from "./offline-sync-exclude-globs.js";
29
30
 
30
31
  export const OFFLINE_SYNC_SNAPSHOT_FORMAT = "remnic.offline-sync.snapshot.v1";
31
32
  export const OFFLINE_SYNC_CHANGESET_FORMAT = "remnic.offline-sync.changeset.v1";
@@ -198,20 +199,6 @@ const EXCLUDED_FILE_PREFIXES = [
198
199
  ".remnic-sync.",
199
200
  ".remnic-sync-state.",
200
201
  ];
201
- // Issue #1786: node-local runtime state that each node rebuilds from synced
202
- // records. Pushing these wastes bandwidth, corrupts the remote's live state
203
- // dir, and trips the large-file push retry loop on a live SQLite database.
204
- const DEFAULT_OFFLINE_SYNC_EXCLUDE_GLOBS: readonly string[] = [
205
- // Leading `**/` matches zero or more segments, so each pattern covers both
206
- // the root `state/` dir AND per-namespace `namespaces/<ns>/state/` dirs
207
- // (Cursor review on PR #1793: multi-namespace deployments previously kept
208
- // pushing their namespaced live sqlite files).
209
- "**/state/*.sqlite",
210
- "**/state/*.sqlite-*",
211
- "**/state/index_tags.json",
212
- "**/state/entity-mention-index.json",
213
- "**/state/memory-governance/runs/**",
214
- ];
215
202
 
216
203
  /**
217
204
  * Convert a tiny subset of glob syntax (`*`, `**`, `?`, literal text) into a
@@ -1987,7 +1987,7 @@ function summarizeSecurityMitigations(
1987
1987
  | "recallAuditAnomalyRepeatQueryLimit"
1988
1988
  | "recallAuditAnomalyNamespaceWalkLimit"
1989
1989
  | "recallAuditAnomalyHighCardinalityLimit"
1990
- | "recallAuditAnomalyRapidFireLimit"
1990
+ | "recallAuditAnomalyRapidFireLimit" | "recallSingleFlightEnabled"
1991
1991
  >,
1992
1992
  ): OperatorDoctorCheck {
1993
1993
  // Resolve access-setup gates once (#1566 Cluster B).