@remnic/core 10.0.37 → 10.0.39

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 (440) hide show
  1. package/dist/access-admin-ops-surface.js +76 -76
  2. package/dist/access-audit.js +2 -2
  3. package/dist/access-authorization-probe.js +77 -77
  4. package/dist/access-boundary.js +76 -76
  5. package/dist/access-citation-namespace.js +2 -2
  6. package/dist/access-cli.js +165 -164
  7. package/dist/access-cli.js.map +1 -1
  8. package/dist/access-extraction-force-flush.js +76 -76
  9. package/dist/access-http-briefing.js +77 -77
  10. package/dist/access-http-query.js +78 -78
  11. package/dist/access-http.js +101 -101
  12. package/dist/access-identity-continuity-surface.js +76 -76
  13. package/dist/access-lcm-surface.js +76 -76
  14. package/dist/access-mcp.js +90 -90
  15. package/dist/access-namespace-preflight.js +76 -76
  16. package/dist/access-observe-write-category.js +15 -15
  17. package/dist/access-observe-write-surface.js +76 -76
  18. package/dist/access-offline-manifest.js +12 -12
  19. package/dist/access-operations-batch.js +80 -80
  20. package/dist/access-operations.js +87 -87
  21. package/dist/access-recall-concurrency.js +76 -76
  22. package/dist/access-recall-diagnostics.js +2 -2
  23. package/dist/access-recall-response.js +76 -76
  24. package/dist/access-recall-surface.js +76 -76
  25. package/dist/access-schema.js +10 -10
  26. package/dist/access-service.js +76 -76
  27. package/dist/access-surface-catalog.js +78 -78
  28. package/dist/active-recall.js +31 -31
  29. package/dist/adapters/index.js +4 -4
  30. package/dist/adapters/registry.js +2 -2
  31. package/dist/{auto-sync-R3XGJL5I.js → auto-sync-BNCBMU6H.js} +9 -9
  32. package/dist/briefing.js +21 -21
  33. package/dist/buffer-types.d.ts +59 -0
  34. package/dist/buffer-types.d.ts.map +1 -0
  35. package/dist/buffer-types.js +1 -0
  36. package/dist/buffer.d.ts +14 -22
  37. package/dist/buffer.d.ts.map +1 -1
  38. package/dist/buffer.js +11 -11
  39. package/dist/calibration.js +3 -3
  40. package/dist/{capsule-crypto-7FJQINUR.js → capsule-crypto-GWVG7LGC.js} +2 -2
  41. package/dist/causal-behavior.js +2 -2
  42. package/dist/causal-chain.js +2 -2
  43. package/dist/causal-consolidation.js +24 -24
  44. package/dist/causal-retrieval.js +2 -2
  45. package/dist/causal-trajectory-graph.js +2 -2
  46. package/dist/causal-trajectory.js +1 -1
  47. package/dist/{chunk-MH3LC7KB.js → chunk-22YJQTPN.js} +2 -2
  48. package/dist/{chunk-MKE5DP3S.js → chunk-23ZMQONL.js} +2 -2
  49. package/dist/{chunk-MGXFJOUR.js → chunk-2AV2U2SZ.js} +4 -4
  50. package/dist/{chunk-HJ3UTGIW.js → chunk-2JNBPOZ2.js} +3 -3
  51. package/dist/{chunk-EEOYF3IB.js → chunk-3RJDYZJE.js} +2 -2
  52. package/dist/{chunk-FBAHBFT5.js → chunk-4HJ2QK32.js} +2 -2
  53. package/dist/{chunk-UXXVOA4D.js → chunk-4LLV2N3R.js} +3 -3
  54. package/dist/{chunk-P5CUEB2Q.js → chunk-4QLKVZH6.js} +8 -8
  55. package/dist/{chunk-2RJO7VS4.js → chunk-4UT2NUAC.js} +2 -2
  56. package/dist/{chunk-R6TCM47S.js → chunk-5KZNWERU.js} +156 -143
  57. package/dist/chunk-5KZNWERU.js.map +1 -0
  58. package/dist/{chunk-MNDHKZZQ.js → chunk-5Q6CR65T.js} +2 -2
  59. package/dist/{chunk-XTBEXZFN.js → chunk-5SF7JOJB.js} +4 -4
  60. package/dist/{chunk-BQ6DGL6A.js → chunk-64WHWIPL.js} +2 -2
  61. package/dist/{chunk-TVIGN3XZ.js → chunk-6FRFVIKC.js} +10 -10
  62. package/dist/{chunk-A23DPFFI.js → chunk-6ITNEPJO.js} +2 -2
  63. package/dist/{chunk-UFBIOF7C.js → chunk-6X3J4NLZ.js} +10 -5
  64. package/dist/chunk-6X3J4NLZ.js.map +1 -0
  65. package/dist/{chunk-G6PPA4TH.js → chunk-6Z2ZWBOV.js} +6 -6
  66. package/dist/{chunk-QEGE5QCL.js → chunk-7IANFJ24.js} +58 -58
  67. package/dist/{chunk-PSQ2P2T3.js → chunk-7XZ7TOLQ.js} +3 -3
  68. package/dist/{chunk-Z5AQZRHF.js → chunk-AER3HD3B.js} +2 -2
  69. package/dist/{chunk-BPBUUGAO.js → chunk-ANV373S5.js} +2 -2
  70. package/dist/{chunk-GMMZ45C4.js → chunk-AVVCPA7U.js} +6 -8
  71. package/dist/chunk-AVVCPA7U.js.map +1 -0
  72. package/dist/{chunk-LSSCMZQ2.js → chunk-B3I2QQU7.js} +3 -3
  73. package/dist/{chunk-NSQSOLCE.js → chunk-B7VKRCAG.js} +2 -2
  74. package/dist/{chunk-HXFIILGF.js → chunk-BFPF5N3H.js} +4 -4
  75. package/dist/{chunk-KQAFEZQX.js → chunk-BUKK5SWA.js} +2 -2
  76. package/dist/{chunk-RBC4GIZU.js → chunk-BUKZ7MTN.js} +2 -2
  77. package/dist/{chunk-FO5AFCRI.js → chunk-CR72WZ3M.js} +9 -9
  78. package/dist/{chunk-YC2C67F7.js → chunk-CRXGQRNA.js} +3 -3
  79. package/dist/{chunk-WRDFYSUC.js → chunk-CZVNOTLR.js} +2 -2
  80. package/dist/{chunk-VPO53QMG.js → chunk-D6DOLQYK.js} +2 -2
  81. package/dist/{chunk-HRT2SJPC.js → chunk-E3NBMTTX.js} +2 -2
  82. package/dist/{chunk-HIMXDRSQ.js → chunk-E5IEI2MR.js} +2 -2
  83. package/dist/{chunk-Z2T5BPOZ.js → chunk-EIYJK7OD.js} +2 -2
  84. package/dist/{chunk-FRAL3EU4.js → chunk-EKPRLTAE.js} +2 -2
  85. package/dist/{chunk-EVVCE7S2.js → chunk-EKR6OO4P.js} +2 -2
  86. package/dist/{chunk-TYGLV6ZG.js → chunk-EYGOM6AI.js} +2 -2
  87. package/dist/{chunk-TYGLV6ZG.js.map → chunk-EYGOM6AI.js.map} +1 -1
  88. package/dist/{chunk-6R6CU3MR.js → chunk-F2IU6A2L.js} +57 -57
  89. package/dist/{chunk-FL6SLVAJ.js → chunk-FAKRTS3Y.js} +3 -3
  90. package/dist/{chunk-64IO6ZEE.js → chunk-FC3ZFEXF.js} +2 -2
  91. package/dist/{chunk-YGYT7S3G.js → chunk-FJ264QBP.js} +31 -9
  92. package/dist/chunk-FJ264QBP.js.map +1 -0
  93. package/dist/{chunk-DGBWPSM6.js → chunk-FLDXEJFX.js} +2 -2
  94. package/dist/{chunk-JH4FCVWJ.js → chunk-G6OFEGUR.js} +2 -2
  95. package/dist/{chunk-Z5QWUR3Y.js → chunk-GCW7UT5I.js} +2 -2
  96. package/dist/{chunk-ULUX6Q7R.js → chunk-GE5ZNDLE.js} +4 -4
  97. package/dist/{chunk-U4JXQCJ3.js → chunk-GLB6VV3J.js} +2 -2
  98. package/dist/{chunk-RWWYBE7E.js → chunk-GPVGAHXL.js} +3 -3
  99. package/dist/{chunk-3BPMYMPX.js → chunk-GSBSGT43.js} +2 -2
  100. package/dist/{chunk-645WOU5I.js → chunk-H7BZBSP6.js} +4 -4
  101. package/dist/{chunk-GFYFKXWZ.js → chunk-HUDPXTXW.js} +2 -2
  102. package/dist/{chunk-L2JQSG5M.js → chunk-I7TR2OCU.js} +2 -2
  103. package/dist/{chunk-HKEK27M4.js → chunk-IAOW2L6K.js} +2 -2
  104. package/dist/{chunk-STM4T335.js → chunk-IJH6METJ.js} +2 -2
  105. package/dist/{chunk-WADPRAZE.js → chunk-IZRNMXZC.js} +2 -2
  106. package/dist/{chunk-JWTUJVIF.js → chunk-JGS55BAS.js} +53 -2
  107. package/dist/chunk-JGS55BAS.js.map +1 -0
  108. package/dist/{chunk-LAQS5HYU.js → chunk-JM6U3SAE.js} +2 -2
  109. package/dist/{chunk-74AY3S7U.js → chunk-JNLYHJG7.js} +4 -4
  110. package/dist/{chunk-7ZBANI3M.js → chunk-JOOGPZJE.js} +2 -2
  111. package/dist/{chunk-V5RJCXLG.js → chunk-JORSMFL6.js} +6 -6
  112. package/dist/{chunk-VKTP3TZB.js → chunk-JQCP5QW3.js} +4 -4
  113. package/dist/{chunk-LRJKHXU4.js → chunk-JRTKYFFY.js} +2 -2
  114. package/dist/{chunk-UMFBHYPW.js → chunk-JT3IXJIL.js} +13 -13
  115. package/dist/{chunk-S53WZWGL.js → chunk-JZFJZLJY.js} +2 -2
  116. package/dist/{chunk-6QOL4G76.js → chunk-KQXRVELF.js} +2 -2
  117. package/dist/{chunk-USOXPN5H.js → chunk-L74NWAD4.js} +2 -2
  118. package/dist/{chunk-Y6Y3TRBN.js → chunk-LJXBFVI2.js} +4 -4
  119. package/dist/{chunk-3L5WH6CV.js → chunk-LPD6I2U6.js} +2 -2
  120. package/dist/{chunk-LDXS746V.js → chunk-LR7RW4T6.js} +3 -3
  121. package/dist/{chunk-FZVZYU5C.js → chunk-LXN737FX.js} +2 -2
  122. package/dist/{chunk-5U3NUHMA.js → chunk-MD3W2H3G.js} +301 -98
  123. package/dist/chunk-MD3W2H3G.js.map +1 -0
  124. package/dist/{chunk-ARFT6ZBE.js → chunk-MGYZENUY.js} +2 -2
  125. package/dist/{chunk-YQ6SLFNZ.js → chunk-MPJDQC4G.js} +3 -3
  126. package/dist/{chunk-5UWP5X3T.js → chunk-NJ2DZYEK.js} +2 -2
  127. package/dist/{chunk-MBMT5FUQ.js → chunk-O2O4FDAH.js} +2 -2
  128. package/dist/{chunk-GCVUBVEN.js → chunk-ODJ2HRFW.js} +10 -10
  129. package/dist/{chunk-2NLLXCJG.js → chunk-OWHERGF2.js} +2 -2
  130. package/dist/{chunk-I73ZSORJ.js → chunk-OXSTKCYK.js} +4 -4
  131. package/dist/{chunk-CNQQNYJ2.js → chunk-P3YUEPSQ.js} +2 -2
  132. package/dist/{chunk-A6PKEU7T.js → chunk-PARM6OYL.js} +1 -1
  133. package/dist/chunk-PARM6OYL.js.map +1 -0
  134. package/dist/{chunk-TPKB7T6Z.js → chunk-Q6UZREJK.js} +2 -2
  135. package/dist/{chunk-UJDTXWMT.js → chunk-QIMGULGN.js} +2 -2
  136. package/dist/{chunk-E24RUQEN.js → chunk-QNIYL5SK.js} +2 -2
  137. package/dist/{chunk-KOY25HUB.js → chunk-QYAXMXOB.js} +2 -2
  138. package/dist/{chunk-CU7WDDPV.js → chunk-RIAKNXZB.js} +4 -4
  139. package/dist/{chunk-UQWA5QDT.js → chunk-RO2NNWR5.js} +3 -3
  140. package/dist/{chunk-AYXRK264.js → chunk-RROFIAYI.js} +9 -9
  141. package/dist/{chunk-L46Y5FPE.js → chunk-RUAIO5UA.js} +2 -2
  142. package/dist/{chunk-QIC7YZ3D.js → chunk-RWW5KPIY.js} +18 -18
  143. package/dist/{chunk-E5PVMB3I.js → chunk-SDXBR5QO.js} +2 -2
  144. package/dist/{chunk-WSLNC5AL.js → chunk-SJHFU52W.js} +8 -8
  145. package/dist/{chunk-7PG7QBWD.js → chunk-SRPGA6WN.js} +2 -2
  146. package/dist/{chunk-CUWOSRCS.js → chunk-SUKPM6DV.js} +2 -2
  147. package/dist/{chunk-BBDASWNT.js → chunk-TJ5YGCPV.js} +81 -76
  148. package/dist/chunk-TJ5YGCPV.js.map +1 -0
  149. package/dist/{chunk-G2SRB62M.js → chunk-TTQYX7VU.js} +2 -2
  150. package/dist/{chunk-TDCR6PQL.js → chunk-TWRPWJJT.js} +2 -2
  151. package/dist/{chunk-KC5SVCUJ.js → chunk-U66CTIF5.js} +2 -2
  152. package/dist/{chunk-D2AKUKAQ.js → chunk-UIK3U36O.js} +2 -2
  153. package/dist/{chunk-XLEP7SS3.js → chunk-UMSH4I3E.js} +2 -2
  154. package/dist/{chunk-X7Y7WX73.js → chunk-UVYI6VIX.js} +1 -1
  155. package/dist/{chunk-LHBOFROT.js → chunk-V2XMG7GM.js} +2 -2
  156. package/dist/chunk-VA3GNAWQ.js +58 -0
  157. package/dist/chunk-VA3GNAWQ.js.map +1 -0
  158. package/dist/{chunk-NQOM6PHO.js → chunk-VCOCOBUS.js} +6 -6
  159. package/dist/{chunk-4P4VLPGB.js → chunk-VECRSYQG.js} +1 -1
  160. package/dist/{chunk-ID2PLENW.js → chunk-VHBGJAYC.js} +2 -2
  161. package/dist/{chunk-RVYXSS3Q.js → chunk-VIS23B6O.js} +8 -8
  162. package/dist/{chunk-NMKETOAX.js → chunk-VSHWPOUB.js} +2 -2
  163. package/dist/{chunk-UBN5AOLT.js → chunk-W5EO4USJ.js} +2 -2
  164. package/dist/{chunk-Y7427SL7.js → chunk-WCGJK4NQ.js} +4 -4
  165. package/dist/{chunk-CCYXCT4B.js → chunk-WQYS47G4.js} +2 -2
  166. package/dist/{chunk-JH2ALMPR.js → chunk-WR5POHQ3.js} +2 -2
  167. package/dist/{chunk-DK5VMJL3.js → chunk-WT2VVYBM.js} +2 -2
  168. package/dist/{chunk-EHIKY2IA.js → chunk-WU5WTCH5.js} +2 -2
  169. package/dist/{chunk-QKXPOLQD.js → chunk-WUBGMV3G.js} +6 -6
  170. package/dist/{chunk-O6YJI5VX.js → chunk-WUL6LDJ4.js} +2 -2
  171. package/dist/{chunk-5EILJ6W2.js → chunk-WXPBDEMW.js} +2 -2
  172. package/dist/{chunk-U7HJBODU.js → chunk-XKTHJHSQ.js} +5 -5
  173. package/dist/{chunk-JFI3ATK4.js → chunk-XMYWYJM2.js} +2 -2
  174. package/dist/{chunk-64S6X4IU.js → chunk-XTN54NML.js} +4 -4
  175. package/dist/{chunk-VGFNTY3Y.js → chunk-YFXRLRKP.js} +2 -2
  176. package/dist/{chunk-DAOMWGO2.js → chunk-ZX5N5D6M.js} +4 -4
  177. package/dist/{chunk-PTRPOJ7U.js → chunk-ZXFKG7VZ.js} +2 -2
  178. package/dist/cli.js +124 -124
  179. package/dist/coding/export-okf-codegraph.js +22 -22
  180. package/dist/coding/pre-action-gate.js +2 -2
  181. package/dist/compounding/engine.js +23 -23
  182. package/dist/config.d.ts.map +1 -1
  183. package/dist/config.js +31 -31
  184. package/dist/connectors/codex-materialize-runner.js +21 -21
  185. package/dist/connectors/index.js +21 -21
  186. package/dist/contradiction/index.js +5 -5
  187. package/dist/convergence-refresh.js +23 -23
  188. package/dist/corpus-watermark.js +23 -23
  189. package/dist/deep-recall-http-glue.js +11 -11
  190. package/dist/deep-recall-policy-llm.js +2 -2
  191. package/dist/deep-recall.js +2 -2
  192. package/dist/entity-retrieval.js +22 -22
  193. package/dist/event-order-recall.js +2 -2
  194. package/dist/explicit-capture.js +6 -6
  195. package/dist/external-wiki-access.js +77 -77
  196. package/dist/extraction-faithfulness.js +2 -2
  197. package/dist/extraction-judge.d.ts +42 -2
  198. package/dist/extraction-judge.d.ts.map +1 -1
  199. package/dist/extraction-judge.js +12 -2
  200. package/dist/extraction-window-drain.d.ts +48 -0
  201. package/dist/extraction-window-drain.d.ts.map +1 -0
  202. package/dist/extraction-window-drain.js +14 -0
  203. package/dist/extraction.js +29 -29
  204. package/dist/fallback-llm.d.ts +1 -0
  205. package/dist/fallback-llm.d.ts.map +1 -1
  206. package/dist/fallback-llm.js +1 -1
  207. package/dist/{graph-edge-decay-2BZTY2IM.js → graph-edge-decay-3HVLMT6U.js} +5 -5
  208. package/dist/graph-edge-decay-3HVLMT6U.js.map +1 -0
  209. package/dist/graph-jsonl.js +3 -3
  210. package/dist/graph-snapshot.js +3 -3
  211. package/dist/graph.js +4 -4
  212. package/dist/harmonic-retrieval.js +22 -22
  213. package/dist/harmonic-source-lookup.js +2 -2
  214. package/dist/index.js +212 -211
  215. package/dist/lcm/engine.js +2 -2
  216. package/dist/lcm/index.js +7 -7
  217. package/dist/local-llm.js +2 -2
  218. package/dist/location/index.js +24 -24
  219. package/dist/maintenance/memory-governance.js +21 -21
  220. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +21 -21
  221. package/dist/maintenance/rebuild-memory-projection-runner.js +23 -23
  222. package/dist/maintenance/rebuild-memory-projection.js +22 -22
  223. package/dist/memory-browse-operations.js +77 -77
  224. package/dist/memory-browse.js +6 -6
  225. package/dist/memory-subject.js +3 -3
  226. package/dist/namespaces/migrate.js +22 -22
  227. package/dist/namespaces/search.js +7 -7
  228. package/dist/namespaces/storage.js +21 -21
  229. package/dist/offline-sync-changeset-generations.js +3 -3
  230. package/dist/offline-sync-embedding-generation.js +2 -2
  231. package/dist/offline-sync-file-io.js +2 -2
  232. package/dist/offline-sync-impression-drain.js +3 -3
  233. package/dist/offline-sync-snapshot-stream.js +8 -8
  234. package/dist/offline-sync-upload-staging.js +3 -3
  235. package/dist/offline-sync.js +9 -9
  236. package/dist/operator-doctor-corpus.js +24 -24
  237. package/dist/operator-toolkit.js +42 -42
  238. package/dist/orchestration/extraction-drain.d.ts +90 -0
  239. package/dist/orchestration/extraction-drain.d.ts.map +1 -0
  240. package/dist/orchestration/extraction-run-helpers.d.ts +3 -0
  241. package/dist/orchestration/extraction-run-helpers.d.ts.map +1 -1
  242. package/dist/orchestration/extraction-run.d.ts +4 -1
  243. package/dist/orchestration/extraction-run.d.ts.map +1 -1
  244. package/dist/orchestration/maintenance.js +35 -35
  245. package/dist/orchestration/turn-ingestion.d.ts +3 -0
  246. package/dist/orchestration/turn-ingestion.d.ts.map +1 -1
  247. package/dist/orchestrator.d.ts +8 -0
  248. package/dist/orchestrator.d.ts.map +1 -1
  249. package/dist/orchestrator.js +165 -164
  250. package/dist/qmd.js +5 -5
  251. package/dist/recall-explain-renderer.js +3 -3
  252. package/dist/recall-navigate-access.js +2 -2
  253. package/dist/recall-navigate-disclosure.js +2 -2
  254. package/dist/recall-navigate.js +2 -2
  255. package/dist/recall-navigation-operations.js +77 -77
  256. package/dist/recall-navigation.js +76 -76
  257. package/dist/recall-planner-llm.js +1 -1
  258. package/dist/recall-state-view-admission.js +6 -6
  259. package/dist/recall-why-service.js +6 -6
  260. package/dist/recall-xray-cli.js +4 -4
  261. package/dist/recall-xray-renderer.js +3 -3
  262. package/dist/recall-xray.js +2 -2
  263. package/dist/reconcile/manifest.js +3 -3
  264. package/dist/{resolution-4ZEQPXUZ.js → resolution-NNYG37YB.js} +6 -6
  265. package/dist/resolution-NNYG37YB.js.map +1 -0
  266. package/dist/resume-bundles.js +32 -32
  267. package/dist/retrieval-agents.js +2 -2
  268. package/dist/salvage-envelope.js +5 -5
  269. package/dist/search/factory.js +6 -6
  270. package/dist/search/index.js +10 -10
  271. package/dist/secure-store/index.js +2 -2
  272. package/dist/semantic-consolidation.js +22 -22
  273. package/dist/semantic-rule-promotion.js +21 -21
  274. package/dist/semantic-rule-verifier.js +21 -21
  275. package/dist/source-agent-qualifier.js +25 -25
  276. package/dist/standup/build.js +21 -21
  277. package/dist/storage/dropped-extraction-chunk.d.ts +8 -0
  278. package/dist/storage/dropped-extraction-chunk.d.ts.map +1 -0
  279. package/dist/storage.d.ts +1 -0
  280. package/dist/storage.d.ts.map +1 -1
  281. package/dist/storage.js +20 -20
  282. package/dist/subject-config.js +4 -4
  283. package/dist/summarizer.js +4 -4
  284. package/dist/support-passport/index.js +79 -79
  285. package/dist/transfer/backup.js +2 -2
  286. package/dist/transfer/capsule-export.js +2 -2
  287. package/dist/transfer/capsule-import.js +2 -2
  288. package/dist/transfer/export-okf.js +22 -22
  289. package/dist/types.d.ts +19 -0
  290. package/dist/types.d.ts.map +1 -1
  291. package/dist/types.js +1 -1
  292. package/dist/verified-recall.js +21 -21
  293. package/dist/who-knows-cli.js +22 -22
  294. package/dist/who-knows.js +21 -21
  295. package/dist/write-envelope.js +4 -4
  296. package/package.json +2 -2
  297. package/src/buffer-drop-extraction-chunk.test.ts +196 -0
  298. package/src/buffer-types.ts +65 -0
  299. package/src/buffer.ts +60 -62
  300. package/src/config.test.ts +16 -0
  301. package/src/config.ts +22 -0
  302. package/src/extraction-judge-chain.test.ts +298 -2
  303. package/src/extraction-judge.ts +147 -82
  304. package/src/extraction-window-drain.test.ts +123 -0
  305. package/src/extraction-window-drain.ts +110 -0
  306. package/src/fallback-llm.test.ts +94 -0
  307. package/src/fallback-llm.ts +7 -7
  308. package/src/orchestration/extraction-drain.ts +261 -0
  309. package/src/orchestration/extraction-run-helpers.ts +8 -0
  310. package/src/orchestration/extraction-run.ts +5 -4
  311. package/src/orchestration/turn-ingestion.ts +9 -5
  312. package/src/orchestrator.ts +21 -0
  313. package/src/secure-store/secure-fs.ts +3 -1
  314. package/src/storage/dropped-extraction-chunk.ts +27 -0
  315. package/src/storage-dropped-chunk-filenames.test.ts +30 -0
  316. package/src/storage.ts +6 -7
  317. package/src/types.ts +19 -0
  318. package/dist/chunk-5U3NUHMA.js.map +0 -1
  319. package/dist/chunk-A6PKEU7T.js.map +0 -1
  320. package/dist/chunk-BBDASWNT.js.map +0 -1
  321. package/dist/chunk-GMMZ45C4.js.map +0 -1
  322. package/dist/chunk-JWTUJVIF.js.map +0 -1
  323. package/dist/chunk-R6TCM47S.js.map +0 -1
  324. package/dist/chunk-UFBIOF7C.js.map +0 -1
  325. package/dist/chunk-YGYT7S3G.js.map +0 -1
  326. /package/dist/{auto-sync-R3XGJL5I.js.map → auto-sync-BNCBMU6H.js.map} +0 -0
  327. /package/dist/{capsule-crypto-7FJQINUR.js.map → buffer-types.js.map} +0 -0
  328. /package/dist/{graph-edge-decay-2BZTY2IM.js.map → capsule-crypto-GWVG7LGC.js.map} +0 -0
  329. /package/dist/{chunk-MH3LC7KB.js.map → chunk-22YJQTPN.js.map} +0 -0
  330. /package/dist/{chunk-MKE5DP3S.js.map → chunk-23ZMQONL.js.map} +0 -0
  331. /package/dist/{chunk-MGXFJOUR.js.map → chunk-2AV2U2SZ.js.map} +0 -0
  332. /package/dist/{chunk-HJ3UTGIW.js.map → chunk-2JNBPOZ2.js.map} +0 -0
  333. /package/dist/{chunk-EEOYF3IB.js.map → chunk-3RJDYZJE.js.map} +0 -0
  334. /package/dist/{chunk-FBAHBFT5.js.map → chunk-4HJ2QK32.js.map} +0 -0
  335. /package/dist/{chunk-UXXVOA4D.js.map → chunk-4LLV2N3R.js.map} +0 -0
  336. /package/dist/{chunk-P5CUEB2Q.js.map → chunk-4QLKVZH6.js.map} +0 -0
  337. /package/dist/{chunk-2RJO7VS4.js.map → chunk-4UT2NUAC.js.map} +0 -0
  338. /package/dist/{chunk-MNDHKZZQ.js.map → chunk-5Q6CR65T.js.map} +0 -0
  339. /package/dist/{chunk-XTBEXZFN.js.map → chunk-5SF7JOJB.js.map} +0 -0
  340. /package/dist/{chunk-BQ6DGL6A.js.map → chunk-64WHWIPL.js.map} +0 -0
  341. /package/dist/{chunk-TVIGN3XZ.js.map → chunk-6FRFVIKC.js.map} +0 -0
  342. /package/dist/{chunk-A23DPFFI.js.map → chunk-6ITNEPJO.js.map} +0 -0
  343. /package/dist/{chunk-G6PPA4TH.js.map → chunk-6Z2ZWBOV.js.map} +0 -0
  344. /package/dist/{chunk-QEGE5QCL.js.map → chunk-7IANFJ24.js.map} +0 -0
  345. /package/dist/{chunk-PSQ2P2T3.js.map → chunk-7XZ7TOLQ.js.map} +0 -0
  346. /package/dist/{chunk-Z5AQZRHF.js.map → chunk-AER3HD3B.js.map} +0 -0
  347. /package/dist/{chunk-BPBUUGAO.js.map → chunk-ANV373S5.js.map} +0 -0
  348. /package/dist/{chunk-LSSCMZQ2.js.map → chunk-B3I2QQU7.js.map} +0 -0
  349. /package/dist/{chunk-NSQSOLCE.js.map → chunk-B7VKRCAG.js.map} +0 -0
  350. /package/dist/{chunk-HXFIILGF.js.map → chunk-BFPF5N3H.js.map} +0 -0
  351. /package/dist/{chunk-KQAFEZQX.js.map → chunk-BUKK5SWA.js.map} +0 -0
  352. /package/dist/{chunk-RBC4GIZU.js.map → chunk-BUKZ7MTN.js.map} +0 -0
  353. /package/dist/{chunk-FO5AFCRI.js.map → chunk-CR72WZ3M.js.map} +0 -0
  354. /package/dist/{chunk-YC2C67F7.js.map → chunk-CRXGQRNA.js.map} +0 -0
  355. /package/dist/{chunk-WRDFYSUC.js.map → chunk-CZVNOTLR.js.map} +0 -0
  356. /package/dist/{chunk-VPO53QMG.js.map → chunk-D6DOLQYK.js.map} +0 -0
  357. /package/dist/{chunk-HRT2SJPC.js.map → chunk-E3NBMTTX.js.map} +0 -0
  358. /package/dist/{chunk-HIMXDRSQ.js.map → chunk-E5IEI2MR.js.map} +0 -0
  359. /package/dist/{chunk-Z2T5BPOZ.js.map → chunk-EIYJK7OD.js.map} +0 -0
  360. /package/dist/{chunk-FRAL3EU4.js.map → chunk-EKPRLTAE.js.map} +0 -0
  361. /package/dist/{chunk-EVVCE7S2.js.map → chunk-EKR6OO4P.js.map} +0 -0
  362. /package/dist/{chunk-6R6CU3MR.js.map → chunk-F2IU6A2L.js.map} +0 -0
  363. /package/dist/{chunk-FL6SLVAJ.js.map → chunk-FAKRTS3Y.js.map} +0 -0
  364. /package/dist/{chunk-64IO6ZEE.js.map → chunk-FC3ZFEXF.js.map} +0 -0
  365. /package/dist/{chunk-DGBWPSM6.js.map → chunk-FLDXEJFX.js.map} +0 -0
  366. /package/dist/{chunk-JH4FCVWJ.js.map → chunk-G6OFEGUR.js.map} +0 -0
  367. /package/dist/{chunk-Z5QWUR3Y.js.map → chunk-GCW7UT5I.js.map} +0 -0
  368. /package/dist/{chunk-ULUX6Q7R.js.map → chunk-GE5ZNDLE.js.map} +0 -0
  369. /package/dist/{chunk-U4JXQCJ3.js.map → chunk-GLB6VV3J.js.map} +0 -0
  370. /package/dist/{chunk-RWWYBE7E.js.map → chunk-GPVGAHXL.js.map} +0 -0
  371. /package/dist/{chunk-3BPMYMPX.js.map → chunk-GSBSGT43.js.map} +0 -0
  372. /package/dist/{chunk-645WOU5I.js.map → chunk-H7BZBSP6.js.map} +0 -0
  373. /package/dist/{chunk-GFYFKXWZ.js.map → chunk-HUDPXTXW.js.map} +0 -0
  374. /package/dist/{chunk-L2JQSG5M.js.map → chunk-I7TR2OCU.js.map} +0 -0
  375. /package/dist/{chunk-HKEK27M4.js.map → chunk-IAOW2L6K.js.map} +0 -0
  376. /package/dist/{chunk-STM4T335.js.map → chunk-IJH6METJ.js.map} +0 -0
  377. /package/dist/{chunk-WADPRAZE.js.map → chunk-IZRNMXZC.js.map} +0 -0
  378. /package/dist/{chunk-LAQS5HYU.js.map → chunk-JM6U3SAE.js.map} +0 -0
  379. /package/dist/{chunk-74AY3S7U.js.map → chunk-JNLYHJG7.js.map} +0 -0
  380. /package/dist/{chunk-7ZBANI3M.js.map → chunk-JOOGPZJE.js.map} +0 -0
  381. /package/dist/{chunk-V5RJCXLG.js.map → chunk-JORSMFL6.js.map} +0 -0
  382. /package/dist/{chunk-VKTP3TZB.js.map → chunk-JQCP5QW3.js.map} +0 -0
  383. /package/dist/{chunk-LRJKHXU4.js.map → chunk-JRTKYFFY.js.map} +0 -0
  384. /package/dist/{chunk-UMFBHYPW.js.map → chunk-JT3IXJIL.js.map} +0 -0
  385. /package/dist/{chunk-S53WZWGL.js.map → chunk-JZFJZLJY.js.map} +0 -0
  386. /package/dist/{chunk-6QOL4G76.js.map → chunk-KQXRVELF.js.map} +0 -0
  387. /package/dist/{chunk-USOXPN5H.js.map → chunk-L74NWAD4.js.map} +0 -0
  388. /package/dist/{chunk-Y6Y3TRBN.js.map → chunk-LJXBFVI2.js.map} +0 -0
  389. /package/dist/{chunk-3L5WH6CV.js.map → chunk-LPD6I2U6.js.map} +0 -0
  390. /package/dist/{chunk-LDXS746V.js.map → chunk-LR7RW4T6.js.map} +0 -0
  391. /package/dist/{chunk-FZVZYU5C.js.map → chunk-LXN737FX.js.map} +0 -0
  392. /package/dist/{chunk-ARFT6ZBE.js.map → chunk-MGYZENUY.js.map} +0 -0
  393. /package/dist/{chunk-YQ6SLFNZ.js.map → chunk-MPJDQC4G.js.map} +0 -0
  394. /package/dist/{chunk-5UWP5X3T.js.map → chunk-NJ2DZYEK.js.map} +0 -0
  395. /package/dist/{chunk-MBMT5FUQ.js.map → chunk-O2O4FDAH.js.map} +0 -0
  396. /package/dist/{chunk-GCVUBVEN.js.map → chunk-ODJ2HRFW.js.map} +0 -0
  397. /package/dist/{chunk-2NLLXCJG.js.map → chunk-OWHERGF2.js.map} +0 -0
  398. /package/dist/{chunk-I73ZSORJ.js.map → chunk-OXSTKCYK.js.map} +0 -0
  399. /package/dist/{chunk-CNQQNYJ2.js.map → chunk-P3YUEPSQ.js.map} +0 -0
  400. /package/dist/{chunk-TPKB7T6Z.js.map → chunk-Q6UZREJK.js.map} +0 -0
  401. /package/dist/{chunk-UJDTXWMT.js.map → chunk-QIMGULGN.js.map} +0 -0
  402. /package/dist/{chunk-E24RUQEN.js.map → chunk-QNIYL5SK.js.map} +0 -0
  403. /package/dist/{chunk-KOY25HUB.js.map → chunk-QYAXMXOB.js.map} +0 -0
  404. /package/dist/{chunk-CU7WDDPV.js.map → chunk-RIAKNXZB.js.map} +0 -0
  405. /package/dist/{chunk-UQWA5QDT.js.map → chunk-RO2NNWR5.js.map} +0 -0
  406. /package/dist/{chunk-AYXRK264.js.map → chunk-RROFIAYI.js.map} +0 -0
  407. /package/dist/{chunk-L46Y5FPE.js.map → chunk-RUAIO5UA.js.map} +0 -0
  408. /package/dist/{chunk-QIC7YZ3D.js.map → chunk-RWW5KPIY.js.map} +0 -0
  409. /package/dist/{chunk-E5PVMB3I.js.map → chunk-SDXBR5QO.js.map} +0 -0
  410. /package/dist/{chunk-WSLNC5AL.js.map → chunk-SJHFU52W.js.map} +0 -0
  411. /package/dist/{chunk-7PG7QBWD.js.map → chunk-SRPGA6WN.js.map} +0 -0
  412. /package/dist/{chunk-CUWOSRCS.js.map → chunk-SUKPM6DV.js.map} +0 -0
  413. /package/dist/{chunk-G2SRB62M.js.map → chunk-TTQYX7VU.js.map} +0 -0
  414. /package/dist/{chunk-TDCR6PQL.js.map → chunk-TWRPWJJT.js.map} +0 -0
  415. /package/dist/{chunk-KC5SVCUJ.js.map → chunk-U66CTIF5.js.map} +0 -0
  416. /package/dist/{chunk-D2AKUKAQ.js.map → chunk-UIK3U36O.js.map} +0 -0
  417. /package/dist/{chunk-XLEP7SS3.js.map → chunk-UMSH4I3E.js.map} +0 -0
  418. /package/dist/{chunk-X7Y7WX73.js.map → chunk-UVYI6VIX.js.map} +0 -0
  419. /package/dist/{chunk-LHBOFROT.js.map → chunk-V2XMG7GM.js.map} +0 -0
  420. /package/dist/{chunk-NQOM6PHO.js.map → chunk-VCOCOBUS.js.map} +0 -0
  421. /package/dist/{chunk-4P4VLPGB.js.map → chunk-VECRSYQG.js.map} +0 -0
  422. /package/dist/{chunk-ID2PLENW.js.map → chunk-VHBGJAYC.js.map} +0 -0
  423. /package/dist/{chunk-RVYXSS3Q.js.map → chunk-VIS23B6O.js.map} +0 -0
  424. /package/dist/{chunk-NMKETOAX.js.map → chunk-VSHWPOUB.js.map} +0 -0
  425. /package/dist/{chunk-UBN5AOLT.js.map → chunk-W5EO4USJ.js.map} +0 -0
  426. /package/dist/{chunk-Y7427SL7.js.map → chunk-WCGJK4NQ.js.map} +0 -0
  427. /package/dist/{chunk-CCYXCT4B.js.map → chunk-WQYS47G4.js.map} +0 -0
  428. /package/dist/{chunk-JH2ALMPR.js.map → chunk-WR5POHQ3.js.map} +0 -0
  429. /package/dist/{chunk-DK5VMJL3.js.map → chunk-WT2VVYBM.js.map} +0 -0
  430. /package/dist/{chunk-EHIKY2IA.js.map → chunk-WU5WTCH5.js.map} +0 -0
  431. /package/dist/{chunk-QKXPOLQD.js.map → chunk-WUBGMV3G.js.map} +0 -0
  432. /package/dist/{chunk-O6YJI5VX.js.map → chunk-WUL6LDJ4.js.map} +0 -0
  433. /package/dist/{chunk-5EILJ6W2.js.map → chunk-WXPBDEMW.js.map} +0 -0
  434. /package/dist/{chunk-U7HJBODU.js.map → chunk-XKTHJHSQ.js.map} +0 -0
  435. /package/dist/{chunk-JFI3ATK4.js.map → chunk-XMYWYJM2.js.map} +0 -0
  436. /package/dist/{chunk-64S6X4IU.js.map → chunk-XTN54NML.js.map} +0 -0
  437. /package/dist/{chunk-VGFNTY3Y.js.map → chunk-YFXRLRKP.js.map} +0 -0
  438. /package/dist/{chunk-DAOMWGO2.js.map → chunk-ZX5N5D6M.js.map} +0 -0
  439. /package/dist/{chunk-PTRPOJ7U.js.map → chunk-ZXFKG7VZ.js.map} +0 -0
  440. /package/dist/{resolution-4ZEQPXUZ.js.map → extraction-window-drain.js.map} +0 -0
