@remnic/core 10.0.84 → 10.0.86

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (545) hide show
  1. package/dist/access-admin-ops-surface.js +90 -88
  2. package/dist/access-authorization-probe.js +91 -89
  3. package/dist/access-boundary.d.ts.map +1 -1
  4. package/dist/access-boundary.js +90 -88
  5. package/dist/access-cli.js +198 -194
  6. package/dist/access-cli.js.map +1 -1
  7. package/dist/access-errors.d.ts +14 -0
  8. package/dist/access-errors.d.ts.map +1 -1
  9. package/dist/access-errors.js +5 -1
  10. package/dist/access-extraction-force-flush.js +90 -88
  11. package/dist/access-http-briefing.js +91 -89
  12. package/dist/access-http-query.js +92 -90
  13. package/dist/access-http.d.ts +12 -0
  14. package/dist/access-http.d.ts.map +1 -1
  15. package/dist/access-http.js +119 -116
  16. package/dist/access-identity-continuity-surface.js +90 -88
  17. package/dist/access-lcm-surface.js +90 -88
  18. package/dist/access-mcp-frames.d.ts +29 -0
  19. package/dist/access-mcp-frames.d.ts.map +1 -0
  20. package/dist/access-mcp-frames.js +10 -0
  21. package/dist/access-mcp.d.ts +1 -1
  22. package/dist/access-mcp.d.ts.map +1 -1
  23. package/dist/access-mcp.js +105 -102
  24. package/dist/access-memory-search-fanout.js +2 -2
  25. package/dist/access-namespace-preflight.js +90 -88
  26. package/dist/access-observe-write-category.js +15 -14
  27. package/dist/access-observe-write-surface.d.ts.map +1 -1
  28. package/dist/access-observe-write-surface.js +90 -88
  29. package/dist/access-offline-manifest.js +10 -10
  30. package/dist/access-operations-batch.js +94 -92
  31. package/dist/access-operations.js +101 -99
  32. package/dist/access-recall-concurrency.js +90 -88
  33. package/dist/access-recall-diagnostics.js +2 -2
  34. package/dist/access-recall-response.js +90 -88
  35. package/dist/access-recall-surface.js +90 -88
  36. package/dist/access-schema.d.ts.map +1 -1
  37. package/dist/access-schema.js +10 -9
  38. package/dist/access-service.d.ts +3 -3
  39. package/dist/access-service.d.ts.map +1 -1
  40. package/dist/access-service.js +90 -88
  41. package/dist/access-surface-catalog.js +92 -90
  42. package/dist/access-surface-catalog.js.map +1 -1
  43. package/dist/access-token-capabilities.js +2 -2
  44. package/dist/active-recall.js +38 -38
  45. package/dist/adapters/index.js +7 -7
  46. package/dist/adapters/registry.js +3 -3
  47. package/dist/{auto-sync-C7E6G7Y2.js → auto-sync-3AZW7MXI.js} +6 -6
  48. package/dist/briefing-deadline.d.ts +2 -2
  49. package/dist/briefing-deadline.d.ts.map +1 -1
  50. package/dist/briefing-deadline.js +1 -1
  51. package/dist/briefing.js +25 -25
  52. package/dist/buffer-admission.d.ts +22 -0
  53. package/dist/buffer-admission.d.ts.map +1 -0
  54. package/dist/buffer-admission.js +13 -0
  55. package/dist/buffer-eviction.d.ts +4 -5
  56. package/dist/buffer-eviction.d.ts.map +1 -1
  57. package/dist/buffer-eviction.js +1 -1
  58. package/dist/buffer-persistence.d.ts +8 -4
  59. package/dist/buffer-persistence.d.ts.map +1 -1
  60. package/dist/buffer-persistence.js +1 -1
  61. package/dist/buffer-turn-helpers.d.ts +12 -0
  62. package/dist/buffer-turn-helpers.d.ts.map +1 -1
  63. package/dist/buffer-turn-helpers.js +9 -1
  64. package/dist/buffer-types.d.ts +24 -1
  65. package/dist/buffer-types.d.ts.map +1 -1
  66. package/dist/buffer.d.ts +21 -19
  67. package/dist/buffer.d.ts.map +1 -1
  68. package/dist/buffer.js +17 -13
  69. package/dist/calibration.js +3 -3
  70. package/dist/{capsule-crypto-YO5QJ6L3.js → capsule-crypto-7FJQINUR.js} +2 -2
  71. package/dist/capsule-gunzip-KGBDGF7P.js +11 -0
  72. package/dist/capsule-gunzip-KGBDGF7P.js.map +1 -0
  73. package/dist/capsule-import-gate.d.ts +11 -0
  74. package/dist/capsule-import-gate.d.ts.map +1 -0
  75. package/dist/capsule-import-gate.js +12 -0
  76. package/dist/capsule-import-gate.js.map +1 -0
  77. package/dist/{capsule-merge-XVTQJJ6R.js → capsule-merge-2IIXFXN5.js} +5 -11
  78. package/dist/capsule-merge-2IIXFXN5.js.map +1 -0
  79. package/dist/causal-behavior.js +2 -2
  80. package/dist/causal-chain.js +2 -2
  81. package/dist/causal-consolidation.js +27 -27
  82. package/dist/causal-retrieval.js +2 -2
  83. package/dist/causal-trajectory-graph.js +2 -2
  84. package/dist/causal-trajectory.js +1 -1
  85. package/dist/{chunk-MSIRVXQ3.js → chunk-2G4TV2ML.js} +12 -12
  86. package/dist/{chunk-B74NPUHT.js → chunk-2JG2NI7C.js} +54 -54
  87. package/dist/chunk-2JG2NI7C.js.map +1 -0
  88. package/dist/{chunk-IR4C3DP2.js → chunk-2K3AUDH7.js} +2 -2
  89. package/dist/{chunk-2IW5PT7U.js → chunk-2N4OUSIA.js} +2 -2
  90. package/dist/{chunk-BXLOS5AJ.js → chunk-2NLLXCJG.js} +2 -2
  91. package/dist/{chunk-QZSIDSB2.js → chunk-2NUDHVYM.js} +2 -2
  92. package/dist/{chunk-HPFVZPRH.js → chunk-2U4LMSEX.js} +3 -3
  93. package/dist/{chunk-WHQXWFH7.js → chunk-2XOFVTTT.js} +2 -2
  94. package/dist/{chunk-I6ORDT54.js → chunk-32CA7B6L.js} +2 -2
  95. package/dist/{chunk-T77AX6DG.js → chunk-32YX7EJ3.js} +4 -4
  96. package/dist/{chunk-HLKUZW42.js → chunk-3CTKEXXF.js} +144 -156
  97. package/dist/chunk-3CTKEXXF.js.map +1 -0
  98. package/dist/{chunk-HLWXCDUQ.js → chunk-3DAWHP5K.js} +5 -5
  99. package/dist/{chunk-ZJJFUEPO.js → chunk-3PJEDHLD.js} +2 -2
  100. package/dist/{chunk-PJYK7HH2.js → chunk-3UZ2VMKD.js} +2 -2
  101. package/dist/{chunk-IN4OFAHX.js → chunk-3Y5X6YFH.js} +2 -2
  102. package/dist/{chunk-YUTT4ZTI.js → chunk-45VUHDV2.js} +2 -2
  103. package/dist/{chunk-T6T2RMWW.js → chunk-4GMI5HFH.js} +12 -12
  104. package/dist/{chunk-YOEYL6CH.js → chunk-4LCVA2LW.js} +3 -3
  105. package/dist/{chunk-66JOLMWS.js → chunk-4X7HQKAG.js} +2 -2
  106. package/dist/{chunk-65SKM4BF.js → chunk-4XYAWK5H.js} +2 -2
  107. package/dist/{chunk-H7BZBSP6.js → chunk-52II7PB6.js} +4 -4
  108. package/dist/{chunk-TPX7XXY4.js → chunk-5SOSQTVE.js} +2 -2
  109. package/dist/{chunk-G3T6YMBO.js → chunk-64S6X4IU.js} +7 -7
  110. package/dist/{chunk-BK7AJUWB.js → chunk-6BCWFCDG.js} +7 -7
  111. package/dist/{chunk-V27FK6D6.js → chunk-6XTUZKCZ.js} +2 -2
  112. package/dist/{chunk-KASJJGRG.js → chunk-6ZELOK6O.js} +3 -8
  113. package/dist/chunk-6ZELOK6O.js.map +1 -0
  114. package/dist/{chunk-LECSS7EE.js → chunk-73UZZFJC.js} +3 -3
  115. package/dist/{chunk-4EACCIPO.js → chunk-77PDJ4OE.js} +3 -3
  116. package/dist/{chunk-GQZSGXR6.js → chunk-7GSL4LBG.js} +2 -2
  117. package/dist/{chunk-B6SPPYGJ.js → chunk-7IWRLYFJ.js} +2 -2
  118. package/dist/{chunk-R45L4TV6.js → chunk-7LCGFUMB.js} +6 -6
  119. package/dist/{chunk-A7BM2JTH.js → chunk-AJHNXIQU.js} +2 -2
  120. package/dist/{chunk-2D7BTSDW.js → chunk-ANZZLRUX.js} +2 -2
  121. package/dist/{chunk-ZXF3O7P4.js → chunk-ARRTLPRC.js} +2 -2
  122. package/dist/{chunk-S5CQI2KF.js → chunk-B3GKQ6DU.js} +2 -2
  123. package/dist/{chunk-XRBHIR7Q.js → chunk-B56LORLY.js} +2 -2
  124. package/dist/{chunk-KO3YBHOV.js → chunk-BIVKPQ6Q.js} +3 -3
  125. package/dist/{chunk-QZBTIYKD.js → chunk-BLSHFIR6.js} +7 -6
  126. package/dist/chunk-BLSHFIR6.js.map +1 -0
  127. package/dist/{chunk-54FDG7K7.js → chunk-C2HORX76.js} +3 -3
  128. package/dist/{chunk-WAD32CZG.js → chunk-CC4V7HNP.js} +43 -30
  129. package/dist/chunk-CC4V7HNP.js.map +1 -0
  130. package/dist/{chunk-LGEH473S.js → chunk-CJCTKL6Y.js} +9 -1
  131. package/dist/chunk-CJCTKL6Y.js.map +1 -0
  132. package/dist/{chunk-E33UJHY3.js → chunk-CN7Q3T2J.js} +4 -4
  133. package/dist/{chunk-YUTG35M4.js → chunk-CYCEROPR.js} +3 -3
  134. package/dist/{chunk-TFLPDNQV.js → chunk-D5EV6Y2L.js} +3 -3
  135. package/dist/{chunk-BFBS7OFQ.js → chunk-DC55RIEZ.js} +4 -4
  136. package/dist/{chunk-B4ZU34JQ.js → chunk-DT7SNJH6.js} +3 -3
  137. package/dist/{chunk-VLMBSGQF.js → chunk-DZ7DPDVW.js} +10 -8
  138. package/dist/chunk-DZ7DPDVW.js.map +1 -0
  139. package/dist/{chunk-FVRTCYZ3.js → chunk-EA2LA5RI.js} +2 -2
  140. package/dist/{chunk-WBN66HPI.js → chunk-ELHJK7LM.js} +6 -6
  141. package/dist/{chunk-77R7BQZ2.js → chunk-EQ4U73UH.js} +77 -24
  142. package/dist/chunk-EQ4U73UH.js.map +1 -0
  143. package/dist/{chunk-3JPTUCD7.js → chunk-EUBDYOLD.js} +32 -23
  144. package/dist/chunk-EUBDYOLD.js.map +1 -0
  145. package/dist/{chunk-YNDLCWXS.js → chunk-EZ25VE3G.js} +4 -4
  146. package/dist/{chunk-YAUHSNPB.js → chunk-F74G4KIH.js} +2 -2
  147. package/dist/{chunk-MPGLM2VU.js → chunk-FF3EFLUT.js} +7 -5
  148. package/dist/chunk-FF3EFLUT.js.map +1 -0
  149. package/dist/{chunk-BV2BRHD4.js → chunk-FHGWKODN.js} +2 -2
  150. package/dist/chunk-FKBGK3NC.js +62 -0
  151. package/dist/chunk-FKBGK3NC.js.map +1 -0
  152. package/dist/{chunk-X2KO4FK5.js → chunk-FNFURZBZ.js} +5 -5
  153. package/dist/chunk-FNFURZBZ.js.map +1 -0
  154. package/dist/{chunk-KESJ5XX3.js → chunk-G54BOKZ6.js} +2 -2
  155. package/dist/{chunk-YK7GOPIE.js → chunk-G67EUQAB.js} +9 -7
  156. package/dist/chunk-G67EUQAB.js.map +1 -0
  157. package/dist/{chunk-K36RMINQ.js → chunk-GOZXQNIM.js} +3 -3
  158. package/dist/{chunk-OQSSQOKQ.js → chunk-GULUWOA5.js} +2 -2
  159. package/dist/{chunk-K6RTQZA4.js → chunk-HFUKXOUW.js} +2 -2
  160. package/dist/{chunk-WV254W4V.js → chunk-HLN2HOXX.js} +2 -2
  161. package/dist/{chunk-FUOAIJKQ.js → chunk-IBDWYRDR.js} +3 -3
  162. package/dist/{chunk-Z3DDQXM4.js → chunk-IBGU6AN6.js} +45 -45
  163. package/dist/chunk-IBGU6AN6.js.map +1 -0
  164. package/dist/{chunk-AJG2TAMR.js → chunk-IEEV27BC.js} +2 -2
  165. package/dist/chunk-IGLJNHOX.js +62 -0
  166. package/dist/chunk-IGLJNHOX.js.map +1 -0
  167. package/dist/{chunk-LTDLJCMQ.js → chunk-IJ3OEECW.js} +4 -4
  168. package/dist/{chunk-BK4FBHZ3.js → chunk-IPD5GC7C.js} +3 -3
  169. package/dist/{chunk-KFLD7ZZG.js → chunk-IUKYFTGW.js} +3 -3
  170. package/dist/{chunk-GCAQ3VUJ.js → chunk-JM2YZKCQ.js} +2 -2
  171. package/dist/{chunk-BNQJKWWZ.js → chunk-K3FH3LAQ.js} +4 -4
  172. package/dist/{chunk-LU66I56Q.js → chunk-KVSOEVAF.js} +61 -12
  173. package/dist/chunk-KVSOEVAF.js.map +1 -0
  174. package/dist/chunk-M3BEJJNV.js +31 -0
  175. package/dist/chunk-M3BEJJNV.js.map +1 -0
  176. package/dist/{chunk-RZH5RVJC.js → chunk-MTTYIXSU.js} +2 -2
  177. package/dist/{chunk-XHGYZRVW.js → chunk-NIVKG3DS.js} +5 -5
  178. package/dist/{chunk-VZELUMKK.js → chunk-NQP4ZYGG.js} +2 -2
  179. package/dist/{chunk-7PMOCQOL.js → chunk-NT7F7WJQ.js} +192 -63
  180. package/dist/chunk-NT7F7WJQ.js.map +1 -0
  181. package/dist/{chunk-YO2JEX2Z.js → chunk-OGBQMY46.js} +2 -2
  182. package/dist/{chunk-TLHF75OR.js → chunk-OL553AWT.js} +12 -12
  183. package/dist/{chunk-CLVILSBR.js → chunk-OZNBZJ3S.js} +22 -22
  184. package/dist/{chunk-VUROWXFL.js → chunk-P452SEKO.js} +2 -2
  185. package/dist/{chunk-JX3E4XCW.js → chunk-PDOOUXCS.js} +2 -2
  186. package/dist/{chunk-6QYPL6NI.js → chunk-PKZ274PI.js} +3 -3
  187. package/dist/{chunk-KJCL2FZO.js → chunk-QD5R6U5J.js} +2 -2
  188. package/dist/{chunk-JRVMCZE3.js → chunk-QEYTRFR3.js} +2 -2
  189. package/dist/{chunk-VKDAJJQP.js → chunk-QEZ3DW5O.js} +11 -11
  190. package/dist/{chunk-WYPCJK6K.js → chunk-QKERFEJS.js} +2 -2
  191. package/dist/{chunk-BDN3TDGV.js → chunk-QKES7GU6.js} +2 -2
  192. package/dist/{chunk-PCQWKMOL.js → chunk-QNSZYTSG.js} +2 -2
  193. package/dist/chunk-QV2VZKD5.js +31 -0
  194. package/dist/chunk-QV2VZKD5.js.map +1 -0
  195. package/dist/{chunk-IZJQNDGI.js → chunk-R6HMAIKM.js} +2 -2
  196. package/dist/{chunk-CIIHIAJ2.js → chunk-ROGO7FRA.js} +6 -5
  197. package/dist/{chunk-CIIHIAJ2.js.map → chunk-ROGO7FRA.js.map} +1 -1
  198. package/dist/{chunk-NUSAAN75.js → chunk-ROKDHO74.js} +2 -2
  199. package/dist/{chunk-D5SSBCYY.js → chunk-RWGRSKN5.js} +7 -5
  200. package/dist/chunk-RWGRSKN5.js.map +1 -0
  201. package/dist/{chunk-FF6N7BXC.js → chunk-S45INSV3.js} +4 -4
  202. package/dist/{chunk-2RUTN7PR.js → chunk-S7GJNA3K.js} +2 -2
  203. package/dist/{chunk-XT45WCKX.js → chunk-SYKJBS7S.js} +10 -10
  204. package/dist/{chunk-5BE3FLKL.js → chunk-TAUHAP5J.js} +4 -4
  205. package/dist/{chunk-RJWL3RHB.js → chunk-TFEHSPGQ.js} +2 -2
  206. package/dist/{chunk-XYP5WBDO.js → chunk-TQ4SCPGQ.js} +76 -60
  207. package/dist/chunk-TQ4SCPGQ.js.map +1 -0
  208. package/dist/{chunk-K3B72DKJ.js → chunk-TRMZHGIX.js} +8 -8
  209. package/dist/{chunk-WBDIZWJQ.js → chunk-TSS3D7ZY.js} +2 -2
  210. package/dist/{chunk-6LCWKS62.js → chunk-UAUV3BWS.js} +104 -121
  211. package/dist/chunk-UAUV3BWS.js.map +1 -0
  212. package/dist/{chunk-KQUSP6LB.js → chunk-UDKWFDV2.js} +1 -1
  213. package/dist/chunk-UDKWFDV2.js.map +1 -0
  214. package/dist/{chunk-HQPFACXO.js → chunk-UH3FPX3L.js} +2 -2
  215. package/dist/{chunk-GGJFRVRD.js → chunk-US7KPQA5.js} +2 -2
  216. package/dist/{chunk-FJ2VJTGA.js → chunk-UWRHHRDK.js} +3 -3
  217. package/dist/{chunk-4KLQI3L2.js → chunk-UXXK523X.js} +40 -2
  218. package/dist/chunk-UXXK523X.js.map +1 -0
  219. package/dist/{chunk-SDESKFKT.js → chunk-UYHDMCY2.js} +2 -2
  220. package/dist/{chunk-3T3VHXUH.js → chunk-VKILERSL.js} +2 -2
  221. package/dist/{chunk-2TGIKMMZ.js → chunk-WXDTOE6F.js} +2 -2
  222. package/dist/{chunk-KQLBXUUQ.js → chunk-WYG5UNDY.js} +2 -2
  223. package/dist/{chunk-DQEMWVMT.js → chunk-X7Y7WX73.js} +1 -1
  224. package/dist/{chunk-MPDLLLOG.js → chunk-XO23OKMK.js} +9 -5
  225. package/dist/chunk-XO23OKMK.js.map +1 -0
  226. package/dist/{chunk-WC475JOG.js → chunk-XU37EJTW.js} +24 -24
  227. package/dist/chunk-XU37EJTW.js.map +1 -0
  228. package/dist/{chunk-FZVROZKC.js → chunk-XVZA6VXC.js} +4 -4
  229. package/dist/{chunk-QA3Y2O6H.js → chunk-YAVIBVCU.js} +2 -2
  230. package/dist/{chunk-2XJZLSXE.js → chunk-YL4UKMD7.js} +124 -58
  231. package/dist/chunk-YL4UKMD7.js.map +1 -0
  232. package/dist/{chunk-VPEIWMUT.js → chunk-YLTU2DC4.js} +2 -2
  233. package/dist/{chunk-HWHNQVRV.js → chunk-YMJRLT7S.js} +28 -8
  234. package/dist/chunk-YMJRLT7S.js.map +1 -0
  235. package/dist/{chunk-EBOHFZI4.js → chunk-YRZPBN46.js} +3 -3
  236. package/dist/{chunk-FMFCQRDM.js → chunk-ZANNIXXE.js} +3 -3
  237. package/dist/{chunk-HQGATKG2.js → chunk-ZBFLV657.js} +3 -3
  238. package/dist/{chunk-6L63IN3M.js → chunk-ZOJUWVAU.js} +1 -1
  239. package/dist/cli.js +144 -141
  240. package/dist/coding/export-okf-codegraph.js +24 -24
  241. package/dist/coding/pre-action-gate.js +2 -2
  242. package/dist/compounding/engine.js +26 -26
  243. package/dist/config.js +35 -35
  244. package/dist/connectors/codex-materialize-runner.js +24 -24
  245. package/dist/connectors/index.js +28 -28
  246. package/dist/contradiction/index.js +4 -4
  247. package/dist/convergence-refresh.js +26 -26
  248. package/dist/corpus-watermark.js +28 -28
  249. package/dist/dashboard-runtime.js +2 -2
  250. package/dist/deep-recall-config.js +2 -2
  251. package/dist/deep-recall-http-glue.js +12 -12
  252. package/dist/entity-retrieval.js +25 -25
  253. package/dist/event-order-recall.js +2 -2
  254. package/dist/explicit-capture.js +6 -6
  255. package/dist/external-wiki-access.js +91 -89
  256. package/dist/extraction-evidence-class.js +2 -2
  257. package/dist/extraction-quote-grounding.d.ts +5 -1
  258. package/dist/extraction-quote-grounding.d.ts.map +1 -1
  259. package/dist/extraction-quote-grounding.js +1 -1
  260. package/dist/extraction-source-grounding-rules.d.ts +3 -1
  261. package/dist/extraction-source-grounding-rules.d.ts.map +1 -1
  262. package/dist/extraction-source-grounding-rules.js +2 -2
  263. package/dist/extraction-source-grounding.d.ts +1 -1
  264. package/dist/extraction-source-grounding.d.ts.map +1 -1
  265. package/dist/extraction-source-grounding.js +5 -5
  266. package/dist/extraction-span-materialize.js +2 -2
  267. package/dist/extraction.d.ts.map +1 -1
  268. package/dist/extraction.js +43 -43
  269. package/dist/{first-start-migration-QVD22WWS.js → first-start-migration-A6PHIBUQ.js} +4 -4
  270. package/dist/{graph-edge-decay-CXTNJ7IQ.js → graph-edge-decay-EKWXRBWF.js} +5 -5
  271. package/dist/graph-edge-decay-EKWXRBWF.js.map +1 -0
  272. package/dist/graph-jsonl.js +3 -3
  273. package/dist/graph-snapshot.js +3 -3
  274. package/dist/graph.js +2 -2
  275. package/dist/harmonic-retrieval.js +24 -24
  276. package/dist/index.js +255 -251
  277. package/dist/lcm/engine.js +2 -2
  278. package/dist/lcm/index.js +5 -5
  279. package/dist/local-llm.js +3 -3
  280. package/dist/location/index.js +28 -28
  281. package/dist/maintenance/memory-governance.js +24 -24
  282. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +24 -24
  283. package/dist/maintenance/rebuild-memory-projection-runner.js +26 -26
  284. package/dist/maintenance/rebuild-memory-projection.js +25 -25
  285. package/dist/memory-browse-http-glue.js +2 -2
  286. package/dist/memory-browse-operations.js +91 -89
  287. package/dist/memory-browse.js +5 -5
  288. package/dist/memory-subject.js +2 -2
  289. package/dist/namespaces/migrate.js +25 -25
  290. package/dist/namespaces/search.d.ts +9 -0
  291. package/dist/namespaces/search.d.ts.map +1 -1
  292. package/dist/namespaces/search.js +13 -7
  293. package/dist/namespaces/storage.js +24 -24
  294. package/dist/offline-sync-changeset-generations.js +3 -3
  295. package/dist/offline-sync-embedding-generation.js +2 -2
  296. package/dist/offline-sync-impression-drain.js +2 -2
  297. package/dist/offline-sync-snapshot-stream.js +6 -6
  298. package/dist/offline-sync.js +5 -5
  299. package/dist/operator-doctor-corpus.js +31 -31
  300. package/dist/operator-doctor-replica.js +4 -4
  301. package/dist/operator-toolkit.js +49 -49
  302. package/dist/orchestration/backlog-scheduler.d.ts +3 -2
  303. package/dist/orchestration/backlog-scheduler.d.ts.map +1 -1
  304. package/dist/orchestration/backlog-scheduler.js +209 -205
  305. package/dist/orchestration/backlog-scheduler.js.map +1 -1
  306. package/dist/orchestration/buffer-drain-runner.d.ts +6 -1
  307. package/dist/orchestration/buffer-drain-runner.d.ts.map +1 -1
  308. package/dist/orchestration/buffer-drain-runner.js +199 -195
  309. package/dist/orchestration/extraction-persist.d.ts.map +1 -1
  310. package/dist/orchestration/fact-dedup-window.d.ts +1 -4
  311. package/dist/orchestration/fact-dedup-window.d.ts.map +1 -1
  312. package/dist/orchestration/maintenance.js +41 -41
  313. package/dist/orchestration/turn-ingestion.d.ts +2 -9
  314. package/dist/orchestration/turn-ingestion.d.ts.map +1 -1
  315. package/dist/orchestrator.js +198 -194
  316. package/dist/provenance.js +2 -2
  317. package/dist/qmd.js +4 -4
  318. package/dist/recall-navigation-http-glue.js +2 -2
  319. package/dist/recall-navigation-operations.js +91 -89
  320. package/dist/recall-navigation.js +90 -88
  321. package/dist/recall-state-view-admission.js +5 -5
  322. package/dist/recall-why-service.js +5 -5
  323. package/dist/reconcile/manifest.js +2 -2
  324. package/dist/replica-divergence.js +3 -3
  325. package/dist/{resolution-BNWE5Y25.js → resolution-23ZBDM6A.js} +5 -5
  326. package/dist/resolution-23ZBDM6A.js.map +1 -0
  327. package/dist/resume-bundles.js +36 -36
  328. package/dist/salvage-envelope.js +4 -4
  329. package/dist/search/factory.js +6 -6
  330. package/dist/search/index.js +12 -12
  331. package/dist/semantic-consolidation.js +25 -25
  332. package/dist/semantic-rule-promotion.js +24 -24
  333. package/dist/semantic-rule-verifier.js +24 -24
  334. package/dist/source-agent-qualifier.d.ts +2 -0
  335. package/dist/source-agent-qualifier.d.ts.map +1 -1
  336. package/dist/source-agent-qualifier.js +36 -36
  337. package/dist/standup/build.js +25 -25
  338. package/dist/storage/buffer-drain-claims.d.ts +18 -6
  339. package/dist/storage/buffer-drain-claims.d.ts.map +1 -1
  340. package/dist/storage/buffer-drain-claims.js +2 -2
  341. package/dist/storage/buffer-session-files.js +2 -2
  342. package/dist/storage/content-hash-index.d.ts +8 -0
  343. package/dist/storage/content-hash-index.d.ts.map +1 -1
  344. package/dist/storage.d.ts +10 -1
  345. package/dist/storage.d.ts.map +1 -1
  346. package/dist/storage.js +23 -23
  347. package/dist/subject-config.js +3 -3
  348. package/dist/summarizer.js +4 -4
  349. package/dist/support-passport/index.js +93 -91
  350. package/dist/tokens.js +3 -3
  351. package/dist/transfer/autodetect.js +1 -1
  352. package/dist/transfer/backup.js +2 -2
  353. package/dist/transfer/capsule-export.js +3 -3
  354. package/dist/transfer/capsule-gunzip.d.ts +14 -0
  355. package/dist/transfer/capsule-gunzip.d.ts.map +1 -0
  356. package/dist/transfer/capsule-import.d.ts.map +1 -1
  357. package/dist/transfer/capsule-import.js +3 -2
  358. package/dist/transfer/capsule-merge.d.ts.map +1 -1
  359. package/dist/transfer/export-okf.js +24 -24
  360. package/dist/verified-recall.js +24 -24
  361. package/dist/who-knows-cli.js +26 -26
  362. package/dist/who-knows.js +25 -25
  363. package/dist/write-envelope.js +3 -3
  364. package/package.json +2 -2
  365. package/src/access-boundary.ts +15 -0
  366. package/src/access-errors.ts +22 -0
  367. package/src/access-fleet-wide-work-peer.test.ts +236 -0
  368. package/src/access-http-peer-fleet-wide.test.ts +192 -0
  369. package/src/access-http.test.ts +249 -4
  370. package/src/access-http.ts +114 -39
  371. package/src/access-mcp-frames.test.ts +47 -0
  372. package/src/access-mcp-frames.ts +74 -0
  373. package/src/access-mcp.test.ts +210 -0
  374. package/src/access-mcp.ts +47 -37
  375. package/src/access-observe-replay-durability.test.ts +40 -4
  376. package/src/access-observe-write-surface.ts +4 -4
  377. package/src/access-operations-batch.ts +23 -12
  378. package/src/access-proto-injection.test.ts +340 -0
  379. package/src/access-schema.ts +31 -5
  380. package/src/access-service-capsule-import.test.ts +235 -0
  381. package/src/access-service.ts +6 -45
  382. package/src/backlog-scheduler.test.ts +443 -3
  383. package/src/briefing-deadline.ts +5 -4
  384. package/src/buffer-admission.ts +45 -0
  385. package/src/buffer-eviction-backpressure.test.ts +211 -0
  386. package/src/buffer-eviction.ts +8 -14
  387. package/src/buffer-incremental-persistence.test.ts +25 -37
  388. package/src/buffer-persistence.ts +15 -6
  389. package/src/buffer-session.test.ts +32 -16
  390. package/src/buffer-turn-helpers.ts +47 -0
  391. package/src/buffer-types.ts +28 -1
  392. package/src/buffer.ts +83 -91
  393. package/src/capsule-import-gate.ts +109 -0
  394. package/src/cli.ts +4 -4
  395. package/src/extraction-quote-grounding.test.ts +125 -0
  396. package/src/extraction-quote-grounding.ts +99 -25
  397. package/src/extraction-source-grounding-rules.ts +6 -1
  398. package/src/extraction-source-grounding.ts +2 -0
  399. package/src/extraction.ts +3 -4
  400. package/src/fact-dedup-window.test.ts +103 -20
  401. package/src/namespaces/search.test.ts +480 -1
  402. package/src/namespaces/search.ts +93 -10
  403. package/src/orchestration/backlog-scheduler.ts +13 -12
  404. package/src/orchestration/buffer-drain-runner.ts +40 -16
  405. package/src/orchestration/extraction-persist.ts +2 -10
  406. package/src/orchestration/fact-dedup-window.ts +5 -12
  407. package/src/orchestration/turn-ingestion.ts +38 -39
  408. package/src/recall-navigation-operations.ts +9 -2
  409. package/src/source-agent-qualifier.ts +3 -0
  410. package/src/storage/buffer-drain-claims.test.ts +330 -6
  411. package/src/storage/buffer-drain-claims.ts +226 -80
  412. package/src/storage/buffer-session-files.ts +2 -2
  413. package/src/storage/content-hash-index.ts +9 -0
  414. package/src/storage.ts +15 -0
  415. package/src/transfer/capsule-gunzip.ts +39 -0
  416. package/src/transfer/capsule-import.test.ts +73 -0
  417. package/src/transfer/capsule-import.ts +2 -2
  418. package/src/transfer/capsule-merge.test.ts +34 -0
  419. package/src/transfer/capsule-merge.ts +2 -10
  420. package/dist/capsule-merge-XVTQJJ6R.js.map +0 -1
  421. package/dist/chunk-2XJZLSXE.js.map +0 -1
  422. package/dist/chunk-3JPTUCD7.js.map +0 -1
  423. package/dist/chunk-4KLQI3L2.js.map +0 -1
  424. package/dist/chunk-6LCWKS62.js.map +0 -1
  425. package/dist/chunk-77R7BQZ2.js.map +0 -1
  426. package/dist/chunk-7PMOCQOL.js.map +0 -1
  427. package/dist/chunk-B74NPUHT.js.map +0 -1
  428. package/dist/chunk-D5SSBCYY.js.map +0 -1
  429. package/dist/chunk-HLKUZW42.js.map +0 -1
  430. package/dist/chunk-HWHNQVRV.js.map +0 -1
  431. package/dist/chunk-KASJJGRG.js.map +0 -1
  432. package/dist/chunk-KQUSP6LB.js.map +0 -1
  433. package/dist/chunk-LGEH473S.js.map +0 -1
  434. package/dist/chunk-LU66I56Q.js.map +0 -1
  435. package/dist/chunk-MPDLLLOG.js.map +0 -1
  436. package/dist/chunk-MPGLM2VU.js.map +0 -1
  437. package/dist/chunk-QZBTIYKD.js.map +0 -1
  438. package/dist/chunk-VLMBSGQF.js.map +0 -1
  439. package/dist/chunk-WAD32CZG.js.map +0 -1
  440. package/dist/chunk-WC475JOG.js.map +0 -1
  441. package/dist/chunk-X2KO4FK5.js.map +0 -1
  442. package/dist/chunk-XYP5WBDO.js.map +0 -1
  443. package/dist/chunk-YK7GOPIE.js.map +0 -1
  444. package/dist/chunk-Z3DDQXM4.js.map +0 -1
  445. /package/dist/{capsule-crypto-YO5QJ6L3.js.map → access-mcp-frames.js.map} +0 -0
  446. /package/dist/{auto-sync-C7E6G7Y2.js.map → auto-sync-3AZW7MXI.js.map} +0 -0
  447. /package/dist/{graph-edge-decay-CXTNJ7IQ.js.map → buffer-admission.js.map} +0 -0
  448. /package/dist/{resolution-BNWE5Y25.js.map → capsule-crypto-7FJQINUR.js.map} +0 -0
  449. /package/dist/{chunk-MSIRVXQ3.js.map → chunk-2G4TV2ML.js.map} +0 -0
  450. /package/dist/{chunk-IR4C3DP2.js.map → chunk-2K3AUDH7.js.map} +0 -0
  451. /package/dist/{chunk-2IW5PT7U.js.map → chunk-2N4OUSIA.js.map} +0 -0
  452. /package/dist/{chunk-BXLOS5AJ.js.map → chunk-2NLLXCJG.js.map} +0 -0
  453. /package/dist/{chunk-QZSIDSB2.js.map → chunk-2NUDHVYM.js.map} +0 -0
  454. /package/dist/{chunk-HPFVZPRH.js.map → chunk-2U4LMSEX.js.map} +0 -0
  455. /package/dist/{chunk-WHQXWFH7.js.map → chunk-2XOFVTTT.js.map} +0 -0
  456. /package/dist/{chunk-I6ORDT54.js.map → chunk-32CA7B6L.js.map} +0 -0
  457. /package/dist/{chunk-T77AX6DG.js.map → chunk-32YX7EJ3.js.map} +0 -0
  458. /package/dist/{chunk-HLWXCDUQ.js.map → chunk-3DAWHP5K.js.map} +0 -0
  459. /package/dist/{chunk-ZJJFUEPO.js.map → chunk-3PJEDHLD.js.map} +0 -0
  460. /package/dist/{chunk-PJYK7HH2.js.map → chunk-3UZ2VMKD.js.map} +0 -0
  461. /package/dist/{chunk-IN4OFAHX.js.map → chunk-3Y5X6YFH.js.map} +0 -0
  462. /package/dist/{chunk-YUTT4ZTI.js.map → chunk-45VUHDV2.js.map} +0 -0
  463. /package/dist/{chunk-T6T2RMWW.js.map → chunk-4GMI5HFH.js.map} +0 -0
  464. /package/dist/{chunk-YOEYL6CH.js.map → chunk-4LCVA2LW.js.map} +0 -0
  465. /package/dist/{chunk-66JOLMWS.js.map → chunk-4X7HQKAG.js.map} +0 -0
  466. /package/dist/{chunk-65SKM4BF.js.map → chunk-4XYAWK5H.js.map} +0 -0
  467. /package/dist/{chunk-H7BZBSP6.js.map → chunk-52II7PB6.js.map} +0 -0
  468. /package/dist/{chunk-TPX7XXY4.js.map → chunk-5SOSQTVE.js.map} +0 -0
  469. /package/dist/{chunk-G3T6YMBO.js.map → chunk-64S6X4IU.js.map} +0 -0
  470. /package/dist/{chunk-BK7AJUWB.js.map → chunk-6BCWFCDG.js.map} +0 -0
  471. /package/dist/{chunk-V27FK6D6.js.map → chunk-6XTUZKCZ.js.map} +0 -0
  472. /package/dist/{chunk-LECSS7EE.js.map → chunk-73UZZFJC.js.map} +0 -0
  473. /package/dist/{chunk-4EACCIPO.js.map → chunk-77PDJ4OE.js.map} +0 -0
  474. /package/dist/{chunk-GQZSGXR6.js.map → chunk-7GSL4LBG.js.map} +0 -0
  475. /package/dist/{chunk-B6SPPYGJ.js.map → chunk-7IWRLYFJ.js.map} +0 -0
  476. /package/dist/{chunk-R45L4TV6.js.map → chunk-7LCGFUMB.js.map} +0 -0
  477. /package/dist/{chunk-A7BM2JTH.js.map → chunk-AJHNXIQU.js.map} +0 -0
  478. /package/dist/{chunk-2D7BTSDW.js.map → chunk-ANZZLRUX.js.map} +0 -0
  479. /package/dist/{chunk-ZXF3O7P4.js.map → chunk-ARRTLPRC.js.map} +0 -0
  480. /package/dist/{chunk-S5CQI2KF.js.map → chunk-B3GKQ6DU.js.map} +0 -0
  481. /package/dist/{chunk-XRBHIR7Q.js.map → chunk-B56LORLY.js.map} +0 -0
  482. /package/dist/{chunk-KO3YBHOV.js.map → chunk-BIVKPQ6Q.js.map} +0 -0
  483. /package/dist/{chunk-54FDG7K7.js.map → chunk-C2HORX76.js.map} +0 -0
  484. /package/dist/{chunk-E33UJHY3.js.map → chunk-CN7Q3T2J.js.map} +0 -0
  485. /package/dist/{chunk-YUTG35M4.js.map → chunk-CYCEROPR.js.map} +0 -0
  486. /package/dist/{chunk-TFLPDNQV.js.map → chunk-D5EV6Y2L.js.map} +0 -0
  487. /package/dist/{chunk-BFBS7OFQ.js.map → chunk-DC55RIEZ.js.map} +0 -0
  488. /package/dist/{chunk-B4ZU34JQ.js.map → chunk-DT7SNJH6.js.map} +0 -0
  489. /package/dist/{chunk-FVRTCYZ3.js.map → chunk-EA2LA5RI.js.map} +0 -0
  490. /package/dist/{chunk-WBN66HPI.js.map → chunk-ELHJK7LM.js.map} +0 -0
  491. /package/dist/{chunk-YNDLCWXS.js.map → chunk-EZ25VE3G.js.map} +0 -0
  492. /package/dist/{chunk-YAUHSNPB.js.map → chunk-F74G4KIH.js.map} +0 -0
  493. /package/dist/{chunk-BV2BRHD4.js.map → chunk-FHGWKODN.js.map} +0 -0
  494. /package/dist/{chunk-KESJ5XX3.js.map → chunk-G54BOKZ6.js.map} +0 -0
  495. /package/dist/{chunk-K36RMINQ.js.map → chunk-GOZXQNIM.js.map} +0 -0
  496. /package/dist/{chunk-OQSSQOKQ.js.map → chunk-GULUWOA5.js.map} +0 -0
  497. /package/dist/{chunk-K6RTQZA4.js.map → chunk-HFUKXOUW.js.map} +0 -0
  498. /package/dist/{chunk-WV254W4V.js.map → chunk-HLN2HOXX.js.map} +0 -0
  499. /package/dist/{chunk-FUOAIJKQ.js.map → chunk-IBDWYRDR.js.map} +0 -0
  500. /package/dist/{chunk-AJG2TAMR.js.map → chunk-IEEV27BC.js.map} +0 -0
  501. /package/dist/{chunk-LTDLJCMQ.js.map → chunk-IJ3OEECW.js.map} +0 -0
  502. /package/dist/{chunk-BK4FBHZ3.js.map → chunk-IPD5GC7C.js.map} +0 -0
  503. /package/dist/{chunk-KFLD7ZZG.js.map → chunk-IUKYFTGW.js.map} +0 -0
  504. /package/dist/{chunk-GCAQ3VUJ.js.map → chunk-JM2YZKCQ.js.map} +0 -0
  505. /package/dist/{chunk-BNQJKWWZ.js.map → chunk-K3FH3LAQ.js.map} +0 -0
  506. /package/dist/{chunk-RZH5RVJC.js.map → chunk-MTTYIXSU.js.map} +0 -0
  507. /package/dist/{chunk-XHGYZRVW.js.map → chunk-NIVKG3DS.js.map} +0 -0
  508. /package/dist/{chunk-VZELUMKK.js.map → chunk-NQP4ZYGG.js.map} +0 -0
  509. /package/dist/{chunk-YO2JEX2Z.js.map → chunk-OGBQMY46.js.map} +0 -0
  510. /package/dist/{chunk-TLHF75OR.js.map → chunk-OL553AWT.js.map} +0 -0
  511. /package/dist/{chunk-CLVILSBR.js.map → chunk-OZNBZJ3S.js.map} +0 -0
  512. /package/dist/{chunk-VUROWXFL.js.map → chunk-P452SEKO.js.map} +0 -0
  513. /package/dist/{chunk-JX3E4XCW.js.map → chunk-PDOOUXCS.js.map} +0 -0
  514. /package/dist/{chunk-6QYPL6NI.js.map → chunk-PKZ274PI.js.map} +0 -0
  515. /package/dist/{chunk-KJCL2FZO.js.map → chunk-QD5R6U5J.js.map} +0 -0
  516. /package/dist/{chunk-JRVMCZE3.js.map → chunk-QEYTRFR3.js.map} +0 -0
  517. /package/dist/{chunk-VKDAJJQP.js.map → chunk-QEZ3DW5O.js.map} +0 -0
  518. /package/dist/{chunk-WYPCJK6K.js.map → chunk-QKERFEJS.js.map} +0 -0
  519. /package/dist/{chunk-BDN3TDGV.js.map → chunk-QKES7GU6.js.map} +0 -0
  520. /package/dist/{chunk-PCQWKMOL.js.map → chunk-QNSZYTSG.js.map} +0 -0
  521. /package/dist/{chunk-IZJQNDGI.js.map → chunk-R6HMAIKM.js.map} +0 -0
  522. /package/dist/{chunk-NUSAAN75.js.map → chunk-ROKDHO74.js.map} +0 -0
  523. /package/dist/{chunk-FF6N7BXC.js.map → chunk-S45INSV3.js.map} +0 -0
  524. /package/dist/{chunk-2RUTN7PR.js.map → chunk-S7GJNA3K.js.map} +0 -0
  525. /package/dist/{chunk-XT45WCKX.js.map → chunk-SYKJBS7S.js.map} +0 -0
  526. /package/dist/{chunk-5BE3FLKL.js.map → chunk-TAUHAP5J.js.map} +0 -0
  527. /package/dist/{chunk-RJWL3RHB.js.map → chunk-TFEHSPGQ.js.map} +0 -0
  528. /package/dist/{chunk-K3B72DKJ.js.map → chunk-TRMZHGIX.js.map} +0 -0
  529. /package/dist/{chunk-WBDIZWJQ.js.map → chunk-TSS3D7ZY.js.map} +0 -0
  530. /package/dist/{chunk-HQPFACXO.js.map → chunk-UH3FPX3L.js.map} +0 -0
  531. /package/dist/{chunk-GGJFRVRD.js.map → chunk-US7KPQA5.js.map} +0 -0
  532. /package/dist/{chunk-FJ2VJTGA.js.map → chunk-UWRHHRDK.js.map} +0 -0
  533. /package/dist/{chunk-SDESKFKT.js.map → chunk-UYHDMCY2.js.map} +0 -0
  534. /package/dist/{chunk-3T3VHXUH.js.map → chunk-VKILERSL.js.map} +0 -0
  535. /package/dist/{chunk-2TGIKMMZ.js.map → chunk-WXDTOE6F.js.map} +0 -0
  536. /package/dist/{chunk-KQLBXUUQ.js.map → chunk-WYG5UNDY.js.map} +0 -0
  537. /package/dist/{chunk-DQEMWVMT.js.map → chunk-X7Y7WX73.js.map} +0 -0
  538. /package/dist/{chunk-FZVROZKC.js.map → chunk-XVZA6VXC.js.map} +0 -0
  539. /package/dist/{chunk-QA3Y2O6H.js.map → chunk-YAVIBVCU.js.map} +0 -0
  540. /package/dist/{chunk-VPEIWMUT.js.map → chunk-YLTU2DC4.js.map} +0 -0
  541. /package/dist/{chunk-EBOHFZI4.js.map → chunk-YRZPBN46.js.map} +0 -0
  542. /package/dist/{chunk-FMFCQRDM.js.map → chunk-ZANNIXXE.js.map} +0 -0
  543. /package/dist/{chunk-HQGATKG2.js.map → chunk-ZBFLV657.js.map} +0 -0
  544. /package/dist/{chunk-6L63IN3M.js.map → chunk-ZOJUWVAU.js.map} +0 -0
  545. /package/dist/{first-start-migration-QVD22WWS.js.map → first-start-migration-A6PHIBUQ.js.map} +0 -0
