@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
package/dist/who-knows.js CHANGED
@@ -9,22 +9,22 @@ import {
9
9
  loadWhoKnowsEntities,
10
10
  tokenizeTopic,
11
11
  validateWhoKnowsInput
12
- } from "./chunk-DK5VMJL3.js";
13
- import "./chunk-R6TCM47S.js";
12
+ } from "./chunk-WT2VVYBM.js";
13
+ import "./chunk-5KZNWERU.js";
14
14
  import "./chunk-UHVXE24Y.js";
15
15
  import "./chunk-DM5QZ3YU.js";
16
16
  import "./chunk-VY6BD5KB.js";
17
- import "./chunk-JH4FCVWJ.js";
18
- import "./chunk-LHBOFROT.js";
19
- import "./chunk-P5CUEB2Q.js";
17
+ import "./chunk-G6OFEGUR.js";
18
+ import "./chunk-V2XMG7GM.js";
19
+ import "./chunk-4QLKVZH6.js";
20
+ import "./chunk-XKDQTDXN.js";
21
+ import "./chunk-CYEPCZN5.js";
20
22
  import "./chunk-XRFLR3XF.js";
21
23
  import "./chunk-7VO6E5UD.js";
22
24
  import "./chunk-EXYT52NR.js";
23
25
  import "./chunk-5CWH2LKL.js";
24
- import "./chunk-XKDQTDXN.js";
25
26
  import "./chunk-WNEVEMJ3.js";
26
27
  import "./chunk-Y5NLBXPV.js";
27
- import "./chunk-CYEPCZN5.js";
28
28
  import "./chunk-TFA6HPOA.js";
29
29
  import "./chunk-F4TWWUMP.js";
30
30
  import "./chunk-72A4L5JJ.js";
@@ -34,17 +34,17 @@ import "./chunk-PPUNC7UX.js";
34
34
  import "./chunk-X3724WL4.js";
35
35
  import "./chunk-MRPOZBJC.js";
36
36
  import "./chunk-S2HLHAZ4.js";
37
- import "./chunk-DM2T26WE.js";
38
37
  import "./chunk-LDXUBPMO.js";
38
+ import "./chunk-DM2T26WE.js";
39
39
  import "./chunk-FF6N7BXC.js";
40
- import "./chunk-5EILJ6W2.js";
40
+ import "./chunk-WXPBDEMW.js";
41
41
  import "./chunk-AAD2ZS6P.js";
42
- import "./chunk-YQ6SLFNZ.js";
42
+ import "./chunk-MPJDQC4G.js";
43
43
  import "./chunk-ZIKENA2C.js";
44
+ import "./chunk-3ONXXHQO.js";
44
45
  import "./chunk-YXZG5TVN.js";
45
46
  import "./chunk-3OUGSOJP.js";
46
47
  import "./chunk-SCU65EZI.js";
47
- import "./chunk-3ONXXHQO.js";
48
48
  import "./chunk-P4GUQSK3.js";
49
49
  import "./chunk-3WU7XOFN.js";
50
50
  import "./chunk-G7D6GZ5J.js";
@@ -55,16 +55,16 @@ import "./chunk-LWRIGKFM.js";
55
55
  import "./chunk-5WITETWU.js";
56
56
  import "./chunk-6CIAGZ6X.js";
57
57
  import "./chunk-7CT3AI52.js";
58
- import "./chunk-AYXRK264.js";
59
- import "./chunk-IUM3VSHI.js";
58
+ import "./chunk-RROFIAYI.js";
60
59
  import "./chunk-G26YNEOC.js";
61
- import "./chunk-VILPVT4S.js";
62
60
  import "./chunk-AF2XMJKD.js";
63
61
  import "./chunk-OR42ZI54.js";
62
+ import "./chunk-IUM3VSHI.js";
63
+ import "./chunk-VILPVT4S.js";
64
64
  import "./chunk-23G5P7TA.js";
65
65
  import "./chunk-C64XATK7.js";
66
66
  import "./chunk-42JKGUFJ.js";
67
- import "./chunk-GMMZ45C4.js";
67
+ import "./chunk-AVVCPA7U.js";
68
68
  import "./chunk-I55KAVET.js";
69
69
  import "./chunk-L2EXJQJP.js";
70
70
  import "./chunk-45GF7Y3V.js";
@@ -77,23 +77,23 @@ import "./chunk-YCVB7X56.js";
77
77
  import "./chunk-PQVCH2AE.js";
