@remnic/core 9.30.0 → 9.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (495) hide show
  1. package/dist/access-admin-ops-surface.d.ts +10 -10
  2. package/dist/access-admin-ops-surface.js +50 -44
  3. package/dist/access-authorization-probe.d.ts +10 -10
  4. package/dist/access-authorization-probe.js +51 -45
  5. package/dist/access-boundary.d.ts +13 -11
  6. package/dist/access-boundary.js +50 -44
  7. package/dist/access-cli.js +168 -123
  8. package/dist/access-cli.js.map +1 -1
  9. package/dist/access-extraction-force-flush.d.ts +119 -0
  10. package/dist/access-extraction-force-flush.js +166 -0
  11. package/dist/access-health-types.d.ts +1 -1
  12. package/dist/access-http-lcm-compaction.d.ts +47 -13
  13. package/dist/access-http-lcm-compaction.js +7 -3
  14. package/dist/access-http-lifecycle-flush.d.ts +132 -0
  15. package/dist/access-http-lifecycle-flush.js +9 -0
  16. package/dist/access-http-lifecycle-flush.js.map +1 -0
  17. package/dist/access-http.d.ts +11 -10
  18. package/dist/access-http.js +66 -59
  19. package/dist/access-identity-continuity-surface.d.ts +8 -8
  20. package/dist/access-identity-continuity-surface.js +50 -44
  21. package/dist/access-lcm-surface.d.ts +10 -10
  22. package/dist/access-lcm-surface.js +50 -44
  23. package/dist/access-mcp-output-schemas.js +1 -1
  24. package/dist/access-mcp.d.ts +16 -10
  25. package/dist/access-mcp.js +58 -52
  26. package/dist/access-memory-search-fanout.d.ts +2 -2
  27. package/dist/{access-namespace-preflight-VfXssvoI.d.ts → access-namespace-preflight-D4vW97H1.d.ts} +1 -1
  28. package/dist/access-namespace-preflight.d.ts +3 -3
  29. package/dist/access-namespace-preflight.js +50 -44
  30. package/dist/access-observe-helpers.d.ts +22 -0
  31. package/dist/access-observe-helpers.js +10 -0
  32. package/dist/access-observe-helpers.js.map +1 -0
  33. package/dist/access-observe-write-surface.d.ts +51 -47
  34. package/dist/access-observe-write-surface.js +50 -44
  35. package/dist/access-operations-batch.js +53 -47
  36. package/dist/access-operations.d.ts +11 -11
  37. package/dist/access-operations.js +55 -49
  38. package/dist/access-recall-concurrency.d.ts +10 -10
  39. package/dist/access-recall-concurrency.js +50 -44
  40. package/dist/access-recall-response.d.ts +10 -10
  41. package/dist/access-recall-response.js +50 -44
  42. package/dist/access-recall-surface.d.ts +10 -10
  43. package/dist/access-recall-surface.js +50 -44
  44. package/dist/access-schema.d.ts +37 -7
  45. package/dist/access-schema.js +5 -3
  46. package/dist/{access-service-B5RwVsTV.d.ts → access-service-B6PZ_xUL.d.ts} +44 -20
  47. package/dist/access-service-helpers.d.ts +113 -0
  48. package/dist/access-service-helpers.js +8 -0
  49. package/dist/access-service-helpers.js.map +1 -0
  50. package/dist/access-service.d.ts +10 -10
  51. package/dist/access-service.js +50 -44
  52. package/dist/access-surface-catalog.d.ts +10 -10
  53. package/dist/access-surface-catalog.js +2 -0
  54. package/dist/access-surface-catalog.js.map +1 -1
  55. package/dist/access-wearables-meetings-surface.d.ts +3 -3
  56. package/dist/action-confidence.d.ts +1 -1
  57. package/dist/active-memory-bridge.d.ts +1 -1
  58. package/dist/active-recall.d.ts +1 -1
  59. package/dist/active-recall.js +1 -1
  60. package/dist/adapters/index.js +7 -7
  61. package/dist/adapters/registry.js +3 -3
  62. package/dist/behavior-learner.d.ts +1 -1
  63. package/dist/behavior-signals.d.ts +1 -1
  64. package/dist/bootstrap.d.ts +8 -8
  65. package/dist/briefing.d.ts +2 -2
  66. package/dist/briefing.js +14 -14
  67. package/dist/buffer-surprise-report.d.ts +1 -1
  68. package/dist/buffer-turn-helpers.d.ts +5 -0
  69. package/dist/buffer-turn-helpers.js +24 -0
  70. package/dist/buffer-turn-helpers.js.map +1 -0
  71. package/dist/buffer.d.ts +17 -4
  72. package/dist/buffer.js +21 -1
  73. package/dist/bulk-import/index.d.ts +3 -3
  74. package/dist/calibration.d.ts +1 -1
  75. package/dist/capabilities.d.ts +1 -1
  76. package/dist/{capsule-crypto-GWVG7LGC.js → capsule-crypto-7FJQINUR.js} +2 -2
  77. package/dist/capsule-crypto-7FJQINUR.js.map +1 -0
  78. package/dist/{capsule-merge-5KKJQBWQ.js → capsule-merge-2H2IUTBT.js} +4 -4
  79. package/dist/{catalog-V7inUQdp.d.ts → catalog-CGFYmTT8.d.ts} +1 -1
  80. package/dist/causal-behavior.d.ts +1 -1
  81. package/dist/causal-behavior.js +2 -2
  82. package/dist/causal-chain.js +2 -2
  83. package/dist/causal-consolidation.d.ts +1 -1
  84. package/dist/causal-consolidation.js +19 -19
  85. package/dist/causal-retrieval.js +2 -2
  86. package/dist/causal-trajectory-graph.d.ts +1 -1
  87. package/dist/causal-trajectory.js +1 -1
  88. package/dist/{chunk-LEPOP46W.js → chunk-227UFSEQ.js} +4 -4
  89. package/dist/{chunk-GIBMDSJ2.js → chunk-27P5YVDU.js} +2 -2
  90. package/dist/{chunk-2SA56WMI.js → chunk-2LTDWSR6.js} +4 -4
  91. package/dist/{chunk-OWHERGF2.js → chunk-2NLLXCJG.js} +2 -2
  92. package/dist/{chunk-YTSNAUXN.js → chunk-3F2LKUMU.js} +22 -8
  93. package/dist/chunk-3F2LKUMU.js.map +1 -0
  94. package/dist/chunk-3QL24R5Y.js +9 -0
  95. package/dist/chunk-3QL24R5Y.js.map +1 -0
  96. package/dist/chunk-4RNZMRAV.js +60 -0
  97. package/dist/chunk-4RNZMRAV.js.map +1 -0
  98. package/dist/{chunk-6U7F52DE.js → chunk-4XHR3I67.js} +60 -60
  99. package/dist/chunk-5IVLTFOV.js +65 -0
  100. package/dist/chunk-5IVLTFOV.js.map +1 -0
  101. package/dist/{chunk-2EUVEDF5.js → chunk-5XA7PQ5I.js} +2 -2
  102. package/dist/{chunk-ALSGMEJR.js → chunk-65ZPVYTA.js} +7 -7
  103. package/dist/{chunk-5VQJBH2G.js → chunk-6TAUHL33.js} +2 -2
  104. package/dist/{chunk-HUHX2OCX.js → chunk-7DRETLP5.js} +1 -1
  105. package/dist/chunk-7DRETLP5.js.map +1 -0
  106. package/dist/{chunk-RGIWINDN.js → chunk-7G5MH4NT.js} +30 -30
  107. package/dist/{chunk-WVO4G37W.js → chunk-7TEZUUGM.js} +3 -3
  108. package/dist/{chunk-MJCGLM25.js → chunk-7VUAG236.js} +5 -5
  109. package/dist/{chunk-M3C2V3PV.js → chunk-AJEMDQNA.js} +12 -12
  110. package/dist/{chunk-RKNJBZ55.js → chunk-AU7Q3LSC.js} +7 -7
  111. package/dist/{chunk-ACXPX4AG.js → chunk-BR2K43MK.js} +2 -2
  112. package/dist/{chunk-IYZ5K7MU.js → chunk-BUE5E2HL.js} +4 -187
  113. package/dist/chunk-BUE5E2HL.js.map +1 -0
  114. package/dist/{chunk-CZRYLSSW.js → chunk-BUGVGH4N.js} +2 -2
  115. package/dist/{chunk-YTQNQ4KB.js → chunk-C4VQMFVM.js} +3 -3
  116. package/dist/{chunk-ZPSVBSOF.js → chunk-CIVDJD6P.js} +3 -3
  117. package/dist/{chunk-K5GB36ME.js → chunk-CZDOT5I2.js} +2 -2
  118. package/dist/{chunk-VI2JQPNQ.js → chunk-E4PWACUN.js} +2 -2
  119. package/dist/{chunk-D2ANTDGO.js → chunk-E6BMSH7U.js} +2 -2
  120. package/dist/{chunk-P5PXWTW7.js → chunk-EJCAV3QZ.js} +3 -3
  121. package/dist/{chunk-CKMO4RDY.js → chunk-EMDLM3LW.js} +4 -4
  122. package/dist/chunk-ER7W6H4T.js +112 -0
  123. package/dist/chunk-ER7W6H4T.js.map +1 -0
  124. package/dist/{chunk-6FUPCJUL.js → chunk-FI4F5X2V.js} +54 -54
  125. package/dist/chunk-FI4F5X2V.js.map +1 -0
  126. package/dist/{chunk-LGHKJABJ.js → chunk-GOUILH55.js} +40 -18
  127. package/dist/chunk-GOUILH55.js.map +1 -0
  128. package/dist/{chunk-G5R3D5UP.js → chunk-GTTAHHD3.js} +2 -2
  129. package/dist/{chunk-H5CPS5JP.js → chunk-H36LJIPD.js} +3 -3
  130. package/dist/{chunk-AITCS2RC.js → chunk-IJ7HK452.js} +4 -4
  131. package/dist/{chunk-D3LMYTBV.js → chunk-J7WZUL2K.js} +9 -9
  132. package/dist/{chunk-5W4ZLBEZ.js → chunk-JCFTIQBR.js} +2 -2
  133. package/dist/{chunk-XOZ4ALGB.js → chunk-KE353EWI.js} +3 -3
  134. package/dist/{chunk-W5EG6LE3.js → chunk-KIT6M7EB.js} +3 -3
  135. package/dist/{chunk-5W7CTZ2E.js → chunk-KQAFEZQX.js} +4 -4
  136. package/dist/{chunk-Z54EM5YZ.js → chunk-MAXVH44E.js} +7 -7
  137. package/dist/{chunk-WZFAPHIK.js → chunk-MU7ZHSZE.js} +2 -2
  138. package/dist/chunk-N5Z4EVOR.js +123 -0
  139. package/dist/chunk-N5Z4EVOR.js.map +1 -0
  140. package/dist/{chunk-66772WBP.js → chunk-NFXQJHJD.js} +5 -5
  141. package/dist/{chunk-AZ5BTEKX.js → chunk-NQUF7XKR.js} +2 -2
  142. package/dist/{chunk-W4FBGYGK.js → chunk-NRV4Y3PM.js} +1 -1
  143. package/dist/{chunk-NHWB6HG2.js → chunk-NYCGIQRA.js} +2 -2
  144. package/dist/{chunk-4WKA6I65.js → chunk-OGCNZPKX.js} +1119 -309
  145. package/dist/chunk-OGCNZPKX.js.map +1 -0
  146. package/dist/{chunk-QJAQNXWI.js → chunk-ONHRRJZM.js} +6 -6
  147. package/dist/{chunk-FDAMS4PK.js → chunk-PNPOWBGC.js} +2 -2
  148. package/dist/{chunk-IC6CBHCA.js → chunk-QGENAYVS.js} +2 -2
  149. package/dist/{chunk-GBJ4RDFR.js → chunk-QIHIHZYC.js} +66 -91
  150. package/dist/chunk-QIHIHZYC.js.map +1 -0
  151. package/dist/{chunk-PUS63Q3G.js → chunk-RUYJ7TWU.js} +517 -2011
  152. package/dist/chunk-RUYJ7TWU.js.map +1 -0
  153. package/dist/{chunk-4A6YGWQN.js → chunk-TL4TO3EA.js} +115 -120
  154. package/dist/chunk-TL4TO3EA.js.map +1 -0
  155. package/dist/{chunk-SPJXKAVF.js → chunk-U52AKICI.js} +14 -13
  156. package/dist/chunk-U52AKICI.js.map +1 -0
  157. package/dist/chunk-ULARSG5Z.js +203 -0
  158. package/dist/chunk-ULARSG5Z.js.map +1 -0
  159. package/dist/{chunk-62U4J2GN.js → chunk-UR77VKF7.js} +2 -2
  160. package/dist/{chunk-JCBWCYEJ.js → chunk-VANLTS5F.js} +2 -2
  161. package/dist/{chunk-4Z4XNEWZ.js → chunk-VCD4PSK2.js} +56 -12
  162. package/dist/chunk-VCD4PSK2.js.map +1 -0
  163. package/dist/{chunk-RMMVQQA6.js → chunk-WDISJRMG.js} +2 -2
  164. package/dist/{chunk-B6JDYXL7.js → chunk-WWUVONGW.js} +7 -1
  165. package/dist/chunk-WWUVONGW.js.map +1 -0
  166. package/dist/{chunk-UVYI6VIX.js → chunk-X7Y7WX73.js} +1 -1
  167. package/dist/{chunk-TH2LSRMG.js → chunk-XHDIB4T4.js} +2 -2
  168. package/dist/{chunk-CVILPI77.js → chunk-XOQSEF7X.js} +6 -6
  169. package/dist/{chunk-LBOD4U5B.js → chunk-YFOMN2II.js} +6 -6
  170. package/dist/{chunk-RPW2NOU6.js → chunk-YIAA2X3D.js} +41 -1
  171. package/dist/chunk-YIAA2X3D.js.map +1 -0
  172. package/dist/chunk-YPC7W6GA.js +1604 -0
  173. package/dist/chunk-YPC7W6GA.js.map +1 -0
  174. package/dist/{chunk-I5NLEENJ.js → chunk-Z4SWV4VW.js} +3 -3
  175. package/dist/{chunk-PHWUFPCO.js → chunk-ZCPP5OW6.js} +61 -53
  176. package/dist/chunk-ZCPP5OW6.js.map +1 -0
  177. package/dist/{cli-C4GbETPC.d.ts → cli-BptUDTtp.d.ts} +5 -5
  178. package/dist/cli.d.ts +12 -12
  179. package/dist/cli.js +91 -84
  180. package/dist/compounding/engine.d.ts +2 -2
  181. package/dist/compounding/engine.js +14 -14
  182. package/dist/compounding/preference-consolidator.d.ts +1 -1
  183. package/dist/compression-optimizer.d.ts +1 -1
  184. package/dist/config.d.ts +1 -1
  185. package/dist/config.js +1 -1
  186. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  187. package/dist/connectors/codex-materialize-runner.js +14 -14
  188. package/dist/connectors/codex-materialize.d.ts +1 -1
  189. package/dist/connectors/index.d.ts +1 -1
  190. package/dist/connectors/index.js +17 -17
  191. package/dist/consolidation-provenance-check.d.ts +2 -2
  192. package/dist/consolidation-provenance-check.js +5 -5
  193. package/dist/consolidation-undo.d.ts +2 -2
  194. package/dist/consolidation-undo.js +3 -3
  195. package/dist/contradiction/index.d.ts +2 -2
  196. package/dist/contradiction/index.js +4 -4
  197. package/dist/conversation-index/backend.d.ts +1 -1
  198. package/dist/conversation-index/backend.js +2 -2
  199. package/dist/conversation-index/chunker.d.ts +1 -1
  200. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  201. package/dist/conversation-index/indexer.d.ts +1 -1
  202. package/dist/conversation-index/search.d.ts +1 -1
  203. package/dist/corpus-watermark.d.ts +1 -1
  204. package/dist/corpus-watermark.js +26 -26
  205. package/dist/day-summary.d.ts +1 -1
  206. package/dist/delinearize.d.ts +1 -1
  207. package/dist/direct-answer-wiring.d.ts +1 -1
  208. package/dist/direct-answer.d.ts +1 -1
  209. package/dist/embedding-fallback.d.ts +1 -1
  210. package/dist/enrichment/index.d.ts +1 -1
  211. package/dist/entity-retrieval.d.ts +2 -2
  212. package/dist/entity-retrieval.js +14 -14
  213. package/dist/entity-schema.d.ts +1 -1
  214. package/dist/explicit-capture.d.ts +8 -8
  215. package/dist/extraction-error-classification.d.ts +1 -1
  216. package/dist/extraction-faithfulness.d.ts +1 -1
  217. package/dist/extraction-judge-telemetry.d.ts +1 -1
  218. package/dist/extraction-judge-training.d.ts +1 -1
  219. package/dist/extraction-judge.d.ts +1 -1
  220. package/dist/extraction-liveness.d.ts +1 -1
  221. package/dist/extraction-source-grounding-rules.d.ts +1 -1
  222. package/dist/extraction-source-grounding.d.ts +15 -2
  223. package/dist/extraction-source-grounding.js +10 -1
  224. package/dist/extraction.d.ts +2 -15
  225. package/dist/extraction.js +5 -4
  226. package/dist/fallback-llm.d.ts +1 -1
  227. package/dist/graph-dashboard-diff.d.ts +1 -1
  228. package/dist/graph-dashboard-key.d.ts +1 -1
  229. package/dist/graph-dashboard-parser.d.ts +1 -1
  230. package/dist/graph-edge-reinforcement.d.ts +1 -1
  231. package/dist/graph-snapshot.d.ts +1 -1
  232. package/dist/graph.d.ts +1 -1
  233. package/dist/importance.d.ts +1 -1
  234. package/dist/importers/index.d.ts +1 -1
  235. package/dist/in-flight-reads.d.ts +1 -1
  236. package/dist/index.d.ts +19 -19
  237. package/dist/index.js +215 -207
  238. package/dist/intent.d.ts +1 -1
  239. package/dist/lcm/engine.d.ts +1 -1
  240. package/dist/lcm/engine.js +3 -3
  241. package/dist/lcm/index.d.ts +1 -1
  242. package/dist/lcm/index.js +6 -6
  243. package/dist/lcm/tools.d.ts +1 -1
  244. package/dist/lifecycle.d.ts +1 -1
  245. package/dist/live-connectors-runner.d.ts +1 -1
  246. package/dist/local-llm-helpers.d.ts +7 -0
  247. package/dist/local-llm-helpers.js +16 -0
  248. package/dist/local-llm-helpers.js.map +1 -0
  249. package/dist/local-llm.d.ts +3 -6
  250. package/dist/local-llm.js +2 -1
  251. package/dist/local-model-endpoint.d.ts +1 -1
  252. package/dist/maintenance/memory-governance.d.ts +1 -1
  253. package/dist/maintenance/memory-governance.js +14 -14
  254. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
  255. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +14 -14
  256. package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
  257. package/dist/maintenance/rebuild-memory-projection.js +15 -15
  258. package/dist/{maintenance-CL30NWtc.d.ts → maintenance-b6f92bRz.d.ts} +3 -3
  259. package/dist/mcp-memory-inspector-app.d.ts +10 -10
  260. package/dist/memory-action-policy.d.ts +1 -1
  261. package/dist/memory-cache.d.ts +1 -1
  262. package/dist/memory-corpus-version.js +2 -2
  263. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  264. package/dist/memory-projection-store.d.ts +1 -1
  265. package/dist/memory-provenance.d.ts +1 -1
  266. package/dist/memory-worth-outcomes.d.ts +2 -2
  267. package/dist/models-json.d.ts +1 -1
  268. package/dist/namespaces/migrate.d.ts +3 -3
  269. package/dist/namespaces/migrate.js +24 -24
  270. package/dist/namespaces/principal.d.ts +1 -1
  271. package/dist/namespaces/search.d.ts +1 -1
  272. package/dist/namespaces/search.js +9 -9
  273. package/dist/namespaces/storage.d.ts +3 -3
  274. package/dist/namespaces/storage.js +14 -14
  275. package/dist/native-knowledge.d.ts +1 -1
  276. package/dist/offline-sync-impression-drain.d.ts +1 -1
  277. package/dist/offline-sync-impression-drain.js +6 -5
  278. package/dist/operator-doctor-corpus.d.ts +1 -1
  279. package/dist/operator-doctor-corpus.js +29 -29
  280. package/dist/operator-doctor-replica.d.ts +1 -1
  281. package/dist/operator-doctor-replica.js +3 -3
  282. package/dist/operator-toolkit.d.ts +3 -3
  283. package/dist/operator-toolkit.js +38 -37
  284. package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
  285. package/dist/orchestration/maintenance.d.ts +4 -4
  286. package/dist/orchestration/maintenance.js +22 -21
  287. package/dist/{orchestrator-CKTCRwWV.d.ts → orchestrator-3uGxC1qO.d.ts} +72 -34
  288. package/dist/orchestrator.d.ts +8 -8
  289. package/dist/orchestrator.js +167 -159
  290. package/dist/page-versioning.js +3 -3
  291. package/dist/patterns-cli.d.ts +1 -1
  292. package/dist/{pipeline-B7wj4rRZ.d.ts → pipeline-DepuNr-m.d.ts} +1 -1
  293. package/dist/policy-runtime.d.ts +1 -1
  294. package/dist/proactive-contention.d.ts +1 -1
  295. package/dist/provenance.d.ts +1 -1
  296. package/dist/{qmd-q9tg4dHp.d.ts → qmd-Dalr3Jby.d.ts} +1 -1
  297. package/dist/qmd-preflight.d.ts +2 -2
  298. package/dist/qmd-recall-cache.d.ts +1 -1
  299. package/dist/qmd.d.ts +2 -2
  300. package/dist/qmd.js +4 -4
  301. package/dist/recall-concurrency-config.d.ts +1 -1
  302. package/dist/recall-disclosure-escalation.d.ts +1 -1
  303. package/dist/recall-explain-renderer.d.ts +1 -1
  304. package/dist/recall-explain-renderer.js +3 -3
  305. package/dist/recall-memory-map.d.ts +1 -1
  306. package/dist/recall-planner-llm.d.ts +1 -1
  307. package/dist/recall-state.d.ts +1 -1
  308. package/dist/recall-tag-filter.d.ts +1 -1
  309. package/dist/recall-timings.d.ts +1 -1
  310. package/dist/recall-xray-cli.d.ts +1 -1
  311. package/dist/recall-xray-cli.js +4 -4
  312. package/dist/recall-xray-renderer.d.ts +1 -1
  313. package/dist/recall-xray-renderer.js +3 -3
  314. package/dist/recall-xray.d.ts +1 -1
  315. package/dist/recall-xray.js +2 -2
  316. package/dist/replay/normalizers/chatgpt.d.ts +1 -1
  317. package/dist/replay/normalizers/claude.d.ts +1 -1
  318. package/dist/replay/normalizers/openclaw.d.ts +1 -1
  319. package/dist/replay/normalizers/shared.d.ts +1 -1
  320. package/dist/replay/runner.d.ts +1 -1
  321. package/dist/replay/types.d.ts +1 -1
  322. package/dist/replica-divergence.d.ts +1 -1
  323. package/dist/replica-divergence.js +2 -2
  324. package/dist/replica-peers-config.d.ts +1 -1
  325. package/dist/resolve-auth-token.d.ts +1 -1
  326. package/dist/resume-bundles.js +1 -1
  327. package/dist/retrieval-agents.d.ts +2 -2
  328. package/dist/retrieval-tiers.d.ts +1 -1
  329. package/dist/routing/engine.d.ts +1 -1
  330. package/dist/routing/store.d.ts +1 -1
  331. package/dist/salvage-envelope.d.ts +1 -1
  332. package/dist/{scope-profiles-CWDyglPM.d.ts → scope-profiles-BpiM5hTU.d.ts} +1 -1
  333. package/dist/search/embed-helper.d.ts +1 -1
  334. package/dist/search/factory.d.ts +1 -1
  335. package/dist/search/factory.js +8 -8
  336. package/dist/search/index.d.ts +1 -1
  337. package/dist/search/index.js +12 -12
  338. package/dist/search/lancedb-backend.d.ts +1 -1
  339. package/dist/search/meilisearch-backend.d.ts +1 -1
  340. package/dist/search/noop-backend.d.ts +1 -1
  341. package/dist/search/orama-backend.d.ts +1 -1
  342. package/dist/search/port.d.ts +1 -1
  343. package/dist/search/remote-backend.d.ts +1 -1
  344. package/dist/{semantic-consolidation-BUE3deLn.d.ts → semantic-consolidation-CMtVrf9f.d.ts} +1 -1
  345. package/dist/semantic-consolidation.d.ts +2 -2
  346. package/dist/semantic-consolidation.js +16 -16
  347. package/dist/semantic-rule-promotion.js +14 -14
  348. package/dist/semantic-rule-verifier.d.ts +1 -1
  349. package/dist/semantic-rule-verifier.js +14 -14
  350. package/dist/{service-CXgM0bQG.d.ts → service-DuAxwSgg.d.ts} +2 -2
  351. package/dist/session-observer-bands.d.ts +1 -1
  352. package/dist/session-observer-state.d.ts +1 -1
  353. package/dist/shared-context/manager.d.ts +1 -1
  354. package/dist/signal.d.ts +1 -1
  355. package/dist/{storage-DysJq-XH.d.ts → storage-CF0Ih8GP.d.ts} +1 -1
  356. package/dist/storage.d.ts +2 -2
  357. package/dist/storage.js +13 -13
  358. package/dist/summarizer.d.ts +1 -1
  359. package/dist/summarizer.js +3 -2
  360. package/dist/summary-snapshot.d.ts +1 -1
  361. package/dist/temporal-supersession.d.ts +2 -2
  362. package/dist/temporal-timeline-recall.d.ts +1 -1
  363. package/dist/temporal-validity.d.ts +1 -1
  364. package/dist/threading.d.ts +1 -1
  365. package/dist/tier-migration.d.ts +2 -2
  366. package/dist/tier-routing.d.ts +1 -1
  367. package/dist/tokens.js +2 -2
  368. package/dist/topics.d.ts +1 -1
  369. package/dist/transcript.d.ts +1 -1
  370. package/dist/transfer/backup.js +2 -2
  371. package/dist/transfer/capsule-export.js +2 -2
  372. package/dist/transfer/capsule-import.js +5 -5
  373. package/dist/trust-score-stage.d.ts +1 -1
  374. package/dist/trust-score.d.ts +1 -1
  375. package/dist/{types-aPPzhnjT.d.ts → types-BpaYvJ6v.d.ts} +22 -2
  376. package/dist/types.d.ts +1 -1
  377. package/dist/types.js +1 -1
  378. package/dist/utility-runtime.d.ts +1 -1
  379. package/dist/verified-recall.js +14 -14
  380. package/dist/write-envelope.d.ts +1 -1
  381. package/package.json +2 -2
  382. package/src/access-boundary.ts +3 -0
  383. package/src/access-cli.test.ts +93 -0
  384. package/src/access-cli.ts +56 -2
  385. package/src/access-extraction-force-flush.ts +177 -0
  386. package/src/access-http-extraction-force-flush.test.ts +132 -0
  387. package/src/access-http-lcm-compaction.ts +99 -22
  388. package/src/access-http-lifecycle-flush.ts +81 -0
  389. package/src/access-http.test.ts +227 -0
  390. package/src/access-http.ts +33 -40
  391. package/src/access-mcp-output-schemas.ts +6 -0
  392. package/src/access-mcp.test.ts +40 -0
  393. package/src/access-mcp.ts +32 -1
  394. package/src/access-observe-helpers.ts +180 -0
  395. package/src/access-observe-write-surface.ts +78 -19
  396. package/src/access-operations-batch.ts +2 -1
  397. package/src/access-schema-pi.test.ts +17 -0
  398. package/src/access-schema.ts +28 -11
  399. package/src/access-service-helpers.ts +46 -0
  400. package/src/access-service-observe-lcm-parity.test.ts +781 -31
  401. package/src/access-service-observe-scope.test.ts +88 -0
  402. package/src/access-service.ts +46 -128
  403. package/src/access-surface-catalog.test.ts +32 -0
  404. package/src/access-surface-catalog.ts +2 -0
  405. package/src/buffer-session.test.ts +148 -0
  406. package/src/buffer-turn-helpers.ts +152 -0
  407. package/src/buffer.ts +126 -201
  408. package/src/correction/correction-access-wiring.ts +79 -27
  409. package/src/correction/correction-executor.test.ts +542 -1
  410. package/src/correction/correction-executor.ts +309 -89
  411. package/src/correction/correction-planner.test.ts +35 -1
  412. package/src/correction/correction-planner.ts +50 -3
  413. package/src/correction/correction-service.ts +12 -7
  414. package/src/correction/correction-storage-integration.test.ts +172 -1
  415. package/src/correction/passive-capture.test.ts +35 -0
  416. package/src/correction/passive-capture.ts +17 -3
  417. package/src/extraction-source-grounding.ts +55 -1
  418. package/src/extraction-timeout.test.ts +51 -0
  419. package/src/extraction.ts +64 -90
  420. package/src/local-llm-headers-timeout.test.ts +48 -0
  421. package/src/local-llm-helpers.ts +58 -0
  422. package/src/local-llm.ts +62 -58
  423. package/src/orchestration/extraction-run-helpers.ts +309 -0
  424. package/src/orchestration/extraction-run.test.ts +350 -7
  425. package/src/orchestration/extraction-run.ts +327 -250
  426. package/src/orchestration/recall-internal-deps.ts +385 -0
  427. package/src/orchestration/recall-internal.ts +16 -375
  428. package/src/orchestration/session-context.ts +193 -18
  429. package/src/orchestration/turn-ingestion.ts +61 -11
  430. package/src/orchestrator-flush.test.ts +511 -5
  431. package/src/orchestrator.ts +8 -6
  432. package/src/types.ts +2 -2
  433. package/dist/chunk-4A6YGWQN.js.map +0 -1
  434. package/dist/chunk-4WKA6I65.js.map +0 -1
  435. package/dist/chunk-4Z4XNEWZ.js.map +0 -1
  436. package/dist/chunk-6FUPCJUL.js.map +0 -1
  437. package/dist/chunk-B6JDYXL7.js.map +0 -1
  438. package/dist/chunk-GBJ4RDFR.js.map +0 -1
  439. package/dist/chunk-HUHX2OCX.js.map +0 -1
  440. package/dist/chunk-IYZ5K7MU.js.map +0 -1
  441. package/dist/chunk-LGHKJABJ.js.map +0 -1
  442. package/dist/chunk-PHWUFPCO.js.map +0 -1
  443. package/dist/chunk-PUS63Q3G.js.map +0 -1
  444. package/dist/chunk-RPW2NOU6.js.map +0 -1
  445. package/dist/chunk-SPJXKAVF.js.map +0 -1
  446. package/dist/chunk-YTSNAUXN.js.map +0 -1
  447. /package/dist/{capsule-crypto-GWVG7LGC.js.map → access-extraction-force-flush.js.map} +0 -0
  448. /package/dist/{capsule-merge-5KKJQBWQ.js.map → capsule-merge-2H2IUTBT.js.map} +0 -0
  449. /package/dist/{chunk-LEPOP46W.js.map → chunk-227UFSEQ.js.map} +0 -0
  450. /package/dist/{chunk-GIBMDSJ2.js.map → chunk-27P5YVDU.js.map} +0 -0
  451. /package/dist/{chunk-2SA56WMI.js.map → chunk-2LTDWSR6.js.map} +0 -0
  452. /package/dist/{chunk-OWHERGF2.js.map → chunk-2NLLXCJG.js.map} +0 -0
  453. /package/dist/{chunk-6U7F52DE.js.map → chunk-4XHR3I67.js.map} +0 -0
  454. /package/dist/{chunk-2EUVEDF5.js.map → chunk-5XA7PQ5I.js.map} +0 -0
  455. /package/dist/{chunk-ALSGMEJR.js.map → chunk-65ZPVYTA.js.map} +0 -0
  456. /package/dist/{chunk-5VQJBH2G.js.map → chunk-6TAUHL33.js.map} +0 -0
  457. /package/dist/{chunk-RGIWINDN.js.map → chunk-7G5MH4NT.js.map} +0 -0
  458. /package/dist/{chunk-WVO4G37W.js.map → chunk-7TEZUUGM.js.map} +0 -0
  459. /package/dist/{chunk-MJCGLM25.js.map → chunk-7VUAG236.js.map} +0 -0
  460. /package/dist/{chunk-M3C2V3PV.js.map → chunk-AJEMDQNA.js.map} +0 -0
  461. /package/dist/{chunk-RKNJBZ55.js.map → chunk-AU7Q3LSC.js.map} +0 -0
  462. /package/dist/{chunk-ACXPX4AG.js.map → chunk-BR2K43MK.js.map} +0 -0
  463. /package/dist/{chunk-CZRYLSSW.js.map → chunk-BUGVGH4N.js.map} +0 -0
  464. /package/dist/{chunk-YTQNQ4KB.js.map → chunk-C4VQMFVM.js.map} +0 -0
  465. /package/dist/{chunk-ZPSVBSOF.js.map → chunk-CIVDJD6P.js.map} +0 -0
  466. /package/dist/{chunk-K5GB36ME.js.map → chunk-CZDOT5I2.js.map} +0 -0
  467. /package/dist/{chunk-VI2JQPNQ.js.map → chunk-E4PWACUN.js.map} +0 -0
  468. /package/dist/{chunk-D2ANTDGO.js.map → chunk-E6BMSH7U.js.map} +0 -0
  469. /package/dist/{chunk-P5PXWTW7.js.map → chunk-EJCAV3QZ.js.map} +0 -0
  470. /package/dist/{chunk-CKMO4RDY.js.map → chunk-EMDLM3LW.js.map} +0 -0
  471. /package/dist/{chunk-G5R3D5UP.js.map → chunk-GTTAHHD3.js.map} +0 -0
  472. /package/dist/{chunk-H5CPS5JP.js.map → chunk-H36LJIPD.js.map} +0 -0
  473. /package/dist/{chunk-AITCS2RC.js.map → chunk-IJ7HK452.js.map} +0 -0
  474. /package/dist/{chunk-D3LMYTBV.js.map → chunk-J7WZUL2K.js.map} +0 -0
  475. /package/dist/{chunk-5W4ZLBEZ.js.map → chunk-JCFTIQBR.js.map} +0 -0
  476. /package/dist/{chunk-XOZ4ALGB.js.map → chunk-KE353EWI.js.map} +0 -0
  477. /package/dist/{chunk-W5EG6LE3.js.map → chunk-KIT6M7EB.js.map} +0 -0
  478. /package/dist/{chunk-5W7CTZ2E.js.map → chunk-KQAFEZQX.js.map} +0 -0
  479. /package/dist/{chunk-Z54EM5YZ.js.map → chunk-MAXVH44E.js.map} +0 -0
  480. /package/dist/{chunk-WZFAPHIK.js.map → chunk-MU7ZHSZE.js.map} +0 -0
  481. /package/dist/{chunk-66772WBP.js.map → chunk-NFXQJHJD.js.map} +0 -0
  482. /package/dist/{chunk-AZ5BTEKX.js.map → chunk-NQUF7XKR.js.map} +0 -0
  483. /package/dist/{chunk-W4FBGYGK.js.map → chunk-NRV4Y3PM.js.map} +0 -0
  484. /package/dist/{chunk-NHWB6HG2.js.map → chunk-NYCGIQRA.js.map} +0 -0
  485. /package/dist/{chunk-QJAQNXWI.js.map → chunk-ONHRRJZM.js.map} +0 -0
  486. /package/dist/{chunk-FDAMS4PK.js.map → chunk-PNPOWBGC.js.map} +0 -0
  487. /package/dist/{chunk-IC6CBHCA.js.map → chunk-QGENAYVS.js.map} +0 -0
  488. /package/dist/{chunk-62U4J2GN.js.map → chunk-UR77VKF7.js.map} +0 -0
  489. /package/dist/{chunk-JCBWCYEJ.js.map → chunk-VANLTS5F.js.map} +0 -0
  490. /package/dist/{chunk-RMMVQQA6.js.map → chunk-WDISJRMG.js.map} +0 -0
  491. /package/dist/{chunk-UVYI6VIX.js.map → chunk-X7Y7WX73.js.map} +0 -0
  492. /package/dist/{chunk-TH2LSRMG.js.map → chunk-XHDIB4T4.js.map} +0 -0
  493. /package/dist/{chunk-CVILPI77.js.map → chunk-XOQSEF7X.js.map} +0 -0
  494. /package/dist/{chunk-LBOD4U5B.js.map → chunk-YFOMN2II.js.map} +0 -0
  495. /package/dist/{chunk-I5NLEENJ.js.map → chunk-Z4SWV4VW.js.map} +0 -0