@@ -3,12 +3,14 @@ import test from "node:test";
3
3
  import os from "node:os";
4
4
  import path from "node:path";
5
5
  import { mkdtemp, rm } from "node:fs/promises";
6
- import { NamespaceSearchRouter, normalizeQmdResultPath } from "./search.js";
6
+ import { setImmediate } from "node:timers/promises";
7
+ import { NamespaceSearchRouter, NAMESPACE_SEARCH_LEG_TIMEOUT_MS, normalizeQmdResultPath } from "./search.js";
7
8
  import { MaintenanceScheduler } from "../orchestration/maintenance.js";
8
9
  import type { NamespaceCatalog } from "./catalog.js";
9
10
  import type {
10
11
  SearchBackend,
11
12
  SearchBackendStatus,
13
+ SearchDegradation,
12
14
  SearchExecutionOptions,
13
15
  SearchQueryOptions,
14
16
  } from "../search/port.js";
@@ -432,6 +434,144 @@ test("searchAcrossNamespaces preserves same path results from distinct namespace
432
434
  ]);
433
435
  });
434
436
 
437
+ class StalledBackend extends FakeBackend {
438
+ override async search(): Promise<QmdSearchResult[]> {
439
+ return new Promise<QmdSearchResult[]>(() => {});
440
+ }
441
+ }
442
+
443
+ test("searchAcrossNamespaces degrades only the namespace whose leg never settles", async (t) => {
444
+ const degradations: SearchDegradation[] = [];
445
+ const router = new NamespaceSearchRouter(
446
+ config(),
447
+ { storageFor: async (namespace: string) => ({ dir: `/tmp/remnic/${namespace}` }) },
448
+ (scopedConfig) =>
449
+ scopedConfig.memoryDir.endsWith("/stuck")
450
+ ? new StalledBackend(false)
451
+ : new FakeBackend(false, [
452
+ { path: "facts/a.md", docid: "a", score: 0.9, snippet: "main" },
453
+ ]),
454
+ );
455
+ t.mock.timers.enable({ apis: ["setTimeout"] });
456
+ const call = router.searchAcrossNamespaces({
457
+ query: "a",
458
+ namespaces: ["main", "stuck"],
459
+ maxResults: 10,
460
+ execution: { onDegradation: (degradation) => degradations.push(degradation) },
461
+ });
462
+ let outcome: "settled" | "rejected" | "stalled" | undefined;
463
+ const guard = new Promise<"stalled">((resolve) => {
464
+ setTimeout(() => resolve("stalled"), 60_000);
465
+ });
466
+ void Promise.race([
467
+ call.then(() => "settled" as const, () => "rejected" as const),
468
+ guard,
469
+ ]).then((value) => {
470
+ outcome = value;
471
+ });
472
+ await setImmediate();
473
+ t.mock.timers.tick(NAMESPACE_SEARCH_LEG_TIMEOUT_MS);
474
+ await setImmediate();
475
+ if (outcome === undefined) {
476
+ t.mock.timers.tick(60_000);
477
+ await setImmediate();
478
+ }
479
+ assert.equal(outcome, "settled", "a stalled namespace leg must not hold the whole search");
480
+ const results = await call;
481
+ assert.deepEqual(results.map((result) => result.snippet), ["main"]);
482
+ assert.equal(degradations.length, 1);
483
+ assert.equal(degradations[0].backend, "qmd");
484
+ assert.equal(degradations[0].code, "deadline_exceeded");
485
+ assert.match(degradations[0].detail ?? "", /stuck/);
486
+ });
487
+
488
+ test("searchAcrossNamespaces still rejects when the caller aborts", async () => {
489
+ const degradations: SearchDegradation[] = [];
490
+ const router = new NamespaceSearchRouter(
491
+ config(),
492
+ { storageFor: async (namespace: string) => ({ dir: `/tmp/remnic/${namespace}` }) },
493
+ () => new StalledBackend(false),
494
+ );
495
+ const caller = new AbortController();
496
+ const call = router.searchAcrossNamespaces({
497
+ query: "a",
498
+ namespaces: ["main"],
499
+ maxResults: 10,
500
+ execution: {
501
+ signal: caller.signal,
502
+ onDegradation: (degradation) => degradations.push(degradation),
503
+ },
504
+ });
505
+ caller.abort();
506
+ await assert.rejects(call, { message: "operation aborted" });
507
+ assert.equal(degradations.length, 0, "a caller abort is not a backend degradation");
508
+ });
509
+
510
+ test("searchAcrossNamespaces propagates backend errors instead of masking them", async () => {
511
+ const degradations: SearchDegradation[] = [];
512
+ class ThrowingBackend extends FakeBackend {
513
+ override async search(): Promise<QmdSearchResult[]> {
514
+ throw new Error("boom");
515
+ }
516
+ }
517
+ const router = new NamespaceSearchRouter(
518
+ config(),
519
+ { storageFor: async (namespace: string) => ({ dir: `/tmp/remnic/${namespace}` }) },
520
+ () => new ThrowingBackend(false),
521
+ );
522
+ const call = router.searchAcrossNamespaces({
523
+ query: "a",
524
+ namespaces: ["main"],
525
+ maxResults: 10,
526
+ execution: { onDegradation: (degradation) => degradations.push(degradation) },
527
+ });
528
+ await assert.rejects(call, { message: "boom" });
529
+ assert.equal(degradations.length, 0, "a backend error is not a deadline");
530
+ });
531
+
532
+ test("searchAcrossNamespaces hands each leg its deadline signal", async (t) => {
533
+ const signals = new Map<string, AbortSignal | undefined>();
534
+ const degradations: SearchDegradation[] = [];
535
+ class RecordingBackend extends FakeBackend {
536
+ constructor(private readonly name: string) {
537
+ super(false);
538
+ }
539
+ override async search(
540
+ _query: string,
541
+ _collection?: string,
542
+ _maxResults?: number,
543
+ _options?: SearchQueryOptions,
544
+ execution?: SearchExecutionOptions,
545
+ ): Promise<QmdSearchResult[]> {
546
+ signals.set(this.name, execution?.signal);
547
+ if (this.name === "stuck") return new Promise<QmdSearchResult[]>(() => {});
548
+ return [{ path: "facts/a.md", docid: "a", score: 0.9, snippet: this.name }];
549
+ }
550
+ }
551
+ const router = new NamespaceSearchRouter(
552
+ config(),
553
+ { storageFor: async (namespace: string) => ({ dir: `/tmp/remnic/${namespace}` }) },
554
+ (scopedConfig) => new RecordingBackend(scopedConfig.memoryDir.endsWith("/stuck") ? "stuck" : "healthy"),
555
+ );
556
+ t.mock.timers.enable({ apis: ["setTimeout"] });
557
+ const call = router.searchAcrossNamespaces({
558
+ query: "a",
559
+ namespaces: ["healthy", "stuck"],
560
+ maxResults: 10,
561
+ execution: { onDegradation: (degradation) => degradations.push(degradation) },
562
+ });
563
+ await setImmediate();
564
+ t.mock.timers.tick(NAMESPACE_SEARCH_LEG_TIMEOUT_MS);
565
+ await setImmediate();
566
+ const results = await call;
567
+ assert.deepEqual(results.map((result) => result.snippet), ["healthy"]);
568
+ assert.equal(signals.get("stuck")?.aborted, true, "the stuck leg's backend must see its deadline abort");
569
+ assert.equal(signals.get("healthy")?.aborted, false, "a finished leg's timer must be cleared");
570
+ const deadlineCodes = degradations.filter((degradation) => degradation.code === "deadline_exceeded");
571
+ assert.equal(deadlineCodes.length, 1);
572
+ assert.match(deadlineCodes[0].detail ?? "", /stuck/);
573
+ });
574
+
435
575
  test("searchAcrossNamespaces passes scoped collection to backend search methods", async () => {
436
576
  const created: FakeBackend[] = [];
437
577
  const router = new NamespaceSearchRouter(
@@ -831,6 +971,345 @@ test("healthForNamespace stops waiting when namespace availability probe aborts"
831
971
  assert.equal(backend.disposed, 1);
832
972
  });
833
973
 
974
+ test("healthForNamespace reuses a completed result within the TTL without re-probing", async (t) => {
975
+ t.mock.timers.enable({ apis: ["Date"], now: 1_700_000_000_000 });
976
+ try {
977
+ const created: FakeBackend[] = [];
978
+ const router = new NamespaceSearchRouter(
979
+ config(),
980
+ { storageFor: async (namespace: string) => ({ dir: `/tmp/remnic/${namespace}` }) },
981
+ () => {
982
+ const backend = new FakeBackend(false, [], { check: "present" }, false, {
983
+ debugStatus: "cached-health",
984
+ });
985
+ backend.statusResult = {
986
+ pendingEmbeddings: 3,
987
+ oldestPendingAgeMs: 1_000,
988
+ totalFiles: 10,
989
+ embeddedFiles: 7,
990
+ };
991
+ created.push(backend);
992
+ return backend;
993
+ },
994
+ );
995
+
996
+ const first = await router.healthForNamespace("shared");
997
+ const second = await router.healthForNamespace("shared");
998
+
999
+ assert.equal(created.length, 1, "second call must not create another backend probe");
1000
+ assert.equal(created[0]?.availabilitySignals.length, 1);
1001
+ assert.deepEqual(created[0]?.checkCollections, ["openclaw-engram--ns-736861726564"]);
1002
+ assert.deepEqual(first, second);
1003
+ assert.equal(first.debugStatus, "cached-health");
1004
+ assert.equal(first.pendingEmbeddings, 3);
1005
+
1006
+ first.available = false;
1007
+ first.debugStatus = "mutated";
1008
+ const third = await router.healthForNamespace("shared");
1009
+ assert.equal(third.available, true, "returned health objects must be copies");
1010
+ assert.equal(third.debugStatus, "cached-health");
1011
+ assert.equal(created.length, 1);
1012
+ } finally {
1013
+ t.mock.timers.reset();
1014
+ }
1015
+ });
1016
+
1017
+ test("healthForNamespace re-probes after the health result TTL elapses", async (t) => {
1018
+ t.mock.timers.enable({ apis: ["Date"], now: 1_700_000_000_000 });
1019
+ try {
1020
+ const created: FakeBackend[] = [];
1021
+ const router = new NamespaceSearchRouter(
1022
+ config(),
1023
+ { storageFor: async (namespace: string) => ({ dir: `/tmp/remnic/${namespace}` }) },
1024
+ () => {
1025
+ const backend = new FakeBackend(false, [], { check: "present" });
1026
+ backend.statusResult = {
1027
+ pendingEmbeddings: created.length,
1028
+ oldestPendingAgeMs: 0,
1029
+ totalFiles: 1,
1030
+ embeddedFiles: 1,
1031
+ };
1032
+ created.push(backend);
1033
+ return backend;
1034
+ },
1035
+ );
1036
+
1037
+ const first = await router.healthForNamespace("shared");
1038
+ assert.equal(created.length, 1);
1039
+ assert.equal(first.pendingEmbeddings, 0);
1040
+
1041
+ t.mock.timers.tick(10_000);
1042
+ const second = await router.healthForNamespace("shared");
1043
+
1044
+ assert.equal(created.length, 2, "TTL expiry must force a fresh backend probe");
1045
+ assert.equal(second.pendingEmbeddings, 1);
1046
+ assert.equal(created[0]?.disposed, 1);
1047
+ assert.equal(created[1]?.disposed, 1);
1048
+ } finally {
1049
+ t.mock.timers.reset();
1050
+ }
1051
+ });
1052
+
1053
+ test("healthForNamespace clearCache forces a re-probe before the TTL", async () => {
1054
+ const created: FakeBackend[] = [];
1055
+ const router = new NamespaceSearchRouter(
1056
+ config(),
1057
+ { storageFor: async (namespace: string) => ({ dir: `/tmp/remnic/${namespace}` }) },
1058
+ () => {
1059
+ const backend = new FakeBackend(false, [], { check: "present" });
1060
+ backend.statusResult = {
1061
+ pendingEmbeddings: created.length + 1,
1062
+ oldestPendingAgeMs: 0,
1063
+ totalFiles: 1,
1064
+ embeddedFiles: 1,
1065
+ };
1066
+ created.push(backend);
1067
+ return backend;
1068
+ },
1069
+ );
1070
+
1071
+ const first = await router.healthForNamespace("shared");
1072
+ assert.equal(created.length, 1);
1073
+ assert.equal(first.pendingEmbeddings, 1);
1074
+
1075
+ router.clearCache();
1076
+ const second = await router.healthForNamespace("shared");
1077
+
1078
+ assert.equal(created.length, 2, "clearCache must drop the health result cache");
1079
+ assert.equal(second.pendingEmbeddings, 2);
1080
+ });
1081
+
1082
+ test("healthForNamespace does not cache a thrown probe", async () => {
1083
+ let attempts = 0;
1084
+ const created: FakeBackend[] = [];
1085
+ const router = new NamespaceSearchRouter(
1086
+ config(),
1087
+ {
1088
+ storageFor: async (namespace: string) => {
1089
+ attempts += 1;
1090
+ if (attempts === 1) {
1091
+ throw new Error("storage unavailable");
1092
+ }
1093
+ return { dir: `/tmp/remnic/${namespace}` };
1094
+ },
1095
+ },
1096
+ () => {
1097
+ const backend = new FakeBackend(false, [], { check: "present" });
1098
+ backend.statusResult = {
1099
+ pendingEmbeddings: 9,
1100
+ oldestPendingAgeMs: 0,
1101
+ totalFiles: 1,
1102
+ embeddedFiles: 1,
1103
+ };
1104
+ created.push(backend);
1105
+ return backend;
1106
+ },
1107
+ );
1108
+
1109
+ await assert.rejects(
1110
+ () => router.healthForNamespace("shared"),
1111
+ /storage unavailable/,
1112
+ );
1113
+ assert.equal(created.length, 0, "failed call must not create a backend");
1114
+
1115
+ const health = await router.healthForNamespace("shared");
1116
+ assert.equal(health.pendingEmbeddings, 9);
1117
+ assert.equal(created.length, 1);
1118
+
1119
+ const cached = await router.healthForNamespace("shared");
1120
+ assert.equal(created.length, 1, "only the successful result is cached");
1121
+ assert.deepEqual(cached, health);
1122
+ });
1123
+
1124
+ test("healthForNamespace does not cache an unavailable answer", async () => {
1125
+ const created: FakeBackend[] = [];
1126
+ const router = new NamespaceSearchRouter(
1127
+ config(),
1128
+ { storageFor: async (namespace: string) => ({ dir: `/tmp/remnic/${namespace}` }) },
1129
+ () => {
1130
+ const backend = new FakeBackend(false, [], { check: "present" });
1131
+ if (created.length === 0) {
1132
+ backend.available = false;
1133
+ }
1134
+ backend.statusResult = {
1135
+ pendingEmbeddings: created.length,
1136
+ oldestPendingAgeMs: 0,
1137
+ totalFiles: 1,
1138
+ embeddedFiles: 1,
1139
+ };
1140
+ created.push(backend);
1141
+ return backend;
1142
+ },
1143
+ );
1144
+
1145
+ const first = await router.healthForNamespace("shared");
1146
+ assert.equal(first.available, false);
1147
+ assert.equal(created.length, 1);
1148
+
1149
+ const second = await router.healthForNamespace("shared");
1150
+ assert.equal(second.available, true, "recovery must be visible on the next probe");
1151
+ assert.equal(created.length, 2, "unavailable answers must not be cached");
1152
+ });
1153
+
1154
+ test("healthForNamespace does not cache a missing-collection answer", async () => {
1155
+ const created: FakeBackend[] = [];
1156
+ const router = new NamespaceSearchRouter(
1157
+ config(),
1158
+ { storageFor: async (namespace: string) => ({ dir: `/tmp/remnic/${namespace}` }) },
1159
+ () => {
1160
+ const backend = new FakeBackend(
1161
+ false,
1162
+ [],
1163
+ created.length === 0 ? { check: "missing" } : { check: "present" },
1164
+ );
1165
+ backend.statusResult = {
1166
+ pendingEmbeddings: created.length,
1167
+ oldestPendingAgeMs: 0,
1168
+ totalFiles: 1,
1169
+ embeddedFiles: 1,
1170
+ };
1171
+ created.push(backend);
1172
+ return backend;
1173
+ },
1174
+ );
1175
+
1176
+ const first = await router.healthForNamespace("shared");
1177
+ assert.equal(first.collectionState, "missing");
1178
+ assert.equal(created.length, 1);
1179
+
1180
+ const second = await router.healthForNamespace("shared");
1181
+ assert.equal(second.collectionState, "present", "collection recovery must re-probe");
1182
+ assert.equal(created.length, 2, "missing-collection answers must not be cached");
1183
+ });
1184
+
1185
+ function routerWithDegradedFirstProbe(
1186
+ created: FakeBackend[],
1187
+ firstCheck: CollectionState,
1188
+ degradeFirst: (backend: FakeBackend) => void,
1189
+ ): NamespaceSearchRouter {
1190
+ return new NamespaceSearchRouter(
1191
+ config(),
1192
+ { storageFor: async (namespace: string) => ({ dir: `/tmp/remnic/${namespace}` }) },
1193
+ () => {
1194
+ const isFirst = created.length === 0;
1195
+ const backend = new FakeBackend(false, [], { check: isFirst ? firstCheck : "present" });
1196
+ backend.statusResult = {
1197
+ pendingEmbeddings: 10,
1198
+ oldestPendingAgeMs: 0,
1199
+ totalFiles: 1,
1200
+ embeddedFiles: 1,
1201
+ };
1202
+ if (isFirst) degradeFirst(backend);
1203
+ created.push(backend);
1204
+ return backend;
1205
+ },
1206
+ );
1207
+ }
1208
+
1209
+ test("healthForNamespace does not cache an unknown-collection answer", async () => {
1210
+ const created: FakeBackend[] = [];
1211
+ const router = routerWithDegradedFirstProbe(created, "unknown", () => {});
1212
+
1213
+ const first = await router.healthForNamespace("shared");
1214
+ assert.equal(first.collectionState, "unknown");
1215
+
1216
+ const second = await router.healthForNamespace("shared");
1217
+ assert.equal(second.collectionState, "present", "recovery must be visible on the next probe");
1218
+ assert.equal(created.length, 2, "unknown-collection answers must not be cached");
1219
+ });
1220
+
1221
+ test("healthForNamespace does not cache an answer whose backend status failed", async () => {
1222
+ const created: FakeBackend[] = [];
1223
+ const router = routerWithDegradedFirstProbe(created, "present", (backend) => {
1224
+ backend.statusResult = null;
1225
+ });
1226
+
1227
+ const first = await router.healthForNamespace("shared");
1228
+ assert.equal(first.pendingEmbeddings, null);
1229
+
1230
+ const second = await router.healthForNamespace("shared");
1231
+ assert.equal(second.pendingEmbeddings, 10, "backlog data must be visible on the next probe");
1232
+ assert.equal(created.length, 2, "answers without backlog data must not be cached");
1233
+ });
1234
+
1235
+ test("healthForNamespace does not cache a backlog over the threshold", async () => {
1236
+ const created: FakeBackend[] = [];
1237
+ const router = routerWithDegradedFirstProbe(created, "present", (backend) => {
1238
+ backend.statusResult = {
1239
+ pendingEmbeddings: config().qmdEmbeddingBacklogThreshold + 1,
1240
+ oldestPendingAgeMs: 0,
1241
+ totalFiles: 1,
1242
+ embeddedFiles: 1,
1243
+ };
1244
+ });
1245
+
1246
+ await router.healthForNamespace("shared");
1247
+
1248
+ const second = await router.healthForNamespace("shared");
1249
+ assert.equal(second.pendingEmbeddings, 10, "a drained backlog must be visible on the next probe");
1250
+ assert.equal(created.length, 2, "over-threshold answers must not be cached");
1251
+ });
1252
+
1253
+ test("healthForNamespace dispose drops the health result cache", async () => {
1254
+ const created: FakeBackend[] = [];
1255
+ const router = new NamespaceSearchRouter(
1256
+ config(),
1257
+ { storageFor: async (namespace: string) => ({ dir: `/tmp/remnic/${namespace}` }) },
1258
+ () => {
1259
+ const backend = new FakeBackend(false, [], { check: "present" });
1260
+ backend.statusResult = {
1261
+ pendingEmbeddings: created.length + 1,
1262
+ oldestPendingAgeMs: 0,
1263
+ totalFiles: 1,
1264
+ embeddedFiles: 1,
1265
+ };
1266
+ created.push(backend);
1267
+ return backend;
1268
+ },
1269
+ );
1270
+
1271
+ const first = await router.healthForNamespace("shared");
1272
+ assert.equal(created.length, 1);
1273
+ assert.equal(first.pendingEmbeddings, 1);
1274
+
1275
+ await router.dispose();
1276
+ const second = await router.healthForNamespace("shared");
1277
+
1278
+ assert.equal(created.length, 2, "dispose must drop the health result cache");
1279
+ assert.equal(second.pendingEmbeddings, 2);
1280
+ });
1281
+
1282
+ test("healthForNamespace disableSearchBackends drops the health result cache", async () => {
1283
+ const created: FakeBackend[] = [];
1284
+ const router = new NamespaceSearchRouter(
1285
+ config(),
1286
+ { storageFor: async (namespace: string) => ({ dir: `/tmp/remnic/${namespace}` }) },
1287
+ () => {
1288
+ const backend = new FakeBackend(false, [], { check: "present" });
1289
+ backend.statusResult = {
1290
+ pendingEmbeddings: created.length + 1,
1291
+ oldestPendingAgeMs: 0,
1292
+ totalFiles: 1,
1293
+ embeddedFiles: 1,
1294
+ };
1295
+ created.push(backend);
1296
+ return backend;
1297
+ },
1298
+ );
1299
+
1300
+ const first = await router.healthForNamespace("shared");
1301
+ assert.equal(created.length, 1);
1302
+ assert.equal(first.pendingEmbeddings, 1);
1303
+
1304
+ await router.disableSearchBackends();
1305
+ const second = await router.healthForNamespace("shared");
1306
+
1307
+ assert.equal(created.length, 2, "disableSearchBackends must drop the health result cache");
1308
+ assert.equal(second.pendingEmbeddings, 2);
1309
+ });
1310
+
1311
+
1312
+
834
1313
  test("ensureNamespaceCollection does not cache aborted namespace backend probes", async () => {
835
1314
  const created: FakeBackend[] = [];
836
1315
  const router = new NamespaceSearchRouter(