@remnic/core 9.69.35 → 9.69.37

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 (570) hide show
  1. package/dist/access-admin-ops-surface.d.ts +12 -12
  2. package/dist/access-admin-ops-surface.js +35 -35
  3. package/dist/access-authorization-probe.d.ts +12 -12
  4. package/dist/access-authorization-probe.js +36 -36
  5. package/dist/access-boundary.d.ts +12 -12
  6. package/dist/access-boundary.js +35 -35
  7. package/dist/access-cli.js +116 -111
  8. package/dist/access-cli.js.map +1 -1
  9. package/dist/access-coding-context-resolution.d.ts +1 -1
  10. package/dist/access-extraction-force-flush.d.ts +12 -12
  11. package/dist/access-extraction-force-flush.js +35 -35
  12. package/dist/access-health-types.d.ts +1 -1
  13. package/dist/access-http-briefing.d.ts +12 -12
  14. package/dist/access-http-briefing.js +36 -36
  15. package/dist/access-http-lcm-compaction.d.ts +12 -12
  16. package/dist/access-http-lifecycle-flush.d.ts +12 -12
  17. package/dist/access-http-offline-stream.d.ts +12 -12
  18. package/dist/access-http-query.d.ts +2 -2
  19. package/dist/access-http-query.js +37 -37
  20. package/dist/access-http.d.ts +13 -13
  21. package/dist/access-http.js +55 -55
  22. package/dist/access-identity-continuity-surface.d.ts +10 -10
  23. package/dist/access-identity-continuity-surface.js +35 -35
  24. package/dist/access-lcm-surface.d.ts +12 -12
  25. package/dist/access-lcm-surface.js +35 -35
  26. package/dist/access-mcp.d.ts +12 -12
  27. package/dist/access-mcp.js +44 -44
  28. package/dist/access-memory-search-fanout.d.ts +2 -2
  29. package/dist/{access-namespace-preflight-D8qri11P.d.ts → access-namespace-preflight-CV5cHujx.d.ts} +1 -1
  30. package/dist/access-namespace-preflight.d.ts +3 -3
  31. package/dist/access-namespace-preflight.js +35 -35
  32. package/dist/access-observe-transcript.d.ts +10 -10
  33. package/dist/access-observe-write-surface.d.ts +12 -12
  34. package/dist/access-observe-write-surface.js +35 -35
  35. package/dist/access-offline-manifest.d.ts +10 -10
  36. package/dist/access-offline-manifest.js +2 -2
  37. package/dist/access-operations-batch.js +38 -38
  38. package/dist/access-operations.d.ts +16 -16
  39. package/dist/access-operations.js +43 -43
  40. package/dist/access-recall-concurrency.d.ts +12 -12
  41. package/dist/access-recall-concurrency.js +35 -35
  42. package/dist/access-recall-response.d.ts +12 -12
  43. package/dist/access-recall-response.js +35 -35
  44. package/dist/access-recall-surface.d.ts +12 -12
  45. package/dist/access-recall-surface.js +35 -35
  46. package/dist/access-schema.d.ts +94 -94
  47. package/dist/access-schema.js +3 -3
  48. package/dist/{access-service-CKu5ixg9.d.ts → access-service-DwHC7lcV.d.ts} +71 -71
  49. package/dist/access-service-helpers.d.ts +12 -12
  50. package/dist/access-service.d.ts +12 -12
  51. package/dist/access-service.js +35 -35
  52. package/dist/access-surface-catalog.d.ts +12 -12
  53. package/dist/access-surface-catalog.js +37 -37
  54. package/dist/access-wearables-meetings-surface.d.ts +3 -3
  55. package/dist/action-confidence.d.ts +1 -1
  56. package/dist/active-memory-bridge.d.ts +1 -1
  57. package/dist/active-recall.d.ts +1 -1
  58. package/dist/active-recall.js +4 -3
  59. package/dist/active-recall.js.map +1 -1
  60. package/dist/activity/digest.d.ts +1 -1
  61. package/dist/adapters/index.js +4 -4
  62. package/dist/adapters/registry.js +2 -2
  63. package/dist/ambient-provenance.d.ts +1 -1
  64. package/dist/artifact-search.d.ts +1 -1
  65. package/dist/{auto-sync-4YFATLFQ.js → auto-sync-FSRJDU63.js} +4 -4
  66. package/dist/behavior-learner.d.ts +1 -1
  67. package/dist/behavior-signals.d.ts +1 -1
  68. package/dist/bootstrap.d.ts +10 -10
  69. package/dist/briefing-window.d.ts +2 -2
  70. package/dist/briefing.d.ts +2 -2
  71. package/dist/briefing.js +9 -9
  72. package/dist/buffer-surprise-report.d.ts +1 -1
  73. package/dist/buffer-turn-helpers.d.ts +1 -1
  74. package/dist/buffer.d.ts +2 -2
  75. package/dist/bulk-import/index.d.ts +3 -3
  76. package/dist/calibration.d.ts +1 -1
  77. package/dist/calibration.js +1 -1
  78. package/dist/capabilities.d.ts +1 -1
  79. package/dist/{capsule-crypto-7FJQINUR.js → capsule-crypto-YO5QJ6L3.js} +2 -2
  80. package/dist/{catalog-Bq1AxZwF.d.ts → catalog-Cl4H8N89.d.ts} +1 -1
  81. package/dist/causal-behavior.d.ts +1 -1
  82. package/dist/causal-behavior.js +2 -2
  83. package/dist/causal-chain.js +2 -2
  84. package/dist/causal-consolidation.d.ts +1 -1
  85. package/dist/causal-consolidation.js +12 -12
  86. package/dist/causal-retrieval.js +2 -2
  87. package/dist/causal-trajectory-graph.d.ts +1 -1
  88. package/dist/causal-trajectory-graph.js +2 -2
  89. package/dist/causal-trajectory.js +1 -1
  90. package/dist/{chunk-RUXPVSML.js → chunk-2AR5JFD7.js} +2 -2
  91. package/dist/{chunk-YNN26CIZ.js → chunk-2JGGZICG.js} +2 -2
  92. package/dist/{chunk-A7GQBJP5.js → chunk-2L5FSNPC.js} +10 -10
  93. package/dist/{chunk-XPJNT6PI.js → chunk-2PUE5P7C.js} +7 -3
  94. package/dist/chunk-2PUE5P7C.js.map +1 -0
  95. package/dist/{chunk-27IOSH2W.js → chunk-375ARKRS.js} +32 -11
  96. package/dist/chunk-375ARKRS.js.map +1 -0
  97. package/dist/{chunk-ZTG4P7NZ.js → chunk-3IXB77DA.js} +67 -67
  98. package/dist/{chunk-WHHEPAO3.js → chunk-3K6UFW5B.js} +3 -3
  99. package/dist/{chunk-UBG4GAEP.js → chunk-3OHISDDW.js} +5 -1
  100. package/dist/chunk-3OHISDDW.js.map +1 -0
  101. package/dist/chunk-3SL52JKD.js +160 -0
  102. package/dist/chunk-3SL52JKD.js.map +1 -0
  103. package/dist/{chunk-EEBQFG5E.js → chunk-3YMDY3ZF.js} +10 -10
  104. package/dist/{chunk-5JG5EBVL.js → chunk-4DPDIOVA.js} +2 -2
  105. package/dist/{chunk-UDZYNIDJ.js → chunk-4WGAMREC.js} +2 -2
  106. package/dist/{chunk-HXSAWV3A.js → chunk-57GDHV2D.js} +3 -3
  107. package/dist/{chunk-Z7ACR6MJ.js → chunk-5LLQAUMI.js} +2 -2
  108. package/dist/{chunk-P3ONDDIJ.js → chunk-5SYI2F47.js} +2 -2
  109. package/dist/{chunk-DGS34QSY.js → chunk-6E5GYDIE.js} +2 -2
  110. package/dist/{chunk-J7PB5UQ4.js → chunk-6Z3WW2MW.js} +2 -2
  111. package/dist/{chunk-GLZH5VEN.js → chunk-76DRU7C4.js} +2 -2
  112. package/dist/{chunk-L2QLDZJC.js → chunk-7MJBKZPU.js} +2 -2
  113. package/dist/{chunk-Y63ZFP4X.js → chunk-7RKBPXY6.js} +2 -2
  114. package/dist/chunk-A6CXG5WI.js +51 -0
  115. package/dist/chunk-A6CXG5WI.js.map +1 -0
  116. package/dist/{chunk-JSRVXI6E.js → chunk-B2YKTE7P.js} +4 -4
  117. package/dist/{chunk-Z3O53WZR.js → chunk-BICNRVEC.js} +2 -2
  118. package/dist/{chunk-BNGHPYZU.js → chunk-BLHX5FQW.js} +2 -2
  119. package/dist/{chunk-7CBKAQIG.js → chunk-BOADKFN4.js} +28 -4
  120. package/dist/chunk-BOADKFN4.js.map +1 -0
  121. package/dist/{chunk-2NLLXCJG.js → chunk-BXLOS5AJ.js} +2 -2
  122. package/dist/{chunk-776GVKL7.js → chunk-CD3C4BJN.js} +2 -2
  123. package/dist/{chunk-LMCD5W5B.js → chunk-CIYUWSMZ.js} +2 -2
  124. package/dist/{chunk-YJ6VCDMZ.js → chunk-CQ7SSBO4.js} +2 -2
  125. package/dist/{chunk-CNV2A557.js → chunk-CYEMS2PG.js} +2 -2
  126. package/dist/{chunk-DVOBLPSQ.js → chunk-D2DIYEFW.js} +6 -6
  127. package/dist/chunk-D2DIYEFW.js.map +1 -0
  128. package/dist/{chunk-OQ7SSRXP.js → chunk-DOKKRZPH.js} +21 -17
  129. package/dist/chunk-DOKKRZPH.js.map +1 -0
  130. package/dist/{chunk-UYUCCQ46.js → chunk-DOQLHCSS.js} +2 -2
  131. package/dist/{chunk-X7Y7WX73.js → chunk-DQEMWVMT.js} +1 -1
  132. package/dist/{chunk-RRZKTSFG.js → chunk-FCFAYMTU.js} +2 -2
  133. package/dist/{chunk-R4OCGPSH.js → chunk-FJMYMJLR.js} +2 -2
  134. package/dist/{chunk-TKFSXDOB.js → chunk-FLLORID2.js} +2 -2
  135. package/dist/{chunk-QATYVTP7.js → chunk-FPQDZCUX.js} +2 -2
  136. package/dist/{chunk-L2WQVSKP.js → chunk-G5MO3VQA.js} +2 -2
  137. package/dist/{chunk-LNDLXMH6.js → chunk-GDDSXVWR.js} +2 -2
  138. package/dist/{chunk-JZ2CHRLB.js → chunk-GHX5PNXW.js} +2 -2
  139. package/dist/{chunk-2BQ4ZIWC.js → chunk-GNR6YEWZ.js} +5 -5
  140. package/dist/{chunk-5FAGCOZD.js → chunk-GWK7FEUL.js} +4 -4
  141. package/dist/{chunk-SCXURCVT.js → chunk-GWQVMKUJ.js} +3 -3
  142. package/dist/{chunk-QBLDCI6E.js → chunk-HHDTBYDJ.js} +2 -2
  143. package/dist/{chunk-2YLMUME2.js → chunk-IQZ6ISFX.js} +2 -2
  144. package/dist/chunk-JE26AUX6.js +16 -0
  145. package/dist/chunk-JE26AUX6.js.map +1 -0
  146. package/dist/{chunk-AJTG3CP7.js → chunk-JHU4EYDV.js} +11 -1
  147. package/dist/chunk-JHU4EYDV.js.map +1 -0
  148. package/dist/{chunk-JHZCXUQI.js → chunk-JLXWRQNR.js} +33 -33
  149. package/dist/{chunk-FVJ4D6L7.js → chunk-JMPYZJQN.js} +1 -1
  150. package/dist/{chunk-HC4GFLMQ.js → chunk-JO5TQAKW.js} +3 -3
  151. package/dist/{chunk-ZBEGS7OB.js → chunk-JPKZTCWZ.js} +3 -3
  152. package/dist/{chunk-AZSKROVQ.js → chunk-JYR4LH76.js} +2 -2
  153. package/dist/{chunk-ECKG5WSI.js → chunk-JZYECQWN.js} +2 -2
  154. package/dist/{chunk-NPNSKE76.js → chunk-KTRXQQFN.js} +2 -2
  155. package/dist/{chunk-LEMD7WZJ.js → chunk-KUK56OPR.js} +62 -17
  156. package/dist/chunk-KUK56OPR.js.map +1 -0
  157. package/dist/{chunk-HUT2JR6I.js → chunk-L5OXE4PX.js} +2 -2
  158. package/dist/{chunk-B3O3IRZN.js → chunk-LMMQKZK3.js} +1 -1
  159. package/dist/{chunk-QURNMKME.js → chunk-LSDEIZ76.js} +2 -2
  160. package/dist/{chunk-XCOV45MO.js → chunk-MR6LQVZ5.js} +2 -2
  161. package/dist/chunk-OEBLZZKK.js +53 -0
  162. package/dist/chunk-OEBLZZKK.js.map +1 -0
  163. package/dist/{chunk-6J6K3STG.js → chunk-OTPXEE6W.js} +6 -6
  164. package/dist/{chunk-LYDJRF45.js → chunk-PNEDMJ53.js} +2 -2
  165. package/dist/{chunk-MPAJFFP3.js → chunk-PPTOAHTZ.js} +4 -4
  166. package/dist/{chunk-MPAJFFP3.js.map → chunk-PPTOAHTZ.js.map} +1 -1
  167. package/dist/{chunk-JRWW7GM6.js → chunk-Q6D7EUSQ.js} +7 -7
  168. package/dist/{chunk-VYXDUPYE.js → chunk-Q7JK6YEB.js} +2 -2
  169. package/dist/chunk-QJ2AX6DU.js +19 -0
  170. package/dist/chunk-QJ2AX6DU.js.map +1 -0
  171. package/dist/{chunk-4MDKNUV4.js → chunk-RN3MVLW3.js} +1 -1
  172. package/dist/chunk-RN3MVLW3.js.map +1 -0
  173. package/dist/{chunk-YXLUTALO.js → chunk-SAKA6PPL.js} +2 -2
  174. package/dist/{chunk-HWLIMQE2.js → chunk-SF6RFI5Z.js} +2 -2
  175. package/dist/{chunk-OS2AT2JU.js → chunk-SROIT6QY.js} +5 -5
  176. package/dist/{chunk-S5G2LAL7.js → chunk-SV4Z2S67.js} +4 -4
  177. package/dist/{chunk-DK4X5B6I.js → chunk-TFRDUD3M.js} +2 -2
  178. package/dist/{chunk-JR6H5CYS.js → chunk-TL7NLM2L.js} +2 -2
  179. package/dist/{chunk-NN4JEFON.js → chunk-TRU6JBOI.js} +2 -2
  180. package/dist/{chunk-PHP3MUGF.js → chunk-UYVXIY6C.js} +2 -2
  181. package/dist/{chunk-KQAFEZQX.js → chunk-VDX2J7OX.js} +2 -2
  182. package/dist/{chunk-ZHXSOMYH.js → chunk-VVX5PZFS.js} +2 -2
  183. package/dist/{chunk-BJETIR53.js → chunk-WS3WNLST.js} +3 -3
  184. package/dist/{chunk-3FJKJ5UZ.js → chunk-X7BCM2NA.js} +2 -2
  185. package/dist/{chunk-Q4AUIFUA.js → chunk-XAITGGX5.js} +4 -4
  186. package/dist/{chunk-WPDKBUWX.js → chunk-XCF3SFHD.js} +2 -2
  187. package/dist/{chunk-LO4UKPKX.js → chunk-YHU5XUF4.js} +2 -2
  188. package/dist/{chunk-F6IVBYFS.js → chunk-YIZ2EUUL.js} +51 -51
  189. package/dist/{chunk-EZ25VE3G.js → chunk-YNDLCWXS.js} +4 -4
  190. package/dist/{chunk-5VAF4ID4.js → chunk-ZEPVWLCN.js} +9 -9
  191. package/dist/{cli-Bk7Ctql4.d.ts → cli-1mzd5TM4.d.ts} +5 -5
  192. package/dist/cli.d.ts +14 -14
  193. package/dist/cli.js +79 -78
  194. package/dist/coding/export-okf-codegraph.d.ts +1 -1
  195. package/dist/coding/export-okf-codegraph.js +8 -8
  196. package/dist/coding/pre-action-gate.d.ts +1 -1
  197. package/dist/coding/pre-action-gate.js +2 -2
  198. package/dist/compounding/engine.d.ts +2 -2
  199. package/dist/compounding/engine.js +9 -9
  200. package/dist/compounding/preference-consolidator.d.ts +1 -1
  201. package/dist/compression-optimizer.d.ts +1 -1
  202. package/dist/config.d.ts +1 -1
  203. package/dist/config.js +4 -3
  204. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  205. package/dist/connectors/codex-materialize-runner.js +9 -9
  206. package/dist/connectors/codex-materialize.d.ts +1 -1
  207. package/dist/connectors/index.d.ts +1 -1
  208. package/dist/connectors/index.js +9 -9
  209. package/dist/consolidation-provenance-check.d.ts +2 -2
  210. package/dist/consolidation-undo.d.ts +2 -2
  211. package/dist/contradiction/index.d.ts +3 -3
  212. package/dist/converge-config.d.ts +1 -1
  213. package/dist/convergence-refresh.d.ts +2 -2
  214. package/dist/convergence-refresh.js +11 -11
  215. package/dist/conversation-index/backend.d.ts +1 -1
  216. package/dist/conversation-index/chunker.d.ts +1 -1
  217. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  218. package/dist/conversation-index/indexer.d.ts +1 -1
  219. package/dist/conversation-index/search.d.ts +1 -1
  220. package/dist/corpus-watermark.d.ts +1 -1
  221. package/dist/corpus-watermark.js +11 -11
  222. package/dist/cross-lingual-recall.d.ts +1 -1
  223. package/dist/dashboard-runtime.js +2 -2
  224. package/dist/day-summary.d.ts +1 -1
  225. package/dist/deep-recall-http-glue.d.ts +12 -12
  226. package/dist/deep-recall-http-glue.js +4 -4
  227. package/dist/deep-recall-mcp-tools.d.ts +12 -12
  228. package/dist/deep-recall-policy-llm.d.ts +1 -1
  229. package/dist/deep-recall-seeds.d.ts +1 -1
  230. package/dist/deep-recall.js +2 -2
  231. package/dist/delinearize.d.ts +1 -1
  232. package/dist/dependency-propagation-config.d.ts +1 -1
  233. package/dist/{dependency-propagation-delivery-DLiAtj25.d.ts → dependency-propagation-delivery-Bua2ApHV.d.ts} +1 -1
  234. package/dist/direct-answer-wiring.d.ts +1 -1
  235. package/dist/direct-answer.d.ts +1 -1
  236. package/dist/embedding-fallback.d.ts +1 -1
  237. package/dist/enrichment/index.d.ts +1 -1
  238. package/dist/entity-origin-fields.d.ts +1 -1
  239. package/dist/entity-retrieval.d.ts +2 -2
  240. package/dist/entity-retrieval.js +9 -9
  241. package/dist/entity-schema.d.ts +1 -1
  242. package/dist/episodic-context.d.ts +1 -1
  243. package/dist/eval-trajectory-contracts.d.ts +1 -1
  244. package/dist/eval-trajectory-store.d.ts +1 -1
  245. package/dist/eval-trajectory.d.ts +1 -1
  246. package/dist/explicit-capture.d.ts +10 -10
  247. package/dist/external-wiki-access.d.ts +12 -12
  248. package/dist/external-wiki-access.js +36 -36
  249. package/dist/external-wiki-collection-registration.d.ts +1 -1
  250. package/dist/external-wiki-collection.d.ts +1 -1
  251. package/dist/external-wiki-mcp-tools.d.ts +12 -12
  252. package/dist/extraction-error-classification.d.ts +1 -1
  253. package/dist/extraction-faithfulness.d.ts +1 -1
  254. package/dist/extraction-judge-telemetry.d.ts +1 -1
  255. package/dist/extraction-judge-training.d.ts +1 -1
  256. package/dist/extraction-judge.d.ts +1 -1
  257. package/dist/extraction-judge.js +2 -2
  258. package/dist/extraction-liveness.d.ts +1 -1
  259. package/dist/extraction-normalization.d.ts +1 -1
  260. package/dist/extraction-normalization.js +2 -2
  261. package/dist/extraction-prompt.d.ts +11 -2
  262. package/dist/extraction-prompt.js +7 -3
  263. package/dist/extraction-source-grounding-rules.d.ts +3 -2
  264. package/dist/extraction-source-grounding-rules.js +1 -1
  265. package/dist/extraction-source-grounding.d.ts +2 -2
  266. package/dist/extraction-source-grounding.js +2 -2
  267. package/dist/extraction-span-config.d.ts +15 -0
  268. package/dist/extraction-span-config.js +15 -0
  269. package/dist/extraction-span-materialize.d.ts +105 -0
  270. package/dist/extraction-span-materialize.js +30 -0
  271. package/dist/extraction-span-materialize.js.map +1 -0
  272. package/dist/extraction-span-slice.js +3 -12
  273. package/dist/extraction-span-slice.js.map +1 -1
  274. package/dist/extraction-span-source-hash.js +4 -46
  275. package/dist/extraction-span-source-hash.js.map +1 -1
  276. package/dist/extraction-span-validate.js +3 -15
  277. package/dist/extraction-span-validate.js.map +1 -1
  278. package/dist/extraction.d.ts +7 -1
  279. package/dist/extraction.js +20 -16
  280. package/dist/fallback-llm.d.ts +1 -1
  281. package/dist/{first-start-migration-L3UFX5CU.js → first-start-migration-GZ45G5FS.js} +4 -4
  282. package/dist/{generic-recall-paths-DbitKJI5.d.ts → generic-recall-paths-DJBADojG.d.ts} +1 -1
  283. package/dist/graph-append-error.d.ts +1 -1
  284. package/dist/graph-dashboard-diff.d.ts +1 -1
  285. package/dist/graph-dashboard-key.d.ts +1 -1
  286. package/dist/graph-dashboard-parser.d.ts +1 -1
  287. package/dist/{graph-edge-decay-MKIRZ762.js → graph-edge-decay-ROSUPDX3.js} +5 -5
  288. package/dist/graph-edge-decay-ROSUPDX3.js.map +1 -0
  289. package/dist/graph-edge-reinforcement.d.ts +1 -1
  290. package/dist/graph-jsonl.d.ts +1 -1
  291. package/dist/graph-jsonl.js +3 -3
  292. package/dist/graph-path-reconstruction.d.ts +1 -1
  293. package/dist/graph-path-scoring.d.ts +1 -1
  294. package/dist/graph-snapshot.d.ts +1 -1
  295. package/dist/graph-snapshot.js +3 -3
  296. package/dist/graph.d.ts +1 -1
  297. package/dist/graph.js +2 -2
  298. package/dist/harmonic-retrieval.js +1 -1
  299. package/dist/importance.d.ts +1 -1
  300. package/dist/importers/index.d.ts +1 -1
  301. package/dist/importers/test-utils.d.ts +1 -1
  302. package/dist/in-flight-reads.d.ts +1 -1
  303. package/dist/{index-BINUgPFo.d.ts → index-Bsy8ygLL.d.ts} +2 -2
  304. package/dist/index.d.ts +700 -700
  305. package/dist/index.js +147 -142
  306. package/dist/intent.d.ts +1 -1
  307. package/dist/lcm/engine.d.ts +1 -1
  308. package/dist/lcm/engine.js +4 -4
  309. package/dist/lcm/index.d.ts +1 -1
  310. package/dist/lcm/index.js +9 -9
  311. package/dist/lcm/tools.d.ts +1 -1
  312. package/dist/lifecycle.d.ts +1 -1
  313. package/dist/live-connectors-runner.d.ts +1 -1
  314. package/dist/local-llm.d.ts +1 -1
  315. package/dist/local-model-endpoint.d.ts +1 -1
  316. package/dist/location/index.d.ts +3 -3
  317. package/dist/location/index.js +11 -11
  318. package/dist/maintenance/memory-governance.d.ts +1 -1
  319. package/dist/maintenance/memory-governance.js +9 -9
  320. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
  321. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +9 -9
  322. package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
  323. package/dist/maintenance/rebuild-memory-projection.js +10 -10
  324. package/dist/{maintenance-ag1gYztC.d.ts → maintenance-DItyBwTC.d.ts} +3 -3
  325. package/dist/mcp-memory-inspector-app.d.ts +12 -12
  326. package/dist/memory-action-policy.d.ts +1 -1
  327. package/dist/memory-cache.d.ts +1 -1
  328. package/dist/memory-controller.d.ts +1 -1
  329. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  330. package/dist/memory-projection-store.d.ts +1 -1
  331. package/dist/memory-provenance.d.ts +1 -1
  332. package/dist/memory-snapshot.d.ts +1 -1
  333. package/dist/memory-subject-cli.d.ts +12 -12
  334. package/dist/memory-subject.d.ts +12 -12
  335. package/dist/memory-worth-outcomes.d.ts +2 -2
  336. package/dist/models-json.d.ts +1 -1
  337. package/dist/namespaces/migrate.d.ts +3 -3
  338. package/dist/namespaces/migrate.js +10 -10
  339. package/dist/namespaces/principal.d.ts +1 -1
  340. package/dist/namespaces/search.d.ts +1 -1
  341. package/dist/namespaces/search.js +5 -5
  342. package/dist/namespaces/storage.d.ts +3 -3
  343. package/dist/namespaces/storage.js +9 -9
  344. package/dist/native-knowledge.d.ts +1 -1
  345. package/dist/offline-sync-impression-drain.d.ts +1 -1
  346. package/dist/operator-doctor-corpus.d.ts +1 -1
  347. package/dist/operator-doctor-corpus.js +12 -12
  348. package/dist/operator-doctor-replica.d.ts +1 -1
  349. package/dist/operator-toolkit.d.ts +3 -3
  350. package/dist/operator-toolkit.js +23 -22
  351. package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
  352. package/dist/orchestration/maintenance.d.ts +4 -4
  353. package/dist/orchestration/maintenance.js +17 -17
  354. package/dist/{orchestrator-Cf3G-3Ed.d.ts → orchestrator-DBUX-aAM.d.ts} +9 -9
  355. package/dist/orchestrator.d.ts +10 -10
  356. package/dist/orchestrator.js +117 -112
  357. package/dist/patterns-cli.d.ts +1 -1
  358. package/dist/{pipeline-AwB03fw_.d.ts → pipeline-BqgcOk1Z.d.ts} +1 -1
  359. package/dist/policy-runtime.d.ts +1 -1
  360. package/dist/proactive-contention.d.ts +1 -1
  361. package/dist/provenance.d.ts +1 -1
  362. package/dist/{public-http-BetSQn7q.d.ts → public-http-CqtZ5kv3.d.ts} +1 -1
  363. package/dist/{qmd-Bfaydrfm.d.ts → qmd-BD0ikV_Y.d.ts} +1 -1
  364. package/dist/qmd-preflight.d.ts +2 -2
  365. package/dist/qmd-recall-cache.d.ts +1 -1
  366. package/dist/qmd.d.ts +2 -2
  367. package/dist/recall-concurrency-config.d.ts +1 -1
  368. package/dist/recall-disclosure-escalation.d.ts +1 -1
  369. package/dist/recall-explain-renderer.d.ts +1 -1
  370. package/dist/recall-explain-renderer.js +3 -3
  371. package/dist/recall-memory-map.d.ts +1 -1
  372. package/dist/recall-navigate-access.d.ts +1 -1
  373. package/dist/recall-navigate-access.js +2 -2
  374. package/dist/recall-navigate-disclosure.d.ts +1 -1
  375. package/dist/recall-navigate-disclosure.js +1 -1
  376. package/dist/recall-navigate.d.ts +1 -1
  377. package/dist/recall-navigate.js +2 -2
  378. package/dist/recall-planner-llm.d.ts +1 -1
  379. package/dist/recall-state-view-admission.d.ts +2 -2
  380. package/dist/recall-state.d.ts +1 -1
  381. package/dist/recall-tag-filter.d.ts +1 -1
  382. package/dist/recall-timings.d.ts +1 -1
  383. package/dist/recall-xray-cli.d.ts +1 -1
  384. package/dist/recall-xray-cli.js +4 -4
  385. package/dist/recall-xray-renderer.d.ts +1 -1
  386. package/dist/recall-xray-renderer.js +3 -3
  387. package/dist/recall-xray.d.ts +1 -1
  388. package/dist/recall-xray.js +2 -2
  389. package/dist/reconcile/cursor.d.ts +1 -1
  390. package/dist/reconcile/manifest.d.ts +11 -2
  391. package/dist/reconcile/manifest.js +5 -3
  392. package/dist/reconcile/plan.d.ts +1 -1
  393. package/dist/replay/normalizers/chatgpt.d.ts +1 -1
  394. package/dist/replay/normalizers/claude.d.ts +1 -1
  395. package/dist/replay/normalizers/openclaw.d.ts +1 -1
  396. package/dist/replay/normalizers/shared.d.ts +1 -1
  397. package/dist/replay/runner.d.ts +1 -1
  398. package/dist/replay/types.d.ts +1 -1
  399. package/dist/replica-divergence.d.ts +1 -1
  400. package/dist/replica-peers-config.d.ts +1 -1
  401. package/dist/resolve-auth-token.d.ts +1 -1
  402. package/dist/resume-bundles.js +5 -4
  403. package/dist/retrieval-agents.d.ts +2 -2
  404. package/dist/retrieval-tiers.d.ts +1 -1
  405. package/dist/routing/engine.d.ts +1 -1
  406. package/dist/routing/store.d.ts +1 -1
  407. package/dist/salvage-envelope.d.ts +1 -1
  408. package/dist/schemas.d.ts +386 -176
  409. package/dist/schemas.js +1 -1
  410. package/dist/{scope-profiles-nxTKvjE-.d.ts → scope-profiles-BIJMsd0B.d.ts} +1 -1
  411. package/dist/search/embed-helper.d.ts +1 -1
  412. package/dist/search/factory.d.ts +1 -1
  413. package/dist/search/factory.js +4 -4
  414. package/dist/search/index.d.ts +1 -1
  415. package/dist/search/index.js +10 -10
  416. package/dist/search/lancedb-backend.d.ts +1 -1
  417. package/dist/search/meilisearch-backend.d.ts +1 -1
  418. package/dist/search/noop-backend.d.ts +1 -1
  419. package/dist/search/orama-backend.d.ts +1 -1
  420. package/dist/search/port.d.ts +1 -1
  421. package/dist/search/remote-backend.d.ts +1 -1
  422. package/dist/{semantic-consolidation-C83DVakV.d.ts → semantic-consolidation-D7sJocll.d.ts} +1 -1
  423. package/dist/semantic-consolidation.d.ts +2 -2
  424. package/dist/semantic-consolidation.js +10 -10
  425. package/dist/semantic-rule-promotion.js +9 -9
  426. package/dist/semantic-rule-verifier.d.ts +1 -1
  427. package/dist/semantic-rule-verifier.js +9 -9
  428. package/dist/{service-q-xtOoAr.d.ts → service-fwgEngUj.d.ts} +2 -2
  429. package/dist/session-observer-bands.d.ts +1 -1
  430. package/dist/session-observer-state.d.ts +1 -1
  431. package/dist/shared-context/manager.d.ts +7 -7
  432. package/dist/signal.d.ts +1 -1
  433. package/dist/source-agent-qualifier.d.ts +1 -1
  434. package/dist/source-agent-qualifier.js +12 -12
  435. package/dist/standup/build.js +9 -9
  436. package/dist/{storage-Ca0MbTfm.d.ts → storage-Cbll3-Tk.d.ts} +1 -1
  437. package/dist/storage.d.ts +2 -2
  438. package/dist/storage.js +8 -8
  439. package/dist/subject-config.d.ts +1 -1
  440. package/dist/summarizer.d.ts +1 -1
  441. package/dist/summary-snapshot.d.ts +1 -1
  442. package/dist/support-passport/index.d.ts +15 -15
  443. package/dist/support-passport/index.js +38 -38
  444. package/dist/temporal-supersession.d.ts +2 -2
  445. package/dist/temporal-timeline-recall.d.ts +1 -1
  446. package/dist/temporal-validity.d.ts +1 -1
  447. package/dist/threading.d.ts +1 -1
  448. package/dist/tier-migration.d.ts +2 -2
  449. package/dist/tier-routing.d.ts +1 -1
  450. package/dist/topics.d.ts +1 -1
  451. package/dist/transcript.d.ts +1 -1
  452. package/dist/transfer/backup.js +2 -2
  453. package/dist/transfer/capsule-export.js +2 -2
  454. package/dist/transfer/capsule-import.js +2 -2
  455. package/dist/transfer/export-okf.d.ts +1 -1
  456. package/dist/transfer/export-okf.js +9 -9
  457. package/dist/transfer/types.d.ts +98 -98
  458. package/dist/trust-score-stage.d.ts +1 -1
  459. package/dist/trust-score.d.ts +1 -1
  460. package/dist/{types-yDgWDkrJ.d.ts → types-48sPkWB0.d.ts} +49 -10
  461. package/dist/types.d.ts +1 -1
  462. package/dist/types.js +1 -1
  463. package/dist/utility-runtime.d.ts +1 -1
  464. package/dist/verified-recall.js +9 -9
  465. package/dist/who-knows-cli.d.ts +12 -12
  466. package/dist/who-knows-cli.js +10 -10
  467. package/dist/who-knows.d.ts +12 -12
  468. package/dist/who-knows.js +9 -9
  469. package/dist/write-envelope.d.ts +1 -1
  470. package/package.json +42 -2
  471. package/src/access-http.test.ts +43 -5
  472. package/src/access-http.ts +2 -0
  473. package/src/config.ts +2 -2
  474. package/src/extraction-prompt.ts +37 -3
  475. package/src/extraction-source-grounding-rules.ts +46 -9
  476. package/src/extraction-source-grounding.ts +2 -1
  477. package/src/extraction-span-config.ts +81 -0
  478. package/src/extraction-span-materialize.test.ts +376 -0
  479. package/src/extraction-span-materialize.ts +241 -0
  480. package/src/extraction.ts +70 -25
  481. package/src/reconcile/manifest.test.ts +11 -1
  482. package/src/reconcile/manifest.ts +12 -0
  483. package/src/schemas.ts +14 -0
  484. package/src/source-agent-qualifier.ts +5 -1
  485. package/src/testing/subjects/extraction-lifecycle.test.ts +27 -10
  486. package/src/types.ts +9 -9
  487. package/dist/chunk-27IOSH2W.js.map +0 -1
  488. package/dist/chunk-4MDKNUV4.js.map +0 -1
  489. package/dist/chunk-7CBKAQIG.js.map +0 -1
  490. package/dist/chunk-AJTG3CP7.js.map +0 -1
  491. package/dist/chunk-DVOBLPSQ.js.map +0 -1
  492. package/dist/chunk-LEMD7WZJ.js.map +0 -1
  493. package/dist/chunk-OQ7SSRXP.js.map +0 -1
  494. package/dist/chunk-UBG4GAEP.js.map +0 -1
  495. package/dist/chunk-XPJNT6PI.js.map +0 -1
  496. /package/dist/{auto-sync-4YFATLFQ.js.map → auto-sync-FSRJDU63.js.map} +0 -0
  497. /package/dist/{capsule-crypto-7FJQINUR.js.map → capsule-crypto-YO5QJ6L3.js.map} +0 -0
  498. /package/dist/{chunk-RUXPVSML.js.map → chunk-2AR5JFD7.js.map} +0 -0
  499. /package/dist/{chunk-YNN26CIZ.js.map → chunk-2JGGZICG.js.map} +0 -0
  500. /package/dist/{chunk-A7GQBJP5.js.map → chunk-2L5FSNPC.js.map} +0 -0
  501. /package/dist/{chunk-ZTG4P7NZ.js.map → chunk-3IXB77DA.js.map} +0 -0
  502. /package/dist/{chunk-WHHEPAO3.js.map → chunk-3K6UFW5B.js.map} +0 -0
  503. /package/dist/{chunk-EEBQFG5E.js.map → chunk-3YMDY3ZF.js.map} +0 -0
  504. /package/dist/{chunk-5JG5EBVL.js.map → chunk-4DPDIOVA.js.map} +0 -0
  505. /package/dist/{chunk-UDZYNIDJ.js.map → chunk-4WGAMREC.js.map} +0 -0
  506. /package/dist/{chunk-HXSAWV3A.js.map → chunk-57GDHV2D.js.map} +0 -0
  507. /package/dist/{chunk-Z7ACR6MJ.js.map → chunk-5LLQAUMI.js.map} +0 -0
  508. /package/dist/{chunk-P3ONDDIJ.js.map → chunk-5SYI2F47.js.map} +0 -0
  509. /package/dist/{chunk-DGS34QSY.js.map → chunk-6E5GYDIE.js.map} +0 -0
  510. /package/dist/{chunk-J7PB5UQ4.js.map → chunk-6Z3WW2MW.js.map} +0 -0
  511. /package/dist/{chunk-GLZH5VEN.js.map → chunk-76DRU7C4.js.map} +0 -0
  512. /package/dist/{chunk-L2QLDZJC.js.map → chunk-7MJBKZPU.js.map} +0 -0
  513. /package/dist/{chunk-Y63ZFP4X.js.map → chunk-7RKBPXY6.js.map} +0 -0
  514. /package/dist/{chunk-JSRVXI6E.js.map → chunk-B2YKTE7P.js.map} +0 -0
  515. /package/dist/{chunk-Z3O53WZR.js.map → chunk-BICNRVEC.js.map} +0 -0
  516. /package/dist/{chunk-BNGHPYZU.js.map → chunk-BLHX5FQW.js.map} +0 -0
  517. /package/dist/{chunk-2NLLXCJG.js.map → chunk-BXLOS5AJ.js.map} +0 -0
  518. /package/dist/{chunk-776GVKL7.js.map → chunk-CD3C4BJN.js.map} +0 -0
  519. /package/dist/{chunk-LMCD5W5B.js.map → chunk-CIYUWSMZ.js.map} +0 -0
  520. /package/dist/{chunk-YJ6VCDMZ.js.map → chunk-CQ7SSBO4.js.map} +0 -0
  521. /package/dist/{chunk-CNV2A557.js.map → chunk-CYEMS2PG.js.map} +0 -0
  522. /package/dist/{chunk-UYUCCQ46.js.map → chunk-DOQLHCSS.js.map} +0 -0
  523. /package/dist/{chunk-X7Y7WX73.js.map → chunk-DQEMWVMT.js.map} +0 -0
  524. /package/dist/{chunk-RRZKTSFG.js.map → chunk-FCFAYMTU.js.map} +0 -0
  525. /package/dist/{chunk-R4OCGPSH.js.map → chunk-FJMYMJLR.js.map} +0 -0
  526. /package/dist/{chunk-TKFSXDOB.js.map → chunk-FLLORID2.js.map} +0 -0
  527. /package/dist/{chunk-QATYVTP7.js.map → chunk-FPQDZCUX.js.map} +0 -0
  528. /package/dist/{chunk-L2WQVSKP.js.map → chunk-G5MO3VQA.js.map} +0 -0
  529. /package/dist/{chunk-LNDLXMH6.js.map → chunk-GDDSXVWR.js.map} +0 -0
  530. /package/dist/{chunk-JZ2CHRLB.js.map → chunk-GHX5PNXW.js.map} +0 -0
  531. /package/dist/{chunk-2BQ4ZIWC.js.map → chunk-GNR6YEWZ.js.map} +0 -0
  532. /package/dist/{chunk-5FAGCOZD.js.map → chunk-GWK7FEUL.js.map} +0 -0
  533. /package/dist/{chunk-SCXURCVT.js.map → chunk-GWQVMKUJ.js.map} +0 -0
  534. /package/dist/{chunk-QBLDCI6E.js.map → chunk-HHDTBYDJ.js.map} +0 -0
  535. /package/dist/{chunk-2YLMUME2.js.map → chunk-IQZ6ISFX.js.map} +0 -0
  536. /package/dist/{chunk-JHZCXUQI.js.map → chunk-JLXWRQNR.js.map} +0 -0
  537. /package/dist/{chunk-FVJ4D6L7.js.map → chunk-JMPYZJQN.js.map} +0 -0
  538. /package/dist/{chunk-HC4GFLMQ.js.map → chunk-JO5TQAKW.js.map} +0 -0
  539. /package/dist/{chunk-ZBEGS7OB.js.map → chunk-JPKZTCWZ.js.map} +0 -0
  540. /package/dist/{chunk-AZSKROVQ.js.map → chunk-JYR4LH76.js.map} +0 -0
  541. /package/dist/{chunk-ECKG5WSI.js.map → chunk-JZYECQWN.js.map} +0 -0
  542. /package/dist/{chunk-NPNSKE76.js.map → chunk-KTRXQQFN.js.map} +0 -0
  543. /package/dist/{chunk-HUT2JR6I.js.map → chunk-L5OXE4PX.js.map} +0 -0
  544. /package/dist/{chunk-B3O3IRZN.js.map → chunk-LMMQKZK3.js.map} +0 -0
  545. /package/dist/{chunk-QURNMKME.js.map → chunk-LSDEIZ76.js.map} +0 -0
  546. /package/dist/{chunk-XCOV45MO.js.map → chunk-MR6LQVZ5.js.map} +0 -0
  547. /package/dist/{chunk-6J6K3STG.js.map → chunk-OTPXEE6W.js.map} +0 -0
  548. /package/dist/{chunk-LYDJRF45.js.map → chunk-PNEDMJ53.js.map} +0 -0
  549. /package/dist/{chunk-JRWW7GM6.js.map → chunk-Q6D7EUSQ.js.map} +0 -0
  550. /package/dist/{chunk-VYXDUPYE.js.map → chunk-Q7JK6YEB.js.map} +0 -0
  551. /package/dist/{chunk-YXLUTALO.js.map → chunk-SAKA6PPL.js.map} +0 -0
  552. /package/dist/{chunk-HWLIMQE2.js.map → chunk-SF6RFI5Z.js.map} +0 -0
  553. /package/dist/{chunk-OS2AT2JU.js.map → chunk-SROIT6QY.js.map} +0 -0
  554. /package/dist/{chunk-S5G2LAL7.js.map → chunk-SV4Z2S67.js.map} +0 -0
  555. /package/dist/{chunk-DK4X5B6I.js.map → chunk-TFRDUD3M.js.map} +0 -0
  556. /package/dist/{chunk-JR6H5CYS.js.map → chunk-TL7NLM2L.js.map} +0 -0
  557. /package/dist/{chunk-NN4JEFON.js.map → chunk-TRU6JBOI.js.map} +0 -0
  558. /package/dist/{chunk-PHP3MUGF.js.map → chunk-UYVXIY6C.js.map} +0 -0
  559. /package/dist/{chunk-KQAFEZQX.js.map → chunk-VDX2J7OX.js.map} +0 -0
  560. /package/dist/{chunk-ZHXSOMYH.js.map → chunk-VVX5PZFS.js.map} +0 -0
  561. /package/dist/{chunk-BJETIR53.js.map → chunk-WS3WNLST.js.map} +0 -0
  562. /package/dist/{chunk-3FJKJ5UZ.js.map → chunk-X7BCM2NA.js.map} +0 -0
  563. /package/dist/{chunk-Q4AUIFUA.js.map → chunk-XAITGGX5.js.map} +0 -0
  564. /package/dist/{chunk-WPDKBUWX.js.map → chunk-XCF3SFHD.js.map} +0 -0
  565. /package/dist/{chunk-LO4UKPKX.js.map → chunk-YHU5XUF4.js.map} +0 -0
  566. /package/dist/{chunk-F6IVBYFS.js.map → chunk-YIZ2EUUL.js.map} +0 -0
  567. /package/dist/{chunk-EZ25VE3G.js.map → chunk-YNDLCWXS.js.map} +0 -0
  568. /package/dist/{chunk-5VAF4ID4.js.map → chunk-ZEPVWLCN.js.map} +0 -0
  569. /package/dist/{graph-edge-decay-MKIRZ762.js.map → extraction-span-config.js.map} +0 -0
  570. /package/dist/{first-start-migration-L3UFX5CU.js.map → first-start-migration-GZ45G5FS.js.map} +0 -0
