@remnic/core 9.7.15 → 9.8.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-DEL4qCrc.d.ts} +25 -32
  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-QKQYXZVS.js → chunk-2EJOEICD.js} +1819 -1481
  88. package/dist/chunk-2EJOEICD.js.map +1 -0
  89. package/dist/{chunk-L2B3EE7B.js → chunk-2QMKMVHH.js} +2 -2
  90. package/dist/{chunk-VJVNLNDQ.js → chunk-2UFO7X4Q.js} +7 -7
  91. package/dist/{chunk-2MR3MFQB.js → chunk-2VEOKUPP.js} +3 -3
  92. package/dist/chunk-2Z24E5W2.js +22 -0
  93. package/dist/chunk-2Z24E5W2.js.map +1 -0
  94. package/dist/{chunk-RHOZ5LLO.js → chunk-347WD2LE.js} +2 -2
  95. package/dist/{chunk-HDTQVNWD.js → chunk-3QAH2S33.js} +3 -3
  96. package/dist/{chunk-37CTGERM.js → chunk-3WCASNQZ.js} +12 -1
  97. package/dist/chunk-3WCASNQZ.js.map +1 -0
  98. package/dist/{chunk-LRNMRXJO.js → chunk-3Y224NYC.js} +3 -3
  99. package/dist/{chunk-3IY64MV6.js → chunk-44XZ75OQ.js} +44 -10
  100. package/dist/chunk-44XZ75OQ.js.map +1 -0
  101. package/dist/{chunk-VFSP73LP.js → chunk-45GF7Y3V.js} +2 -2
  102. package/dist/{chunk-K7LOWSLU.js → chunk-4BJQODZF.js} +2479 -1520
  103. package/dist/chunk-4BJQODZF.js.map +1 -0
  104. package/dist/{chunk-JREB6UFH.js → chunk-57OWKFUQ.js} +17 -6
  105. package/dist/chunk-57OWKFUQ.js.map +1 -0
  106. package/dist/{chunk-OEHCMALU.js → chunk-5I4M26Q7.js} +5 -5
  107. package/dist/{chunk-2AZXIZEN.js → chunk-5Q7EVV4X.js} +6 -6
  108. package/dist/{chunk-LC7OODWZ.js → chunk-5SB7SC2G.js} +80 -49
  109. package/dist/chunk-5SB7SC2G.js.map +1 -0
  110. package/dist/{chunk-PUBTHW5O.js → chunk-6DRPPQEJ.js} +2 -2
  111. package/dist/{chunk-NWTGD4AN.js → chunk-6KIQT7RG.js} +10 -9
  112. package/dist/chunk-6KIQT7RG.js.map +1 -0
  113. package/dist/{chunk-FDCTQWLW.js → chunk-6O22TZSB.js} +3 -3
  114. package/dist/{chunk-ZQ7UBUZ6.js → chunk-6QYST5XN.js} +6 -6
  115. package/dist/{chunk-W4PGTAS2.js → chunk-6WAFYNVT.js} +3 -3
  116. package/dist/chunk-6ZMAMSHS.js +20 -0
  117. package/dist/chunk-6ZMAMSHS.js.map +1 -0
  118. package/dist/{chunk-R5VAVVHP.js → chunk-72A4L5JJ.js} +2 -2
  119. package/dist/{chunk-X64YLC24.js → chunk-72VAXGEI.js} +5 -13
  120. package/dist/chunk-72VAXGEI.js.map +1 -0
  121. package/dist/{chunk-IKQTFQMI.js → chunk-755Q3DGF.js} +22 -3
  122. package/dist/chunk-755Q3DGF.js.map +1 -0
  123. package/dist/{chunk-OVJ2HIPE.js → chunk-76GLCM57.js} +158 -125
  124. package/dist/chunk-76GLCM57.js.map +1 -0
  125. package/dist/{chunk-D7FOKIY5.js → chunk-7AMFUATK.js} +12 -9
  126. package/dist/{chunk-D7FOKIY5.js.map → chunk-7AMFUATK.js.map} +1 -1
  127. package/dist/{chunk-BFVEEB7W.js → chunk-7ON2JW73.js} +57 -22
  128. package/dist/chunk-7ON2JW73.js.map +1 -0
  129. package/dist/chunk-7RNBVZZO.js +270 -0
  130. package/dist/chunk-7RNBVZZO.js.map +1 -0
  131. package/dist/{chunk-3FAMU5TX.js → chunk-A6USBZTO.js} +2 -2
  132. package/dist/{chunk-ZHIVCODT.js → chunk-A72SWTWW.js} +7 -7
  133. package/dist/{chunk-FC77VUX5.js → chunk-A7Q43EUZ.js} +2 -2
  134. package/dist/{chunk-UJBESW6X.js → chunk-AE7WMV4V.js} +7 -7
  135. package/dist/{chunk-J2HSAU72.js → chunk-AIK5W3IW.js} +29 -1
  136. package/dist/chunk-AIK5W3IW.js.map +1 -0
  137. package/dist/{chunk-A5UXZRRM.js → chunk-AJ7QCSIS.js} +2 -2
  138. package/dist/{chunk-FNMFJWBY.js → chunk-ANEUPF6O.js} +5 -5
  139. package/dist/chunk-AREGMX2J.js +50 -0
  140. package/dist/chunk-AREGMX2J.js.map +1 -0
  141. package/dist/chunk-AVPXXV6J.js +448 -0
  142. package/dist/chunk-AVPXXV6J.js.map +1 -0
  143. package/dist/{chunk-2A3OXAP2.js → chunk-B7RWBZXW.js} +2 -2
  144. package/dist/{chunk-GWTFLF2P.js → chunk-BJMBJZ2Y.js} +59 -59
  145. package/dist/chunk-BJMBJZ2Y.js.map +1 -0
  146. package/dist/{chunk-74F5STS4.js → chunk-BLAKS3CP.js} +4 -4
  147. package/dist/{chunk-M7VGG3ID.js → chunk-BV5WMSIJ.js} +9 -9
  148. package/dist/{chunk-2BFLDH5F.js → chunk-BXLOS5AJ.js} +2 -2
  149. package/dist/{chunk-UXKMMNJD.js → chunk-C23BYTJV.js} +6 -6
  150. package/dist/{chunk-JZHHREBL.js → chunk-C3AKM55W.js} +2 -2
  151. package/dist/{chunk-RP7YXA67.js → chunk-C5JF6EZ7.js} +2 -2
  152. package/dist/{chunk-T7Y5KPLN.js → chunk-C6XBRYVD.js} +16 -15
  153. package/dist/chunk-C6XBRYVD.js.map +1 -0
  154. package/dist/{chunk-FTYDWKO6.js → chunk-CEN6DW6X.js} +12 -2
  155. package/dist/chunk-CEN6DW6X.js.map +1 -0
  156. package/dist/chunk-CGASUJVP.js +421 -0
  157. package/dist/chunk-CGASUJVP.js.map +1 -0
  158. package/dist/{chunk-EHCONI6E.js → chunk-CQMEM5CC.js} +2 -2
  159. package/dist/{chunk-PBNZVPFS.js → chunk-CXZQOVIE.js} +12 -12
  160. package/dist/chunk-D3V3UMET.js +44 -0
  161. package/dist/chunk-D3V3UMET.js.map +1 -0
  162. package/dist/{chunk-7N2RUBAP.js → chunk-DDA47TES.js} +2 -2
  163. package/dist/{chunk-64SE4X5G.js → chunk-DEBHXHJR.js} +3 -3
  164. package/dist/{chunk-EHK6KZHK.js → chunk-DNHVPZOD.js} +2 -2
  165. package/dist/{chunk-437S3G37.js → chunk-DQEMWVMT.js} +2 -2
  166. package/dist/{chunk-LZZNTPLR.js → chunk-DX3XRGLH.js} +2 -2
  167. package/dist/chunk-EA2H5LML.js +72 -0
  168. package/dist/chunk-EA2H5LML.js.map +1 -0
  169. package/dist/{chunk-INELTPRG.js → chunk-EEC7UJPX.js} +103 -106
  170. package/dist/chunk-EEC7UJPX.js.map +1 -0
  171. package/dist/{chunk-KSNVDPDF.js → chunk-EKBNDKDY.js} +21 -20
  172. package/dist/chunk-EKBNDKDY.js.map +1 -0
  173. package/dist/{chunk-YF6FMLBT.js → chunk-EQWEIIKQ.js} +64 -34
  174. package/dist/chunk-EQWEIIKQ.js.map +1 -0
  175. package/dist/{chunk-DZKHSDOM.js → chunk-ES36HTSC.js} +4 -4
  176. package/dist/{chunk-TN7THW5U.js → chunk-ET356KSB.js} +2 -2
  177. package/dist/{chunk-YNDLCWXS.js → chunk-EZ25VE3G.js} +4 -4
  178. package/dist/{chunk-DMSDUGDM.js → chunk-F7GAIWFA.js} +20 -20
  179. package/dist/{chunk-G6XXLKC5.js → chunk-FFPJINJE.js} +6 -6
  180. package/dist/chunk-FMLKOL2Z.js +636 -0
  181. package/dist/chunk-FMLKOL2Z.js.map +1 -0
  182. package/dist/chunk-FQC3DHH2.js +20 -0
  183. package/dist/chunk-FQC3DHH2.js.map +1 -0
  184. package/dist/{chunk-G4CN3ZXL.js → chunk-FUTF72MJ.js} +15 -15
  185. package/dist/chunk-GCASGYIO.js +71 -0
  186. package/dist/chunk-GCASGYIO.js.map +1 -0
  187. package/dist/{chunk-HF77M34J.js → chunk-GFPZS3F5.js} +8 -8
  188. package/dist/{chunk-BCDKBDSY.js → chunk-GNVZQ5JN.js} +99 -41
  189. package/dist/chunk-GNVZQ5JN.js.map +1 -0
  190. package/dist/{chunk-G6NKALRN.js → chunk-H4WG3UQZ.js} +2 -2
  191. package/dist/{chunk-UDQUSU27.js → chunk-HNZKVLAN.js} +2 -2
  192. package/dist/{chunk-5EZXHU36.js → chunk-HYQJQGD3.js} +2 -2
  193. package/dist/{chunk-OAZVR2BV.js → chunk-IDZFBSHN.js} +8 -6
  194. package/dist/{chunk-OAZVR2BV.js.map → chunk-IDZFBSHN.js.map} +1 -1
  195. package/dist/{chunk-PLQE6MJA.js → chunk-IFH6LWTO.js} +50 -8
  196. package/dist/chunk-IFH6LWTO.js.map +1 -0
  197. package/dist/{chunk-RULE4VG5.js → chunk-ILGC6JH6.js} +21 -6
  198. package/dist/chunk-ILGC6JH6.js.map +1 -0
  199. package/dist/chunk-IUM3VSHI.js +113 -0
  200. package/dist/chunk-IUM3VSHI.js.map +1 -0
  201. package/dist/{chunk-DCFV7A7H.js → chunk-IYNGIMVG.js} +101 -91
  202. package/dist/chunk-IYNGIMVG.js.map +1 -0
  203. package/dist/{chunk-TRWPCR6P.js → chunk-JECBQBEX.js} +3 -3
  204. package/dist/{chunk-E6CBU7XP.js → chunk-JYIFGGEM.js} +2 -2
  205. package/dist/{chunk-VA4WSW54.js → chunk-JYIJNNN3.js} +3 -3
  206. package/dist/{chunk-L5HJQC36.js → chunk-K2TDK7GG.js} +3 -3
  207. package/dist/{chunk-KDXVOFYY.js → chunk-KAVBJSBQ.js} +4 -4
  208. package/dist/{chunk-BS4SGLWV.js → chunk-KF5EUVKQ.js} +16 -6
  209. package/dist/chunk-KF5EUVKQ.js.map +1 -0
  210. package/dist/chunk-KFZY2OFH.js +42 -0
  211. package/dist/chunk-KFZY2OFH.js.map +1 -0
  212. package/dist/{chunk-4OKLXWDZ.js → chunk-KNB7IBBU.js} +2 -2
  213. package/dist/{chunk-QLULYKWZ.js → chunk-KSXJOC4F.js} +2 -2
  214. package/dist/{chunk-2S6QHZGJ.js → chunk-L2DPF4DF.js} +1 -1
  215. package/dist/{chunk-JI5AVXYO.js → chunk-LEPOP46W.js} +6 -6
  216. package/dist/{chunk-O7BBFJLP.js → chunk-LTAVSOZW.js} +2 -2
  217. package/dist/{chunk-E3VODCC3.js → chunk-LUDXM7MD.js} +14 -2
  218. package/dist/{chunk-E3VODCC3.js.map → chunk-LUDXM7MD.js.map} +1 -1
  219. package/dist/{chunk-2IZAGAJR.js → chunk-LULR4IUW.js} +3 -3
  220. package/dist/{chunk-QQGPUKMT.js → chunk-MC5Q3J7S.js} +398 -7
  221. package/dist/chunk-MC5Q3J7S.js.map +1 -0
  222. package/dist/{chunk-WMWVO45V.js → chunk-MC6XO7T4.js} +2 -2
  223. package/dist/chunk-MKQBXQKU.js +107 -0
  224. package/dist/chunk-MKQBXQKU.js.map +1 -0
  225. package/dist/{chunk-7PND4PUC.js → chunk-MMGGVZ4Q.js} +29 -9
  226. package/dist/{chunk-7PND4PUC.js.map → chunk-MMGGVZ4Q.js.map} +1 -1
  227. package/dist/{chunk-D6RIFG4O.js → chunk-MNB5RMAY.js} +2 -2
  228. package/dist/{chunk-Q5WG43OP.js → chunk-MYFQ3ED4.js} +7 -7
  229. package/dist/{chunk-V3UE5I5F.js → chunk-MYVPLJOO.js} +2 -2
  230. package/dist/chunk-NINSR6LX.js +83 -0
  231. package/dist/chunk-NINSR6LX.js.map +1 -0
  232. package/dist/{chunk-MTWKDOVO.js → chunk-NLE6TSLG.js} +2 -2
  233. package/dist/{chunk-DBRYEIGY.js → chunk-OJP3N7UK.js} +2 -2
  234. package/dist/{chunk-VDW4VU7B.js → chunk-OQJIB32H.js} +28 -23
  235. package/dist/chunk-OQJIB32H.js.map +1 -0
  236. package/dist/{chunk-SMX5267P.js → chunk-OZKOPQCM.js} +2 -2
  237. package/dist/{chunk-JCK7V6SN.js → chunk-P65YJEEL.js} +2 -2
  238. package/dist/{chunk-MTR7BZQN.js → chunk-PBGWYM3H.js} +3 -3
  239. package/dist/chunk-PIG4WJFQ.js +87 -0
  240. package/dist/chunk-PIG4WJFQ.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-SICXL4MK.js +165 -0
  263. package/dist/chunk-SICXL4MK.js.map +1 -0
  264. package/dist/chunk-SK7AMF2J.js +168 -0
  265. package/dist/chunk-SK7AMF2J.js.map +1 -0
  266. package/dist/{chunk-LZOV7MX7.js → chunk-TDTXKOAJ.js} +6474 -5747
  267. package/dist/chunk-TDTXKOAJ.js.map +1 -0
  268. package/dist/{chunk-KSBEEMQF.js → chunk-TG6IHVE2.js} +151 -6
  269. package/dist/chunk-TG6IHVE2.js.map +1 -0
  270. package/dist/{chunk-7K5Q6COX.js → chunk-TVVEYCNW.js} +4 -4
  271. package/dist/{chunk-DPAENM7O.js → chunk-U3ZAVRP3.js} +2 -2
  272. package/dist/{chunk-ODPLEWB6.js → chunk-UFGFMWAD.js} +47 -17
  273. package/dist/chunk-UFGFMWAD.js.map +1 -0
  274. package/dist/{chunk-4KJLYTLS.js → chunk-V57NLO5P.js} +2 -2
  275. package/dist/{chunk-FLVL4L3L.js → chunk-VDX2J7OX.js} +2 -2
  276. package/dist/{chunk-AJLLIIML.js → chunk-W4FBGYGK.js} +1 -1
  277. package/dist/{chunk-TXLGHDHS.js → chunk-W4XJFLAL.js} +53 -32
  278. package/dist/chunk-W4XJFLAL.js.map +1 -0
  279. package/dist/{chunk-6SXVCD7W.js → chunk-W7IGLX4G.js} +2 -2
  280. package/dist/{chunk-KQDNAXOM.js → chunk-WG5HSQ4P.js} +19 -6
  281. package/dist/chunk-WG5HSQ4P.js.map +1 -0
  282. package/dist/{chunk-LTJAMRGI.js → chunk-WL5EBRDH.js} +17 -3
  283. package/dist/chunk-WL5EBRDH.js.map +1 -0
  284. package/dist/{chunk-KAWTOYAW.js → chunk-WLZYGLJ4.js} +2 -2
  285. package/dist/{chunk-RO4LQGT3.js → chunk-WON4APQY.js} +4 -4
  286. package/dist/{chunk-PQVK2S3J.js → chunk-WZFAPHIK.js} +6 -6
  287. package/dist/{chunk-KQPJLK3X.js → chunk-XL24QQ63.js} +2 -2
  288. package/dist/{chunk-RVZRYUQH.js → chunk-YROFNEG5.js} +7 -7
  289. package/dist/{chunk-RAR2BSEM.js → chunk-YV32N67O.js} +1 -1
  290. package/dist/chunk-YV32N67O.js.map +1 -0
  291. package/dist/{chunk-PBSAPHHA.js → chunk-YVKF3HEW.js} +1 -1
  292. package/dist/chunk-YVKF3HEW.js.map +1 -0
  293. package/dist/{chunk-VRAD2FGO.js → chunk-Z54EM5YZ.js} +12 -12
  294. package/dist/{chunk-2VN4JAX7.js → chunk-ZOKZIR5K.js} +95 -33
  295. package/dist/chunk-ZOKZIR5K.js.map +1 -0
  296. package/dist/{cli-Cd5fMmhq.d.ts → cli-C_pqqTCw.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 +79 -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 +120 -0
  617. package/src/access-observe-write-surface.ts +130 -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 +182 -175
  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 +193 -0
  781. package/src/write-quarantine.ts +241 -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
@@ -2,18 +2,80 @@ import path from "node:path";
2
2
  import { stat } from "node:fs/promises";
3
3
  import { StorageManager } from "../storage.js";
4
4
  import { log } from "../logger.js";
5
+ import { displayErrorDetail } from "../runtime/better-sqlite.js";
5
6
  import type { MemoryLifecycleEvent } from "../types.js";
6
7
  import { toBackupStamp } from "./backup-stamp.js";
7
- import { writeFileAtomically } from "./atomic-file.js";
8
+ import { copyExistingFileToBackup, writeFileAtomically } from "./atomic-file.js";
8
9
  import {
9
10
  buildLifecycleEventsForMemory,
11
+ compareMemoryLifecycleEvents,
10
12
  sortMemoryLifecycleEvents,
13
+ memoryLifecycleLedgerLockPath,
14
+ MEMORY_LIFECYCLE_LEDGER_LOCK_STALE_MS,
11
15
  } from "../memory-lifecycle-ledger-utils.js";
16
+ import { withHeldFileLock, type HeldFileLockOptions, type HeldFileLockController } from "../utils/serialize-mutations.js";
17
+ import { probeEncryptedRegularFileHeader } from "../secure-store/secure-fs.js";
18
+
19
+ /**
20
+ * Event types `buildLifecycleEventsForMemory` reconstructs from frontmatter.
21
+ * Everything else in the ledger is append-only history with no frontmatter
22
+ * equivalent and must be carried over by a preserving rebuild (issue #1910).
23
+ */
24
+ const FRONTMATTER_DERIVED_EVENT_TYPES: Record<string, true> = {
25
+ created: true,
26
+ updated: true,
27
+ superseded: true,
28
+ archived: true,
29
+ };
12
30
 
13
31
  export interface RebuildMemoryLifecycleLedgerOptions {
14
32
  memoryDir: string;
15
33
  dryRun?: boolean;
16
34
  now?: Date;
35
+ /**
36
+ * Active storage context (issue #1910). When provided, memories are read
37
+ * through it (so encrypted-at-rest memories in a secure-store deployment are
38
+ * decrypted with the live key) and the rebuilt ledger is rewritten through
39
+ * its secure writer (so it stays encrypted at rest). Its `dir` MUST equal
40
+ * `memoryDir`. When omitted, a fresh plaintext `StorageManager` is used and
41
+ * the ledger is written as plaintext — the CLI default.
42
+ */
43
+ storage?: StorageManager;
44
+ /**
45
+ * Preserve append-only lifecycle events that have no frontmatter equivalent
46
+ * (issue #1910). `buildLifecycleEventsForMemory` only reconstructs
47
+ * `created`/`updated`/`superseded`/`archived` from frontmatter, so a bare
48
+ * rebuild silently drops history like `explicit_capture_accepted`,
49
+ * `explicit_capture_queued`, `imported`, `promoted`, `merged`, `restored`,
50
+ * and `rejected`. When true, the existing ledger's non-reconstructable rows
51
+ * are read (via the same secure/permissive `readAllMemoryLifecycleEvents`
52
+ * path), merged with the rebuilt rows, deduplicated by `eventId`, and sorted
53
+ * canonically. Background auto-compaction sets this so it never loses events;
54
+ * the manual/CLI repair rebuild leaves it off (reconstruct purely from
55
+ * frontmatter).
56
+ */
57
+ preserveExistingEvents?: boolean;
58
+ /**
59
+ * Override the ledger-lock acquisition timing (issue #2033). Only
60
+ * `maxWaitMs`/`pollMs` are honored; `staleMs` stays fixed at
61
+ * `MEMORY_LIFECYCLE_LEDGER_LOCK_STALE_MS`. Used by tests to force the
62
+ * lock-acquisition-failure branch (`acquired=false`) deterministically
63
+ * without a multi-second wait.
64
+ */
65
+ lockOptions?: Pick<HeldFileLockOptions, "maxWaitMs" | "pollMs">;
66
+ /**
67
+ * Upper bound (bytes) on the rewritten ledger when preserving events (issue
68
+ * #2033). A preserving compaction carries over ALL append-only history, which
69
+ * — if the history alone is large — could leave the rewritten ledger over the
70
+ * whole-file read/decrypt cap (STATE_FILE_MAX_DECRYPT_BYTES), the exact
71
+ * unreadable-ledger failure compaction exists to prevent. When set and the
72
+ * preserved payload would exceed it, the OLDEST rows are dropped from the
73
+ * active ledger until it fits; because the full pre-compaction ledger is
74
+ * copied verbatim to the timestamped backup first, those rows are archived,
75
+ * not lost. Ignored when `preserveExistingEvents` is off (a frontmatter-only
76
+ * rebuild is already bounded by the corpus). `0`/undefined disables bounding.
77
+ */
78
+ maxLedgerBytes?: number;
17
79
  }
18
80
 
19
81
  export interface SkippedLifecycleBlankIdMemory {
@@ -34,12 +96,84 @@ export interface RebuildMemoryLifecycleLedgerResult {
34
96
  backupPath?: string;
35
97
  skippedBlankIdMemories: SkippedLifecycleBlankIdMemory[];
36
98
  skippedDuplicateEvents: SkippedDuplicateLifecycleEvent[];
99
+ /**
100
+ * Count of existing-ledger rows carried over beyond the frontmatter
101
+ * reconstruction (only set when `preserveExistingEvents` is on; issue #1910):
102
+ * append-only history with no frontmatter equivalent, plus any
103
+ * frontmatter-derived row that raced in after the corpus scan and so was not
104
+ * reproduced by the reconstruction (#2033).
105
+ */
106
+ preservedAppendOnlyRows?: number;
107
+ /**
108
+ * Count of oldest rows dropped from the ACTIVE ledger to keep it under
109
+ * `maxLedgerBytes` (issue #2033). They remain in the verbatim timestamped
110
+ * backup, so this is a bound-and-archive, not a loss. Set only when bounding
111
+ * actually trimmed rows.
112
+ */
113
+ archivedOverflowRows?: number;
114
+ /**
115
+ * Whether the active ledger was actually backed up and rewritten (issue #2033
116
+ * thread PRRT_kwDORJXyws6SExst). A preserving write-mode rebuild that would
117
+ * reproduce the current ledger byte-for-byte (same decrypted content AND same
118
+ * at-rest format) skips the backup+rewrite, so callers can distinguish a real
119
+ * compaction from a no-op and avoid re-archiving an unchanged ledger every
120
+ * interval. `true` for every dry run's non-write preview is never set — only
121
+ * write-mode results carry it; defaults to `false` when no rewrite happened.
122
+ */
123
+ rewritten?: boolean;
37
124
  }
38
125
 
39
126
  function isNodeError(err: unknown): err is NodeJS.ErrnoException {
40
127
  return typeof err === "object" && err !== null && "code" in err;
41
128
  }
42
129
 
130
+ /** Serialized on-disk size (bytes, incl. trailing newline) of one ledger row. */
131
+ function lifecycleRowBytes(event: MemoryLifecycleEvent): number {
132
+ return Buffer.byteLength(`${JSON.stringify(event)}\n`, "utf8");
133
+ }
134
+
135
+ /**
136
+ * Keep the NEWEST canonically-ordered events whose serialized payload fits
137
+ * strictly under `cap` bytes (issue #2033). Recency is by `timestamp` (newest
138
+ * first), tie-broken by the canonical comparator, so a large append-only
139
+ * history is trimmed to its most recent rows rather than to a single memoryId
140
+ * group (the ledger's on-disk order is by memoryId then time).
141
+ *
142
+ * A row too large to fit the remaining budget is SKIPPED, and scanning
143
+ * continues to older rows that still fit — one oversized (or future-dated,
144
+ * hence recency-first) row cannot truncate the entire older history. The kept
145
+ * subset is returned in the input's canonical order; the caller relies on the
146
+ * verbatim backup to retain the dropped rows.
147
+ */
148
+ export function boundLifecycleEventsToByteCap(
149
+ events: MemoryLifecycleEvent[],
150
+ cap: number,
151
+ ): { kept: MemoryLifecycleEvent[]; dropped: number } {
152
+ if (!(cap > 0)) return { kept: events, dropped: 0 };
153
+ const sizes = new Map<MemoryLifecycleEvent, number>();
154
+ let total = 0;
155
+ for (const event of events) {
156
+ const bytes = lifecycleRowBytes(event);
157
+ sizes.set(event, bytes);
158
+ total += bytes;
159
+ }
160
+ if (total <= cap) return { kept: events, dropped: 0 };
161
+ const byRecency = [...events].sort((a, b) => {
162
+ if (a.timestamp !== b.timestamp) return b.timestamp.localeCompare(a.timestamp);
163
+ return -compareMemoryLifecycleEvents(a, b);
164
+ });
165
+ const keep = new Set<MemoryLifecycleEvent>();
166
+ let running = 0;
167
+ for (const event of byRecency) {
168
+ const bytes = sizes.get(event)!;
169
+ if (running + bytes > cap) continue; // skip this row, keep scanning older rows that still fit
170
+ running += bytes;
171
+ keep.add(event);
172
+ }
173
+ const kept = events.filter((event) => keep.has(event));
174
+ return { kept, dropped: events.length - kept.length };
175
+ }
176
+
43
177
  export async function backupExistingLedger(
44
178
  memoryDir: string,
45
179
  outputPath: string,
@@ -71,7 +205,14 @@ export async function rebuildMemoryLifecycleLedger(
71
205
  const dryRun = options.dryRun !== false;
72
206
  const now = options.now ?? new Date();
73
207
  const outputPath = path.join(options.memoryDir, "state", "memory-lifecycle-ledger.jsonl");
74
- const storage = new StorageManager(options.memoryDir);
208
+ const storage = options.storage ?? new StorageManager(options.memoryDir);
209
+ if (options.storage && path.resolve(storage.dir) !== path.resolve(options.memoryDir)) {
210
+ throw new Error(
211
+ `rebuildMemoryLifecycleLedger: storage.dir (${storage.dir}) must match `
212
+ + `memoryDir (${options.memoryDir})`,
213
+ );
214
+ }
215
+ const secureRewrite = options.storage !== undefined;
75
216
  const tiers = [
76
217
  await storage.readAllMemories(),
77
218
  await storage.readAllColdMemories(),
@@ -119,24 +260,247 @@ export async function rebuildMemoryLifecycleLedger(
119
260
  events.push(event);
120
261
  }
121
262
 
263
+ let finalEvents = events;
264
+ let preservedAppendOnlyRows: number | undefined;
265
+ let archivedOverflowRows: number | undefined;
122
266
  let backupPath: string | undefined;
267
+ let rewritten = false;
268
+ // The preserve-read + whole-file rewrite are serialized against concurrent
269
+ // lifecycle appends ONLY in write mode (issue #1910, codex):
270
+ // appendMemoryLifecycleEvents holds this same cross-process lock, so an event
271
+ // appended after the preserve-read but before the atomic rename waits and
272
+ // lands on the compacted ledger instead of being clobbered by the rename. A
273
+ // DRY RUN takes no lock — it reads the ledger read-only to compute the
274
+ // preserve/merge/byte-cap PREVIEW and never rewrites, so it must not block
275
+ // appends (#2033 Cursor). The corpus scan above stays outside the lock in
276
+ // both modes — frontmatter-derived rows come from the memory files.
277
+ const runLedgerCriticalSection = async (
278
+ acquired: boolean,
279
+ lock: HeldFileLockController | null,
280
+ ): Promise<void> => {
281
+ // A WRITE that read or rewrote the ledger without the lock could race a
282
+ // concurrent append/rewrite and lose data, so REFUSE the unlocked fallback
283
+ // withHeldFileLock takes on acquisition timeout (issue #2033 CodeRabbit
284
+ // Critical / codex). A dry run passes lock=null and acquired=true: it never
285
+ // reaches the rewrite, so the unlocked preview read is safe.
286
+ if (!dryRun && !acquired) {
287
+ throw new Error(
288
+ "lifecycle ledger rebuild aborted: could not acquire the ledger lock within the "
289
+ + "acquisition budget; refusing to read or rewrite unlocked so a concurrent append "
290
+ + "or compaction cannot be clobbered (issue #1910).",
291
+ );
292
+ }
293
+ if (options.preserveExistingEvents) {
294
+ // Merge the frontmatter reconstruction (`events`) with the CURRENT ledger
295
+ // so compaction never deletes a lifecycle row that raced the scan (issue
296
+ // #1910, #2033). Read the existing ledger through the uncapped BUFFER
297
+ // path — it decrypts with the live key when `storage` carries the secure
298
+ // context and bypasses the whole-file string decrypt cap, so an oversize
299
+ // encrypted ledger (the exact file compaction must shrink) is still
300
+ // readable here rather than aborting (#2033 Cursor High).
301
+ // preserveExistingEvents means "never lose history": if the current
302
+ // ledger genuinely cannot be read (corruption, or a locked required
303
+ // store), ABORT rather than rewrite from frontmatter only and silently
304
+ // drop that history. An absent ledger reads as [] (ENOENT swallowed
305
+ // downstream), so a throw here is always a real read failure.
306
+ let existing: MemoryLifecycleEvent[];
307
+ try {
308
+ existing = await storage.readAllMemoryLifecycleEventsForCompaction();
309
+ } catch (err) {
310
+ throw new Error(
311
+ `lifecycle ledger rebuild aborted: cannot read existing events to preserve `
312
+ + `(${displayErrorDetail(err) || "unknown error"})`,
313
+ );
314
+ }
315
+ // The corpus scan (`events`) runs OUTSIDE the lock and is therefore a
316
+ // stale snapshot; `existing` is read here under the lock and is
317
+ // authoritative for what the ledger holds at rewrite time. A
318
+ // frontmatter-derived row (created/updated/superseded/archived) is safe to
319
+ // collapse into the reconstruction ONLY when the scan actually reproduced
320
+ // the same logical event — same (memoryId, eventType, timestamp), which is
321
+ // exactly what the live append stamps (fm.created/updated/...) and what
322
+ // makeRebuiltMemoryLifecycleEvent emits. A frontmatter-derived row whose
323
+ // content key the reconstruction did NOT produce raced in after the scan
324
+ // (a memory created/updated between the scan and this locked read); the
325
+ // reconstruction has no equivalent, so dropping it by eventType alone
326
+ // would delete it. Preserve it instead, deduped by content key so a
327
+ // retried append of the same logical event still collapses to one. Rows
328
+ // that are not frontmatter-derived are append-only history with no
329
+ // reconstruction — always carried over, deduped by eventId in the merge.
330
+ const contentKey = (event: MemoryLifecycleEvent): string =>
331
+ `${event.memoryId}\u0000${event.eventType}\u0000${event.timestamp}`;
332
+ const reconstructedKeys = new Set(events.map(contentKey));
333
+ const racedFrontmatterByKey = new Map<string, MemoryLifecycleEvent>();
334
+ const appendOnly: MemoryLifecycleEvent[] = [];
335
+ for (const event of existing) {
336
+ if (!FRONTMATTER_DERIVED_EVENT_TYPES[event.eventType]) {
337
+ appendOnly.push(event);
338
+ continue;
339
+ }
340
+ const key = contentKey(event);
341
+ if (reconstructedKeys.has(key)) continue; // collapsed into reconstruction
342
+ if (!racedFrontmatterByKey.has(key)) racedFrontmatterByKey.set(key, event);
343
+ }
344
+ const mergedById = new Map<string, MemoryLifecycleEvent>();
345
+ for (const event of sortMemoryLifecycleEvents([
346
+ ...events,
347
+ ...racedFrontmatterByKey.values(),
348
+ ...appendOnly,
349
+ ])) {
350
+ if (!mergedById.has(event.eventId)) mergedById.set(event.eventId, event);
351
+ }
352
+ finalEvents = [...mergedById.values()];
353
+ preservedAppendOnlyRows = finalEvents.length - events.length;
354
+ // Bound the rewritten ledger so a preserving compaction can never leave it
355
+ // over the whole-file read/decrypt cap (#2033). This must run whenever a
356
+ // cap is set — NOT only when `existing.length > 0`: an oversized on-disk
357
+ // ledger whose every row fails validation reads as `existing === []`, yet
358
+ // `finalEvents` (the frontmatter reconstruction) can itself exceed the cap.
359
+ // Overflow (oldest) rows are dropped from the active ledger but survive
360
+ // both in the timestamped backup (a verbatim copy when the ledger is
361
+ // plaintext, re-encrypted under the backup path's own AAD when it is
362
+ // encrypted so it still decrypts there, #2033) and, for frontmatter-derived
363
+ // rows, in the memory files they were reconstructed from — so a later full
364
+ // rebuild regenerates them.
365
+ if (options.maxLedgerBytes && options.maxLedgerBytes > 0) {
366
+ const bounded = boundLifecycleEventsToByteCap(finalEvents, options.maxLedgerBytes);
367
+ if (bounded.dropped > 0) {
368
+ finalEvents = bounded.kept;
369
+ archivedOverflowRows = bounded.dropped;
370
+ log.warn(
371
+ `lifecycle ledger rebuild bounded to ${options.maxLedgerBytes} bytes: `
372
+ + `dropped ${bounded.dropped} oldest row(s) from the active ledger `
373
+ + `(preserved in the backup) to stay under the read/decrypt cap.`,
374
+ );
375
+ }
376
+ }
377
+ }
378
+
379
+ // Re-assert the lock immediately before the destructive active-ledger
380
+ // rewrite. Everything above (the preserve read, merge, sort, byte-cap
381
+ // bound, and JSON serialize) is CPU-bound and blocks the event loop, so the
382
+ // timer heartbeat inside withHeldFileLock cannot refresh the lock's mtime;
383
+ // a peer that judged the lock stale within the 30s window could have broken
384
+ // it and appended to the current ledger. `lock.refresh()` (a) reports the
385
+ // lock LOST so we ABORT rather than rename our compacted file over that
386
+ // peer's append, and (b) when still held, re-stamps the mtime so the bounded
387
+ // write below cannot itself be judged stale mid-rename (issue #1910/#2033).
388
+ const abortIfLockLost = async (): Promise<void> => {
389
+ if (lock && await lock.refresh()) return;
390
+ throw new Error(
391
+ "lifecycle ledger rebuild aborted: lost the ledger lock during the compaction "
392
+ + "rewrite (a peer stale-broke it while the event loop was blocked by CPU-bound "
393
+ + "merge/serialize); refusing to clobber a concurrent append (issue #1910/#2033).",
394
+ );
395
+ };
396
+ if (!dryRun) {
397
+ const payload = finalEvents.map((event) => JSON.stringify(event)).join("\n");
398
+ const content = payload.length > 0 ? `${payload}\n` : "";
399
+ // No-op skip (#2033 thread PRRT_kwDORJXyws6SExst): a preserving rebuild
400
+ // bounds the ACTIVE ledger to the read/decrypt cap, so a VALID ledger that
401
+ // sits above the configured compaction trigger but below the cap would
402
+ // otherwise be rewritten to identical content and re-archived on every
403
+ // maintenance interval — unbounded growth of archive/memory-lifecycle-ledger
404
+ // plus pointless disk/CPU churn. Skip the backup+rewrite when it would
405
+ // change neither the logical (decrypted) content NOR the at-rest format.
406
+ // The raw read here doubles as the source for the encrypted verbatim backup
407
+ // below, so the current ledger is read at most once. An absent ledger reads
408
+ // as ENOENT (a create is always a real change) and any other read/probe
409
+ // error propagates rather than masking a needed rewrite.
410
+ let currentEncrypted = false;
411
+ let priorRawBuffer: Buffer | null = null;
412
+ try {
413
+ currentEncrypted = await probeEncryptedRegularFileHeader(outputPath);
414
+ priorRawBuffer = await storage.readMemoryLifecycleLedgerRawBufferForCompaction();
415
+ } catch (err) {
416
+ if (!isNodeError(err) || err.code !== "ENOENT") throw err;
417
+ }
418
+ // Preserve encryption at rest (#2033). An already-encrypted ledger (or its
419
+ // encrypted backup) MUST be rewritten encrypted even when the
420
+ // `secureStoreEncryptOnWrite` policy is paused — otherwise the compaction
421
+ // silently DOWNGRADES encrypted state to plaintext. Force encryption
422
+ // whenever the current ledger is encrypted and the store is unlocked (a
423
+ // key is available); reaching this point with an encrypted ledger already
424
+ // implies an unlocked store, since the raw read above decrypts and would
425
+ // have thrown under a locked key. A plaintext ledger keeps the ordinary
426
+ // policy (`willEncryptStateWrites`), so existing plaintext behavior holds.
427
+ const forceEncrypt =
428
+ secureRewrite && currentEncrypted && storage.isSecureStoreUnlocked();
429
+ const replacementEncrypted =
430
+ secureRewrite && (storage.willEncryptStateWrites() || forceEncrypt);
431
+ // Compare as buffers, never decoding the raw ledger to one giant string:
432
+ // a multi-hundred-MB decrypted ledger can exceed V8's max string length,
433
+ // so `priorRawBuffer.equals(...)` (byte compare) must be used, NOT
434
+ // `.toString()` (#2033 giant-string invariant). `content` is the freshly
435
+ // serialized replacement, already a string; Buffer.from() reuses it.
436
+ if (
437
+ priorRawBuffer !== null &&
438
+ currentEncrypted === replacementEncrypted &&
439
+ priorRawBuffer.equals(Buffer.from(content, "utf8"))
440
+ ) {
441
+ // Nothing to change: leave the active ledger and archive untouched.
442
+ rewritten = false;
443
+ } else {
444
+ const desiredBackup = await backupExistingLedger(options.memoryDir, outputPath, now);
445
+ if (secureRewrite) {
446
+ // Preserve encrypted-at-rest (issue #1910). The BACKUP needs care under
447
+ // secure-store (#2033): when the existing ledger is encrypted, its bytes
448
+ // are path-bound via AAD, so a byte-for-byte copy to the archive path
449
+ // cannot be decrypted there — it would silently orphan the overflow rows
450
+ // a bounded rewrite claims to preserve. Reuse the RAW decrypted ledger
451
+ // content read above (no event parsing, so malformed/truncated/future
452
+ // rows survive exactly as the plaintext verbatim copy keeps them) and
453
+ // re-encrypt it under the backup path's own AAD, yielding a directly
454
+ // decryptable backup that retains every original byte. A PLAINTEXT
455
+ // existing ledger is already readable, so a verbatim copy is correct.
456
+ // Then rewrite the active ledger through the secure writer.
457
+ if (desiredBackup && currentEncrypted) {
458
+ const rawForBackup =
459
+ priorRawBuffer ?? (await storage.readMemoryLifecycleLedgerRawBufferForCompaction());
460
+ await storage.writeMemoryLifecycleLedgerContent(rawForBackup, desiredBackup, forceEncrypt);
461
+ backupPath = desiredBackup;
462
+ } else {
463
+ backupPath = desiredBackup
464
+ ? await copyExistingFileToBackup(outputPath, desiredBackup)
465
+ : undefined;
466
+ }
467
+ await abortIfLockLost();
468
+ await storage.writeMemoryLifecycleLedgerContent(content, undefined, forceEncrypt);
469
+ } else {
470
+ await abortIfLockLost();
471
+ backupPath = await writeFileAtomically(outputPath, content, desiredBackup);
472
+ }
473
+ rewritten = true;
474
+ }
475
+ }
476
+ };
477
+ // Write mode holds the ledger lock across the preserve-read and atomic
478
+ // rewrite so a concurrent append lands on the compacted ledger instead of
479
+ // being clobbered. A dry run computes the SAME preserve/merge/byte-cap
480
+ // preview but WITHOUT the lock (read-only, no rewrite), so `rebuiltRows`,
481
+ // `preservedAppendOnlyRows`, and `archivedOverflowRows` report what a --write
482
+ // would apply while never blocking concurrent appends (#2033 Cursor). A dry
483
+ // run with nothing to preserve touches nothing at all.
123
484
  if (!dryRun) {
124
- backupPath = await backupExistingLedger(options.memoryDir, outputPath, now);
125
- const payload = events.map((event) => JSON.stringify(event)).join("\n");
126
- backupPath = await writeFileAtomically(
127
- outputPath,
128
- payload.length > 0 ? `${payload}\n` : "",
129
- backupPath,
485
+ await withHeldFileLock(
486
+ memoryLifecycleLedgerLockPath(outputPath),
487
+ { staleMs: MEMORY_LIFECYCLE_LEDGER_LOCK_STALE_MS, ...options.lockOptions },
488
+ runLedgerCriticalSection,
130
489
  );
490
+ } else if (options.preserveExistingEvents) {
491
+ await runLedgerCriticalSection(true, null);
131
492
  }
132
493
 
133
494
  return {
134
495
  dryRun,
135
496
  scannedMemories: allMemories.length,
136
- rebuiltRows: events.length,
497
+ rebuiltRows: finalEvents.length,
137
498
  outputPath,
138
499
  backupPath,
139
500
  skippedBlankIdMemories,
140
501
  skippedDuplicateEvents,
502
+ preservedAppendOnlyRows,
503
+ archivedOverflowRows,
504
+ rewritten,
141
505
  };
142
506
  }
@@ -24,6 +24,47 @@ export const MEMORY_LIFECYCLE_EVENT_SORT_ORDER: Record<MemoryLifecycleEventType,
24
24
  archived: 10,
25
25
  };
26
26
 
27
+ /**
28
+ * Deterministic sort rank for a lifecycle event type. The ledger readers admit
29
+ * any structurally valid row (permissive `eventType`, issue #1910), so an
30
+ * unknown/typoed type must still sort deterministically: it ranks AFTER every
31
+ * known type and keeps the comparator total. Without this fallback,
32
+ * `map[unknown] - map[known]` is `NaN`, an invalid comparator result.
33
+ */
34
+ const UNKNOWN_LIFECYCLE_EVENT_SORT_RANK = Number.MAX_SAFE_INTEGER;
35
+
36
+ export function lifecycleEventSortRank(eventType: string): number {
37
+ return (
38
+ MEMORY_LIFECYCLE_EVENT_SORT_ORDER[eventType as MemoryLifecycleEventType] ??
39
+ UNKNOWN_LIFECYCLE_EVENT_SORT_RANK
40
+ );
41
+ }
42
+
43
+ /**
44
+ * Cross-process lock path guarding lifecycle-ledger mutations (issue #1910,
45
+ * codex): `appendMemoryLifecycleEvents` and the compaction rewrite both hold
46
+ * this lock so a lifecycle event appended during compaction's read->rewrite
47
+ * window cannot be clobbered by the atomic rename that replaces the ledger.
48
+ */
49
+ export function memoryLifecycleLedgerLockPath(ledgerPath: string): string {
50
+ return `${ledgerPath}.lock`;
51
+ }
52
+
53
+ /** Stale-break window for the lifecycle-ledger lock, shared by append + rewrite. */
54
+ export const MEMORY_LIFECYCLE_LEDGER_LOCK_STALE_MS = 30_000;
55
+
56
+ /**
57
+ * Acquisition budget for a lifecycle append waiting on the shared ledger lock
58
+ * (issue #2033). Set to twice the stale-break window so a normal append waits
59
+ * out an in-progress compaction rewrite instead of giving up at
60
+ * withHeldFileLock's 5s default and dropping the event: a live compaction
61
+ * releases within its own runtime, and a crashed holder's lock is stale-broken
62
+ * at MEMORY_LIFECYCLE_LEDGER_LOCK_STALE_MS, so the append still acquires well
63
+ * inside this budget rather than failing open.
64
+ */
65
+ export const MEMORY_LIFECYCLE_LEDGER_APPEND_LOCK_MAX_WAIT_MS =
66
+ MEMORY_LIFECYCLE_LEDGER_LOCK_STALE_MS * 2;
67
+
27
68
  export function toMemoryPathRel(baseDir: string, filePath: string): string {
28
69
  if (!baseDir) return filePath.split(path.sep).join("/");
29
70
  return path.relative(baseDir, filePath).split(path.sep).join("/");
@@ -107,10 +148,15 @@ export function buildLifecycleEventsForMemory(memory: MemoryFile): MemoryLifecyc
107
148
  return events;
108
149
  }
109
150
 
151
+ export function compareMemoryLifecycleEvents(
152
+ a: MemoryLifecycleEvent,
153
+ b: MemoryLifecycleEvent,
154
+ ): number {
155
+ if (a.memoryId !== b.memoryId) return a.memoryId.localeCompare(b.memoryId);
156
+ if (a.timestamp !== b.timestamp) return a.timestamp.localeCompare(b.timestamp);
157
+ return lifecycleEventSortRank(a.eventType) - lifecycleEventSortRank(b.eventType);
158
+ }
159
+
110
160
  export function sortMemoryLifecycleEvents(events: MemoryLifecycleEvent[]): MemoryLifecycleEvent[] {
111
- return [...events].sort((a, b) => {
112
- if (a.memoryId !== b.memoryId) return a.memoryId.localeCompare(b.memoryId);
113
- if (a.timestamp !== b.timestamp) return a.timestamp.localeCompare(b.timestamp);
114
- return MEMORY_LIFECYCLE_EVENT_SORT_ORDER[a.eventType] - MEMORY_LIFECYCLE_EVENT_SORT_ORDER[b.eventType];
115
- });
161
+ return [...events].sort(compareMemoryLifecycleEvents);
116
162
  }
@@ -12,7 +12,7 @@
12
12
  import assert from "node:assert/strict";
13
13
  import test from "node:test";
14
14
 
15
- import { canReadNamespace, resolvePrincipal } from "./principal.js";
15
+ import { canReadNamespace, isNamespacePolicyCovered, resolvePrincipal } from "./principal.js";
16
16
  import type { PluginConfig } from "../types.js";
17
17
 
18
18
  // ──────────────────────────────────────────────────────────────────────────
@@ -249,3 +249,39 @@ test("resolvePrincipal: regex rules are skipped for overlong session keys", () =
249
249
 
250
250
  assert.equal(resolvePrincipal("a".repeat(1_000), config), "default");
251
251
  });
252
+
253
+ test("isNamespacePolicyCovered mirrors canWriteNamespace: default + policy-with-writers covered; shared/no-writers/uncovered not", () => {
254
+ const config = makeConfig(true, [
255
+ { name: "team-a", readPrincipals: [], writePrincipals: ["alice"] },
256
+ { name: "readonly-ns", readPrincipals: ["*"], writePrincipals: [] },
257
+ { name: "blank-writer-ns", readPrincipals: ["*"], writePrincipals: [""] },
258
+ ]);
259
+ // Covered: the default namespace, and a policy that grants at least one writer.
260
+ assert.equal(isNamespacePolicyCovered("default", config), true);
261
+ assert.equal(isNamespacePolicyCovered("team-a", config), true);
262
+ // NOT covered: shared is not implicitly writable (matches canWriteNamespace),
263
+ // a policy with no writePrincipals grants nobody, and an unlisted namespace is
264
+ // the jw14m2-class misconfiguration #1888 targets (writes rejected + parked).
265
+ assert.equal(isNamespacePolicyCovered("shared", config), false);
266
+ assert.equal(isNamespacePolicyCovered("readonly-ns", config), false);
267
+ // Blank writer entries never match a real principal, so they grant no one.
268
+ assert.equal(isNamespacePolicyCovered("blank-writer-ns", config), false);
269
+ assert.equal(isNamespacePolicyCovered("team-b", config), false);
270
+ // Namespaces disabled: every write is allowed, so nothing is flagged.
271
+ const disabled = makeConfig(false);
272
+ assert.equal(isNamespacePolicyCovered("anything", disabled), true);
273
+ assert.equal(isNamespacePolicyCovered("team-b", disabled), true);
274
+ });
275
+
276
+ test("isNamespacePolicyCovered: an explicit default-namespace policy overrides the default fallback", () => {
277
+ // canWriteNamespace looks up a policy BEFORE falling back to defaultNamespace,
278
+ // so a policy naming the default with no (or blank-only) writers makes the
279
+ // default unwritable. The lint must mirror that precedence, not short-circuit
280
+ // on `namespace === defaultNamespace`.
281
+ const emptyDefault = makeConfig(true, [{ name: "default", readPrincipals: ["*"], writePrincipals: [] }]);
282
+ assert.equal(isNamespacePolicyCovered("default", emptyDefault), false);
283
+ const blankDefault = makeConfig(true, [{ name: "default", readPrincipals: [], writePrincipals: [" "] }]);
284
+ assert.equal(isNamespacePolicyCovered("default", blankDefault), false);
285
+ const grantedDefault = makeConfig(true, [{ name: "default", readPrincipals: [], writePrincipals: ["alice"] }]);
286
+ assert.equal(isNamespacePolicyCovered("default", grantedDefault), true);
287
+ });
@@ -67,6 +67,31 @@ export function canWriteNamespace(principal: string | undefined, namespace: stri
67
67
  return policy.writePrincipals.includes(principal) || policy.writePrincipals.includes("*");
68
68
  }
69
69
 
70
+ /**
71
+ * Config-time namespace-policy lint (issue #1888 improvement 3). Principal-
72
+ * agnostic mirror of {@link canWriteNamespace}: true when the namespace is
73
+ * writable by AT LEAST ONE principal. When namespace enforcement is off every
74
+ * write is allowed. Otherwise an explicit `namespacePolicies` entry takes
75
+ * precedence (exactly as `canWriteNamespace`): with a matching policy the
76
+ * namespace is covered only if that policy grants at least one non-blank
77
+ * writer — even when the name equals `defaultNamespace`; without a policy it
78
+ * is covered only if it IS the `defaultNamespace`. The `sharedNamespace` is
79
+ * NOT implicitly writable (matching
80
+ * `canWriteNamespace`), and a policy entry with no `writePrincipals` grants
81
+ * nobody. A configured namespace that is NOT covered is writable for no one,
82
+ * so every write to it is rejected by the ACL and dead-lettered — `remnic
83
+ * doctor` warns on that before a session silently loses memory.
84
+ */
85
+ export function isNamespacePolicyCovered(namespace: string, config: PluginConfig): boolean {
86
+ if (!resolveNamespaceCapabilities(config).namespaces) return true;
87
+ // An explicit policy wins over the default fallback (exactly as
88
+ // canWriteNamespace), so a policy naming the default with no writers is NOT
89
+ // covered. Only fall back to defaultNamespace when no policy matches.
90
+ const policy = config.namespacePolicies.find((p) => p.name === namespace);
91
+ if (!policy) return namespace === config.defaultNamespace;
92
+ return policy.writePrincipals.some((w) => w.trim().length > 0);
93
+ }
94
+
70
95
  /**
71
96
  * Default "self" namespace for a principal.
72
97
  *
@@ -102,3 +127,26 @@ export function recallNamespacesForPrincipal(principal: string | undefined, conf
102
127
 
103
128
  return out;
104
129
  }
130
+
131
+ /**
132
+ * Namespaces a principal may attribute a citation to: the default-recall
133
+ * namespaces, every readable policy namespace, and the readable built-in
134
+ * default/shared namespaces — which `defaultRecallNamespaces` can omit even
135
+ * though `canReadNamespace` grants access (#2020).
136
+ */
137
+ export function citationAuthorizedNamespaces(
138
+ principal: string | undefined,
139
+ config: PluginConfig,
140
+ ): string[] {
141
+ return Array.from(
142
+ new Set([
143
+ ...recallNamespacesForPrincipal(principal, config),
144
+ ...config.namespacePolicies
145
+ .filter((p) => canReadNamespace(principal, p.name, config))
146
+ .map((p) => p.name),
147
+ ...[config.defaultNamespace, config.sharedNamespace].filter((ns) =>
148
+ canReadNamespace(principal, ns, config),
149
+ ),
150
+ ]),
151
+ );
152
+ }