@@ -38,6 +38,7 @@ export interface ExtractionRunResult {
38
38
  persistedCount: number;
39
39
  durableOutputCount: number;
40
40
  postPersistMetadataFailed?: boolean;
41
+ retainedBuffer?: boolean; failureClass?: ExtractionFailureClass; // retained: the run left the window in the buffer for a retry (a recorded failure) of this class
41
42
  }
42
43
 
43
44
  export class ExtractionDeadlineError extends Error {
@@ -118,7 +119,7 @@ import {
118
119
  commitEmptySuccessExtraction,
119
120
  computeExtractionRetryNextEligibleMs,
120
121
  deriveSourceConnector,
121
- deriveTopicsFromExtraction,
122
+ deriveTopicsFromExtraction, emptyExtractionResult,
122
123
  runExtractionPostPersist,
123
124
  runExtractionPostPersistBestEffort,
124
125
  EXTRACTION_RETRY_STATE_MAX_ENTRIES,
@@ -439,7 +440,7 @@ export class ExtractionRunCoordinator {
439
440
  turns: BufferTurn[],
440
441
  options: {
441
442
  clearBufferAfterExtraction?: boolean;
442
- clearMatchingTurns?: boolean;
443
+ clearMatchingTurns?: boolean; retentionWindow?: readonly BufferTurn[];
443
444
  skipCharThreshold?: boolean;
444
445
  skipUserTurnThreshold?: boolean;
445
446
  deadlineMs?: number;
@@ -1044,7 +1045,7 @@ export class ExtractionRunCoordinator {
1044
1045
  if (!shouldPersistProcessedFingerprint) {
1045
1046
  await commitEmptySuccessExtraction(emptySuccessCommit);
1046
1047
  }
1047
- return { status: "skipped", reason: "empty_extraction_result", persistedCount: 0, durableOutputCount: 0 };
1048
+ return emptyExtractionResult(recordedRetryFailure, result.extractionFailureClass);
1048
1049
  }
1049
1050
 
1050
1051
  let threadIdForExtraction: string | null = null;
@@ -1108,7 +1109,7 @@ export class ExtractionRunCoordinator {
1108
1109
  normalizedTurns: normalizedTurns as BufferTurn[],
1109
1110
  bufferKey,
1110
1111
  retainDeferredTurns: (key, retainedTurns, max) =>
1111
- this.deps.getBuffer().retainDeferredTurns(key, retainedTurns, max, turns),
1112
+ this.deps.getBuffer().retainDeferredTurns(key, retainedTurns, max, options.retentionWindow ?? turns),
1112
1113
  clearBuffer,
1113
1114
  failOnExtractionFailure: options.failOnExtractionFailure === true,
1114
1115
  });
@@ -42,6 +42,7 @@ import { TranscriptManager } from "../transcript.js";
42
42
  import type { BufferTurn, PluginConfig, SourceConnectorProvenance } from "../types.js";
43
43
 
44
44
  import { groupTurnsByExtractionScope, bufferTurnsEqual } from "../buffer-turn-helpers.js";
45
+ import { ExtractionDrain } from "./extraction-drain.js";
45
46
  import { resolveScopeProfilePlan, type ResolvedScopeProfilePlan, hasExplicitNamespacePolicy } from "../namespaces/scope-profiles.js";
46
47
  import { resolveCodingNamespaceOverlay, combineNamespaces } from "../coding/coding-namespace.js";
47
48
  import { canWriteNamespace, defaultNamespaceForPrincipal } from "../namespaces/principal.js";
@@ -114,6 +115,8 @@ export interface TurnIngestionDeps {
114
115
  },
115
116
  ): Promise<void>;
116
117
  resolveMemoryIdOrHandle(ref: string, sessionKey?: string): string;
118
+ /** Max conversation chars the extraction model accepts; absent on legacy hosts (single-run behavior). */
119
+ extractionWindowBudgetChars?(): number;
117
120
  runExtraction(
118
121
  ...args: Parameters<ExtractionRunCoordinator["runExtraction"]>
119
122
  ): Promise<ExtractionRunResult>;
@@ -156,9 +159,10 @@ function isFlushPlanRecoveryTurn(
156
159
  }
157
160
 
158
161
  export class TurnIngestionCoordinator {
159
- constructor(
160
- private readonly deps: TurnIngestionDeps,
161
- ) {}
162
+ private readonly drain: ExtractionDrain; // chunked trigger-drain (extraction-drain.ts)
163
+ constructor(private readonly deps: TurnIngestionDeps) {
164
+ this.drain = new ExtractionDrain(deps);
165
+ }
162
166
 
163
167
  async processTurn(
164
168
  role: "user" | "assistant",
@@ -1067,7 +1071,7 @@ export class TurnIngestionCoordinator {
1067
1071
  effectiveScopePlan = fresh;
1068
1072
  }
1069
1073
  }
1070
- const result = await this.deps.runExtraction(effectiveTurns, {
1074
+ const result = await this.drain.run(effectiveTurns, {
1071
1075
  clearBufferAfterExtraction:
1072
1076
  options.clearBufferAfterExtraction ?? true,
1073
1077
  clearMatchingTurns: options.clearMatchingTurns === true,
@@ -1083,7 +1087,7 @@ export class TurnIngestionCoordinator {
1083
1087
  principalOverride: options.principalOverride,
1084
1088
  scopeProfileWritePlan: effectiveScopePlan,
1085
1089
  forceExtractionAttempt: options.forceExtractionAttempt === true,
1086
- });
1090
+ }, preemptable);
1087
1091
  settleTask(undefined, result);
1088
1092
  } catch (err) {
1089
1093
  const reason = abortSignal.reason;
@@ -238,6 +238,7 @@ import {
238
238
  } from "./maintenance/pattern-reinforcement.js";
239
239
  import { refreshConvergedNamespaces } from "./convergence-refresh.js";
240
240
  import { ModelRegistry } from "./model-registry.js";
241
+ import { extractionWindowBudgetChars } from "./extraction-window-drain.js";
241
242
  import { applyRuntimeRetrievalPolicy, expandQuery } from "./retrieval.js";
242
243
  import {
243
244
  mergeWithAgentResults,
@@ -3062,6 +3063,26 @@ export class Orchestrator {
3062
3063
  );
3063
3064
  }
3064
3065
 
3066
+ /**
3067
+ * Max conversation characters the extraction model can take as input
3068
+ * (context window the ModelRegistry learned, capped by
3069
+ * `localLlmMaxContext` when set). Exposed for the trigger-drain chunking
3070
+ * in the turn-ingestion coordinator so an oversized buffer window is
3071
+ * drained in fitting chunks instead of failing whole.
3072
+ */
3073
+ private extractionWindowBudgetChars(): number {
3074
+ // Object.create(Orchestrator.prototype) test doubles skip the constructor,
3075
+ // so neither modelRegistry nor config exists there: report "no budget".
3076
+ if (!this.modelRegistry) return Number.POSITIVE_INFINITY;
3077
+ return extractionWindowBudgetChars({
3078
+ registry: this.modelRegistry,
3079
+ localExtractionActive:
3080
+ this.config.modelSource !== "gateway" && resolveLocalLlmCapabilities(this.config).localLlm,
3081
+ model: this.config.localLlmModel,
3082
+ maxContext: this.config.localLlmMaxContext,
3083
+ });
3084
+ }
3085
+
3065
3086
  private normalizeExtractionFingerprintTurns(turns: BufferTurn[]): string[] {
3066
3087
  return this.extractionRunCoordinator.normalizeExtractionFingerprintTurns(turns);
3067
3088
  }
@@ -902,7 +902,9 @@ const ENCRYPTABLE_STATE_SIDECARS = new Set([
902
902
  ]);
903
903
 
904
904
  function isEncryptableStateSidecar(normalized: string): boolean {
905
- return ENCRYPTABLE_STATE_SIDECARS.has(normalized);
905
+ // state/dropped/ holds copies of extraction-buffer turns dropped after
906
+ // repeated extraction failures — same content sensitivity as buffer.json.
907
+ return ENCRYPTABLE_STATE_SIDECARS.has(normalized) || normalized.startsWith("state/dropped/");
906
908
  }
907
909
 
908
910
  /**
@@ -0,0 +1,27 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { mkdir } from "node:fs/promises";
3
+ import path from "node:path";
4
+ import type { BufferTurn } from "../types.js";
5
+
6
+ /**
7
+ * Persist a copy of extraction-buffer turns that are being DROPPED after repeated extraction failures (trigger-drain drop
8
+ * path), so a destructive drop never loses content silently. Written under `<stateDir>/dropped/` through the store's secure
9
+ * writer, so encrypted stores keep it encrypted (secure-fs encrypts the whole `state/dropped/` prefix). Returns the path.
10
+ */
11
+ export async function saveDroppedExtractionChunk(
12
+ stateDir: string,
13
+ writeSecureFile: (filePath: string, content: string) => Promise<void>,
14
+ bufferKey: string,
15
+ reason: string,
16
+ turns: readonly BufferTurn[],
17
+ ): Promise<string> {
18
+ const droppedDir = path.join(stateDir, "dropped");
19
+ await mkdir(droppedDir, { recursive: true });
20
+ const safeKey = bufferKey.replace(/[^a-zA-Z0-9._-]/g, "-").slice(0, 80) || "default";
21
+ // The random suffix keeps copies written in the same millisecond (or for keys that truncate to the same name) from
22
+ // overwriting each other.
23
+ const filePath = path.join(droppedDir, `${Date.now()}-${randomUUID().slice(0, 8)}-${safeKey}.json`);
24
+ const payload = { bufferKey, reason, droppedAt: new Date().toISOString(), turns };
25
+ await writeSecureFile(filePath, JSON.stringify(payload, null, 2));
26
+ return filePath;
27
+ }
@@ -0,0 +1,30 @@
1
+ import assert from "node:assert/strict";
2
+ import { mkdtemp, readdir, rm } from "node:fs/promises";
3
+ import os from "node:os";
4
+ import path from "node:path";
5
+ import test from "node:test";
6
+ import { StorageManager } from "./storage.js";
7
+ import type { BufferTurn } from "./types.js";
8
+
9
+ function makeTurn(content: string): BufferTurn {
10
+ return { role: "user", content, timestamp: "2026-10-29T00:00:00.000Z", sessionKey: "s1" };
11
+ }
12
+
13
+ test("dropped-chunk recovery files never overwrite each other, even within one millisecond", async () => {
14
+ const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-dropped-chunks-"));
15
+ const realNow = Date.now;
16
+ try {
17
+ Date.now = () => 1_793_000_000_000;
18
+ const storage = new StorageManager(dir);
19
+ await storage.ensureDirectories();
20
+ const first = await storage.saveDroppedExtractionChunk("same-key", "first", [makeTurn("one")]);
21
+ const second = await storage.saveDroppedExtractionChunk("same-key", "second", [makeTurn("two")]);
22
+
23
+ assert.notEqual(first, second);
24
+ const files = await readdir(path.dirname(first));
25
+ assert.equal(files.length, 2, "both safety copies exist");
26
+ } finally {
27
+ Date.now = realNow;
28
+ await rm(dir, { recursive: true, force: true });
29
+ }
30
+ });
package/src/storage.ts CHANGED
@@ -144,6 +144,7 @@ import {
144
144
  import { supersessionKeysForFact } from "./temporal-supersession.js";
145
145
  import { BufferSessionFiles } from "./storage/buffer-session-files.js";
146
146
  import { runSupersessionSideEffects, type SupersessionAuditOptions } from "./storage/supersession-side-effects.js";
147
+ import { saveDroppedExtractionChunk as saveDroppedChunk } from "./storage/dropped-extraction-chunk.js";
147
148
  import type {
148
149
  AccessTrackingEntry,
149
150
  BufferEntryState,
@@ -4799,7 +4800,6 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
4799
4800
  return results.filter((filePath): filePath is string => filePath !== null);
4800
4801
  }
4801
4802
 
4802
-
4803
4803
  private orderWindowPaths(filePaths: string[]): string[] {
4804
4804
  const correctionPaths: string[] = [];
4805
4805
  const factPaths: string[] = [];
@@ -5520,6 +5520,9 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
5520
5520
  async saveBuffer(state: BufferState): Promise<void> { await this.bufferSessionFiles().reconcile(state); }
5521
5521
  async saveBufferSession(key: string, entry: BufferEntryState): Promise<void> { await this.bufferSessionFiles().save(key, entry); }
5522
5522
  async deleteBufferSession(key: string): Promise<void> { await this.bufferSessionFiles().remove(key); }
5523
+ saveDroppedExtractionChunk(bufferKey: string, reason: string, turns: readonly import("./types.js").BufferTurn[]): Promise<string> { // storage/dropped-extraction-chunk.ts
5524
+ return saveDroppedChunk(this.stateDir, (file, content) => this.writeStorageSecureFile(file, content), bufferKey, reason, turns);
5525
+ }
5523
5526
 
5524
5527
  async loadMeta(): Promise<MetaState> {
5525
5528
  const metaPath = path.join(this.stateDir, "meta.json");
@@ -5564,8 +5567,7 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
5564
5567
 
5565
5568
  async saveMeta(state: MetaState): Promise<void> {
5566
5569
  await this.ensureDirectories();
5567
- const metaPath = path.join(this.stateDir, "meta.json");
5568
- await this.writeStorageSecureFile(metaPath, JSON.stringify(state, null, 2));
5570
+ await this.writeStorageSecureFile(path.join(this.stateDir, "meta.json"), JSON.stringify(state, null, 2));
5569
5571
  }
5570
5572
 
5571
5573
  async appendMemoryActionEvents(events: MemoryActionEvent[]): Promise<number> {
@@ -7208,10 +7210,7 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
7208
7210
  async saveTopics(topics: TopicScore[]): Promise<void> {
7209
7211
  const metaPath = path.join(this.stateDir, "topics.json");
7210
7212
  await mkdir(this.stateDir, { recursive: true });
7211
- await this.writeStorageSecureFile(
7212
- metaPath,
7213
- JSON.stringify({ topics, updatedAt: new Date().toISOString() }, null, 2)
7214
- );
7213
+ await this.writeStorageSecureFile(metaPath, JSON.stringify({ topics, updatedAt: new Date().toISOString() }, null, 2));
7215
7214
  log.debug(`saved ${topics.length} topic scores`);
7216
7215
  }
7217
7216
 
package/src/types.ts CHANGED
@@ -1299,6 +1299,18 @@ export interface PluginConfig
1299
1299
  extractionJudgeModel: string;
1300
1300
  /** Maximum number of candidate facts per judge LLM batch call. */
1301
1301
  extractionJudgeBatchSize: number;
1302
+ /**
1303
+ * Per-call timeout for the judge LLM (ms). Default 20000: measured 2.1-2.5 s
1304
+ * per compact verdict call (completion budget 24 tokens per candidate, up
1305
+ * to 2048) on a small fast judge model; the big shared core model measured
1306
+ * 13-22 s per compact call, 41 s verbose — raise it there. The earlier 150s
1307
+ * default only papered over 59-305s verbose replies; sub-second budgets
1308
+ * abort every call. On the local LLM path each attempt lasts
1309
+ * min(localLlmTimeoutMs, extractionJudgeTimeoutMs) (localLlmTimeoutMs
1310
+ * defaults to 180000), so a value above localLlmTimeoutMs does not lengthen
1311
+ * an attempt: raise both settings for a slower judge model.
1312
+ */
1313
+ extractionJudgeTimeoutMs: number;
1302
1314
  /** Shadow mode: log judge verdicts but do not filter facts. Default false. */
1303
1315
  extractionJudgeShadow: boolean;
1304
1316
  /**
@@ -1685,6 +1697,13 @@ export interface PluginConfig
1685
1697
  extractionBreakerCooldownMs: number;
1686
1698
  /** Breaker open cooldown (ms) for auth/config failures (longer — provider is misconfigured). */
1687
1699
  extractionBreakerAuthCooldownMs: number;
1700
+ /**
1701
+ * Consecutive failed extraction attempts after which the failing
1702
+ * trigger-drain chunk is dropped (with a side-file copy under
1703
+ * `state/dropped/`) so a session whose window never extracts cannot stall
1704
+ * the buffer forever. Default: `5`.
1705
+ */
1706
+ extractionChunkDropAfterFailures: number;
1688
1707
  // Local LLM fast tier (v9.1) — smaller model for quick ops
1689
1708
  localLlmFastEnabled: boolean;
1690
1709
  localLlmFastModel: string;