@@ -29,6 +29,7 @@ import {
29
29
  export interface ExtractionSourceGroundingOptions {
30
30
  sourceGrounding: boolean;
31
31
  anchorTemporalExpressions: boolean;
32
+ spanMode?: "off" | "shadow" | "on";
32
33
  }
33
34
 
34
35
  export function applyExtractionSourceGrounding(
@@ -60,6 +61,7 @@ export function applyExtractionSourceGrounding(
60
61
  anchorSource(assertionSourceText),
61
62
  anchoredRoleSources,
62
63
  options.anchorTemporalExpressions ? anchorSource : undefined,
64
+ options.spanMode ?? "off",
63
65
  );
64
66
  }
65
67
 
@@ -653,18 +655,51 @@ function filterGroundedFact(
653
655
  assertionSource: string | undefined,
654
656
  roleAssertionSources: ExtractionGroundingRoleSources | undefined,
655
657
  eventTimeNormalizer: ((eventTime: string) => string) | undefined,
658
+ spanMode: "off" | "shadow" | "on" = "off",
656
659
  ): ExtractionResult["facts"][number] | undefined {
657
- const factContext = selectGroundingContext(
660
+ // Span-materialized content (issue #2333) is "frame: verbatim slice". The
661
+ // frame is generated deixis, so full-content gating would drop a verbatim
662
+ // fact. Only on-mode facts whose content is that materialized shape may
663
+ // fall back to the slice. Shadow stays zero-diff with off.
664
+ const quote = typeof fact.quote === "string" ? fact.quote : "";
665
+ const materializedPrefix = quote.length > 0 && fact.content.endsWith(quote) && fact.content !== quote
666
+ ? fact.content.slice(0, fact.content.length - quote.length)
667
+ : "";
668
+ const embeddedQuote =
669
+ spanMode === "on"
670
+ && quote.trim().length > 0
671
+ && (materializedPrefix.endsWith(": ") || /[:—-]\s$/.test(materializedPrefix))
672
+ ? quote
673
+ : undefined;
674
+ const contentContext = selectGroundingContext(
658
675
  fact.content,
659
676
  resolveGroundingContext(fact.content, source, assertionSource, roleAssertionSources),
660
677
  );
661
- if (!isGroundedCandidate(
662
- fact.content,
663
- factContext.source,
664
- factContext.assertionSource,
665
- false,
666
- factContext.allowRoleNormalization,
667
- )) return undefined;
678
+ let gateContent = fact.content;
679
+ let factContext = contentContext;
680
+ if (
681
+ !isGroundedCandidate(
682
+ fact.content,
683
+ contentContext.source,
684
+ contentContext.assertionSource,
685
+ false,
686
+ contentContext.allowRoleNormalization,
687
+ )
688
+ ) {
689
+ if (embeddedQuote === undefined) return undefined;
690
+ gateContent = embeddedQuote;
691
+ factContext = selectGroundingContext(
692
+ gateContent,
693
+ resolveGroundingContext(gateContent, source, assertionSource, roleAssertionSources),
694
+ );
695
+ if (!isGroundedCandidate(
696
+ gateContent,
697
+ factContext.source,
698
+ factContext.assertionSource,
699
+ false,
700
+ factContext.allowRoleNormalization,
701
+ )) return undefined;
702
+ }
668
703
  const factEventTime = fact.eventTime;
669
704
  const groundedFactEventTime = factEventTime === undefined
670
705
  ? undefined
@@ -672,7 +707,7 @@ function filterGroundedFact(
672
707
  const factSupportingSentences = sourceSentences(factContext.assertionSource ?? factContext.source).filter(
673
708
  (sentence) =>
674
709
  isGroundedCandidate(
675
- fact.content,
710
+ gateContent,
676
711
  sentence,
677
712
  undefined,
678
713
  false,
@@ -1068,6 +1103,7 @@ export function filterExtractionResultBySource(
1068
1103
  assertionSource?: string,
1069
1104
  roleAssertionSources?: ExtractionGroundingRoleSources,
1070
1105
  eventTimeNormalizer?: (eventTime: string) => string,
1106
+ spanMode: "off" | "shadow" | "on" = "off",
1071
1107
  ): ExtractionResult {
1072
1108
  if (source.trim().length === 0) {
1073
1109
  return {
@@ -1088,6 +1124,7 @@ export function filterExtractionResultBySource(
1088
1124
  assertionSource,
1089
1125
  roleAssertionSources,
1090
1126
  eventTimeNormalizer,
1127
+ spanMode,
1091
1128
  );
1092
1129
  return grounded === undefined ? [] : [grounded];
1093
1130
  });
@@ -99,6 +99,7 @@ export function filterExtractionResultBySource(
99
99
  assertionSource?: string,
100
100
  roleAssertionSources?: ExtractionGroundingRoleSources,
101
101
  eventTimeNormalizer?: (eventTime: string) => string,
102
+ spanMode: "off" | "shadow" | "on" = "off",
102
103
  ): ExtractionResult {
103
- return filterGroundingRules(result, source, assertionSource, roleAssertionSources, eventTimeNormalizer);
104
+ return filterGroundingRules(result, source, assertionSource, roleAssertionSources, eventTimeNormalizer, spanMode);
104
105
  }
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Span-mode extraction config + fact span-ref types (issue #2333 Phase B,
3
+ * bench-gated). Sibling module so config.ts and types.ts stay under their
4
+ * structural ratchets (#1995); types.ts re-exports both.
5
+ *
6
+ * Default "off"; an unrecognized value is REJECTED, never defaulted
7
+ * (checklist #39) — silently ignoring it would run an unbenched extraction
8
+ * contract.
9
+ */
10
+
11
+ import { z } from "zod";
12
+ import { parseExtractionLivenessConfig } from "./extraction-liveness.js";
13
+
14
+ export interface ExtractionSpanConfig {
15
+ /**
16
+ * - "off" (default): extraction generates content as before.
17
+ * - "shadow": request spans AND content; materialize + compare + log
18
+ * agreement telemetry; persist the generated content (zero behavior
19
+ * change).
20
+ * - "on": persist materialized frame+span content, falling back per fact
21
+ * to generated content when the span fails validation.
22
+ */
23
+ spanMode: "off" | "shadow" | "on";
24
+ }
25
+
26
+ export interface ExtractedFactSpanRef {
27
+ /** Ordinal of the source turn in the extraction segment (0-based). */
28
+ sourceMessageIndex: number;
29
+ /** [charStart, charEnd) into the turn's exact in-memory text (UTF-16 code units). */
30
+ charStart: number;
31
+ charEnd: number;
32
+ /** ≤ 15 generated words making the span self-contained (resolves deixis). */
33
+ frame: string;
34
+ /** Optional prompt-source identity; when present it must match the captured stamp. */
35
+ sourceHash?: string;
36
+ sourceLength?: number;
37
+ }
38
+
39
+ export const EXTRACTION_SPAN_MODES = ["off", "shadow", "on"] as const;
40
+ const extractionSpanBlockSchema = z.object({ spanMode: z.unknown().optional() }).strict();
41
+
42
+ /** Span + liveness fields for parseConfig. One spread keeps config.ts at the ratchet. */
43
+ export function parseExtractionFields(cfg: Record<string, unknown>) {
44
+ return {
45
+ extraction: parseExtractionSpanConfig(cfg.extraction),
46
+ extractionLiveness: parseExtractionLivenessConfig(cfg),
47
+ };
48
+ }
49
+
50
+ export function parseExtractionSpanConfig(raw: unknown): ExtractionSpanConfig {
51
+ if (raw === undefined) {
52
+ return { spanMode: "off" };
53
+ }
54
+ if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
55
+ throw new Error(
56
+ `extraction must be an object with optional spanMode (got ${JSON.stringify(raw)}). Omit the key for the default "off".`,
57
+ );
58
+ }
59
+ const block = raw as Record<string, unknown>;
60
+ const parsed = extractionSpanBlockSchema.safeParse(block);
61
+ if (!parsed.success) {
62
+ const unknownKeys = parsed.error.issues.flatMap((issue) =>
63
+ issue.code === "unrecognized_keys" ? issue.keys : []
64
+ );
65
+ throw new Error(
66
+ `extraction has unknown propert${unknownKeys.length === 1 ? "y" : "ies"}: ${unknownKeys.join(", ")}. Allowed: "spanMode".`,
67
+ );
68
+ }
69
+ const spanMode = block.spanMode;
70
+ if (spanMode === undefined) {
71
+ return { spanMode: "off" };
72
+ }
73
+ for (const mode of EXTRACTION_SPAN_MODES) {
74
+ if (spanMode === mode) {
75
+ return { spanMode: mode };
76
+ }
77
+ }
78
+ throw new Error(
79
+ `extraction.spanMode must be one of "off", "shadow", "on" (got ${JSON.stringify(spanMode)}). Omit the key for the default "off".`,
80
+ );
81
+ }
@@ -0,0 +1,376 @@
1
+ /**
2
+ * Span-mode materialization tests (issue #2333 Phase B).
3
+ *
4
+ * Covers the Phase B test contract: bounds off-by-one at both ends
5
+ * ([charStart, charEnd) end-exclusive), hash-mismatch (offset drift)
6
+ * rejection, per-fact fail-open, shadow-mode zero-diff vs "off", oversized
7
+ * span rejection, frame word-count limits, untrusted-span stripping in "off",
8
+ * and strict config enum handling.
9
+ */
10
+
11
+ import assert from "node:assert/strict";
12
+ import test from "node:test";
13
+ import { stampSpanSource } from "./extraction-span-source-hash.js";
14
+ import {
15
+ applyExtractionSpanMaterialization,
16
+ bindLocalExtractionPrompt,
17
+ buildSpanMaterializeTurns,
18
+ factCarriesSpan,
19
+ materializeFactSpan,
20
+ spanAgreesWithContent,
21
+ stripUntrustedFactSpans,
22
+ SPAN_MAX_SLICE_CHARS,
23
+ type SpanMaterializeTurn,
24
+ } from "./extraction-span-materialize.js";
25
+ import { renderExtractionConversation } from "./source-agent-qualifier.js";
26
+ import { parseConfig } from "./config.js";
27
+ import type { BufferTurn, ExtractedFact } from "./types.js";
28
+ import type { ExtractedFactSpanRef } from "./extraction-span-config.js";
29
+
30
+ const TURN_TEXT = "Maya moved to Seattle last spring for a new senior role.";
31
+
32
+ function turns(...texts: string[]): SpanMaterializeTurn[] {
33
+ return buildSpanMaterializeTurns(texts);
34
+ }
35
+
36
+ function fact(overrides: {
37
+ charStart: number;
38
+ charEnd: number;
39
+ frame?: string;
40
+ content?: string;
41
+ sourceMessageIndex?: number;
42
+ sourceHash?: string;
43
+ sourceLength?: number;
44
+ }): ExtractedFact {
45
+ const span: ExtractedFactSpanRef = {
46
+ sourceMessageIndex: overrides.sourceMessageIndex ?? 0,
47
+ charStart: overrides.charStart,
48
+ charEnd: overrides.charEnd,
49
+ frame: overrides.frame ?? "Maya's relocation",
50
+ ...(overrides.sourceHash !== undefined && overrides.sourceLength !== undefined
51
+ ? { sourceHash: overrides.sourceHash, sourceLength: overrides.sourceLength }
52
+ : {}),
53
+ };
54
+ return {
55
+ category: "fact",
56
+ content: overrides.content ?? "Maya moved to Seattle last spring for a new senior role.",
57
+ confidence: 0.9,
58
+ tags: ["relocation"],
59
+ span,
60
+ };
61
+ }
62
+
63
+ test("on-mode materializes frame + verbatim slice and sets the grounding quote", () => {
64
+ const start = TURN_TEXT.indexOf("Seattle");
65
+ const result = materializeFactSpan(
66
+ fact({ charStart: start, charEnd: start + "Seattle".length }),
67
+ turns(TURN_TEXT),
68
+ "on",
69
+ );
70
+ assert.equal(result.outcome, "span");
71
+ assert.equal(result.fact.content, "Maya's relocation: Seattle");
72
+ assert.equal(result.fact.quote, "Seattle");
73
+ assert.equal(result.fact.span, undefined, "offsets die at materialization");
74
+ });
75
+
76
+ test("[charStart, charEnd) is end-exclusive — off-by-one at both ends", () => {
77
+ const start = TURN_TEXT.indexOf("Seattle");
78
+ const messages = turns(TURN_TEXT);
79
+ const inner = materializeFactSpan(fact({ charStart: start + 1, charEnd: start + 6 }), messages, "on");
80
+ assert.equal(inner.fact.quote, "eattl");
81
+ const lastChar = materializeFactSpan(
82
+ fact({ charStart: TURN_TEXT.length - 1, charEnd: TURN_TEXT.length }),
83
+ messages,
84
+ "on",
85
+ );
86
+ assert.equal(lastChar.outcome, "span");
87
+ assert.equal(lastChar.fact.quote, ".");
88
+ assert.equal(
89
+ materializeFactSpan(fact({ charStart: 0, charEnd: TURN_TEXT.length + 1 }), messages, "on").outcome,
90
+ "fallback",
91
+ );
92
+ assert.equal(
93
+ materializeFactSpan(fact({ charStart: -1, charEnd: 4 }), messages, "on").outcome,
94
+ "fallback",
95
+ );
96
+ assert.equal(
97
+ materializeFactSpan(fact({ charStart: 5, charEnd: 5 }), messages, "on").outcome,
98
+ "fallback",
99
+ );
100
+ assert.equal(
101
+ materializeFactSpan(fact({ charStart: 9, charEnd: 4 }), messages, "on").outcome,
102
+ "fallback",
103
+ );
104
+ });
105
+
106
+ test("offset drift (turn text changed after stamping) is rejected", () => {
107
+ // The stamp was computed over the exact double-spaced string the model saw;
108
+ // the turn text here has been renormalized — verify must fail.
109
+ const drifted: SpanMaterializeTurn[] = [
110
+ { text: "Maya moved to Seattle.", stamp: stampSpanSource("Maya moved to Seattle.") },
111
+ ];
112
+ assert.notEqual(drifted[0].stamp.hash, stampSpanSource(drifted[0].text).hash);
113
+ const result = materializeFactSpan(fact({ charStart: 0, charEnd: 4 }), drifted, "on");
114
+ assert.equal(result.outcome, "fallback");
115
+ assert.equal(result.fact.content, "Maya moved to Seattle last spring for a new senior role.");
116
+ assert.equal(result.fact.span, undefined);
117
+ });
118
+
119
+ test("oversized slice (>400 chars) is rejected; exactly 400 passes", () => {
120
+ const long = "a".repeat(600);
121
+ const messages = turns(long);
122
+ assert.equal(
123
+ materializeFactSpan(fact({ charStart: 0, charEnd: SPAN_MAX_SLICE_CHARS + 1 }), messages, "on").outcome,
124
+ "fallback",
125
+ );
126
+ assert.equal(
127
+ materializeFactSpan(fact({ charStart: 0, charEnd: SPAN_MAX_SLICE_CHARS }), messages, "on").outcome,
128
+ "span",
129
+ );
130
+ });
131
+
132
+ test("whitespace-only slice and frame word-count limits are rejected", () => {
133
+ const messages = turns("word1 word2 word3");
134
+ const words = (count: number) => Array.from({ length: count }, (_, i) => `w${i}`).join(" ");
135
+ assert.equal(
136
+ materializeFactSpan(fact({ charStart: 5, charEnd: 7 }), messages, "on").outcome,
137
+ "fallback",
138
+ );
139
+ assert.equal(
140
+ materializeFactSpan(fact({ charStart: 0, charEnd: 5, frame: words(15) }), messages, "on").outcome,
141
+ "span",
142
+ );
143
+ assert.equal(
144
+ materializeFactSpan(fact({ charStart: 0, charEnd: 5, frame: " " }), messages, "on").outcome,
145
+ "fallback",
146
+ );
147
+ });
148
+
149
+ test("per-fact fail-open: one invalid span among three persists all three", () => {
150
+ const messages = turns(TURN_TEXT);
151
+ const seattle = TURN_TEXT.indexOf("Seattle");
152
+ const facts = [
153
+ fact({ charStart: seattle, charEnd: seattle + 7, content: "fallback A" }),
154
+ fact({ charStart: 0, charEnd: TURN_TEXT.length + 5, content: "fallback B" }),
155
+ fact({ charStart: 0, charEnd: 4, content: "fallback C" }),
156
+ ];
157
+ const outcomes = facts.map((f) => materializeFactSpan(f, messages, "on"));
158
+ assert.deepEqual(
159
+ outcomes.map((o) => o.outcome),
160
+ ["span", "fallback", "span"],
161
+ );
162
+ for (const outcome of outcomes) {
163
+ assert.ok(outcome.fact.content.length > 0);
164
+ assert.equal(outcome.fact.span, undefined);
165
+ }
166
+ });
167
+
168
+ test("shadow mode is zero-diff: byte-identical facts vs the same input", () => {
169
+ const messages = turns(TURN_TEXT);
170
+ const seattle = TURN_TEXT.indexOf("Seattle");
171
+ const spanFact = fact({ charStart: seattle, charEnd: seattle + 7, content: "generated restatement" });
172
+ const shadow = materializeFactSpan(spanFact, messages, "shadow");
173
+ assert.equal(shadow.outcome, "span");
174
+ assert.equal(shadow.fact.content, "generated restatement", "shadow persists generated content");
175
+ assert.ok(!("quote" in shadow.fact), "shadow does not touch the grounding quote");
176
+ assert.equal(shadow.fact.span, undefined);
177
+ // Zero-diff vs "off": the persisted fact is byte-identical to simply
178
+ // stripping the span — same content, same fields, nothing added.
179
+ const stripped = stripUntrustedFactSpans([spanFact])[0];
180
+ assert.deepEqual(shadow.fact, stripped);
181
+ // And the comparison materialization is still produced for telemetry.
182
+ assert.equal(shadow.materialized, "Maya's relocation: Seattle");
183
+ });
184
+
185
+ test("shadow agreement predicate: exact or containment", () => {
186
+ assert.equal(spanAgreesWithContent("a: b c", "b c"), true);
187
+ assert.equal(spanAgreesWithContent("b c", "a: b c"), true);
188
+ assert.equal(spanAgreesWithContent("a: b c", "a: b c"), true);
189
+ assert.equal(spanAgreesWithContent("a: b c", "z z z"), false);
190
+ });
191
+
192
+ test("stray span in off-mode is stripped untrusted; factCarriesSpan detects spans", () => {
193
+ const messages = turns(TURN_TEXT);
194
+ const stray = fact({ charStart: 0, charEnd: 900, content: "kept" });
195
+ assert.ok(factCarriesSpan(stray));
196
+ const strippedFacts = stripUntrustedFactSpans([stray]);
197
+ assert.equal(strippedFacts[0].span, undefined);
198
+ assert.equal(strippedFacts[0].content, "kept");
199
+ assert.ok(!factCarriesSpan(strippedFacts[0]));
200
+ // materializeFactSpan in off mode never validates — callers strip instead;
201
+ // a fallback here still must not lose content.
202
+ const result = materializeFactSpan(stray, messages, "off");
203
+ assert.equal(result.fact.content, "kept");
204
+ });
205
+
206
+ test("config: extraction.spanMode default off, valid values accepted, unknown rejected", () => {
207
+ assert.equal(parseConfig({}).extraction.spanMode, "off");
208
+ assert.equal(parseConfig({}).extractionLiveness.enabled, true);
209
+ assert.equal(parseConfig({ extractionLiveness: { enabled: false } }).extractionLiveness.enabled, false);
210
+ assert.equal(parseConfig({ extraction: { spanMode: "shadow" } }).extraction.spanMode, "shadow");
211
+ assert.equal(parseConfig({ extraction: { spanMode: "on" } }).extraction.spanMode, "on");
212
+ assert.equal(parseConfig({ extraction: {} }).extraction.spanMode, "off");
213
+ assert.throws(
214
+ () => parseConfig({ extraction: { spanMode: "sometimes" } }),
215
+ /extraction\.spanMode must be one of "off", "shadow", "on"/,
216
+ );
217
+ assert.throws(
218
+ () => parseConfig({ extraction: { spanMode: 1 } }),
219
+ /extraction\.spanMode must be one of "off", "shadow", "on"/,
220
+ );
221
+ });
222
+
223
+ test("config: extraction block must be an object, not an array or scalar", () => {
224
+ assert.throws(() => parseConfig({ extraction: [] }), /extraction must be an object/);
225
+ assert.throws(() => parseConfig({ extraction: "on" }), /extraction must be an object/);
226
+ assert.throws(() => parseConfig({ extraction: null }), /extraction must be an object/);
227
+ });
228
+
229
+ test("config: unknown extraction keys including spanMode typos are rejected", () => {
230
+ assert.throws(
231
+ () => parseConfig({ extraction: { spanMdoe: "on" } }),
232
+ /extraction has unknown property: spanMdoe/,
233
+ );
234
+ assert.throws(
235
+ () => parseConfig({ extraction: { spanMode: "on", extra: true } }),
236
+ /extraction has unknown property: extra/,
237
+ );
238
+ assert.equal(parseConfig({ extraction: { spanMode: "on" } }).extraction.spanMode, "on");
239
+ });
240
+
241
+ test("applyExtractionSpanMaterialization uses captured prompt stamps, not a restamp", () => {
242
+ const generated = "Maya moved to Seattle last spring for a new senior role.";
243
+ const result = {
244
+ facts: [fact({ charStart: 0, charEnd: 4, content: generated })],
245
+ entities: [],
246
+ questions: [],
247
+ profileUpdates: [],
248
+ };
249
+ const captured = buildSpanMaterializeTurns([TURN_TEXT]);
250
+ const ok = applyExtractionSpanMaterialization(result, captured, "on");
251
+ assert.equal(ok.facts[0]?.content, "Maya's relocation: Maya");
252
+
253
+ const drifted = [{ text: TURN_TEXT, stamp: stampSpanSource("different prompt text") }];
254
+ const fallback = applyExtractionSpanMaterialization(result, drifted, "on");
255
+ assert.equal(fallback.facts[0]?.content, generated);
256
+ });
257
+
258
+ test("span sourceHash/sourceLength must match the captured prompt stamp", () => {
259
+ const captured = buildSpanMaterializeTurns([TURN_TEXT]);
260
+ const stamp = captured[0]?.stamp;
261
+ assert.ok(stamp);
262
+ const matching = materializeFactSpan(
263
+ fact({ charStart: 0, charEnd: 4, sourceHash: stamp.hash, sourceLength: stamp.length }),
264
+ captured,
265
+ "on",
266
+ );
267
+ assert.equal(matching.outcome, "span");
268
+ const mismatched = materializeFactSpan(
269
+ fact({ charStart: 0, charEnd: 4, sourceHash: "0".repeat(64), sourceLength: stamp.length }),
270
+ captured,
271
+ "on",
272
+ );
273
+ assert.equal(mismatched.outcome, "fallback");
274
+ });
275
+
276
+ test("local prompt bind stamps the truncated visible prefix, not the unseen suffix", () => {
277
+ const visible = "Maya moved to Seattle last spring";
278
+ const unseen = " for a new senior role. UNSEEN_SUFFIX";
279
+ const content = `${visible}${unseen}`;
280
+ const turns: BufferTurn[] = [{ role: "user", content, timestamp: "2026-05-21T00:00:00.000Z" }];
281
+ const { conversation, renderedConversation } = renderExtractionConversation(turns, undefined);
282
+ const cut = conversation.indexOf(unseen);
283
+ assert.ok(cut > 0);
284
+ const bound = bindLocalExtractionPrompt(conversation, turns, cut, renderedConversation);
285
+ assert.match(bound.promptConversation, /\[truncated\]$/);
286
+ assert.equal(bound.spanTurns[0]?.text, visible);
287
+ assert.equal(bound.spanTurns[0]?.stamp.length, visible.length);
288
+ assert.notEqual(bound.spanTurns[0]?.stamp.hash, stampSpanSource(content).hash);
289
+
290
+ const leakStart = content.indexOf("UNSEEN_SUFFIX");
291
+ const againstFull = materializeFactSpan(
292
+ fact({ charStart: leakStart, charEnd: content.length, content: "kept-frame" }),
293
+ buildSpanMaterializeTurns([content]),
294
+ "on",
295
+ );
296
+ assert.equal(againstFull.outcome, "span");
297
+ assert.match(againstFull.fact.content ?? "", /UNSEEN_SUFFIX/);
298
+
299
+ const againstBound = materializeFactSpan(
300
+ fact({ charStart: leakStart, charEnd: content.length, content: "kept-frame" }),
301
+ bound.spanTurns,
302
+ "on",
303
+ );
304
+ assert.equal(againstBound.outcome, "fallback");
305
+ assert.equal(againstBound.fact.content, "kept-frame");
306
+
307
+ const visibleOk = materializeFactSpan(
308
+ fact({
309
+ charStart: 0,
310
+ charEnd: visible.length,
311
+ content: "kept-frame",
312
+ sourceHash: bound.spanTurns[0]?.stamp.hash,
313
+ sourceLength: bound.spanTurns[0]?.stamp.length,
314
+ }),
315
+ bound.spanTurns,
316
+ "on",
317
+ );
318
+ assert.equal(visibleOk.outcome, "span");
319
+ assert.equal(visibleOk.fact.quote, visible);
320
+ const fullStamp = stampSpanSource(content);
321
+ const wrongHash = materializeFactSpan(
322
+ fact({
323
+ charStart: 0,
324
+ charEnd: visible.length,
325
+ content: "kept-frame",
326
+ sourceHash: fullStamp.hash,
327
+ sourceLength: fullStamp.length,
328
+ }),
329
+ bound.spanTurns,
330
+ "on",
331
+ );
332
+ assert.equal(wrongHash.outcome, "fallback");
333
+ });
334
+
335
+ test("on-mode facts that omit span are dropped instead of persisting the frame", () => {
336
+ const generated = {
337
+ facts: [
338
+ {
339
+ category: "fact" as const,
340
+ content: "Maya's relocation",
341
+ confidence: 0.9,
342
+ tags: ["relocation"],
343
+ },
344
+ ],
345
+ entities: [],
346
+ questions: [],
347
+ profileUpdates: [],
348
+ };
349
+ const on = applyExtractionSpanMaterialization(generated, turns(TURN_TEXT), "on");
350
+ assert.equal(on.facts.length, 0);
351
+ const shadow = applyExtractionSpanMaterialization(generated, turns(TURN_TEXT), "shadow");
352
+ assert.equal(shadow.facts[0]?.content, "Maya's relocation");
353
+ const off = applyExtractionSpanMaterialization(generated, turns(TURN_TEXT), "off");
354
+ assert.equal(off.facts[0]?.content, "Maya's relocation");
355
+ });
356
+
357
+ test("on-mode mixed batch keeps validated spans and drops omitted spans", () => {
358
+ const seattle = TURN_TEXT.indexOf("Seattle");
359
+ const result = {
360
+ facts: [
361
+ fact({ charStart: seattle, charEnd: seattle + 7 }),
362
+ {
363
+ category: "fact" as const,
364
+ content: "Maya's relocation",
365
+ confidence: 0.9,
366
+ tags: [],
367
+ },
368
+ ],
369
+ entities: [],
370
+ questions: [],
371
+ profileUpdates: [],
372
+ };
373
+ const on = applyExtractionSpanMaterialization(result, turns(TURN_TEXT), "on");
374
+ assert.equal(on.facts.length, 1);
375
+ assert.equal(on.facts[0]?.content, "Maya's relocation: Seattle");
376
+ });