78
78
  import "./chunk-PJKTFXE2.js";
79
79
  import "./chunk-W5BIQOAJ.js";
80
- import "./chunk-A6PKEU7T.js";
80
+ import "./chunk-PARM6OYL.js";
81
81
  import "./chunk-YBA52OKG.js";
82
- import "./chunk-TDCR6PQL.js";
82
+ import "./chunk-TWRPWJJT.js";
83
83
  import "./chunk-BT7NVCML.js";
84
- import "./chunk-E5PVMB3I.js";
84
+ import "./chunk-SDXBR5QO.js";
85
85
  import "./chunk-BJMBJZ2Y.js";
86
86
  import "./chunk-UKJAGEXH.js";
87
87
  import "./chunk-FP2373TW.js";
88
88
  import "./chunk-L272A5QW.js";
89
- import "./chunk-UJDTXWMT.js";
89
+ import "./chunk-QIMGULGN.js";
90
90
  import "./chunk-ZA53AZND.js";
91
91
  import "./chunk-7RJUVTVF.js";
92
92
  import "./chunk-AL3UYZ5N.js";
93
93
  import "./chunk-RL6NEVXT.js";
94
94
  import "./chunk-YET735EZ.js";
95
95
  import "./chunk-PWPIERBM.js";
96
- import "./chunk-UBN5AOLT.js";
96
+ import "./chunk-W5EO4USJ.js";
97
97
  import "./chunk-5FVVY2EB.js";
98
98
  import "./chunk-BTNNL7ZW.js";
99
99
  import "./chunk-JDSVLVCG.js";
@@ -111,7 +111,7 @@ import "./chunk-3MUKQQ7A.js";
111
111
  import "./chunk-R2MBW2S4.js";
112
112
  import "./chunk-QUIRIG2P.js";
113
113
  import "./chunk-LDPPTPO5.js";
114
- import "./chunk-TYGLV6ZG.js";
114
+ import "./chunk-EYGOM6AI.js";
115
115
  import "./chunk-A6XUJE5D.js";
116
116
  import "./chunk-C7HJ3NEI.js";
117
117
  import "./chunk-VS2IYZRU.js";
@@ -12,10 +12,10 @@ import {
12
12
  isMemoryCategory,
13
13
  isSealedMemoryEnvelope,
14
14
  sealedWriteToLegacyArgs
15
- } from "./chunk-TDCR6PQL.js";
15
+ } from "./chunk-TWRPWJJT.js";
16
16
  import "./chunk-BT7NVCML.js";
17
- import "./chunk-E5PVMB3I.js";
18
- import "./chunk-UBN5AOLT.js";
17
+ import "./chunk-SDXBR5QO.js";
18
+ import "./chunk-W5EO4USJ.js";
19
19
  import "./chunk-5FVVY2EB.js";
20
20
  import "./chunk-JDSVLVCG.js";
21
21
  import "./chunk-5GKPFL3S.js";
@@ -24,7 +24,7 @@ import "./chunk-EBRG7ZIK.js";
24
24
  import "./chunk-P7FMDTKL.js";
25
25
  import "./chunk-X4OZMANG.js";
26
26
  import "./chunk-R2MBW2S4.js";
27
- import "./chunk-TYGLV6ZG.js";
27
+ import "./chunk-EYGOM6AI.js";
28
28
  import "./chunk-A6XUJE5D.js";
29
29
  import "./chunk-C7HJ3NEI.js";
30
30
  import "./chunk-VS2IYZRU.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remnic/core",
3
- "version": "10.0.37",
3
+ "version": "10.0.39",
4
4
  "description": "Framework-agnostic Remnic memory engine — orchestrator, storage, extraction, search, trust zones",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -3347,7 +3347,7 @@
3347
3347
  "core"
3348
3348
  ],
3349
3349
  "peerDependencies": {
3350
- "@remnic/coding-graph": "^10.0.37"
3350
+ "@remnic/coding-graph": "^10.0.39"
3351
3351
  },