@@ -15,10 +15,12 @@ import test from "node:test";
15
15
 
16
16
  import { SmartBuffer } from "../buffer.js";
17
17
  import {
18
+ ExtractionDeadlineError,
18
19
  ExtractionRunCoordinator,
19
20
  type ExtractionRunCoordinatorDeps,
20
21
  computeExtractionRetryNextEligibleMs,
21
22
  capExtractionRetryStateEntries,
23
+ deriveTopicsFromExtraction,
22
24
  } from "./extraction-run.js";
23
25
  import { StorageManager } from "../storage.js";
24
26
  import { parseConfig } from "../config.js";
@@ -85,9 +87,13 @@ const migrationSummary: TierMigrationCycleSummary = {
85
87
  interface Harness {
86
88
  config: PluginConfig;
87
89
  storageForNs: (ns: string) => Promise<StorageManager>;
90
+ setStorageForDelay: (delayMs: number) => void;
88
91
  newCoordinator: () => ExtractionRunCoordinator;
89
92
  engineCalls: () => number;
90
- setRespond: (fn: (turns: BufferTurn[]) => ExtractionResult) => void;
93
+ setRespond: (fn: (turns: BufferTurn[]) => ExtractionResult | Promise<ExtractionResult>) => void;
94
+ setPassiveCapture: (fn: () => void | Promise<void>) => void;
95
+ setMemoryBox: (fn: () => void | Promise<void>) => void;
96
+ setPersist: (fn: () => void | Promise<void>) => void;
91
97
  recordedProcessedCount: () => number;
92
98
  run: (
93
99
  coord: ExtractionRunCoordinator,
@@ -95,6 +101,9 @@ interface Harness {
95
101
  opts?: { force?: boolean; failClosed?: boolean; writeNamespaceOverride?: string },
96
102
  ) => Promise<{ status: string; reason?: string }>;
97
103
  cleanup: () => Promise<void>;
104
+ passiveCapture: () => { principal?: string; namespace?: string } | null;
105
+ setThreadingBlock: (blocked: boolean) => void;
106
+ persistCalls: () => number;
98
107
  }
99
108
 
100
109
  async function makeHarness(overrides: Record<string, unknown> = {}): Promise<Harness> {
@@ -107,7 +116,11 @@ async function makeHarness(overrides: Record<string, unknown> = {}): Promise<Har
107
116
  });
108
117
 
109
118
  const storages = new Map<string, StorageManager>();
119
+ let storageForDelayMs = 0;
110
120
  const storageForNs = async (ns: string): Promise<StorageManager> => {
121
+ if (storageForDelayMs > 0) {
122
+ await new Promise((resolve) => setTimeout(resolve, storageForDelayMs));
123
+ }
111
124
  let s = storages.get(ns);
112
125
  if (!s) {
113
126
  s = new StorageManager(path.join(baseDir, `ns-${ns.replace(/[^a-z0-9]+/gi, "_")}`));
@@ -120,11 +133,16 @@ async function makeHarness(overrides: Record<string, unknown> = {}): Promise<Har
120
133
  const defaultStorage = await storageForNs("default");
121
134
  const buffer = new SmartBuffer(config, defaultStorage);
122
135
  await buffer.load();
123
-
124
136
  let engineCalls = 0;
125
- let respond: (turns: BufferTurn[]) => ExtractionResult = () => successResult();
137
+ let respond: (turns: BufferTurn[]) => ExtractionResult | Promise<ExtractionResult> = () => successResult();
138
+ let passiveCaptureHandler: () => void | Promise<void> = async () => {};
139
+ let passiveCapture: { principal?: string; namespace?: string } | null = null;
140
+ let persistHandler: () => void | Promise<void> = async () => {};
141
+ let memoryBoxHandler: () => void | Promise<void> = async () => {};
126
142
  let recordedProcessedCount = 0;
127
143
 
144
+ let threadingBlocked = false;
145
+ let persistCalls = 0;
128
146
  const makeDeps = (): ExtractionRunCoordinatorDeps => ({
129
147
  config,
130
148
  getBuffer: () => buffer,
@@ -138,15 +156,29 @@ async function makeHarness(overrides: Record<string, unknown> = {}): Promise<Har
138
156
  storageFor: async (ns: string) => storageForNs(ns),
139
157
  }),
140
158
  getThreading: () => ({
141
- processTurn: async (..._args: Parameters<ThreadingManager["processTurn"]>) => "thread-1",
159
+ processTurn: async (..._args: Parameters<ThreadingManager["processTurn"]>) => {
160
+ if (threadingBlocked) await new Promise<void>(() => {});
161
+ return "thread-1";
162
+ },
142
163
  updateThreadTitle: async (..._args: Parameters<ThreadingManager["updateThreadTitle"]>) => {},
143
164
  }),
144
- persistExtraction: async () => ({ persistedIds: ["memory-1"], memoryPathById: new Map() }),
145
- maybeCapturePassiveCorrections: async () => {},
165
+ persistExtraction: async () => {
166
+ persistCalls += 1;
167
+ await persistHandler();
168
+ return { persistedIds: ["memory-1"], memoryPathById: new Map() };
169
+ },
170
+ maybeCapturePassiveCorrections: async (_turns, options) => {
171
+ await passiveCaptureHandler();
172
+ passiveCapture = { principal: options.principal, namespace: options.namespace };
173
+ },
146
174
  resolveSelfNamespace: () => "default",
147
175
  getCodingContextForSession: () => null,
148
176
  applyCodingNamespaceOverlay: () => "default",
149
- boxBuilderFor: () => ({ onExtraction: async () => {} }),
177
+ boxBuilderFor: () => ({
178
+ onExtraction: async () => {
179
+ await memoryBoxHandler();
180
+ },
181
+ }),
150
182
  appendPersistedThreadEpisodes: async () => {},
151
183
  maybeScheduleConsolidation: () => {},
152
184
  requestQmdMaintenance: () => {},
@@ -160,12 +192,29 @@ async function makeHarness(overrides: Record<string, unknown> = {}): Promise<Har
160
192
  return {
161
193
  config,
162
194
  storageForNs,
195
+ setStorageForDelay: (delayMs) => {
196
+ storageForDelayMs = delayMs;
197
+ },
198
+ setThreadingBlock: (blocked) => {
199
+ threadingBlocked = blocked;
200
+ },
201
+ persistCalls: () => persistCalls,
163
202
  newCoordinator: () => new ExtractionRunCoordinator(makeDeps()),
164
203
  engineCalls: () => engineCalls,
165
204
  setRespond: (fn) => {
166
205
  respond = fn;
167
206
  },
207
+ setPassiveCapture: (fn) => {
208
+ passiveCaptureHandler = fn;
209
+ },
210
+ setMemoryBox: (fn) => {
211
+ memoryBoxHandler = fn;
212
+ },
213
+ setPersist: (fn) => {
214
+ persistHandler = fn;
215
+ },
168
216
  recordedProcessedCount: () => recordedProcessedCount,
217
+ passiveCapture: () => passiveCapture,
169
218
  run: async (coord, content, opts = {}) => {
170
219
  const result = await coord.runExtraction(makeTurns(content), {
171
220
  skipCharThreshold: true,
@@ -185,6 +234,235 @@ async function makeHarness(overrides: Record<string, unknown> = {}): Promise<Har
185
234
  };
186
235
  }
187
236
 
237
+ test("context-only extraction honors scoped principal and namespace overrides", async () => {
238
+ const harness = await makeHarness();
239
+ try {
240
+ const coordinator = harness.newCoordinator();
241
+ const result = await coordinator.runExtraction(
242
+ [
243
+ {
244
+ role: "user",
245
+ content: "Please use the blue dashboard.",
246
+ timestamp: "2026-07-15T00:00:00Z",
247
+ sessionKey: "opaque-session",
248
+ extractionContextOnly: true,
249
+ },
250
+ ],
251
+ {
252
+ bufferKey: "opaque-session",
253
+ clearBufferAfterExtraction: false,
254
+ principalOverride: "alice",
255
+ writeNamespaceOverride: "alice-project",
256
+ },
257
+ );
258
+
259
+ assert.equal(result.reason, "empty_normalized_turns");
260
+ assert.deepEqual(harness.passiveCapture(), {
261
+ principal: "alice",
262
+ namespace: "alice-project",
263
+ });
264
+ } finally {
265
+ await harness.cleanup();
266
+ }
267
+ });
268
+
269
+ test("context-only extraction bounds passive capture by its deadline", async () => {
270
+ const harness = await makeHarness();
271
+ try {
272
+ harness.setPassiveCapture(() => new Promise<void>(() => {}));
273
+ const coordinator = harness.newCoordinator();
274
+ const startedAt = Date.now();
275
+ await assert.rejects(
276
+ coordinator.runExtraction(
277
+ [
278
+ {
279
+ role: "user",
280
+ content: "The correction capture must not clear this buffer after its deadline.",
281
+ timestamp: "2026-07-15T00:00:00Z",
282
+ sessionKey: "context-only-deadline",
283
+ extractionContextOnly: true,
284
+ },
285
+ ],
286
+ {
287
+ bufferKey: "context-only-deadline",
288
+ clearBufferAfterExtraction: false,
289
+ deadlineMs: startedAt + 25,
290
+ },
291
+ ),
292
+ (error: unknown) => {
293
+ assert.ok(error instanceof ExtractionDeadlineError);
294
+ assert.equal(error.stage, "during_passive_capture");
295
+ return true;
296
+ },
297
+ );
298
+ assert.ok(Date.now() - startedAt < 1_000, "passive capture must not outlive its deadline");
299
+ } finally {
300
+ await harness.cleanup();
301
+ }
302
+ });
303
+
304
+ test("runExtraction aborts an in-flight provider when its deadline expires", async () => {
305
+ const harness = await makeHarness();
306
+ try {
307
+ const coordinator = harness.newCoordinator();
308
+ harness.setRespond(() => new Promise<ExtractionResult>(() => {}));
309
+ await assert.rejects(
310
+ coordinator.runExtraction(makeTurns("deadline"), {
311
+ skipCharThreshold: true,
312
+ skipUserTurnThreshold: true,
313
+ clearBufferAfterExtraction: false,
314
+ bufferKey: "deadline",
315
+ deadlineMs: Date.now() + 40,
316
+ }),
317
+ (error: unknown) => error instanceof ExtractionDeadlineError && error.stage === "during_extract",
318
+ );
319
+ } finally {
320
+ await harness.cleanup();
321
+ }
322
+ });
323
+
324
+ test("runExtraction bounds storage preparation by its deadline", async () => {
325
+ const scenarios = [
326
+ {
327
+ name: "storageFor",
328
+ stage: "during_storage",
329
+ configure: (harness: Harness) => harness.setStorageForDelay(100),
330
+ },
331
+ {
332
+ name: "loadMeta",
333
+ stage: "during_load_meta",
334
+ configure: async (harness: Harness) => {
335
+ const storage = await harness.storageForNs("default");
336
+ const loadMeta = storage.loadMeta.bind(storage);
337
+ storage.loadMeta = async () => {
338
+ await new Promise((resolve) => setTimeout(resolve, 100));
339
+ return loadMeta();
340
+ };
341
+ },
342
+ },
343
+ {
344
+ name: "listEntityNames",
345
+ stage: "during_list_entity_names",
346
+ configure: async (harness: Harness) => {
347
+ const storage = await harness.storageForNs("default");
348
+ const listEntityNames = storage.listEntityNames.bind(storage);
349
+ storage.listEntityNames = async () => {
350
+ await new Promise((resolve) => setTimeout(resolve, 100));
351
+ return listEntityNames();
352
+ };
353
+ },
354
+ },
355
+ ] as const;
356
+
357
+ for (const scenario of scenarios) {
358
+ const harness = await makeHarness();
359
+ try {
360
+ await scenario.configure(harness);
361
+ await assert.rejects(
362
+ harness.newCoordinator().runExtraction(makeTurns(`deadline-${scenario.name}`), {
363
+ skipCharThreshold: true,
364
+ skipUserTurnThreshold: true,
365
+ clearBufferAfterExtraction: false,
366
+ bufferKey: `deadline-${scenario.name}`,
367
+ deadlineMs: Date.now() + 40,
368
+ }),
369
+ (error: unknown) => error instanceof ExtractionDeadlineError && error.stage === scenario.stage,
370
+ );
371
+ assert.equal(harness.engineCalls(), 0, `${scenario.name} timeout must happen before provider extraction`);
372
+ } finally {
373
+ await harness.cleanup();
374
+ }
375
+ }
376
+ });
377
+
378
+ test("runExtraction does not wait past its deadline for post-persist memory boxes", async () => {
379
+ const harness = await makeHarness({ memoryBoxesEnabled: true });
380
+ try {
381
+ harness.setMemoryBox(() => new Promise<void>(() => {}));
382
+ const startedAt = Date.now();
383
+ const result = await harness.newCoordinator().runExtraction(makeTurns("deadline-memory-box"), {
384
+ skipCharThreshold: true,
385
+ skipUserTurnThreshold: true,
386
+ clearBufferAfterExtraction: false,
387
+ bufferKey: "deadline-memory-box",
388
+ deadlineMs: startedAt + 200,
389
+ });
390
+ assert.equal(result.status, "completed");
391
+ assert.equal(harness.persistCalls(), 1, "durable persistence must complete before helper timeout");
392
+ assert.ok(Date.now() - startedAt < 1_500, "post-persist helper must not hold the extraction indefinitely");
393
+ } finally {
394
+ await harness.cleanup();
395
+ }
396
+ });
397
+
398
+ test("runExtraction force flush reports a late deadline after clearing committed turns", async () => {
399
+ const harness = await makeHarness();
400
+ try {
401
+ harness.setPersist(() => new Promise<void>((resolve) => setTimeout(resolve, 150)));
402
+ const deadlineMs = Date.now() + 50;
403
+ await assert.rejects(
404
+ harness.newCoordinator().runExtraction(makeTurns("late-persist-deadline"), {
405
+ skipCharThreshold: true,
406
+ skipUserTurnThreshold: true,
407
+ clearBufferAfterExtraction: true,
408
+ bufferKey: "late-persist-deadline",
409
+ deadlineMs,
410
+ failOnExtractionFailure: true,
411
+ }),
412
+ (error: unknown) => error instanceof ExtractionDeadlineError && error.stage === "during_buffer_clear",
413
+ );
414
+ assert.equal(harness.persistCalls(), 1, "the late deadline must follow durable persistence");
415
+ } finally {
416
+ await harness.cleanup();
417
+ }
418
+ });
419
+
420
+ test("runExtraction bounds threading pre-persist work by its deadline", async () => {
421
+ const harness = await makeHarness({ threadingEnabled: true });
422
+ try {
423
+ harness.setRespond(() => successResult());
424
+ harness.setThreadingBlock(true);
425
+ await assert.rejects(
426
+ harness.newCoordinator().runExtraction(makeTurns("deadline-threading"), {
427
+ skipCharThreshold: true,
428
+ skipUserTurnThreshold: true,
429
+ clearBufferAfterExtraction: false,
430
+ bufferKey: "deadline-threading",
431
+ deadlineMs: Date.now() + 40,
432
+ }),
433
+ (error: unknown) => error instanceof ExtractionDeadlineError && error.stage === "during_threading",
434
+ );
435
+ assert.equal(harness.persistCalls(), 0, "deadline must prevent durable persistence");
436
+ } finally {
437
+ await harness.cleanup();
438
+ }
439
+ });
440
+
441
+ test("runExtraction clamps long deadline timers to the Node setTimeout limit", async () => {
442
+ const harness = await makeHarness();
443
+ const timerGlobal = globalThis as unknown as { setTimeout: typeof setTimeout };
444
+ const realSetTimeout = timerGlobal.setTimeout;
445
+ const armedDelays: number[] = [];
446
+ timerGlobal.setTimeout = ((handler: (...args: unknown[]) => void, delay?: number, ...args: unknown[]) => {
447
+ if (typeof delay === "number") armedDelays.push(delay);
448
+ return realSetTimeout(handler, 0, ...args);
449
+ }) as typeof setTimeout;
450
+ try {
451
+ const coordinator = harness.newCoordinator();
452
+ await coordinator.runExtraction(makeTurns("long-deadline"), {
453
+ skipCharThreshold: true,
454
+ skipUserTurnThreshold: true,
455
+ clearBufferAfterExtraction: false,
456
+ bufferKey: "long-deadline",
457
+ deadlineMs: Date.now() + 2_147_483_647 + 60_000,
458
+ });
459
+ } finally {
460
+ timerGlobal.setTimeout = realSetTimeout;
461
+ await harness.cleanup();
462
+ }
463
+ assert.ok(armedDelays.includes(2_147_483_647), `expected a clamped deadline timer, got ${armedDelays.join(", ")}`);
464
+ });
465
+
188
466
  // ---------------------------------------------------------------------------
189
467
  // Backoff math (pure)
190
468
  // ---------------------------------------------------------------------------
@@ -227,6 +505,71 @@ test("capExtractionRetryStateEntries: caps to newest and guards maxEntries<=0",
227
505
  assert.deepEqual(capExtractionRetryStateEntries(entries, 0), []);
228
506
  assert.deepEqual(capExtractionRetryStateEntries(entries, -5), []);
229
507
  });
508
+ test("extraction helpers ignore malformed runtime values", () => {
509
+ const malformed = {
510
+ facts: [
511
+ null,
512
+ { tags: [42, "OK"], entityRef: 7, category: "project" },
513
+ { tags: ["valid"], entityRef: "Entity" },
514
+ ],
515
+ entities: [null, 4, { name: "Tool" }],
516
+ } as unknown as ExtractionResult;
517
+ assert.deepEqual(deriveTopicsFromExtraction(malformed), ["ok", "project", "valid", "entity", "tool"]);
518
+ assert.deepEqual(
519
+ deriveTopicsFromExtraction(null as unknown as ExtractionResult),
520
+ [],
521
+ );
522
+ });
523
+
524
+ test("computeExtractionRetryNextEligibleMs rejects invalid numeric inputs", () => {
525
+ assert.throws(
526
+ () => computeExtractionRetryNextEligibleMs(Number.NaN, [1000], 5000, 0.2, 100),
527
+ /attempts must be a finite integer/,
528
+ );
529
+ assert.throws(
530
+ () => computeExtractionRetryNextEligibleMs(0, [1000], 5000, 0.2, 100),
531
+ /attempts must be a finite integer/,
532
+ );
533
+ assert.throws(
534
+ () => computeExtractionRetryNextEligibleMs(1.5, [1000], 5000, 0.2, 100),
535
+ /attempts must be a finite integer/,
536
+ );
537
+ assert.throws(
538
+ () => computeExtractionRetryNextEligibleMs(1, [1000], Number.POSITIVE_INFINITY, 0.2, 100),
539
+ /maxBackoffMs must be a finite number/,
540
+ );
541
+ assert.throws(
542
+ () => computeExtractionRetryNextEligibleMs(1, [1000], -1, 0.2, 100),
543
+ /maxBackoffMs must be a finite number/,
544
+ );
545
+ assert.throws(
546
+ () => computeExtractionRetryNextEligibleMs(1, [1000], 5000, Number.NaN, 100),
547
+ /jitterRatio must be a finite number/,
548
+ );
549
+ assert.throws(
550
+ () => computeExtractionRetryNextEligibleMs(1, [1000], 5000, 2, 100),
551
+ /jitterRatio must be a finite number/,
552
+ );
553
+ assert.throws(
554
+ () => computeExtractionRetryNextEligibleMs(1, [1000], 5000, 0.2, 100, () => Number.NaN),
555
+ /rng\(\) must return a finite number/,
556
+ );
557
+ assert.throws(
558
+ () => computeExtractionRetryNextEligibleMs(1, [1000], 5000, 0.2, 100, () => -0.1),
559
+ /rng\(\) must return a finite number/,
560
+ );
561
+ assert.throws(
562
+ () => computeExtractionRetryNextEligibleMs(1, [1000], 5000, 0.2, 100, () => 1.1),
563
+ /rng\(\) must return a finite number/,
564
+ );
565
+ });
566
+
567
+ test("capExtractionRetryStateEntries rejects non-finite and fractional caps", () => {
568
+ const entries = [{ firstFailedAt: "2026-07-15T00:00:00.000Z" }];
569
+ assert.deepEqual(capExtractionRetryStateEntries(entries, Number.NaN), []);
570
+ assert.deepEqual(capExtractionRetryStateEntries(entries, Number.POSITIVE_INFINITY), []);
571
+ assert.deepEqual(capExtractionRetryStateEntries(entries, 1.5), []);
572
+ });
230
573
 
231
574
  // ---------------------------------------------------------------------------
232
575
  // Backoff eligibility gate