3352
3352
  "peerDependenciesMeta": {
3353
3353
  "@remnic/coding-graph": {
@@ -0,0 +1,196 @@
1
+ import test from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { mkdtemp, rm } from "node:fs/promises";
4
+ import os from "node:os";
5
+ import path from "node:path";
6
+ import { SmartBuffer } from "./buffer.js";
7
+ import { parseConfig } from "./config.js";
8
+ import { StorageManager } from "./storage.js";
9
+ import type { BufferTurn } from "./types.js";
10
+ import { ExtractionDrain } from "./orchestration/extraction-drain.js";
11
+ import type { ExtractionRunResult } from "./orchestration/extraction-run.js";
12
+
13
+ function makeTurn(sessionKey: string, content: string): BufferTurn {
14
+ return {
15
+ role: "user",
16
+ content,
17
+ timestamp: "2026-10-29T12:00:00.000Z",
18
+ sessionKey,
19
+ };
20
+ }
21
+
22
+ /** A real buffer on real storage; `restart()` is what a process restart would load from disk. */
23
+ async function withBuffer(run: (buffer: SmartBuffer, restart: () => Promise<SmartBuffer>) => Promise<void>): Promise<void> {
24
+ const root = await mkdtemp(path.join(os.tmpdir(), "remnic-drop-chunk-"));
25
+ try {
26
+ const buffer = new SmartBuffer(parseConfig({}), new StorageManager(root));
27
+ await run(buffer, async () => {
28
+ const reloaded = new SmartBuffer(parseConfig({}), new StorageManager(root));
29
+ await reloaded.load();
30
+ return reloaded;
31
+ });
32
+ } finally {
33
+ await rm(root, { recursive: true, force: true });
34
+ }
35
+ }
36
+
37
+ test("dropExtractionChunk removes the matched prefix and the drop survives a restart", async () => {
38
+ await withBuffer(async (buffer, restart) => {
39
+ const turns = [makeTurn("s1", "turn one"), makeTurn("s1", "turn two"), makeTurn("s1", "turn three")];
40
+ for (const turn of turns) await buffer.addTurn("s1", turn);
41
+ await buffer.flushPendingSave();
42
+
43
+ const dropped = await buffer.dropExtractionChunk("s1", turns.slice(0, 2));
44
+
45
+ assert.equal(dropped, 2);
46
+ assert.deepEqual(buffer.getTurns("s1").map((turn) => turn.content), ["turn three"]);
47
+ assert.deepEqual((await restart()).getTurns("s1").map((turn) => turn.content), ["turn three"], "what a restart loads");
48
+ // A drop is not an extraction: the extraction bookkeeping stays untouched.
49
+ assert.equal(buffer.getExtractionCount("s1"), 0);
50
+ });
51
+ });
52
+
53
+ test("dropExtractionChunk returns zero without dropping when turns no longer match", async () => {
54
+ await withBuffer(async (buffer, restart) => {
55
+ await buffer.addTurn("s1", makeTurn("s1", "kept turn"));
56
+ await buffer.flushPendingSave();
57
+
58
+ const dropped = await buffer.dropExtractionChunk("s1", [makeTurn("s1", "already extracted elsewhere")]);
59
+
60
+ assert.equal(dropped, 0);
61
+ assert.equal(buffer.getTurns("s1").length, 1);
62
+ assert.equal((await restart()).getTurns("s1").length, 1, "the kept turn is still there after a restart");
63
+ });
64
+ });
65
+
66
+ test("dropExtractionChunk drops the whole matched window and a restart finds the buffer empty", async () => {
67
+ await withBuffer(async (buffer, restart) => {
68
+ const turns = [makeTurn("s1", "only turn")];
69
+ await buffer.addTurn("s1", turns[0]!);
70
+ await buffer.flushPendingSave();
71
+
72
+ const dropped = await buffer.dropExtractionChunk("s1", turns);
73
+
74
+ assert.equal(dropped, 1);
75
+ assert.equal(buffer.getTurns("s1").length, 0);
76
+ assert.equal((await restart()).getTurns("s1").length, 0);
77
+ });
78
+ });
79
+
80
+ const FAILED: ExtractionRunResult = { status: "skipped", reason: "empty_extraction_result", retainedBuffer: true, failureClass: "parse_empty", persistedCount: 0, durableOutputCount: 0 };
81
+ const DONE: ExtractionRunResult = { status: "completed", persistedCount: 1, durableOutputCount: 1 };
82
+
83
+ /** w7K's probe on #3266: a pinned capture sits before a native group drained with clearMatchingTurns. */
84
+ async function drainBehindPinnedCapture(buffer: SmartBuffer, results: ExtractionRunResult[], dropAfter: number): Promise<ExtractionRunResult> {
85
+ const pinned: BufferTurn = { ...makeTurn("s1", "pinned capture"), acceptedCapture: true };
86
+ const native = [makeTurn("s1", "a".repeat(60)), makeTurn("s1", "b".repeat(60))];
87
+ for (const turn of [pinned, ...native]) await buffer.addTurn("s1", turn);
88
+ await buffer.flushPendingSave();
89
+ const drain = new ExtractionDrain({
90
+ config: { extractionMinUserTurns: 1, extractionMinChars: 0, extractionMaxTurnChars: 100_000, extractionChunkDropAfterFailures: dropAfter },
91
+ extractionWindowBudgetChars: () => 100,
92
+ runExtraction: async (turns, options) => {
93
+ const result = results.shift() ?? DONE;
94
+ // A successful run clears its chunk the way the coordinator does for a native group: by identity.
95
+ if (result.status === "completed") await buffer.clearAfterExtraction("s1", turns, options?.clearMatchingTurns === true ? { allowNonPrefix: true } : undefined);
96
+ return result;
97
+ },
98
+ getStorage: async () => ({ saveDroppedExtractionChunk: async () => "/recovery/copy.json" }),
99
+ buffer,
100
+ extractionQueueCoordinator: { beginPreemptable: () => {} },
101
+ });
102
+ return await drain.run(native, {
103
+ bufferKey: "s1",
104
+ clearBufferAfterExtraction: true,
105
+ clearMatchingTurns: true,
106
+ skipUserTurnThreshold: false,
107
+ failOnExtractionFailure: false,
108
+ forceExtractionAttempt: false,
109
+ });
110
+ }
111
+
112
+ test("a dropped chunk behind a pinned capture is removed by identity, like a successful clear (w7K)", async () => {
113
+ await withBuffer(async (buffer, restart) => {
114
+ const result = await drainBehindPinnedCapture(buffer, [FAILED, DONE], 1);
115
+
116
+ assert.equal(result.status, "completed");
117
+ assert.deepEqual(buffer.getTurns("s1").map((turn) => turn.content), ["pinned capture"], "the failed turn is gone, the pinned capture stays");
118
+ assert.deepEqual((await restart()).getTurns("s1").map((turn) => turn.content), ["pinned capture"], "and a restart agrees");
119
+ });
120
+ });
121
+
122
+ test("a failed chunk made only of deferred-retained turns can be dropped, and a restart agrees (Codex P2)", async () => {
123
+ await withBuffer(async (buffer, restart) => {
124
+ const retained = [makeTurn("s1", "retained one"), makeTurn("s1", "retained two")];
125
+ const live = makeTurn("s1", "live turn");
126
+ await buffer.retainDeferredTurns("s1", retained);
127
+ await buffer.addTurn("s1", live);
128
+ await buffer.flushPendingSave();
129
+
130
+ // The window a trigger snapshot sees is the retained turns followed by the live ones; the first chunk is retained-only.
131
+ const dropped = await buffer.dropExtractionChunk("s1", retained);
132
+
133
+ assert.equal(dropped, 2);
134
+ assert.deepEqual(buffer.getRetainedDeferredTurns("s1"), []);
135
+ assert.deepEqual(buffer.getTurns("s1").map((turn) => turn.content), ["live turn"]);
136
+ const reloaded = await restart();
137
+ assert.deepEqual(reloaded.getRetainedDeferredTurns("s1"), [], "retained turns stay dropped after a restart");
138
+ assert.deepEqual(reloaded.getTurns("s1").map((turn) => turn.content), ["live turn"]);
139
+ });
140
+ });
141
+
142
+ test("a chunk that spans retained and live turns drops both", async () => {
143
+ await withBuffer(async (buffer, restart) => {
144
+ const retained = [makeTurn("s1", "retained one")];
145
+ const live = [makeTurn("s1", "live one"), makeTurn("s1", "live two")];
146
+ await buffer.retainDeferredTurns("s1", retained);
147
+ for (const turn of live) await buffer.addTurn("s1", turn);
148
+ await buffer.flushPendingSave();
149
+
150
+ const dropped = await buffer.dropExtractionChunk("s1", [...retained, live[0]!]);
151
+
152
+ assert.equal(dropped, 2);
153
+ assert.deepEqual((await restart()).getTurns("s1").map((turn) => turn.content), ["live two"]);
154
+ });
155
+ });
156
+
157
+ test("deferred retention across chunks of one window stays within one retention window (Codex P2)", async () => {
158
+ await withBuffer(async (buffer, restart) => {
159
+ const window = Array.from({ length: 30 }, (_, i) => makeTurn("s1", `turn ${i}`));
160
+ for (const turn of window) await buffer.addTurn("s1", turn);
161
+ // Three chunks of ten, each deferring all of its turns; every run names the whole window as the processed snapshot.
162
+ for (let chunk = 0; chunk < 3; chunk++) {
163
+ await buffer.retainDeferredTurns("s1", window.slice(chunk * 10, chunk * 10 + 10), 10, window);
164
+ }
165
+ assert.equal(buffer.getRetainedDeferredTurns("s1").length, 10, "the latest chunk's retention replaces the earlier ones");
166
+ assert.equal((await restart()).getRetainedDeferredTurns("s1").length, 10);
167
+ });
168
+ });
169
+
170
+ test("a chunk holding only some retained turns drops those and keeps the rest of the retention slot (Phosphene)", async () => {
171
+ await withBuffer(async (buffer, restart) => {
172
+ const retained = [makeTurn("s1", "retained one"), makeTurn("s1", "retained two"), makeTurn("s1", "retained three")];
173
+ await buffer.retainDeferredTurns("s1", retained);
174
+ await buffer.addTurn("s1", makeTurn("s1", "live turn"));
175
+ await buffer.flushPendingSave();
176
+
177
+ const dropped = await buffer.dropExtractionChunk("s1", retained.slice(0, 2));
178
+
179
+ assert.equal(dropped, 2);
180
+ assert.deepEqual(buffer.getRetainedDeferredTurns("s1").map((turn) => turn.content), ["retained three"]);
181
+ const reloaded = await restart();
182
+ assert.deepEqual(reloaded.getRetainedDeferredTurns("s1").map((turn) => turn.content), ["retained three"]);
183
+ assert.deepEqual(reloaded.getTurns("s1").map((turn) => turn.content), ["retained three", "live turn"]);
184
+ });
185
+ });
186
+
187
+ test("retention for an early chunk leaves the retained turns of a later, unprocessed chunk alone (Codex P2)", async () => {
188
+ await withBuffer(async (buffer, restart) => {
189
+ const retained = [makeTurn("s1", "early retained"), makeTurn("s1", "late retained")];
190
+ await buffer.retainDeferredTurns("s1", retained);
191
+ // Chunk 0 holds the first retained turn; nothing was deferred in it, so it clears the slot for the turns it processed.
192
+ await buffer.retainDeferredTurns("s1", [], 0, retained.slice(0, 1));
193
+ assert.deepEqual(buffer.getRetainedDeferredTurns("s1").map((turn) => turn.content), ["late retained"]);
194
+ assert.deepEqual((await restart()).getRetainedDeferredTurns("s1").map((turn) => turn.content), ["late retained"]);
195
+ });
196
+ });
@@ -0,0 +1,65 @@
1
+ /** Types split out of buffer.ts (structural ratchet, issue #1995). */
2
+
3
+ import type { BufferTurn } from "./types.js";
4
+
5
+ /**
6
+ * Optional surprise probe injected into `SmartBuffer`.
7
+ *
8
+ * Computes a D-MEM-style novelty score in `[0, 1]` for an incoming turn.
9
+ * The buffer treats the probe as purely additive: if it is not provided, if
10
+ * the feature flag is off, or if the probe throws/times out, the buffer
11
+ * falls back to the existing signal/turn-count/time triggers unchanged.
12
+ *
13
+ * Callers are responsible for sampling recent memories and passing them
14
+ * through the embedding pipeline — the buffer does not want to know about
15
+ * storage, embeddings, or QMD.
16
+ *
17
+ * @param bufferKey Identifier for the active buffer (session/thread).
18
+ * @param turn The incoming turn whose novelty is being scored.
19
+ * @param recentTurns Turns already buffered for this key (most recent first
20
+ * is NOT guaranteed — treat as unordered corpus).
21
+ * @returns A surprise score in `[0, 1]`, or `null` if no score could be
22
+ * produced (e.g. empty corpus, probe declined to embed).
23
+ */
24
+ export interface BufferSurpriseProbe {
25
+ scoreTurn(
26
+ bufferKey: string,
27
+ turn: BufferTurn,
28
+ recentTurns: readonly BufferTurn[],
29
+ ): Promise<number | null>;
30
+ }
31
+
32
+ /**
33
+ * Minimal data carried on the serialized telemetry write chain
34
+ * (issue #563 PR 3).
35
+ *
36
+ * We intentionally do NOT capture the full `BufferTurn` here: under
37
+ * slow filesystem latency the chain can back up, and retaining
38
+ * `turn.content` for every pending append causes memory pressure on
39
+ * large conversations. Only the fields the ledger row actually needs
40
+ * cross the chain boundary.
41
+ */
42
+ export interface SurpriseTelemetryQueueEntry {
43
+ bufferKey: string;
44
+ turnRole: "user" | "assistant";
45
+ sessionKey: string | null;
46
+ surpriseScore: number;
47
+ triggered: boolean;
48
+ turnCountInWindow: number;
49
+ /**
50
+ * ISO timestamp captured at the moment the turn was scored, NOT when
51
+ * the ledger append eventually runs. Backpressure on the serialized
52
+ * write chain could otherwise shift event timestamps away from the
53
+ * real decision moment and distort the distribution report (p90
54
+ * inflated, current-threshold row misidentified).
55
+ */
56
+ timestamp: string;
57
+ /**
58
+ * Threshold value in force when `triggered` was computed. Must be
59
+ * snapshot here rather than read from `config` at emit time — a
60
+ * concurrent config change between queue and write would otherwise
61
+ * record `triggered=true` against a newer threshold the operator
62
+ * never set, distorting precision/recall interpretation.
63
+ */
64
+ threshold: number;
65
+ }
package/src/buffer.ts CHANGED
@@ -31,6 +31,9 @@ import {
31
31
 
32
32
  export type TriggerDecision = "extract_now" | "extract_batch" | "keep_buffering";
33
33
 
34
+ export type { BufferSurpriseProbe } from "./buffer-types.js";
35
+ import type { BufferSurpriseProbe, SurpriseTelemetryQueueEntry } from "./buffer-types.js";
36
+
34
37
  export interface AddTurnOutcome {
35
38
  decision: TriggerDecision;
36
39
  extractionTurns?: BufferTurn[];
@@ -46,33 +49,6 @@ export interface RetainedTurnCleanupOptions {
46
49
  codingContext?: import("./types.js").CodingContext;
47
50
  }
48
51
 
49
- /**
50
- * Optional surprise probe injected into `SmartBuffer`.
51
- *
52
- * Computes a D-MEM-style novelty score in `[0, 1]` for an incoming turn.
53
- * The buffer treats the probe as purely additive: if it is not provided, if
54
- * the feature flag is off, or if the probe throws/times out, the buffer
55
- * falls back to the existing signal/turn-count/time triggers unchanged.
56
- *
57
- * Callers are responsible for sampling recent memories and passing them
58
- * through the embedding pipeline — the buffer does not want to know about
59
- * storage, embeddings, or QMD.
60
- *
61
- * @param bufferKey Identifier for the active buffer (session/thread).
62
- * @param turn The incoming turn whose novelty is being scored.
63
- * @param recentTurns Turns already buffered for this key (most recent first
64
- * is NOT guaranteed — treat as unordered corpus).
65
- * @returns A surprise score in `[0, 1]`, or `null` if no score could be
66
- * produced (e.g. empty corpus, probe declined to embed).
67
- */
68
- export interface BufferSurpriseProbe {
69
- scoreTurn(
70
- bufferKey: string,
71
- turn: BufferTurn,
72
- recentTurns: readonly BufferTurn[],
73
- ): Promise<number | null>;
74
- }
75
-
76
52
  const MAX_BUFFER_ENTRY_COUNT = 200;
77
53
  const isAcceptedTurn = (t: { acceptedCapture?: boolean; writeNamespaceOverride?: string }): boolean =>
78
54
  t.acceptedCapture === true || t.writeNamespaceOverride !== undefined;
@@ -96,41 +72,6 @@ const BUFFER_SAVE_MAX_DEFER_MULTIPLIER = 5;
96
72
  */
97
73
  const MAX_SET_TIMEOUT_MS = 2_147_483_647;
98
74
 
99
- /**
100
- * Minimal data carried on the serialized telemetry write chain
101
- * (issue #563 PR 3).
102
- *
103
- * We intentionally do NOT capture the full `BufferTurn` here: under
104
- * slow filesystem latency the chain can back up, and retaining
105
- * `turn.content` for every pending append causes memory pressure on
106
- * large conversations. Only the fields the ledger row actually needs
107
- * cross the chain boundary.
108
- */
109
- interface SurpriseTelemetryQueueEntry {
110
- bufferKey: string;
111
- turnRole: "user" | "assistant";
112
- sessionKey: string | null;
113
- surpriseScore: number;
114
- triggered: boolean;
115
- turnCountInWindow: number;
116
- /**
117
- * ISO timestamp captured at the moment the turn was scored, NOT when
118
- * the ledger append eventually runs. Backpressure on the serialized
119
- * write chain could otherwise shift event timestamps away from the
120
- * real decision moment and distort the distribution report (p90
121
- * inflated, current-threshold row misidentified).
122
- */
123
- timestamp: string;
124
- /**
125
- * Threshold value in force when `triggered` was computed. Must be
126
- * snapshot here rather than read from `config` at emit time — a
127
- * concurrent config change between queue and write would otherwise
128
- * record `triggered=true` against a newer threshold the operator
129
- * never set, distorting precision/recall interpretation.
130
- */
131
- threshold: number;
132
- }
133
-
134
75
  interface AddTurnMutationResult {
135
76
  decision: TriggerDecision;
136
77
  signalLevel: SignalLevel;
@@ -1148,6 +1089,63 @@ export class SmartBuffer {
1148
1089
  });
1149
1090
  }
1150
1091
 
1092
+ /**
1093
+ * Remove an extraction-window chunk from the buffer WITHOUT recording an
1094
+ * extraction (trigger-drain drop path). Used when a chunk fails extraction
1095
+ * repeatedly and must be dropped so the session can drain; the caller is
1096
+ * responsible for the side-file copy and logging. Returns the number of
1097
+ * live turns dropped; 0 when the turns no longer match. `allowNonPrefix`
1098
+ * matches by identity, like `clearAfterExtraction`, for callers (native
1099
+ * groups) whose chunk can sit behind a pinned capture.
1100
+ */
1101
+ async dropExtractionChunk(
1102
+ bufferKey = "default",
1103
+ turns: readonly BufferTurn[],
1104
+ options?: { allowNonPrefix?: boolean },
1105
+ ): Promise<number> {
1106
+ return await this.enqueueMutation(async () => {
1107
+ await this.loadUnlocked();
1108
+ const entry = this.entryFor(bufferKey);
1109
+ // A window's head can be deferred-retained turns (retainDeferredTurns): take those out of the chunk first.
1110
+ const retained = [...(entry.retainedTurns ?? [])];
1111
+ const liveTurns: BufferTurn[] = [];
1112
+ for (const turn of turns) {
1113
+ const at = retained.findIndex((kept) => bufferTurnsEqual(kept, turn));
1114
+ if (at >= 0) retained.splice(at, 1);
1115
+ else liveTurns.push(turn);
1116
+ }
1117
+ const retainedDropped = (entry.retainedTurns?.length ?? 0) - retained.length;
1118
+ let remaining = entry.turns;
1119
+ if (options?.allowNonPrefix === true) {
1120
+ remaining = [...entry.turns];
1121
+ for (const turn of liveTurns) {
1122
+ const at = remaining.findIndex((live) => bufferTurnsEqual(live, turn));
1123
+ if (at >= 0) remaining.splice(at, 1);
1124
+ }
1125
+ } else {
1126
+ remaining = entry.turns.slice(matchingQueuedExtractionPrefixLength(entry.turns, liveTurns));
1127
+ }
1128
+ const matchedCount = entry.turns.length - remaining.length + retainedDropped;
1129
+ if (matchedCount === 0) return 0;
1130
+ if (this.saveTimer) {
1131
+ clearTimeout(this.saveTimer);
1132
+ this.saveTimer = null;
1133
+ }
1134
+ entry.turns = remaining;
1135
+ if (retainedDropped > 0) {
1136
+ if (retained.length > 0) entry.retainedTurns = retained;
1137
+ else delete entry.retainedTurns;
1138
+ }
1139
+ if (bufferKey === "default") {
1140
+ this.state.turns = entry.turns;
1141
+ }
1142
+ this.persistence.markDirty(bufferKey);
1143
+ this.pruneEntries([bufferKey]);
1144
+ await this.saveNowRetainingPendingOnFailure("dropExtractionChunk");
1145
+ return matchedCount;
1146
+ });
1147
+ }
1148
+
1151
1149
  getExtractionCount(bufferKey = "default"): number {
1152
1150
  return this.peekEntry(bufferKey)?.extractionCount ?? 0;
1153
1151
  }
@@ -1060,6 +1060,22 @@ test("parseConfig localLlmTimeoutMs clamps invalid values to a positive timeout"
1060
1060
  assert.equal(parseConfig({ localLlmTimeoutMs: Number.NaN }).localLlmTimeoutMs, 180_000);
1061
1061
  });
1062
1062
 
1063
+ test("parseConfig extractionJudgeTimeoutMs defaults to 20000 — compact verdict measures 2.1-2.5 s on a small fast judge model", () => {
1064
+ assert.equal(parseConfig({}).extractionJudgeTimeoutMs, 20_000);
1065
+ });
1066
+
1067
+ test("parseConfig extractionJudgeTimeoutMs accepts numbers and CLI-style numeric strings", () => {
1068
+ assert.equal(parseConfig({ extractionJudgeTimeoutMs: 45_000 }).extractionJudgeTimeoutMs, 45_000);
1069
+ assert.equal(parseConfig({ extractionJudgeTimeoutMs: "90000" }).extractionJudgeTimeoutMs, 90_000);
1070
+ });
1071
+
1072
+ test("parseConfig extractionJudgeTimeoutMs falls back to the default on unusable values and caps the top", () => {
1073
+ for (const value of [0, -1, Number.NaN, "abc"]) {
1074
+ assert.equal(parseConfig({ extractionJudgeTimeoutMs: value }).extractionJudgeTimeoutMs, 20_000);
1075
+ }
1076
+ assert.equal(parseConfig({ extractionJudgeTimeoutMs: 10_000_000 }).extractionJudgeTimeoutMs, 3_600_000);
1077
+ });
1078
+
1063
1079
  test("parseConfig validates localLlmMaxContext as a usable context window", () => {
1064
1080
  assert.equal(parseConfig({ localLlmMaxContext: 4096 }).localLlmMaxContext, 4096);
1065
1081
  assert.equal(parseConfig({ localLlmMaxContext: "8192" }).localLlmMaxContext, 8192);
package/src/config.ts CHANGED
@@ -2731,6 +2731,20 @@ export function parseConfig(
2731
2731
  typeof cfg.extractionJudgeBatchSize === "number" && Number.isFinite(cfg.extractionJudgeBatchSize)
2732
2732
  ? Math.max(1, Math.round(cfg.extractionJudgeBatchSize))
2733
2733
  : 20,
2734
+ // Judge LLM timeout (issue #376 follow-up, Studio 2026-10-29; tightened in
2735
+ // PR 3264): the judge requests a compact verdict with a batch-scaled
2736
+ // completion budget (24 tokens per candidate, up to 2048). Measured
2737
+ // 2.1-2.5 s per call on a small fast judge
2738
+ // model; the big shared core model measured 13-22 s per compact call,
2739
+ // 41 s verbose. The 20s default assumes the fast model, stays fail-open
2740
+ // on timeout, and needs a raise if extractionJudgeModel points at the
2741
+ // slow core model. Non-positive / unusable values fall back to the
2742
+ // default rather than a 1ms timeout that would silently disable judging.
2743
+ extractionJudgeTimeoutMs: ((): number => {
2744
+ const coerced = coerceNumber(cfg.extractionJudgeTimeoutMs);
2745
+ if (coerced === undefined || coerced < 1) return 20_000;
2746
+ return Math.min(3_600_000, Math.floor(coerced));
2747
+ })(),
2734
2748
  extractionJudgeShadow: cfg.extractionJudgeShadow === true,
2735
2749
  // Defer cap (issue #562 PR 2): max re-deferrals for the same candidate
2736
2750
  // text before the verdict is forcibly converted to reject.
@@ -2854,6 +2868,14 @@ export function parseConfig(
2854
2868
  extractionBreakerAuthCooldownMs:
2855
2869
  typeof cfg.extractionBreakerAuthCooldownMs === "number" && cfg.extractionBreakerAuthCooldownMs >= 0
2856
2870
  ? cfg.extractionBreakerAuthCooldownMs : 1_800_000,
2871
+ // Trigger-drain drop threshold: consecutive failed extraction attempts
2872
+ // before the failing buffer chunk is dropped (side-file copied first).
2873
+ extractionChunkDropAfterFailures: parseIntegerAtLeast(
2874
+ cfg.extractionChunkDropAfterFailures,
2875
+ 5,
2876
+ 1,
2877
+ "extractionChunkDropAfterFailures",
2878
+ ),
2857
2879
  // Local LLM fast tier (v9.1)
2858
2880
  localLlmFastEnabled: cfg.localLlmFastEnabled === true,
2859
2881
  localLlmFastModel: