@remnic/core 10.0.13 → 10.0.14

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 (476) hide show
  1. package/dist/access-admin-ops-surface.js +86 -84
  2. package/dist/access-authorization-probe.js +87 -85
  3. package/dist/access-boundary.js +86 -84
  4. package/dist/access-cli.js +183 -180
  5. package/dist/access-cli.js.map +1 -1
  6. package/dist/access-extraction-force-flush.js +86 -84
  7. package/dist/access-http-briefing.js +87 -85
  8. package/dist/access-http-query.js +88 -86
  9. package/dist/access-http.js +110 -108
  10. package/dist/access-idempotency.js +3 -2
  11. package/dist/access-identity-continuity-surface.js +86 -84
  12. package/dist/access-lcm-surface.js +86 -84
  13. package/dist/access-mcp.js +99 -97
  14. package/dist/access-namespace-preflight.js +86 -84
  15. package/dist/access-observe-write-category.js +17 -17
  16. package/dist/access-observe-write-surface.js +86 -84
  17. package/dist/access-offline-manifest.js +16 -15
  18. package/dist/access-operations-batch.js +90 -88
  19. package/dist/access-operations.js +97 -95
  20. package/dist/access-recall-concurrency.js +86 -84
  21. package/dist/access-recall-diagnostics.js +2 -2
  22. package/dist/access-recall-response.js +86 -84
  23. package/dist/access-recall-surface.js +86 -84
  24. package/dist/access-schema.d.ts +2 -2
  25. package/dist/access-schema.js +12 -12
  26. package/dist/access-service.js +86 -84
  27. package/dist/access-surface-catalog.js +88 -86
  28. package/dist/access-surface-catalog.js.map +1 -1
  29. package/dist/active-recall.js +39 -37
  30. package/dist/active-recall.js.map +1 -1
  31. package/dist/adapters/index.js +4 -4
  32. package/dist/adapters/registry.js +2 -2
  33. package/dist/{auto-sync-DGJOZYGT.js → auto-sync-7WWAKW6F.js} +8 -8
  34. package/dist/briefing.js +29 -27
  35. package/dist/buffer.js +13 -13
  36. package/dist/{capsule-merge-M4HETD27.js → capsule-merge-LGYURS3C.js} +6 -5
  37. package/dist/{capsule-merge-M4HETD27.js.map → capsule-merge-LGYURS3C.js.map} +1 -1
  38. package/dist/capture-write-lock-backoff.d.ts +50 -0
  39. package/dist/capture-write-lock-backoff.d.ts.map +1 -0
  40. package/dist/capture-write-lock-backoff.js +30 -0
  41. package/dist/capture-write-lock.d.ts +6 -0
  42. package/dist/capture-write-lock.d.ts.map +1 -0
  43. package/dist/capture-write-lock.js +15 -0
  44. package/dist/causal-behavior.js +2 -2
  45. package/dist/causal-chain.js +2 -2
  46. package/dist/causal-consolidation.js +32 -30
  47. package/dist/causal-consolidation.js.map +1 -1
  48. package/dist/causal-retrieval.js +2 -2
  49. package/dist/causal-trajectory-graph.js +7 -6
  50. package/dist/causal-trajectory-graph.js.map +1 -1
  51. package/dist/causal-trajectory.js +1 -1
  52. package/dist/{chunk-ZUMXY4KA.js → chunk-22W2XWGH.js} +3 -3
  53. package/dist/{chunk-AV2OQF2O.js → chunk-3F3HA3R2.js} +2 -2
  54. package/dist/{chunk-QZZPUREO.js → chunk-3GYSZHMT.js} +3 -3
  55. package/dist/{chunk-QWWMS4AE.js → chunk-3MO4LWYU.js} +1 -1
  56. package/dist/chunk-3MO4LWYU.js.map +1 -0
  57. package/dist/{chunk-AL6EHLB5.js → chunk-3X3PNU3T.js} +2 -2
  58. package/dist/{chunk-BTJ6CAIA.js → chunk-4IYIGN53.js} +10 -10
  59. package/dist/{chunk-BZTRPCCH.js → chunk-4KY5GSMB.js} +2 -2
  60. package/dist/{chunk-UZSBCQEC.js → chunk-4OSG5Y6M.js} +2 -2
  61. package/dist/{chunk-EHRE7ZG3.js → chunk-5B5WYAHQ.js} +2 -2
  62. package/dist/{chunk-WCGJK4NQ.js → chunk-5FNZ3G6X.js} +10 -10
  63. package/dist/{chunk-Y6DZ33PA.js → chunk-5GX5457J.js} +4 -4
  64. package/dist/{chunk-OFCHT2TN.js → chunk-5LRV557D.js} +2 -2
  65. package/dist/{chunk-CKUUP64O.js → chunk-5WCJLQTM.js} +2 -2
  66. package/dist/{chunk-MZBWIJJN.js → chunk-63B2IZYE.js} +19 -19
  67. package/dist/{chunk-DGRMWDQY.js → chunk-66BCOVW2.js} +7 -7
  68. package/dist/chunk-6EDW54SQ.js +298 -0
  69. package/dist/chunk-6EDW54SQ.js.map +1 -0
  70. package/dist/{chunk-P2S6P7X6.js → chunk-6LG7BWKW.js} +2 -2
  71. package/dist/chunk-77R7BQZ2.js +152 -0
  72. package/dist/chunk-77R7BQZ2.js.map +1 -0
  73. package/dist/{chunk-IPLYGWQF.js → chunk-7LCGFUMB.js} +6 -6
  74. package/dist/{chunk-KYY4EACB.js → chunk-7Z3DLNSD.js} +2 -2
  75. package/dist/{chunk-LNH76ZJX.js → chunk-AIYXVWUH.js} +27 -2
  76. package/dist/{chunk-LNH76ZJX.js.map → chunk-AIYXVWUH.js.map} +1 -1
  77. package/dist/{chunk-O4KYRDRT.js → chunk-B665A6BO.js} +2 -2
  78. package/dist/{chunk-AKREOU5F.js → chunk-CB6ANA2I.js} +2 -2
  79. package/dist/{chunk-5JMI26Q7.js → chunk-CBH2Z4UA.js} +2 -2
  80. package/dist/{chunk-YRH3C2OJ.js → chunk-CIIHIAJ2.js} +13 -5
  81. package/dist/chunk-CIIHIAJ2.js.map +1 -0
  82. package/dist/{chunk-6M56RFFJ.js → chunk-CJRENHVZ.js} +3 -3
  83. package/dist/{chunk-EGDYVYU7.js → chunk-CLWBFR7Q.js} +3 -3
  84. package/dist/{chunk-375ARKRS.js → chunk-D5SSBCYY.js} +70 -59
  85. package/dist/chunk-D5SSBCYY.js.map +1 -0
  86. package/dist/{chunk-KI6UOSNR.js → chunk-DEY7B77Y.js} +2 -2
  87. package/dist/chunk-DEY7B77Y.js.map +1 -0
  88. package/dist/{chunk-6VAHJ2F6.js → chunk-DMDWFQMR.js} +2 -2
  89. package/dist/{chunk-6OQ6N5RP.js → chunk-DPR2WTN3.js} +20 -20
  90. package/dist/{chunk-K4QY55XV.js → chunk-EH4BQ7LT.js} +2 -2
  91. package/dist/chunk-EHHQJTAU.js +131 -0
  92. package/dist/chunk-EHHQJTAU.js.map +1 -0
  93. package/dist/{chunk-5JCLELOP.js → chunk-EPJDSQHF.js} +2 -2
  94. package/dist/{chunk-K2FSASGZ.js → chunk-EU534WGS.js} +2 -2
  95. package/dist/{chunk-GD7BWGIB.js → chunk-EU6IRUCY.js} +6 -4
  96. package/dist/{chunk-GD7BWGIB.js.map → chunk-EU6IRUCY.js.map} +1 -1
  97. package/dist/{chunk-IWHEJXR2.js → chunk-EUAIYYYR.js} +8 -8
  98. package/dist/{chunk-7KYJNHGM.js → chunk-EUCYTCFP.js} +2 -2
  99. package/dist/{chunk-YNDLCWXS.js → chunk-EZ25VE3G.js} +4 -4
  100. package/dist/{chunk-ON4ILX3G.js → chunk-FFOVKNQV.js} +2 -2
  101. package/dist/{chunk-2KRNPFPK.js → chunk-FLI6DEIU.js} +2 -2
  102. package/dist/{chunk-4G4B3Z2B.js → chunk-FP4JYE66.js} +2 -2
  103. package/dist/{chunk-B7CANWCA.js → chunk-FSIMZNBC.js} +2 -2
  104. package/dist/{chunk-OAIWPB2I.js → chunk-FT4UQYOV.js} +2 -2
  105. package/dist/{chunk-X3VID2TT.js → chunk-FUFAXVBA.js} +3 -3
  106. package/dist/{chunk-HYNEDMYJ.js → chunk-G2OYFTUD.js} +2 -2
  107. package/dist/{chunk-XTN54NML.js → chunk-G3T6YMBO.js} +4 -4
  108. package/dist/{chunk-XHWJRUVP.js → chunk-GELS5Z5Z.js} +3 -3
  109. package/dist/{chunk-RT6D3WN7.js → chunk-GH7AOMJD.js} +2 -2
  110. package/dist/{chunk-2LUSQV4U.js → chunk-GKJJNO7C.js} +2 -2
  111. package/dist/{chunk-6Z2AZ4AJ.js → chunk-GMXWTJNU.js} +2 -2
  112. package/dist/{chunk-B657ZGDH.js → chunk-HQSK2INQ.js} +2 -2
  113. package/dist/{chunk-RWRQ67OR.js → chunk-I7S55EOB.js} +2 -2
  114. package/dist/{chunk-KZO43HPY.js → chunk-J7JWFZHI.js} +100 -100
  115. package/dist/{chunk-EMFBC7L3.js → chunk-JDZFIR2S.js} +2 -2
  116. package/dist/{chunk-4THZGKQ2.js → chunk-JIHMUOOS.js} +3 -3
  117. package/dist/{chunk-YYO447A7.js → chunk-JNIVZNIB.js} +41 -253
  118. package/dist/chunk-JNIVZNIB.js.map +1 -0
  119. package/dist/{chunk-FZB4TS2W.js → chunk-JPTPS4OB.js} +5 -5
  120. package/dist/{chunk-CS2JEHTB.js → chunk-JQ7XU625.js} +8 -8
  121. package/dist/{chunk-3I3U6FFT.js → chunk-K7BN34IA.js} +2 -2
  122. package/dist/{chunk-7OAIOE5P.js → chunk-KH2LKDX7.js} +2 -2
  123. package/dist/{chunk-DA2INEB5.js → chunk-KR6ZKECI.js} +4 -4
  124. package/dist/{chunk-5AOAQR37.js → chunk-L5DAHSEZ.js} +3 -3
  125. package/dist/{chunk-RP5SJ3XR.js → chunk-LCKVXX5F.js} +2 -2
  126. package/dist/{chunk-ZI7LMSNI.js → chunk-LLHZZOIB.js} +2 -2
  127. package/dist/{chunk-OYKQ6T4V.js → chunk-MATDGSJ7.js} +2 -2
  128. package/dist/{chunk-3NFN4Y4P.js → chunk-MGCKZWAE.js} +5 -5
  129. package/dist/{chunk-6OMUHXHP.js → chunk-ML7ZJAKJ.js} +2 -2
  130. package/dist/{chunk-YDH2FSDI.js → chunk-N45NEBOD.js} +2 -2
  131. package/dist/{chunk-A2E4WNW4.js → chunk-N4C7QKOG.js} +2 -2
  132. package/dist/{chunk-B43NMCGQ.js → chunk-N7KYEVLK.js} +2 -2
  133. package/dist/{chunk-HT2C4EXO.js → chunk-NIRQGDYC.js} +4 -4
  134. package/dist/{chunk-DXHVD4DS.js → chunk-NW2E4CI2.js} +3 -3
  135. package/dist/{chunk-4NDWE44P.js → chunk-NZFFGO5O.js} +2 -2
  136. package/dist/{chunk-KC46VZR5.js → chunk-O2IPAX26.js} +8 -8
  137. package/dist/{chunk-M7V65M6H.js → chunk-O4SGYW7H.js} +2 -2
  138. package/dist/{chunk-QUA7RLK6.js → chunk-OP6N4H6A.js} +2 -2
  139. package/dist/{chunk-ZSJGYC3C.js → chunk-OQJKY3Z5.js} +2 -2
  140. package/dist/{chunk-OFEHITAZ.js → chunk-OXNTOHL6.js} +2 -2
  141. package/dist/{chunk-FQD2KPQH.js → chunk-P55FACBG.js} +2 -2
  142. package/dist/{chunk-XERVJYH2.js → chunk-P5NQN4JE.js} +3 -3
  143. package/dist/{chunk-XZLWYZ7C.js → chunk-P7TOIOT7.js} +2 -2
  144. package/dist/{chunk-Y3VDGK2O.js → chunk-PAZ35RJ4.js} +44 -31
  145. package/dist/chunk-PAZ35RJ4.js.map +1 -0
  146. package/dist/chunk-PGRZ3FYC.js +34 -0
  147. package/dist/chunk-PGRZ3FYC.js.map +1 -0
  148. package/dist/{chunk-PBVNVKYN.js → chunk-PIN5OPBA.js} +2 -2
  149. package/dist/{chunk-CNG2XVZG.js → chunk-PZHQWFR3.js} +2 -2
  150. package/dist/{chunk-SVDU4OHO.js → chunk-Q35L7TYB.js} +2 -2
  151. package/dist/{chunk-YEM7K3KD.js → chunk-QODKDRSP.js} +6 -6
  152. package/dist/{chunk-IZT3BVDW.js → chunk-QOZJCSFO.js} +2 -2
  153. package/dist/{chunk-6T42L5FI.js → chunk-QS3OLP5I.js} +2 -2
  154. package/dist/{chunk-PAAJWQH5.js → chunk-QUMKDRCF.js} +2 -2
  155. package/dist/{chunk-JFVCDEIC.js → chunk-QX6JN3O4.js} +7 -7
  156. package/dist/{chunk-KZEMFD6E.js → chunk-R2H4ZFBJ.js} +3 -3
  157. package/dist/{chunk-GKIXBH7Y.js → chunk-RTKV5XHL.js} +4 -4
  158. package/dist/{chunk-ZQ3WU6JO.js → chunk-RXFCU3CY.js} +2 -2
  159. package/dist/{chunk-BOOFTFFE.js → chunk-S2I7DL5Q.js} +1 -1
  160. package/dist/{chunk-2NCBDGND.js → chunk-SA6GMZJY.js} +3 -3
  161. package/dist/{chunk-NSFOERZQ.js → chunk-SIIRTDJ4.js} +2 -2
  162. package/dist/{chunk-A6TVQ3QP.js → chunk-SS3IS2JR.js} +3 -3
  163. package/dist/{chunk-VFTK5WKI.js → chunk-STBX5X6B.js} +2 -2
  164. package/dist/{chunk-WVHRNAXL.js → chunk-SWWHIJUJ.js} +2 -2
  165. package/dist/{chunk-WADSXS4K.js → chunk-SX4QDWXK.js} +2 -2
  166. package/dist/{chunk-ZIZ2G47N.js → chunk-TITG2NBS.js} +2 -2
  167. package/dist/{chunk-LZKOVXMX.js → chunk-TRMJ6BYC.js} +2 -2
  168. package/dist/{chunk-U7VPOXVM.js → chunk-TZNDKTX5.js} +65 -65
  169. package/dist/{chunk-WWSRLS4M.js → chunk-UMTCNEVQ.js} +15 -15
  170. package/dist/{chunk-4TTGRETU.js → chunk-UQDG3YLN.js} +5 -5
  171. package/dist/{chunk-AAM66QCP.js → chunk-UZRSI6NX.js} +2 -2
  172. package/dist/{chunk-2CXQZXWM.js → chunk-V4MB5ONM.js} +6 -6
  173. package/dist/{chunk-CYEK6Z3P.js → chunk-VW6VIJOS.js} +2 -2
  174. package/dist/{chunk-5ZJYHOJT.js → chunk-W47S5TIH.js} +8 -8
  175. package/dist/{chunk-CBP4HWCL.js → chunk-W5MCEVUS.js} +3 -3
  176. package/dist/{chunk-WETFW255.js → chunk-WLMZ2L5P.js} +2 -2
  177. package/dist/{chunk-XRBHXUTQ.js → chunk-WSGPFRBH.js} +5 -5
  178. package/dist/{chunk-UOKPJFO3.js → chunk-WVADKFWV.js} +3 -3
  179. package/dist/{chunk-P34FDDB5.js → chunk-XISROV24.js} +2 -2
  180. package/dist/{chunk-FZVROZKC.js → chunk-XVZA6VXC.js} +4 -4
  181. package/dist/{chunk-JUWJYXI4.js → chunk-Y4NKEXQT.js} +4 -4
  182. package/dist/{chunk-2ZQJLBV6.js → chunk-YE36AJL7.js} +4 -4
  183. package/dist/chunk-YET735EZ.js +99 -0
  184. package/dist/chunk-YET735EZ.js.map +1 -0
  185. package/dist/{chunk-PCWXLAJY.js → chunk-YFMBHQRG.js} +2 -2
  186. package/dist/{chunk-RBJQYMMT.js → chunk-YRULQW5J.js} +4 -4
  187. package/dist/{chunk-QUNDYIYZ.js → chunk-YYEOR4XN.js} +3 -3
  188. package/dist/{chunk-VYPFEVOM.js → chunk-ZJVMUBYF.js} +2 -2
  189. package/dist/{chunk-5MDM7UE4.js → chunk-ZSH2NRDV.js} +2 -2
  190. package/dist/{chunk-3J5JKBYD.js → chunk-ZV65I6ME.js} +67 -67
  191. package/dist/cli.js +138 -136
  192. package/dist/coding/export-okf-codegraph.js +29 -27
  193. package/dist/coding/export-okf-codegraph.js.map +1 -1
  194. package/dist/coding/pre-action-gate.js +2 -2
  195. package/dist/compounding/engine.js +31 -29
  196. package/dist/config.js +39 -37
  197. package/dist/connectors/codex-materialize-runner.js +29 -27
  198. package/dist/connectors/index.js +29 -27
  199. package/dist/console/trace.d.ts +5 -14
  200. package/dist/console/trace.d.ts.map +1 -1
  201. package/dist/consolidation-provenance-check.js +7 -6
  202. package/dist/consolidation-undo.js +5 -4
  203. package/dist/consolidation-undo.js.map +1 -1
  204. package/dist/contradiction/index.js +7 -6
  205. package/dist/converge-config.d.ts +2 -0
  206. package/dist/converge-config.d.ts.map +1 -1
  207. package/dist/converge-config.js +7 -3
  208. package/dist/convergence-refresh.js +31 -29
  209. package/dist/corpus-watermark.js +31 -29
  210. package/dist/dashboard-runtime.js +2 -2
  211. package/dist/deep-recall-http-glue.js +13 -13
  212. package/dist/deep-recall.js +2 -2
  213. package/dist/embedding-fallback.js +5 -4
  214. package/dist/embedding-generation-lock.js +4 -3
  215. package/dist/entity-retrieval.js +30 -28
  216. package/dist/explicit-capture.js +11 -8
  217. package/dist/external-wiki-access.js +87 -85
  218. package/dist/extraction-quote-grounding.d.ts +67 -0
  219. package/dist/extraction-quote-grounding.d.ts.map +1 -0
  220. package/dist/extraction-quote-grounding.js +27 -0
  221. package/dist/extraction-quote-grounding.js.map +1 -0
  222. package/dist/extraction-source-grounding-helpers.d.ts +8 -0
  223. package/dist/extraction-source-grounding-helpers.d.ts.map +1 -1
  224. package/dist/extraction-source-grounding-helpers.js +11 -1
  225. package/dist/extraction-source-grounding-rules.d.ts +3 -1
  226. package/dist/extraction-source-grounding-rules.d.ts.map +1 -1
  227. package/dist/extraction-source-grounding-rules.js +3 -2
  228. package/dist/extraction-source-grounding.d.ts +1 -1
  229. package/dist/extraction-source-grounding.d.ts.map +1 -1
  230. package/dist/extraction-source-grounding.js +4 -3
  231. package/dist/extraction-span-materialize.js +2 -2
  232. package/dist/extraction.js +40 -37
  233. package/dist/{first-start-migration-HYAMKJ6V.js → first-start-migration-6A5BJPDW.js} +4 -4
  234. package/dist/{forget-OHAJ6PSU.js → forget-GXBWFKRC.js} +5 -4
  235. package/dist/{forget-OHAJ6PSU.js.map → forget-GXBWFKRC.js.map} +1 -1
  236. package/dist/{graph-edge-decay-CZ3SYLM4.js → graph-edge-decay-BYPZVJT4.js} +10 -9
  237. package/dist/graph-edge-decay-BYPZVJT4.js.map +1 -0
  238. package/dist/graph-jsonl.js +8 -7
  239. package/dist/graph-snapshot.js +8 -7
  240. package/dist/graph-write-lock.js +4 -3
  241. package/dist/graph.js +9 -8
  242. package/dist/harmonic-retrieval.js +29 -27
  243. package/dist/http-retry.js +2 -1
  244. package/dist/http-retry.js.map +1 -1
  245. package/dist/index.d.ts +1 -1
  246. package/dist/index.d.ts.map +1 -1
  247. package/dist/index.js +223 -218
  248. package/dist/lcm/engine.js +4 -4
  249. package/dist/lcm/index.js +12 -12
  250. package/dist/location/index.js +32 -30
  251. package/dist/maintenance/memory-governance.js +29 -27
  252. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +29 -27
  253. package/dist/maintenance/rebuild-memory-projection-runner.js +31 -29
  254. package/dist/maintenance/rebuild-memory-projection.js +30 -28
  255. package/dist/memory-browse-operations.js +87 -85
  256. package/dist/memory-browse.js +7 -7
  257. package/dist/memory-subject.js +5 -4
  258. package/dist/namespaces/migrate.js +30 -28
  259. package/dist/namespaces/search.js +9 -9
  260. package/dist/namespaces/storage.js +29 -27
  261. package/dist/offline-sync-changeset-generations.js +7 -6
  262. package/dist/offline-sync-embedding-generation.js +6 -5
  263. package/dist/offline-sync-impression-drain.js +4 -4
  264. package/dist/offline-sync-snapshot-stream.js +9 -9
  265. package/dist/offline-sync.js +10 -10
  266. package/dist/operator-doctor-corpus.js +32 -30
  267. package/dist/operator-toolkit.js +53 -51
  268. package/dist/orchestration/maintenance.js +41 -39
  269. package/dist/orchestrator.js +185 -182
  270. package/dist/page-versioning.js +5 -4
  271. package/dist/qmd-daemon-session.js +2 -2
  272. package/dist/qmd.js +4 -4
  273. package/dist/recall-explain-renderer.js +3 -3
  274. package/dist/recall-navigate-access.js +2 -2
  275. package/dist/recall-navigate-disclosure.js +2 -2
  276. package/dist/recall-navigate.js +2 -2
  277. package/dist/recall-navigation-operations.js +87 -85
  278. package/dist/recall-navigation.js +86 -84
  279. package/dist/recall-state-view-admission.js +7 -7
  280. package/dist/recall-state.js +4 -3
  281. package/dist/recall-why-service.js +7 -7
  282. package/dist/recall-xray-cli.js +4 -4
  283. package/dist/recall-xray-renderer.js +3 -3
  284. package/dist/recall-xray.js +2 -2
  285. package/dist/reconcile/cursor.js +4 -2
  286. package/dist/reconcile/cursor.js.map +1 -1
  287. package/dist/reconcile/manifest.js +9 -6
  288. package/dist/reconcile/plan.js +4 -2
  289. package/dist/{resolution-EKJHREVJ.js → resolution-7AY36LGJ.js} +8 -7
  290. package/dist/resolution-7AY36LGJ.js.map +1 -0
  291. package/dist/resume-bundles.js +40 -38
  292. package/dist/salvage-envelope.js +7 -6
  293. package/dist/search/factory.js +8 -8
  294. package/dist/search/index.js +14 -14
  295. package/dist/semantic-consolidation.js +34 -32
  296. package/dist/semantic-rule-promotion.js +29 -27
  297. package/dist/semantic-rule-verifier.js +29 -27
  298. package/dist/source-agent-qualifier.js +37 -34
  299. package/dist/standup/build.js +29 -27
  300. package/dist/storage/content-hash-index.d.ts +10 -0
  301. package/dist/storage/content-hash-index.d.ts.map +1 -1
  302. package/dist/storage/tombstone-blocked-capture-index.d.ts +3 -0
  303. package/dist/storage/tombstone-blocked-capture-index.d.ts.map +1 -1
  304. package/dist/storage/tombstone-blocked-capture-mutation.d.ts +23 -3
  305. package/dist/storage/tombstone-blocked-capture-mutation.d.ts.map +1 -1
  306. package/dist/storage.d.ts +6 -0
  307. package/dist/storage.d.ts.map +1 -1
  308. package/dist/storage.js +30 -28
  309. package/dist/subject-config.js +6 -5
  310. package/dist/summarizer.js +4 -4
  311. package/dist/summary-snapshot.js +4 -3
  312. package/dist/support-passport/index.js +89 -87
  313. package/dist/{trace-LXXCMZJA.js → trace-QBQVS5BC.js} +5 -21
  314. package/dist/trace-QBQVS5BC.js.map +1 -0
  315. package/dist/transfer/autodetect.js +1 -1
  316. package/dist/transfer/backup.js +1 -1
  317. package/dist/transfer/capsule-export.js +3 -3
  318. package/dist/transfer/capsule-import.js +7 -6
  319. package/dist/transfer/export-okf.js +29 -27
  320. package/dist/types.d.ts +9 -0
  321. package/dist/types.d.ts.map +1 -1
  322. package/dist/types.js +1 -1
  323. package/dist/utils/serialize-mutations.js +3 -2
  324. package/dist/utils/sleep.d.ts +6 -0
  325. package/dist/utils/sleep.d.ts.map +1 -1
  326. package/dist/verified-recall.js +29 -27
  327. package/dist/who-knows-cli.js +30 -28
  328. package/dist/who-knows.js +29 -27
  329. package/dist/write-envelope.js +6 -5
  330. package/package.json +22 -2
  331. package/src/capture-write-lock-backoff.test.ts +534 -0
  332. package/src/capture-write-lock-backoff.ts +140 -0
  333. package/src/capture-write-lock.ts +8 -0
  334. package/src/console/trace.ts +5 -36
  335. package/src/converge-config.ts +80 -1
  336. package/src/extraction-quote-grounding.test.ts +546 -0
  337. package/src/extraction-quote-grounding.ts +232 -0
  338. package/src/extraction-source-grounding-helpers.ts +35 -0
  339. package/src/extraction-source-grounding-rules.ts +90 -65
  340. package/src/extraction-source-grounding.ts +11 -2
  341. package/src/index.ts +1 -1
  342. package/src/providers/codex-subscription.test.ts +15 -3
  343. package/src/storage/content-hash-index.ts +10 -0
  344. package/src/storage/tombstone-blocked-capture-index.ts +8 -1
  345. package/src/storage/tombstone-blocked-capture-mutation.ts +133 -43
  346. package/src/storage.ts +13 -0
  347. package/src/types.ts +9 -0
  348. package/src/utils/sleep.ts +28 -0
  349. package/dist/chunk-375ARKRS.js.map +0 -1
  350. package/dist/chunk-6MINUTGJ.js +0 -64
  351. package/dist/chunk-6MINUTGJ.js.map +0 -1
  352. package/dist/chunk-7LEQREP2.js +0 -9
  353. package/dist/chunk-7LEQREP2.js.map +0 -1
  354. package/dist/chunk-KI6UOSNR.js.map +0 -1
  355. package/dist/chunk-QWWMS4AE.js.map +0 -1
  356. package/dist/chunk-Y3VDGK2O.js.map +0 -1
  357. package/dist/chunk-YRH3C2OJ.js.map +0 -1
  358. package/dist/chunk-YYO447A7.js.map +0 -1
  359. package/dist/trace-LXXCMZJA.js.map +0 -1
  360. /package/dist/{auto-sync-DGJOZYGT.js.map → auto-sync-7WWAKW6F.js.map} +0 -0
  361. /package/dist/{graph-edge-decay-CZ3SYLM4.js.map → capture-write-lock-backoff.js.map} +0 -0
  362. /package/dist/{resolution-EKJHREVJ.js.map → capture-write-lock.js.map} +0 -0
  363. /package/dist/{chunk-ZUMXY4KA.js.map → chunk-22W2XWGH.js.map} +0 -0
  364. /package/dist/{chunk-AV2OQF2O.js.map → chunk-3F3HA3R2.js.map} +0 -0
  365. /package/dist/{chunk-QZZPUREO.js.map → chunk-3GYSZHMT.js.map} +0 -0
  366. /package/dist/{chunk-AL6EHLB5.js.map → chunk-3X3PNU3T.js.map} +0 -0
  367. /package/dist/{chunk-BTJ6CAIA.js.map → chunk-4IYIGN53.js.map} +0 -0
  368. /package/dist/{chunk-BZTRPCCH.js.map → chunk-4KY5GSMB.js.map} +0 -0
  369. /package/dist/{chunk-UZSBCQEC.js.map → chunk-4OSG5Y6M.js.map} +0 -0
  370. /package/dist/{chunk-EHRE7ZG3.js.map → chunk-5B5WYAHQ.js.map} +0 -0
  371. /package/dist/{chunk-WCGJK4NQ.js.map → chunk-5FNZ3G6X.js.map} +0 -0
  372. /package/dist/{chunk-Y6DZ33PA.js.map → chunk-5GX5457J.js.map} +0 -0
  373. /package/dist/{chunk-OFCHT2TN.js.map → chunk-5LRV557D.js.map} +0 -0
  374. /package/dist/{chunk-CKUUP64O.js.map → chunk-5WCJLQTM.js.map} +0 -0
  375. /package/dist/{chunk-MZBWIJJN.js.map → chunk-63B2IZYE.js.map} +0 -0
  376. /package/dist/{chunk-DGRMWDQY.js.map → chunk-66BCOVW2.js.map} +0 -0
  377. /package/dist/{chunk-P2S6P7X6.js.map → chunk-6LG7BWKW.js.map} +0 -0
  378. /package/dist/{chunk-IPLYGWQF.js.map → chunk-7LCGFUMB.js.map} +0 -0
  379. /package/dist/{chunk-KYY4EACB.js.map → chunk-7Z3DLNSD.js.map} +0 -0
  380. /package/dist/{chunk-O4KYRDRT.js.map → chunk-B665A6BO.js.map} +0 -0
  381. /package/dist/{chunk-AKREOU5F.js.map → chunk-CB6ANA2I.js.map} +0 -0
  382. /package/dist/{chunk-5JMI26Q7.js.map → chunk-CBH2Z4UA.js.map} +0 -0
  383. /package/dist/{chunk-6M56RFFJ.js.map → chunk-CJRENHVZ.js.map} +0 -0
  384. /package/dist/{chunk-EGDYVYU7.js.map → chunk-CLWBFR7Q.js.map} +0 -0
  385. /package/dist/{chunk-6VAHJ2F6.js.map → chunk-DMDWFQMR.js.map} +0 -0
  386. /package/dist/{chunk-6OQ6N5RP.js.map → chunk-DPR2WTN3.js.map} +0 -0
  387. /package/dist/{chunk-K4QY55XV.js.map → chunk-EH4BQ7LT.js.map} +0 -0
  388. /package/dist/{chunk-5JCLELOP.js.map → chunk-EPJDSQHF.js.map} +0 -0
  389. /package/dist/{chunk-K2FSASGZ.js.map → chunk-EU534WGS.js.map} +0 -0
  390. /package/dist/{chunk-IWHEJXR2.js.map → chunk-EUAIYYYR.js.map} +0 -0
  391. /package/dist/{chunk-7KYJNHGM.js.map → chunk-EUCYTCFP.js.map} +0 -0
  392. /package/dist/{chunk-YNDLCWXS.js.map → chunk-EZ25VE3G.js.map} +0 -0
  393. /package/dist/{chunk-ON4ILX3G.js.map → chunk-FFOVKNQV.js.map} +0 -0
  394. /package/dist/{chunk-2KRNPFPK.js.map → chunk-FLI6DEIU.js.map} +0 -0
  395. /package/dist/{chunk-4G4B3Z2B.js.map → chunk-FP4JYE66.js.map} +0 -0
  396. /package/dist/{chunk-B7CANWCA.js.map → chunk-FSIMZNBC.js.map} +0 -0
  397. /package/dist/{chunk-OAIWPB2I.js.map → chunk-FT4UQYOV.js.map} +0 -0
  398. /package/dist/{chunk-X3VID2TT.js.map → chunk-FUFAXVBA.js.map} +0 -0
  399. /package/dist/{chunk-HYNEDMYJ.js.map → chunk-G2OYFTUD.js.map} +0 -0
  400. /package/dist/{chunk-XTN54NML.js.map → chunk-G3T6YMBO.js.map} +0 -0
  401. /package/dist/{chunk-XHWJRUVP.js.map → chunk-GELS5Z5Z.js.map} +0 -0
  402. /package/dist/{chunk-RT6D3WN7.js.map → chunk-GH7AOMJD.js.map} +0 -0
  403. /package/dist/{chunk-2LUSQV4U.js.map → chunk-GKJJNO7C.js.map} +0 -0
  404. /package/dist/{chunk-6Z2AZ4AJ.js.map → chunk-GMXWTJNU.js.map} +0 -0
  405. /package/dist/{chunk-B657ZGDH.js.map → chunk-HQSK2INQ.js.map} +0 -0
  406. /package/dist/{chunk-RWRQ67OR.js.map → chunk-I7S55EOB.js.map} +0 -0
  407. /package/dist/{chunk-KZO43HPY.js.map → chunk-J7JWFZHI.js.map} +0 -0
  408. /package/dist/{chunk-EMFBC7L3.js.map → chunk-JDZFIR2S.js.map} +0 -0
  409. /package/dist/{chunk-4THZGKQ2.js.map → chunk-JIHMUOOS.js.map} +0 -0
  410. /package/dist/{chunk-FZB4TS2W.js.map → chunk-JPTPS4OB.js.map} +0 -0
  411. /package/dist/{chunk-CS2JEHTB.js.map → chunk-JQ7XU625.js.map} +0 -0
  412. /package/dist/{chunk-3I3U6FFT.js.map → chunk-K7BN34IA.js.map} +0 -0
  413. /package/dist/{chunk-7OAIOE5P.js.map → chunk-KH2LKDX7.js.map} +0 -0
  414. /package/dist/{chunk-DA2INEB5.js.map → chunk-KR6ZKECI.js.map} +0 -0
  415. /package/dist/{chunk-5AOAQR37.js.map → chunk-L5DAHSEZ.js.map} +0 -0
  416. /package/dist/{chunk-RP5SJ3XR.js.map → chunk-LCKVXX5F.js.map} +0 -0
  417. /package/dist/{chunk-ZI7LMSNI.js.map → chunk-LLHZZOIB.js.map} +0 -0
  418. /package/dist/{chunk-OYKQ6T4V.js.map → chunk-MATDGSJ7.js.map} +0 -0
  419. /package/dist/{chunk-3NFN4Y4P.js.map → chunk-MGCKZWAE.js.map} +0 -0
  420. /package/dist/{chunk-6OMUHXHP.js.map → chunk-ML7ZJAKJ.js.map} +0 -0
  421. /package/dist/{chunk-YDH2FSDI.js.map → chunk-N45NEBOD.js.map} +0 -0
  422. /package/dist/{chunk-A2E4WNW4.js.map → chunk-N4C7QKOG.js.map} +0 -0
  423. /package/dist/{chunk-B43NMCGQ.js.map → chunk-N7KYEVLK.js.map} +0 -0
  424. /package/dist/{chunk-HT2C4EXO.js.map → chunk-NIRQGDYC.js.map} +0 -0
  425. /package/dist/{chunk-DXHVD4DS.js.map → chunk-NW2E4CI2.js.map} +0 -0
  426. /package/dist/{chunk-4NDWE44P.js.map → chunk-NZFFGO5O.js.map} +0 -0
  427. /package/dist/{chunk-KC46VZR5.js.map → chunk-O2IPAX26.js.map} +0 -0
  428. /package/dist/{chunk-M7V65M6H.js.map → chunk-O4SGYW7H.js.map} +0 -0
  429. /package/dist/{chunk-QUA7RLK6.js.map → chunk-OP6N4H6A.js.map} +0 -0
  430. /package/dist/{chunk-ZSJGYC3C.js.map → chunk-OQJKY3Z5.js.map} +0 -0
  431. /package/dist/{chunk-OFEHITAZ.js.map → chunk-OXNTOHL6.js.map} +0 -0
  432. /package/dist/{chunk-FQD2KPQH.js.map → chunk-P55FACBG.js.map} +0 -0
  433. /package/dist/{chunk-XERVJYH2.js.map → chunk-P5NQN4JE.js.map} +0 -0
  434. /package/dist/{chunk-XZLWYZ7C.js.map → chunk-P7TOIOT7.js.map} +0 -0
  435. /package/dist/{chunk-PBVNVKYN.js.map → chunk-PIN5OPBA.js.map} +0 -0
  436. /package/dist/{chunk-CNG2XVZG.js.map → chunk-PZHQWFR3.js.map} +0 -0
  437. /package/dist/{chunk-SVDU4OHO.js.map → chunk-Q35L7TYB.js.map} +0 -0
  438. /package/dist/{chunk-YEM7K3KD.js.map → chunk-QODKDRSP.js.map} +0 -0
  439. /package/dist/{chunk-IZT3BVDW.js.map → chunk-QOZJCSFO.js.map} +0 -0
  440. /package/dist/{chunk-6T42L5FI.js.map → chunk-QS3OLP5I.js.map} +0 -0
  441. /package/dist/{chunk-PAAJWQH5.js.map → chunk-QUMKDRCF.js.map} +0 -0
  442. /package/dist/{chunk-JFVCDEIC.js.map → chunk-QX6JN3O4.js.map} +0 -0
  443. /package/dist/{chunk-KZEMFD6E.js.map → chunk-R2H4ZFBJ.js.map} +0 -0
  444. /package/dist/{chunk-GKIXBH7Y.js.map → chunk-RTKV5XHL.js.map} +0 -0
  445. /package/dist/{chunk-ZQ3WU6JO.js.map → chunk-RXFCU3CY.js.map} +0 -0
  446. /package/dist/{chunk-BOOFTFFE.js.map → chunk-S2I7DL5Q.js.map} +0 -0
  447. /package/dist/{chunk-2NCBDGND.js.map → chunk-SA6GMZJY.js.map} +0 -0
  448. /package/dist/{chunk-NSFOERZQ.js.map → chunk-SIIRTDJ4.js.map} +0 -0
  449. /package/dist/{chunk-A6TVQ3QP.js.map → chunk-SS3IS2JR.js.map} +0 -0
  450. /package/dist/{chunk-VFTK5WKI.js.map → chunk-STBX5X6B.js.map} +0 -0
  451. /package/dist/{chunk-WVHRNAXL.js.map → chunk-SWWHIJUJ.js.map} +0 -0
  452. /package/dist/{chunk-WADSXS4K.js.map → chunk-SX4QDWXK.js.map} +0 -0
  453. /package/dist/{chunk-ZIZ2G47N.js.map → chunk-TITG2NBS.js.map} +0 -0
  454. /package/dist/{chunk-LZKOVXMX.js.map → chunk-TRMJ6BYC.js.map} +0 -0
  455. /package/dist/{chunk-U7VPOXVM.js.map → chunk-TZNDKTX5.js.map} +0 -0
  456. /package/dist/{chunk-WWSRLS4M.js.map → chunk-UMTCNEVQ.js.map} +0 -0
  457. /package/dist/{chunk-4TTGRETU.js.map → chunk-UQDG3YLN.js.map} +0 -0
  458. /package/dist/{chunk-AAM66QCP.js.map → chunk-UZRSI6NX.js.map} +0 -0
  459. /package/dist/{chunk-2CXQZXWM.js.map → chunk-V4MB5ONM.js.map} +0 -0
  460. /package/dist/{chunk-CYEK6Z3P.js.map → chunk-VW6VIJOS.js.map} +0 -0
  461. /package/dist/{chunk-5ZJYHOJT.js.map → chunk-W47S5TIH.js.map} +0 -0
  462. /package/dist/{chunk-CBP4HWCL.js.map → chunk-W5MCEVUS.js.map} +0 -0
  463. /package/dist/{chunk-WETFW255.js.map → chunk-WLMZ2L5P.js.map} +0 -0
  464. /package/dist/{chunk-XRBHXUTQ.js.map → chunk-WSGPFRBH.js.map} +0 -0
  465. /package/dist/{chunk-UOKPJFO3.js.map → chunk-WVADKFWV.js.map} +0 -0
  466. /package/dist/{chunk-P34FDDB5.js.map → chunk-XISROV24.js.map} +0 -0
  467. /package/dist/{chunk-FZVROZKC.js.map → chunk-XVZA6VXC.js.map} +0 -0
  468. /package/dist/{chunk-JUWJYXI4.js.map → chunk-Y4NKEXQT.js.map} +0 -0
  469. /package/dist/{chunk-2ZQJLBV6.js.map → chunk-YE36AJL7.js.map} +0 -0
  470. /package/dist/{chunk-PCWXLAJY.js.map → chunk-YFMBHQRG.js.map} +0 -0
  471. /package/dist/{chunk-RBJQYMMT.js.map → chunk-YRULQW5J.js.map} +0 -0
  472. /package/dist/{chunk-QUNDYIYZ.js.map → chunk-YYEOR4XN.js.map} +0 -0
  473. /package/dist/{chunk-VYPFEVOM.js.map → chunk-ZJVMUBYF.js.map} +0 -0
  474. /package/dist/{chunk-5MDM7UE4.js.map → chunk-ZSH2NRDV.js.map} +0 -0
  475. /package/dist/{chunk-3J5JKBYD.js.map → chunk-ZV65I6ME.js.map} +0 -0
  476. /package/dist/{first-start-migration-HYAMKJ6V.js.map → first-start-migration-6A5BJPDW.js.map} +0 -0
@@ -4,6 +4,7 @@ import { mkdir, readFile, readdir, rename, stat, unlink, writeFile } from "node:
4
4
  import path from "node:path";
5
5
  import { promisify } from "node:util";
6
6
  import { log } from "../logger.js";
7
+ import type { CaptureWriteLockLimitSource } from "../capture-write-lock-backoff.js";
7
8
  import type { MemoryFile, MemoryFrontmatter } from "../types.js";
8
9
  import { RECALL_FALLBACK_DIRS } from "../utils/category-dir.js";
9
10
  import { isErrnoCode } from "../utils/errno.js";
@@ -54,6 +55,8 @@ export type TombstoneBlockedCaptureIndexOptions = {
54
55
  readonly secureStoreKeyProvider: () => Buffer | null;
55
56
  readonly secureStoreWriteKeyProvider: () => Buffer | null;
56
57
  readonly lockOptions: () => ContentHashIndexLockOptions;
58
+ /** Capture-write-lock limit source; undefined until converge installs limits. */
59
+ readonly captureLockLimitSource?: () => CaptureWriteLockLimitSource | undefined;
57
60
  readonly readAllMemories: () => Promise<MemoryFile[]>;
58
61
  readonly readAllColdMemories: () => Promise<MemoryFile[]>;
59
62
  readonly parseMemory?: OfflineSyncMemoryParser;
@@ -77,7 +80,11 @@ export class TombstoneBlockedCaptureIndex {
77
80
 
78
81
  constructor(options: TombstoneBlockedCaptureIndexOptions) {
79
82
  this.options = options;
80
- this.captureWriteLock = new TombstoneBlockedCaptureWriteLock(options);
83
+ this.captureWriteLock = new TombstoneBlockedCaptureWriteLock({
84
+ stateDir: options.stateDir,
85
+ withHeldFileLock: options.withHeldFileLock,
86
+ lockOptions: options.captureLockLimitSource,
87
+ });
81
88
  }
82
89
 
83
90
  private createIndex(): ContentHashIndex {
@@ -2,17 +2,30 @@ import { AsyncLocalStorage } from "node:async_hooks";
2
2
  import { createHash } from "node:crypto";
3
3
  import { mkdir } from "node:fs/promises";
4
4
  import path from "node:path";
5
- import { withHeldFileLock } from "../utils/serialize-mutations.js";
5
+ import { raceAbort, throwIfAborted } from "../abort-error.js";
6
+ import {
7
+ CAPTURE_WRITE_LOCK_BUSY_MESSAGE,
8
+ type CaptureWriteLockLimitSource,
9
+ captureWriteLockDelayMs,
10
+ resolveCaptureWriteLockBackoffLimits,
11
+ } from "../capture-write-lock-backoff.js";
12
+ import { log } from "../logger.js";
6
13
  import type { MemoryFile, MemoryFrontmatter } from "../types.js";
14
+ import { withHeldFileLock } from "../utils/serialize-mutations.js";
15
+ import { sleepAbortable } from "../utils/sleep.js";
7
16
  import type { CasRevisionTransaction } from "./cas-revision-store.js";
8
- const TOMBSTONE_CAPTURE_WRITE_LOCK_STALE_MS = 60_000;
9
- const CAPTURE_WRITE_LOCK_MAX_ATTEMPTS = 3;
10
- const CAPTURE_WRITE_LOCK_RETRY_BASE_MS = 25;
11
- const CAPTURE_WRITE_LOCK_BUSY_MESSAGE = "tombstone-blocked capture write lock remained busy";
12
17
 
13
- export function isTombstoneBlockedCaptureWriteLockBusy(error: unknown): boolean {
14
- return error instanceof Error && error.message === CAPTURE_WRITE_LOCK_BUSY_MESSAGE;
15
- }
18
+ export { isTombstoneBlockedCaptureWriteLockBusy } from "../capture-write-lock-backoff.js";
19
+
20
+ const TOMBSTONE_CAPTURE_WRITE_LOCK_STALE_MS = 60_000;
21
+ /**
22
+ * One exclusive-create probe. The bounded wait lives in the outer backoff,
23
+ * which runs only after every lock from this attempt has been released.
24
+ * A multi-second poll here would hold an already-acquired sibling lock.
25
+ */
26
+ const CAPTURE_WRITE_LOCK_PROBE_MS = 1;
27
+ const CAPTURE_WRITE_LOCK_RETRY = Symbol("capture-write-lock-retry");
28
+ const CAPTURE_WRITE_LOCK_PERMANENT = Symbol("capture-write-lock-permanent-failure");
16
29
 
17
30
  export function normalizeExplicitCaptureContent(value: string): string {
18
31
  return value.toLowerCase().replace(/\s+/g, " ").trim();
@@ -46,6 +59,15 @@ export function captureIdentityHash(memory: MemoryFile): string {
46
59
  export type TombstoneBlockedCaptureWriteLockOptions = {
47
60
  readonly stateDir: string;
48
61
  readonly withHeldFileLock?: typeof withHeldFileLock;
62
+ /** Read when an acquire starts, after the caller has installed converge config. */
63
+ readonly lockOptions?: () => CaptureWriteLockLimitSource | undefined;
64
+ readonly now?: () => number;
65
+ readonly random?: () => number;
66
+ readonly sleep?: (ms: number, signal?: AbortSignal) => Promise<void>;
67
+ readonly logDebug?: (message: string) => void;
68
+ readonly logWarn?: (message: string) => void;
69
+ /** Direct seam. Converge passes the same signal through `lockOptions` instead. */
70
+ readonly signal?: AbortSignal;
49
71
  };
50
72
 
51
73
  export class TombstoneBlockedCaptureWriteLock {
@@ -59,45 +81,107 @@ export class TombstoneBlockedCaptureWriteLock {
59
81
  return path.join(this.options.stateDir, "tombstone-blocked-capture", filename);
60
82
  }
61
83
 
62
- private async withSingleCaptureWriteLock<T>(lockPath: string, task: () => Promise<T>): Promise<T> {
84
+ private now(): number {
85
+ return this.options.now?.() ?? Date.now();
86
+ }
87
+
88
+ private debug(message: string): void {
89
+ if (this.options.logDebug) {
90
+ this.options.logDebug(message);
91
+ return;
92
+ }
93
+ log.debug(message);
94
+ }
95
+
96
+ private warn(message: string): void {
97
+ if (this.options.logWarn) {
98
+ this.options.logWarn(message);
99
+ return;
100
+ }
101
+ log.warn(message);
102
+ }
103
+
104
+ /** Prefer the constructor seam; converge installs the signal on lock options at acquire time. */
105
+ private captureAbortSignal(): AbortSignal | undefined {
106
+ return this.options.signal ?? this.options.lockOptions?.()?.captureWriteLockSignal;
107
+ }
108
+
109
+ /**
110
+ * One probe of a single lock file. Returns the retry symbol when the lock
111
+ * is busy and the permanent symbol on a filesystem error. Does not sleep:
112
+ * the caller backs off only after the whole chain has unwound.
113
+ */
114
+ private async withSingleCaptureWriteLockOnce<T>(
115
+ lockPath: string,
116
+ task: () => Promise<T | typeof CAPTURE_WRITE_LOCK_RETRY>
117
+ ): Promise<T | typeof CAPTURE_WRITE_LOCK_RETRY | typeof CAPTURE_WRITE_LOCK_PERMANENT> {
63
118
  await mkdir(path.dirname(lockPath), { recursive: true });
64
- const retry = Symbol("retry");
65
- const permanentFailure = Symbol("permanent-failure");
66
119
  const runWithHeldFileLock = this.options.withHeldFileLock ?? withHeldFileLock;
67
- for (let attempt = 0; attempt < CAPTURE_WRITE_LOCK_MAX_ATTEMPTS; attempt += 1) {
68
- const result = await runWithHeldFileLock<T | typeof retry | typeof permanentFailure>(
69
- lockPath,
70
- {
71
- staleMs: TOMBSTONE_CAPTURE_WRITE_LOCK_STALE_MS,
72
- maxWaitMs: 1_000,
73
- pollMs: 25,
74
- },
75
- async (acquired, controller) => {
76
- if (acquired) return await task();
77
- return controller.failure === "error" ? permanentFailure : retry;
78
- }
79
- );
80
- if (result === permanentFailure) {
81
- throw new Error("tombstone-blocked capture write lock acquisition failed");
120
+ return await runWithHeldFileLock(
121
+ lockPath,
122
+ {
123
+ staleMs: TOMBSTONE_CAPTURE_WRITE_LOCK_STALE_MS,
124
+ maxWaitMs: CAPTURE_WRITE_LOCK_PROBE_MS,
125
+ pollMs: CAPTURE_WRITE_LOCK_PROBE_MS,
126
+ },
127
+ async (acquired, controller) => {
128
+ if (acquired) return await task();
129
+ return controller.failure === "error" ? CAPTURE_WRITE_LOCK_PERMANENT : CAPTURE_WRITE_LOCK_RETRY;
82
130
  }
83
- if (result !== retry) return result;
84
- if (attempt === CAPTURE_WRITE_LOCK_MAX_ATTEMPTS - 1) break;
85
- const delayState = Promise.withResolvers<void>();
86
- setTimeout(delayState.resolve, CAPTURE_WRITE_LOCK_RETRY_BASE_MS * 2 ** attempt);
87
- await delayState.promise;
88
- }
89
- throw new Error(CAPTURE_WRITE_LOCK_BUSY_MESSAGE);
131
+ );
90
132
  }
133
+
91
134
  private async withPhysicalCaptureWriteLocks<T>(
92
135
  task: () => Promise<T>,
93
136
  identityHashes: readonly string[]
94
137
  ): Promise<T> {
138
+ const signal = this.captureAbortSignal();
95
139
  const lockPaths = [...new Set(identityHashes.map((hash) => this.captureWriteLockPathForHash(hash)))];
96
- const acquire = async (index: number): Promise<T> => {
97
- if (index === lockPaths.length) return await task();
98
- return await this.withSingleCaptureWriteLock(lockPaths[index], () => acquire(index + 1));
140
+ const limits = resolveCaptureWriteLockBackoffLimits(this.options.lockOptions?.());
141
+ const deadline = this.now() + limits.deadlineMs;
142
+ const giveUp = (): never => {
143
+ throwIfAborted(signal);
144
+ this.warn(
145
+ `tombstone-blocked capture write lock remained busy after ${limits.deadlineMs}ms; failing this write so the rest of the cycle can continue`
146
+ );
147
+ throw new Error(CAPTURE_WRITE_LOCK_BUSY_MESSAGE);
99
148
  };
100
- return await acquire(0);
149
+ const acquire = async (
150
+ index: number
151
+ ): Promise<T | typeof CAPTURE_WRITE_LOCK_RETRY | typeof CAPTURE_WRITE_LOCK_PERMANENT> => {
152
+ throwIfAborted(signal);
153
+ // The deadline gates each probe: a chain that started before the
154
+ // deadline must not keep probing locks (or run the write) after it.
155
+ const runTask = async (): Promise<T> => {
156
+ if (this.now() >= deadline) giveUp();
157
+ return await task();
158
+ };
159
+ if (index === lockPaths.length) return await runTask();
160
+ const lockPath = lockPaths[index];
161
+ if (lockPath === undefined) return await runTask();
162
+ if (this.now() >= deadline) giveUp();
163
+ return await this.withSingleCaptureWriteLockOnce(lockPath, () => acquire(index + 1));
164
+ };
165
+ for (let attempt = 0; ; attempt += 1) {
166
+ throwIfAborted(signal);
167
+ const outcome = await acquire(0);
168
+ if (outcome === CAPTURE_WRITE_LOCK_PERMANENT) {
169
+ throw new Error("tombstone-blocked capture write lock acquisition failed");
170
+ }
171
+ if (outcome !== CAPTURE_WRITE_LOCK_RETRY) return outcome;
172
+ throwIfAborted(signal);
173
+ const now = this.now();
174
+ if (now >= deadline) giveUp();
175
+ const delay = Math.min(
176
+ captureWriteLockDelayMs(attempt, limits, this.options.random ?? Math.random),
177
+ deadline - now
178
+ );
179
+ if (delay <= 0) giveUp();
180
+ this.debug(`tombstone-blocked capture write lock busy; backing off ${delay}ms before retry ${attempt + 1}`);
181
+ // raceAbort covers seam sleeps that ignore the signal; the default
182
+ // sleepAbortable also clears its timer so abort holds no Timeout.
183
+ await raceAbort((this.options.sleep ?? sleepAbortable)(delay, signal), signal);
184
+ }
101
185
  }
102
186
 
103
187
  async withCaptureWriteLock<T>(task: () => Promise<T>, identity?: string | readonly string[]): Promise<T> {
@@ -125,6 +209,7 @@ export class TombstoneBlockedCaptureWriteLock {
125
209
  identities: readonly string[],
126
210
  identityHashes: readonly string[]
127
211
  ): Promise<T> {
212
+ throwIfAborted(this.captureAbortSignal());
128
213
  const current = this.context.getStore();
129
214
  const hashToken = (key: string): string =>
130
215
  `\u0000${key.length === 0 ? "" : createHash("sha256").update(key).digest("hex")}`;
@@ -179,7 +264,10 @@ export class TombstoneBlockedCaptureWriteLock {
179
264
  next.add(hashToken(key));
180
265
  }
181
266
  for (const hash of hashes) next.add(`\u0000${hash}`);
182
- const run = () => this.context.run(next, task);
267
+ const run = () => {
268
+ throwIfAborted(this.captureAbortSignal());
269
+ return this.context.run(next, task);
270
+ };
183
271
  if (physicalMissing.length === 0) return await run();
184
272
  return await this.withPhysicalCaptureWriteLocks(run, physicalMissing);
185
273
  }
@@ -197,7 +285,10 @@ export type TombstoneBlockedMutationHost = {
197
285
  writeStorageSecureFile: (pathname: string, fileContent: string) => Promise<void>;
198
286
  withCaptureWriteLock: (task: () => Promise<void>, identity: string | readonly string[]) => Promise<void>;
199
287
  logWarning: (message: string) => void;
200
- beginDurableMemoryRevision?: (pathname: string, expectedContent?: string | Buffer | null) => Promise<CasRevisionTransaction | undefined>;
288
+ beginDurableMemoryRevision?: (
289
+ pathname: string,
290
+ expectedContent?: string | Buffer | null
291
+ ) => Promise<CasRevisionTransaction | undefined>;
201
292
  };
202
293
 
203
294
  export type TombstoneBlockedMutation = {
@@ -263,7 +354,7 @@ export async function runTombstoneBlockedMutation(
263
354
  await transaction.abort();
264
355
  } catch (abortError) {
265
356
  host.logWarning(
266
- `storage.tombstoneBlocked failed to abort the reserved receipt (pending marker preserved): ${abortError}`,
357
+ `storage.tombstoneBlocked failed to abort the reserved receipt (pending marker preserved): ${abortError}`
267
358
  );
268
359
  }
269
360
  }
@@ -280,7 +371,7 @@ export async function runTombstoneBlockedMutation(
280
371
  await transaction.writeLanded();
281
372
  } catch (evidenceError) {
282
373
  host.logWarning(
283
- `storage.tombstoneBlocked failed to record receipt crash evidence (pending marker preserved): ${evidenceError}`,
374
+ `storage.tombstoneBlocked failed to record receipt crash evidence (pending marker preserved): ${evidenceError}`
284
375
  );
285
376
  }
286
377
  try {
@@ -292,7 +383,7 @@ export async function runTombstoneBlockedMutation(
292
383
  // and promotion/rollback refuse until recovery reconciles. The
293
384
  // reservation must NOT be aborted: the write is on disk.
294
385
  host.logWarning(
295
- `storage.tombstoneBlocked receipt publication failed after the memory write (pending marker preserved for recovery): ${err}`,
386
+ `storage.tombstoneBlocked receipt publication failed after the memory write (pending marker preserved for recovery): ${err}`
296
387
  );
297
388
  await discardRebuildMarker();
298
389
  throw err;
@@ -318,7 +409,6 @@ export async function runTombstoneBlockedMutation(
318
409
  }
319
410
  }
320
411
 
321
-
322
412
  export function tombstoneBlocked(frontmatter: MemoryFrontmatter): boolean {
323
413
  return frontmatter.status === "pending_review" && Boolean(frontmatter.blockedBy);
324
414
  }
package/src/storage.ts CHANGED
@@ -3219,6 +3219,7 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
3219
3219
  secureStoreKeyProvider: () => this._secureStoreKey,
3220
3220
  secureStoreWriteKeyProvider: () => this.resolveWriteKey(),
3221
3221
  lockOptions: () => this.factHashIndexLockOptions,
3222
+ captureLockLimitSource: () => this.captureLockLimitSource(),
3222
3223
  parseMemory: (filePath, content) =>
3223
3224
  parseTombstoneBlockedOfflineSyncMemory(
3224
3225
  filePath,
@@ -3232,6 +3233,18 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
3232
3233
  readAllColdMemories: () => this.readAllColdMemories(),
3233
3234
  };
3234
3235
  }
3236
+
3237
+ /**
3238
+ * Lock-limit source for tombstone-blocked captures. Undefined until the
3239
+ * converge path installs capture-lock limits, so an ordinary capture
3240
+ * resolves to the legacy short bounds instead of the converge deadline.
3241
+ */
3242
+ private captureLockLimitSource(): ContentHashIndexLockOptions | undefined {
3243
+ const options = this.factHashIndexLockOptions;
3244
+ const keys = ["captureWriteLockInitialDelayMs", "captureWriteLockMaxDelayMs", "captureWriteLockDeadlineMs", "captureWriteLockSignal"] as const;
3245
+ return keys.some((key) => options[key] !== undefined) ? options : undefined;
3246
+ }
3247
+
3235
3248
  private async getFactHashIndex(): Promise<ContentHashIndex> {
3236
3249
  if (this.factHashIndex) {
3237
3250
  return this.factHashIndex;
package/src/types.ts CHANGED
@@ -41,6 +41,15 @@ export interface ConvergeConfig {
41
41
  conflictPolicy: ConvergeConflictPolicy;
42
42
  /** Per-request peer HTTP timeout in ms (plan/apply/watch). Default 30000; clamped to <= 3600000. */
43
43
  peerRequestTimeoutMs?: number;
44
+ /**
45
+ * Tombstone-blocked capture write-lock backoff for converge apply/watch.
46
+ * Defaults: 50ms initial (jittered to 25–50), 2000ms cap per wait, 60000ms
47
+ * deadline. Positive integers, clamped to <= 3600000. An inverted schedule
48
+ * (initial > max, or max > deadline) is rejected.
49
+ */
50
+ captureWriteLockInitialDelayMs?: number;
51
+ captureWriteLockMaxDelayMs?: number;
52
+ captureWriteLockDeadlineMs?: number;
44
53
  }
45
54
  export type SignalLevel = "none" | "low" | "medium" | "high";
46
55
  export type MemoryCategory =
@@ -3,3 +3,31 @@ export function sleep(ms: number): Promise<void> {
3
3
  // Constructor form keeps this reachable utility compatible with ES2022 adapter type graphs.
4
4
  return new Promise((resolve) => setTimeout(resolve, ms));
5
5
  }
6
+
7
+ import { abortError } from "../abort-error.js";
8
+
9
+ /**
10
+ * Wait until `ms` elapses, or reject with `AbortError` when `signal` fires.
11
+ * The timer is cleared on abort so a cancelled wait holds no Timeout handle.
12
+ * Executor form: this module targets ES2022 type graphs (no withResolvers).
13
+ */
14
+ export function sleepAbortable(ms: number, signal?: AbortSignal): Promise<void> {
15
+ return new Promise((resolve, reject) => {
16
+ if (signal?.aborted) {
17
+ reject(abortError("operation aborted"));
18
+ return;
19
+ }
20
+ const timer = setTimeout(() => {
21
+ if (signal && onAbort) signal.removeEventListener("abort", onAbort);
22
+ resolve();
23
+ }, ms);
24
+ let onAbort: (() => void) | null = null;
25
+ if (signal) {
26
+ onAbort = () => {
27
+ clearTimeout(timer);
28
+ reject(abortError("operation aborted"));
29
+ };
30
+ signal.addEventListener("abort", onAbort, { once: true });
31
+ }
32
+ });
33
+ }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/extraction-source-grounding-rules.ts"],"sourcesContent":["import type { ExtractionResult } from \"./types.js\";\nimport { anchorTemporalExpressions } from \"./delinearize.js\";\nimport {\n GROUNDING_AUXILIARY_TOKENS,\n GROUNDING_COPULAR_FORMS,\n GROUNDING_ENTITY_TYPE_PREFIXES,\n GROUNDING_MIN_COVERAGE,\n GROUNDING_MIN_SHARED_TOKENS,\n GROUNDING_STOPWORDS,\n areGroundingTokensCompatible,\n containsContiguousGroundingTokens,\n containsExactTokenSequence,\n groundingLexemes,\n groundingTokenSequence,\n hasContradictoryPolarity,\n hasExplicitRoleSubjectToken,\n isInterrogativeSourceSentence,\n normalizeForExactMatch,\n normalizedGroundingAlignmentTokenSequence,\n normalizedGroundingTokenSequence,\n sourceSentences,\n spacelessScriptGroundedTokenScore,\n splitGroundingClauses,\n stemToken,\n tokenize,\n tokenSequence,\n} from \"./extraction-source-grounding-helpers.js\";\n\nexport interface ExtractionSourceGroundingOptions {\n sourceGrounding: boolean;\n anchorTemporalExpressions: boolean;\n spanMode?: \"off\" | \"shadow\" | \"on\";\n}\n\nexport function applyExtractionSourceGrounding(\n result: ExtractionResult,\n sourceText: string,\n assertionSourceText: string = sourceText,\n roleAssertionSources: ExtractionGroundingRoleSources | undefined,\n messageTimestamp: Date | undefined,\n options: ExtractionSourceGroundingOptions,\n): ExtractionResult {\n if (!options.sourceGrounding) return result;\n const anchorSource = (source: string): string =>\n options.anchorTemporalExpressions\n ? anchorTemporalExpressions(source, messageTimestamp ?? new Date())\n : source;\n const anchoredRoleSources = roleAssertionSources === undefined\n ? undefined\n : {\n profile: roleAssertionSources.profile === undefined\n ? undefined\n : anchorSource(roleAssertionSources.profile),\n identity: roleAssertionSources.identity === undefined\n ? undefined\n : anchorSource(roleAssertionSources.identity),\n };\n return filterExtractionResultBySource(\n result,\n anchorSource(sourceText),\n anchorSource(assertionSourceText),\n anchoredRoleSources,\n options.anchorTemporalExpressions ? anchorSource : undefined,\n options.spanMode ?? \"off\",\n );\n}\n\nexport interface ExtractionGroundingRoleSources {\n profile?: string;\n identity?: string;\n}\n\n\n\ninterface GroundingCopularClaim {\n subject: string;\n predicate: string;\n}\n\nfunction groundingCopularClaim(text: string): GroundingCopularClaim | undefined {\n const lexemes = groundingLexemes(text);\n const copulaIndex = lexemes.findIndex(({ token }) => GROUNDING_COPULAR_FORMS.has(token));\n if (copulaIndex <= 0) return undefined;\n\n let subjectIndex = copulaIndex - 1;\n while (\n subjectIndex >= 0\n && GROUNDING_AUXILIARY_TOKENS.has(lexemes[subjectIndex]!.token)\n ) {\n subjectIndex -= 1;\n }\n const subjectLexeme = lexemes[subjectIndex];\n const predicateLexeme = lexemes\n .slice(copulaIndex + 1)\n .find(({ token }) => GROUNDING_STOPWORDS[token] !== true);\n if (subjectLexeme === undefined || predicateLexeme === undefined) return undefined;\n\n return {\n subject: stemToken(subjectLexeme.token, subjectLexeme.preserveTerminalS, true),\n predicate: stemToken(predicateLexeme.token, predicateLexeme.preserveTerminalS, true),\n };\n}\n\nfunction hasCopularPredicateEvidence(candidate: string, source: string): boolean {\n const candidateClaim = groundingCopularClaim(candidate);\n if (candidateClaim === undefined) return true;\n const sourceClaim = groundingCopularClaim(source);\n return sourceClaim !== undefined\n && areGroundingTokensCompatible(candidateClaim.subject, sourceClaim.subject)\n && areGroundingTokensCompatible(candidateClaim.predicate, sourceClaim.predicate);\n}\nconst GROUNDING_ALIGNMENT_MODIFIERS = new Set([\n \"actively\",\n \"again\",\n \"already\",\n \"currently\",\n \"eventually\",\n \"finally\",\n \"generally\",\n \"mainly\",\n \"newly\",\n \"now\",\n \"often\",\n \"previously\",\n \"primarily\",\n \"quickly\",\n \"recently\",\n \"repeatedly\",\n \"simply\",\n \"slowly\",\n \"sometimes\",\n \"still\",\n \"successfully\",\n \"typically\",\n \"usually\",\n]);\n\nfunction isGroundingAlignmentModifier(token: string): boolean {\n return GROUNDING_ALIGNMENT_MODIFIERS.has(token);\n}\n\nfunction groundingSubjectTokenSequence(text: string): string[] {\n const lexemes = groundingLexemes(text)\n .filter(({ token }) => GROUNDING_STOPWORDS[token] !== true);\n const predicateIndex = lexemes.findIndex(({ isPredicate }) => isPredicate);\n if (predicateIndex < 1) return [];\n return lexemes\n .slice(0, predicateIndex)\n .filter(({ token }) => !isGroundingAlignmentModifier(token) && !token.endsWith(\"ly\"))\n .map(({ token, preserveTerminalS }) => stemToken(token, preserveTerminalS, true));\n}\n\n\nfunction hasAlignedSubjectPredicateOverlap(candidate: string, source: string): boolean {\n const candidateTokens = normalizedGroundingAlignmentTokenSequence(candidate);\n const sourceTokens = normalizedGroundingAlignmentTokenSequence(source);\n const candidateSubjectTokens = groundingSubjectTokenSequence(candidate);\n const sourceSubjectTokens = groundingSubjectTokenSequence(source);\n const hasCorrectionReordering = /\\b(?:rather\\s+than|instead\\s+of)\\b/iu.test(candidate)\n && /\\b(?:not|rather\\s+than|instead\\s+of)\\b/iu.test(source);\n if (\n candidateSubjectTokens.length > 0\n && sourceSubjectTokens.length > 0\n && !hasCorrectionReordering\n && (\n candidateSubjectTokens.length !== sourceSubjectTokens.length\n || candidateSubjectTokens.some(\n (token, index) => !areGroundingTokensCompatible(token, sourceSubjectTokens[index]!),\n )\n )\n ) {\n return false;\n }\n if (candidateTokens.length < 3 || sourceTokens.length < 3) {\n return hasCopularPredicateEvidence(candidate, source);\n }\n\n const candidateSubject = candidateTokens[0];\n if (candidateSubject === undefined) return false;\n for (let sourceSubjectIndex = 0; sourceSubjectIndex < sourceTokens.length; sourceSubjectIndex += 1) {\n if (!areGroundingTokensCompatible(candidateSubject, sourceTokens[sourceSubjectIndex]!)) continue;\n let sourceCursor = sourceSubjectIndex + 1;\n let foundAlignedToken = false;\n let aligned = true;\n for (let candidateIndex = 1; candidateIndex < candidateTokens.length; candidateIndex += 1) {\n const candidateToken = candidateTokens[candidateIndex]!;\n const sourceIndex = sourceTokens.findIndex(\n (sourceToken, index) =>\n index >= sourceCursor && areGroundingTokensCompatible(candidateToken, sourceToken),\n );\n if (sourceIndex === -1) {\n if (hasCorrectionReordering) continue;\n aligned = false;\n break;\n }\n foundAlignedToken = true;\n const candidateNext = candidateTokens[candidateIndex + 1];\n const sourceNext = sourceTokens[sourceIndex + 1];\n if (\n candidateNext !== undefined\n && sourceNext !== undefined\n && !hasCorrectionReordering\n && !areGroundingTokensCompatible(candidateNext, sourceNext)\n && !isGroundingAlignmentModifier(sourceNext)\n ) {\n aligned = false;\n break;\n }\n sourceCursor = sourceIndex + 1;\n }\n if (aligned && foundAlignedToken) return true;\n }\n return false;\n}\n\nfunction omitsSourceDisjunction(candidate: string, source: string): boolean {\n if (!/\\bor\\b/iu.test(source) || /\\bor\\b/iu.test(candidate)) return false;\n const candidateTokens = normalizedGroundingTokenSequence(candidate);\n return splitGroundingClauses([source], true).some((sourceSpan) => {\n const sourceSpanTokens = normalizedGroundingTokenSequence(sourceSpan);\n return candidateTokens.length === sourceSpanTokens.length\n && candidateTokens.every(\n (token, index) => areGroundingTokensCompatible(token, sourceSpanTokens[index]!),\n );\n });\n}\n\nfunction groundedTokenScore(\n candidate: string,\n source: string,\n requireAlignedArguments = true,\n requireAllCandidateTokensGrounded = true,\n): number {\n const scriptAwareScore = spacelessScriptGroundedTokenScore(candidate, source);\n if (scriptAwareScore !== null) return scriptAwareScore;\n const candidateTokens = tokenize(candidate);\n if (candidateTokens.size === 0) return 0;\n const sourceTokens = tokenize(source);\n const allowCorrectionReordering = /\\b(?:rather\\s+than|instead\\s+of)\\b/iu.test(candidate);\n let sharedTokens = 0;\n let allCandidateTokensGrounded = true;\n for (const token of candidateTokens) {\n if ([...sourceTokens].some((sourceToken) => areGroundingTokensCompatible(token, sourceToken))) {\n sharedTokens += 1;\n } else if (!allowCorrectionReordering && token !== \"rather\" && token !== \"instead\") {\n allCandidateTokensGrounded = false;\n }\n }\n if (\n (requireAllCandidateTokensGrounded && !allCandidateTokensGrounded)\n || sharedTokens < GROUNDING_MIN_SHARED_TOKENS\n || sharedTokens / candidateTokens.size < GROUNDING_MIN_COVERAGE\n ) {\n return 0;\n }\n if (requireAlignedArguments && !hasAlignedSubjectPredicateOverlap(candidate, source)) return 0;\n return sharedTokens / candidateTokens.size;\n}\n\nfunction candidateClauses(candidate: string): string[] {\n return sourceSentences(candidate).flatMap((sentence) =>\n /\\bor\\b/iu.test(sentence) ? [sentence] : splitGroundingClauses([sentence]));\n}\n\nfunction isSourceGroundedClause(\n candidate: string,\n source: string,\n includeInterrogativeSource = false,\n): boolean {\n let bestSupportedScore = 0;\n let bestContradictedScore = 0;\n const sentences = sourceSentences(source);\n for (let index = 0; index < sentences.length; index += 1) {\n const sentence = sentences[index];\n if (isYesNoAnswer(sentence)) {\n const precedingSentence = sentences[index - 1];\n const answerToken = tokenSequence(sentence)[0];\n const contradictoryPolarity = precedingSentence !== undefined\n ? hasContradictoryPolarity(candidate, precedingSentence)\n : false;\n if (\n precedingSentence !== undefined\n && isInterrogativeSourceSentence(precedingSentence)\n && !omitsSourceDisjunction(candidate, precedingSentence)\n && groundedTokenScore(candidate, precedingSentence) === 1\n && (\n (answerToken === \"yes\" && !contradictoryPolarity)\n || (answerToken === \"no\" && contradictoryPolarity)\n )\n ) {\n return true;\n }\n continue;\n }\n const sentenceText = normalizeForExactMatch(sentence);\n const isExplanatoryLabel = sentenceText.startsWith(`${normalizeForExactMatch(candidate)}:`)\n && !sentence.trim().endsWith(\"?\");\n if (!includeInterrogativeSource && isInterrogativeSourceSentence(sentence) && !isExplanatoryLabel) {\n continue;\n }\n if (omitsSourceDisjunction(candidate, sentence)) continue;\n const sourceSpans = /\\b(?:rather\\s+than|instead\\s+of)\\b/iu.test(candidate)\n ? [sentence]\n : splitGroundingClauses([sentence], true);\n for (const sourceSpan of sourceSpans) {\n const sourceSpanText = normalizeForExactMatch(sourceSpan);\n if (containsExactTokenSequence(candidate, sourceSpanText)) {\n if (!hasContradictoryPolarity(candidate, sourceSpan)) return true;\n bestContradictedScore = Math.max(bestContradictedScore, 1);\n continue;\n }\n const score = groundedTokenScore(\n candidate,\n sourceSpan,\n !includeInterrogativeSource,\n !includeInterrogativeSource,\n );\n if (score === 0) continue;\n if (hasContradictoryPolarity(candidate, sourceSpan)) {\n bestContradictedScore = Math.max(bestContradictedScore, score);\n } else {\n bestSupportedScore = Math.max(bestSupportedScore, score);\n }\n }\n }\n return bestSupportedScore > bestContradictedScore;\n}\nfunction isSourceGrounded(\n candidate: string,\n source: string,\n includeInterrogativeSource = false,\n): boolean {\n const candidateText = normalizeForExactMatch(candidate);\n const sourceText = source.normalize(\"NFKC\").trim();\n if (candidateText.length === 0 || sourceText.length === 0) return false;\n const hasSupportedExactMatch = sourceSentences(sourceText).some((sentence) => {\n const sentenceText = normalizeForExactMatch(sentence);\n const isExplanatoryLabel = sentenceText.startsWith(`${candidateText}:`)\n && !sentence.trim().endsWith(\"?\");\n if (!includeInterrogativeSource && isInterrogativeSourceSentence(sentence) && !isExplanatoryLabel) return false;\n if (omitsSourceDisjunction(candidateText, sentenceText)) return false;\n return containsExactTokenSequence(candidateText, sentenceText)\n && !hasContradictoryPolarity(candidateText, sentenceText);\n });\n if (hasSupportedExactMatch) return true;\n\n const clauses = candidateClauses(candidate);\n if (clauses.length > 1) {\n return clauses.every((clause) =>\n isSourceGroundedClause(clause, sourceText, includeInterrogativeSource));\n }\n return isSourceGroundedClause(candidate, sourceText, includeInterrogativeSource);\n}\n\nfunction normalizedEntityIdentifierTokens(name: string): string[] {\n const identifier = normalizeForExactMatch(name).replace(/[-_]+/gu, \" \");\n const tokens = groundingLexemes(identifier)\n .filter(({ token }) => GROUNDING_STOPWORDS[token] !== true)\n .map(({ token }) => stemToken(token, true));\n return tokens.length > 1 && GROUNDING_ENTITY_TYPE_PREFIXES.has(tokens[0] ?? \"\")\n ? tokens.slice(1)\n : tokens;\n}\n\nfunction isGroundedEntityName(name: string, source: string): boolean {\n const nameTokens = normalizedEntityIdentifierTokens(name);\n return nameTokens.length > 0 && sourceSentences(source).some((sentence) => {\n const sentenceTokens = groundingLexemes(sentence)\n .filter(({ token }) => GROUNDING_STOPWORDS[token] !== true)\n .map(({ token, preserveTerminalS }) => stemToken(token, preserveTerminalS));\n return containsContiguousGroundingTokens(nameTokens, sentenceTokens);\n });\n}\nfunction buildEntitySupportSource(name: string, source: string): string {\n const nameTokens = normalizedEntityIdentifierTokens(name);\n if (nameTokens.length === 0) return \"\";\n return sourceSentences(source)\n .filter((sentence) => {\n const sentenceTokens = groundingLexemes(sentence)\n .filter(({ token }) => GROUNDING_STOPWORDS[token] !== true)\n .map(({ token, preserveTerminalS }) => stemToken(token, preserveTerminalS));\n return containsContiguousGroundingTokens(nameTokens, sentenceTokens);\n })\n .join(\" \");\n}\n\nfunction hasGroundedPredicateAnchor(candidate: string, sentence: string): boolean {\n const candidateTokens = normalizedGroundingTokenSequence(candidate);\n const sourceTokens = normalizedGroundingTokenSequence(sentence);\n const comparableCandidateTokens = GROUNDING_ROLE_SUBJECT_TOKENS.has(\n (candidateTokens[0] ?? \"\").replace(/^[\\u0000\\u0001]/u, \"\"),\n )\n ? candidateTokens.slice(1)\n : candidateTokens;\n if (comparableCandidateTokens.length < 2) return false;\n const subjectToken = comparableCandidateTokens[0];\n if (\n subjectToken === undefined\n || !sourceTokens.some((sourceToken) => areGroundingTokensCompatible(subjectToken, sourceToken))\n ) {\n return false;\n }\n const candidatePredicateTokens = comparableCandidateTokens.slice(1);\n const sharedPredicateTokens = candidatePredicateTokens.filter((token) =>\n sourceTokens.some((sourceToken) => areGroundingTokensCompatible(token, sourceToken)));\n const requiredSharedTokens = Math.min(2, candidatePredicateTokens.length);\n return sharedPredicateTokens.length >= requiredSharedTokens;\n}\nfunction hasGroundingAnchor(\n candidate: string,\n assertionSource: string,\n includeInterrogativeSource = false,\n requirePredicateSupport = false,\n): boolean {\n return sourceSentences(assertionSource).some((sentence) => {\n if (!includeInterrogativeSource && isInterrogativeSourceSentence(sentence)) return false;\n if (omitsSourceDisjunction(candidate, sentence)) return false;\n const sourceSpans = /\\b(?:rather\\s+than|instead\\s+of)\\b/iu.test(candidate)\n ? [sentence]\n : splitGroundingClauses([sentence], true);\n return sourceSpans.some((sourceSpan) => {\n const exactMatch = containsExactTokenSequence(candidate, sourceSpan)\n && !hasContradictoryPolarity(candidate, sourceSpan);\n if (exactMatch) return true;\n if (requirePredicateSupport && !hasGroundedPredicateAnchor(candidate, sourceSpan)) return false;\n return groundedTokenScore(candidate, sourceSpan) > 0\n || hasRoleNormalizedGrounding(candidate, sourceSpan);\n });\n });\n}\n\nfunction hasAnswerSupport(\n candidate: string,\n source: string,\n assertionSource: string,\n): boolean {\n const assertedAnswerSentences = new Set(\n sourceSentences(assertionSource)\n .filter((sentence) => {\n const answerToken = tokenSequence(sentence)[0];\n return answerToken === \"yes\" || answerToken === \"no\";\n })\n .map((sentence) => normalizeForExactMatch(sentence)),\n );\n if (assertedAnswerSentences.size === 0) return false;\n const sentences = sourceSentences(source);\n return sentences.some((sentence, index) => {\n const answerToken = tokenSequence(sentence)[0];\n if (answerToken !== \"yes\" && answerToken !== \"no\") return false;\n if (!assertedAnswerSentences.has(normalizeForExactMatch(sentence))) return false;\n const precedingSentence = sentences[index - 1];\n if (\n precedingSentence === undefined\n || !isInterrogativeSourceSentence(precedingSentence)\n || omitsSourceDisjunction(candidate, precedingSentence)\n || groundedTokenScore(candidate, precedingSentence) !== 1\n ) {\n return false;\n }\n const contradictoryPolarity = hasContradictoryPolarity(candidate, precedingSentence);\n return answerToken === \"yes\" ? !contradictoryPolarity : contradictoryPolarity;\n });\n}\n\nconst GROUNDING_ROLE_SUBJECT_TOKENS = new Set([\"assistant\", \"user\"]);\n\nfunction hasRoleNormalizedGrounding(candidate: string, source: string): boolean {\n const candidateTokens = groundingTokenSequence(candidate);\n if (!GROUNDING_ROLE_SUBJECT_TOKENS.has(\n (candidateTokens[0] ?? \"\").replace(/^[\\u0000\\u0001]/u, \"\"),\n )) return false;\n const claimTokens = candidateTokens.slice(1);\n if (claimTokens.length === 0) return false;\n\n return sourceSentences(source).some((sentence) => {\n if (isInterrogativeSourceSentence(sentence)) return false;\n const sourceTokens = groundingTokenSequence(sentence);\n const requiredSharedTokens = Math.min(GROUNDING_MIN_SHARED_TOKENS, claimTokens.length);\n let sourceIndex = 0;\n let sharedTokens = 0;\n for (const claimToken of claimTokens) {\n const matchingIndex = sourceTokens.findIndex(\n (sourceToken, index) =>\n index >= sourceIndex && areGroundingTokensCompatible(claimToken, sourceToken),\n );\n if (matchingIndex === -1) continue;\n sharedTokens += 1;\n sourceIndex = matchingIndex + 1;\n }\n return sharedTokens >= requiredSharedTokens\n && !hasContradictoryPolarity(candidate, sentence);\n });\n}\n\ninterface GroundingContext {\n source: string;\n assertionSource: string | undefined;\n allowRoleNormalization: boolean;\n fallbackSource?: string;\n fallbackAssertionSource?: string;\n}\n\nfunction resolveGroundingContext(\n candidate: string,\n source: string,\n assertionSource: string | undefined,\n roleAssertionSources: ExtractionGroundingRoleSources | undefined,\n): GroundingContext {\n const candidateRole = (groundingTokenSequence(candidate)[0] ?? \"\")\n .replace(/^[\\u0000\\u0001]/u, \"\");\n if (!GROUNDING_ROLE_SUBJECT_TOKENS.has(candidateRole)) {\n return { source, assertionSource, allowRoleNormalization: false };\n }\n if (roleAssertionSources === undefined) {\n return { source, assertionSource, allowRoleNormalization: true };\n }\n const roleSource = candidateRole === \"user\"\n ? roleAssertionSources.profile\n : roleAssertionSources.identity;\n if (roleSource === undefined) {\n return { source, assertionSource, allowRoleNormalization: true };\n }\n return {\n source: roleSource,\n assertionSource: roleSource,\n allowRoleNormalization: true,\n fallbackSource: source,\n fallbackAssertionSource: assertionSource,\n };\n}\n\nfunction selectGroundingContext(candidate: string, context: GroundingContext): GroundingContext {\n if (isGroundedCandidate(\n candidate,\n context.source,\n context.assertionSource,\n false,\n context.allowRoleNormalization,\n )) {\n return context;\n }\n if (\n context.fallbackSource === undefined\n || !hasExplicitRoleSubjectToken(\n (groundingTokenSequence(candidate)[0] ?? \"\").replace(/^[\\u0000\\u0001]/u, \"\"),\n sourceSentences(context.fallbackSource).map((sentence) => groundingTokenSequence(sentence)),\n )\n ) return context;\n const fallbackContext: GroundingContext = {\n source: context.fallbackSource,\n assertionSource: context.fallbackAssertionSource,\n allowRoleNormalization: false,\n };\n return isGroundedCandidate(\n candidate,\n fallbackContext.source,\n fallbackContext.assertionSource,\n false,\n fallbackContext.allowRoleNormalization,\n )\n ? fallbackContext\n : context;\n}\n\nfunction isGroundedCandidate(\n candidate: string,\n source: string,\n assertionSource: string | undefined,\n includeInterrogativeSource = false,\n allowRoleNormalization = false,\n): boolean {\n const allowInterrogativeSource = includeInterrogativeSource\n || (\n assertionSource !== undefined\n && normalizeForExactMatch(assertionSource) !== normalizeForExactMatch(source)\n );\n const sourceGrounded = isSourceGrounded(candidate, source, allowInterrogativeSource);\n const roleGrounded = allowRoleNormalization && hasRoleNormalizedGrounding(candidate, source);\n const candidateTokens = groundingTokenSequence(candidate);\n const roleNormalizedCandidate = allowRoleNormalization\n && GROUNDING_ROLE_SUBJECT_TOKENS.has(\n (candidateTokens[0] ?? \"\").replace(/^[\\u0000\\u0001]/u, \"\"),\n );\n if (roleNormalizedCandidate && !roleGrounded) return false;\n if (!sourceGrounded && !roleGrounded) return false;\n if (assertionSource === undefined) return true;\n const clauses = candidateClauses(candidate);\n const requirePredicateSupport = !includeInterrogativeSource\n && assertionSource !== undefined\n && normalizeForExactMatch(assertionSource) !== normalizeForExactMatch(source);\n return clauses.length > 0\n && (\n clauses.every((clause) =>\n hasGroundingAnchor(clause, assertionSource, includeInterrogativeSource, requirePredicateSupport))\n || hasAnswerSupport(candidate, source, assertionSource)\n );\n}\n\nfunction buildFactSupportSource(\n source: string,\n supportingSentences: ReadonlyArray<string>,\n): string {\n const sentences = sourceSentences(source);\n const selectedIndices = new Set<number>();\n for (const supportingSentence of supportingSentences) {\n const supportIndex = sentences.indexOf(supportingSentence);\n if (supportIndex < 0) continue;\n let endIndex = supportIndex;\n while (\n endIndex < sentences.length - 1\n && sentences[endIndex]!.trimEnd().endsWith(\";\")\n && /^(?:its|their|this|that|these|those)\\b/iu.test(\n sentences[endIndex + 1]!.trimStart(),\n )\n ) {\n endIndex += 1;\n }\n for (let index = supportIndex; index <= endIndex; index += 1) {\n selectedIndices.add(index);\n }\n }\n return [...selectedIndices]\n .sort((left, right) => left - right)\n .map((index) => sentences[index]!)\n .join(\" \");\n}\nfunction buildProcedureSupportSource(\n fact: ExtractionResult[\"facts\"][number],\n source: string,\n factSupportSource: string,\n): string {\n if (fact.category !== \"procedure\" || fact.procedureSteps === undefined) return factSupportSource;\n const parentSupportSentences = new Set(\n sourceSentences(factSupportSource).map((sentence) => normalizeForExactMatch(sentence)),\n );\n const parentGroundedSteps = fact.procedureSteps.filter((step) =>\n isGroundedCandidate(step.intent, factSupportSource, undefined, false),\n );\n if (parentGroundedSteps.length === 0) return factSupportSource;\n return sourceSentences(source)\n .filter((sentence) => {\n if (parentSupportSentences.has(normalizeForExactMatch(sentence))) return true;\n const sentenceTokens = tokenize(sentence);\n return parentGroundedSteps.some((step) =>\n [...tokenize(step.intent)].some((token) =>\n [...sentenceTokens].some((sourceToken) => areGroundingTokensCompatible(token, sourceToken)),\n ),\n );\n })\n .join(\" \");\n}\nfunction filterGroundedFact(\n fact: ExtractionResult[\"facts\"][number],\n source: string,\n assertionSource: string | undefined,\n roleAssertionSources: ExtractionGroundingRoleSources | undefined,\n eventTimeNormalizer: ((eventTime: string) => string) | undefined,\n spanMode: \"off\" | \"shadow\" | \"on\" = \"off\",\n): ExtractionResult[\"facts\"][number] | undefined {\n // Span-materialized content (issue #2333) is \"frame: verbatim slice\". The\n // frame is generated deixis, so full-content gating would drop a verbatim\n // fact. Only on-mode facts whose content is that materialized shape may\n // fall back to the slice. Shadow stays zero-diff with off.\n const quote = typeof fact.quote === \"string\" ? fact.quote : \"\";\n const materializedPrefix = quote.length > 0 && fact.content.endsWith(quote) && fact.content !== quote\n ? fact.content.slice(0, fact.content.length - quote.length)\n : \"\";\n const embeddedQuote =\n spanMode === \"on\"\n && quote.trim().length > 0\n && (materializedPrefix.endsWith(\": \") || /[:—-]\\s$/.test(materializedPrefix))\n ? quote\n : undefined;\n const contentContext = selectGroundingContext(\n fact.content,\n resolveGroundingContext(fact.content, source, assertionSource, roleAssertionSources),\n );\n let gateContent = fact.content;\n let factContext = contentContext;\n if (\n !isGroundedCandidate(\n fact.content,\n contentContext.source,\n contentContext.assertionSource,\n false,\n contentContext.allowRoleNormalization,\n )\n ) {\n if (embeddedQuote === undefined) return undefined;\n gateContent = embeddedQuote;\n factContext = selectGroundingContext(\n gateContent,\n resolveGroundingContext(gateContent, source, assertionSource, roleAssertionSources),\n );\n if (!isGroundedCandidate(\n gateContent,\n factContext.source,\n factContext.assertionSource,\n false,\n factContext.allowRoleNormalization,\n )) return undefined;\n }\n const factEventTime = fact.eventTime;\n const groundedFactEventTime = factEventTime === undefined\n ? undefined\n : eventTimeNormalizer?.(factEventTime) ?? factEventTime;\n const factSupportingSentences = sourceSentences(factContext.assertionSource ?? factContext.source).filter(\n (sentence) =>\n isGroundedCandidate(\n gateContent,\n sentence,\n undefined,\n false,\n factContext.allowRoleNormalization,\n ),\n );\n const factSupportingSource = factEventTime === undefined\n ? factSupportingSentences[0]\n : factSupportingSentences.find((sentence) =>\n isGroundedCandidate(\n groundedFactEventTime ?? factEventTime,\n sentence,\n undefined,\n false,\n factContext.allowRoleNormalization,\n ),\n ) ?? factSupportingSentences[0];\n const eventTimeSource = factSupportingSource ?? factContext.source;\n const eventTimeAssertionSource = factSupportingSource === undefined\n ? factContext.assertionSource\n : undefined;\n\n const factSupportSource = buildFactSupportSource(\n factContext.assertionSource ?? factContext.source,\n factSupportingSentences,\n );\n const groundedAttributes = fact.structuredAttributes\n ? Object.fromEntries(\n Object.entries(fact.structuredAttributes)\n .filter(([key, value]) =>\n isGroundedCandidate(\n `${key}: ${value}`,\n factSupportSource,\n undefined,\n false,\n factContext.allowRoleNormalization,\n ),\n ),\n )\n : undefined;\n const procedureGroundingSource = buildProcedureSupportSource(\n fact,\n factContext.assertionSource ?? factContext.source,\n factSupportSource,\n );\n const groundedProcedureSteps = fact.procedureSteps\n ? fact.procedureSteps.flatMap((step) => {\n if (!isGroundedCandidate(step.intent, procedureGroundingSource, undefined, false)) return [];\n const expectedOutcome = step.expectedOutcome\n && isGroundedCandidate(step.expectedOutcome, procedureGroundingSource, undefined, false)\n ? step.expectedOutcome\n : undefined;\n const toolCall = step.toolCall\n && isGroundedCandidate(step.toolCall.signature, procedureGroundingSource, undefined, false)\n ? step.toolCall\n : undefined;\n const {\n expectedOutcome: _expectedOutcome,\n toolCall: _toolCall,\n ...stepWithoutOptionalFields\n } = step;\n return [{\n ...stepWithoutOptionalFields,\n ...(expectedOutcome !== undefined ? { expectedOutcome } : {}),\n ...(toolCall !== undefined ? { toolCall } : {}),\n }];\n })\n : undefined;\n const groundedReasoningTrace = fact.reasoningTrace\n && fact.reasoningTrace.steps.length > 0\n && isGroundedCandidate(\n fact.reasoningTrace.finalAnswer,\n factContext.source,\n factContext.assertionSource,\n false,\n factContext.allowRoleNormalization,\n )\n && fact.reasoningTrace.steps.every((step) =>\n isGroundedCandidate(\n step.description,\n factContext.source,\n factContext.assertionSource,\n false,\n factContext.allowRoleNormalization,\n ),\n )\n ? {\n steps: fact.reasoningTrace.steps,\n finalAnswer: fact.reasoningTrace.finalAnswer,\n ...(fact.reasoningTrace.observedOutcome\n && isGroundedCandidate(\n fact.reasoningTrace.observedOutcome,\n factContext.source,\n factContext.assertionSource,\n false,\n factContext.allowRoleNormalization,\n )\n ? { observedOutcome: fact.reasoningTrace.observedOutcome }\n : {}),\n }\n : undefined;\n const groundedEventTime = groundedFactEventTime\n && isGroundedCandidate(groundedFactEventTime, eventTimeSource, eventTimeAssertionSource)\n ? factEventTime\n : undefined;\n const groundedEntityRef = fact.entityRef !== undefined\n && isGroundedEntityName(fact.entityRef, factSupportSource)\n ? fact.entityRef\n : undefined;\n const {\n entityRef: _entityRef,\n structuredAttributes: _structuredAttributes,\n procedureSteps: _procedureSteps,\n reasoningTrace: _reasoningTrace,\n eventTime: _eventTime,\n ...factWithoutGroundingFields\n } = fact;\n return {\n ...factWithoutGroundingFields,\n ...(groundedEntityRef !== undefined ? { entityRef: groundedEntityRef } : {}),\n ...(groundedAttributes && Object.keys(groundedAttributes).length > 0\n ? { structuredAttributes: groundedAttributes }\n : {}),\n ...(groundedProcedureSteps && groundedProcedureSteps.length > 0\n ? { procedureSteps: groundedProcedureSteps }\n : {}),\n ...(groundedReasoningTrace !== undefined ? { reasoningTrace: groundedReasoningTrace } : {}),\n ...(groundedEventTime !== undefined ? { eventTime: groundedEventTime } : {}),\n };\n}\n\nfunction filterGroundedEntity(\n entity: ExtractionResult[\"entities\"][number],\n source: string,\n assertionSource: string | undefined,\n): ExtractionResult[\"entities\"][number] | undefined {\n if (!isGroundedEntityName(entity.name, source)) return undefined;\n const entitySource = buildEntitySupportSource(entity.name, source);\n const entityAssertionSource = assertionSource === undefined\n ? undefined\n : buildEntitySupportSource(entity.name, assertionSource);\n const facts = entity.facts.filter((fact) =>\n isGroundedCandidate(fact, entitySource, entityAssertionSource),\n );\n const structuredSections = entity.structuredSections\n ?.flatMap((section) => {\n const groundedFacts = section.facts.filter((fact) =>\n isGroundedCandidate(fact, entitySource, entityAssertionSource),\n );\n return groundedFacts.length > 0\n ? [{ ...section, facts: groundedFacts }]\n : [];\n });\n if (facts.length === 0 && (structuredSections === undefined || structuredSections.length === 0)) {\n return undefined;\n }\n const { structuredSections: _structuredSections, ...entityWithoutSections } = entity;\n return {\n ...entityWithoutSections,\n facts,\n ...(structuredSections && structuredSections.length > 0 ? { structuredSections } : {}),\n };\n}\n\nfunction normalizedEntitySourceText(name: string): string {\n return normalizedEntityIdentifierTokens(name).join(\" \");\n}\n\nfunction isGroundedRelationship(\n relationship: NonNullable<ExtractionResult[\"relationships\"]>[number],\n source: string,\n assertionSource: string | undefined,\n): boolean {\n const sourceName = normalizedEntitySourceText(relationship.source);\n const targetName = normalizedEntitySourceText(relationship.target);\n const labelTokens = tokenize(relationship.label);\n if (sourceName.length === 0 || targetName.length === 0 || labelTokens.size === 0) return false;\n const relationText = `${sourceName} ${relationship.label} ${targetName}`;\n const hasCoherentSourceSpan = sourceSentences(source).some((sentence) => {\n if (isInterrogativeSourceSentence(sentence)) return false;\n return groundedTokenScore(relationText, sentence) === 1\n && !hasContradictoryPolarity(relationText, sentence);\n });\n return hasCoherentSourceSpan\n && isGroundedCandidate(relationText, source, assertionSource);\n}\nconst GROUNDING_TEMPORAL_WORDS = new Set([\n \"today\",\n \"yesterday\",\n \"tomorrow\",\n \"now\",\n \"recently\",\n \"earlier\",\n \"later\",\n \"soon\",\n \"morning\",\n \"afternoon\",\n \"evening\",\n \"tonight\",\n \"night\",\n \"noon\",\n \"midnight\",\n \"monday\",\n \"tuesday\",\n \"wednesday\",\n \"thursday\",\n \"friday\",\n \"saturday\",\n \"sunday\",\n \"january\",\n \"february\",\n \"march\",\n \"april\",\n \"may\",\n \"june\",\n \"july\",\n \"august\",\n \"september\",\n \"october\",\n \"november\",\n \"december\",\n \"q1\",\n \"q2\",\n \"q3\",\n \"q4\",\n]);\nconst GROUNDING_TEMPORAL_CLOCK_PATTERN = /\\b\\d{1,2}:\\d{2}(?:\\s*[ap]\\.?m\\.?)?\\b/iu;\nconst GROUNDING_TEMPORAL_DURATION_PATTERN = new RegExp(\n \"\\\\b(?:\\\\d+|one|two|three|four|five|six|seven|eight|nine|ten)\\\\s+\"\n + \"(?:seconds?|minutes?|hours?|days?|weeks?|months?|quarters?|years?)\\\\b\",\n \"iu\",\n);\n\nfunction isWhenQuestion(question: string): boolean {\n return /^(?:when|what\\s+(?:time|date)|which\\s+day)\\b/iu.test(question.trim());\n}\nfunction isWhyQuestion(question: string): boolean {\n return /^why\\b/iu.test(question.trim());\n}\n\nfunction hasCausalAnswerEvidence(question: string, sentence: string): boolean {\n if (!isWhyQuestion(question)) return true;\n return /\\b(?:because|since|due\\s+to|owing\\s+to|thanks\\s+to|therefore|thus|hence|so)\\b/iu.test(\n sentence,\n );\n}\n\nfunction hasTemporalAnswerEvidence(question: string, sentence: string): boolean {\n if (!isWhenQuestion(question)) return true;\n return groundingLexemes(sentence).some(({ token }) =>\n GROUNDING_TEMPORAL_WORDS.has(token) || /^(?:19|20)\\d{2}$/u.test(token),\n )\n || GROUNDING_TEMPORAL_CLOCK_PATTERN.test(sentence)\n || GROUNDING_TEMPORAL_DURATION_PATTERN.test(sentence);\n}\n\n\nfunction isUnknownAnswerSentence(sentence: string): boolean {\n return /\\b(?:unknown|unclear|unsure|unresolved|unanswered|not\\s+(?:known|sure|available)|don't\\s+know|do\\s+not\\s+know|no\\s+idea|pending)\\b/iu\n .test(sentence);\n}\n\nfunction isYesNoAnswer(sentence: string): boolean {\n return /^(?:yes|no)(?:[.!?]|,\\s*(?:absolutely|definitely|indeed|exactly|correct|of\\s+course|use\\s+that|do\\s+that)[.!?]?)?$/iu\n .test(sentence.trim());\n}\n\nconst GROUNDING_WH_OBJECT_QUESTION_PATTERN = new RegExp(\n \"^(?:(?:what|which)(?:\\\\s+.+?)?|who|whom)\\\\s+\"\n + \"(?:is|are|was|were|do|does|did|can|could|will|would|should|has|have|had)\\\\s+\"\n + \"(.+?)\\\\??$\",\n \"iu\",\n);\n\nfunction hasWhAnswerRoleAlignment(question: string, sentence: string): boolean {\n const normalizedQuestion = question.trim();\n const objectQuestionMatch = GROUNDING_WH_OBJECT_QUESTION_PATTERN.exec(normalizedQuestion);\n const sourceTokens = normalizedGroundingTokenSequence(sentence);\n if (objectQuestionMatch !== null) {\n const questionBodyLexemes = groundingLexemes(objectQuestionMatch[1] ?? \"\");\n const predicateIndex = questionBodyLexemes.findIndex(({ isPredicate }) => isPredicate);\n if (predicateIndex < 1) return false;\n const subjectTokens = groundingTokenSequence(\n questionBodyLexemes.slice(0, predicateIndex).map(({ surface }) => surface).join(\" \"),\n );\n const predicateTokens = groundingTokenSequence(\n questionBodyLexemes.slice(predicateIndex).map(({ surface }) => surface).join(\" \"),\n );\n if (subjectTokens.length === 0 || predicateTokens.length === 0) return false;\n let sourceIndex = 0;\n for (const token of [...subjectTokens, ...predicateTokens]) {\n const matchedIndex = sourceTokens.findIndex(\n (sourceToken, index) =>\n index >= sourceIndex && areGroundingTokensCompatible(token, sourceToken),\n );\n if (matchedIndex === -1) return false;\n sourceIndex = matchedIndex + 1;\n }\n return true;\n }\n\n const subjectQuestionMatch = /^(?:who|what)\\s+([^\\s?]+)\\s+(.+?)\\??$/iu.exec(normalizedQuestion);\n if (subjectQuestionMatch === null) return true;\n const predicateTokens = groundingTokenSequence(subjectQuestionMatch[1] ?? \"\");\n const objectTokens = groundingTokenSequence(subjectQuestionMatch[2] ?? \"\");\n if (predicateTokens.length === 0 || objectTokens.length === 0) return true;\n const predicateStart = sourceTokens.findIndex((sourceToken) =>\n areGroundingTokensCompatible(predicateTokens[0]!, sourceToken));\n if (predicateStart === -1) return false;\n let sourceIndex = predicateStart + predicateTokens.length;\n for (const objectToken of objectTokens) {\n const objectIndex = sourceTokens.findIndex(\n (sourceToken, index) =>\n index >= sourceIndex && areGroundingTokensCompatible(objectToken, sourceToken),\n );\n if (objectIndex === -1) return false;\n sourceIndex = objectIndex + 1;\n }\n return true;\n}\n\nfunction isQuestionAnsweredBySource(\n question: string,\n source: string,\n assertionSource: string | undefined,\n): boolean {\n const questionTokens = tokenize(question);\n if (questionTokens.size === 0) return false;\n const isYesNoQuestion = /^(?:is|are|am|was|were|do|does|did|can|could|will|would|should|has|have|had)\\b/iu\n .test(question.trim());\n const assertedSentences = new Set(sourceSentences(assertionSource ?? source).map((sentence) => normalizeForExactMatch(sentence)));\n const sentences = sourceSentences(source);\n return sentences.some((sentence, index) => {\n if (!assertedSentences.has(normalizeForExactMatch(sentence))) return false;\n if (isInterrogativeSourceSentence(sentence)) return false;\n if (isYesNoAnswer(sentence)) {\n const precedingSentence = sentences[index - 1];\n return precedingSentence !== undefined\n && isInterrogativeSourceSentence(precedingSentence)\n && groundedTokenScore(question, precedingSentence) === 1;\n }\n if (isUnknownAnswerSentence(sentence)) return false;\n const score = groundedTokenScore(question, sentence, false);\n if (score !== 1) return false;\n const sentenceTokens = tokenize(sentence);\n const hasAnswerToken = [...sentenceTokens].some((token) => !questionTokens.has(token));\n return (isYesNoQuestion || hasAnswerToken)\n && hasTemporalAnswerEvidence(question, sentence)\n && hasCausalAnswerEvidence(question, sentence)\n && hasWhAnswerRoleAlignment(question, sentence);\n });\n}\n\nfunction groundQuestion(\n question: ExtractionResult[\"questions\"][number],\n source: string,\n assertionSource: string | undefined,\n): ExtractionResult[\"questions\"][number] | undefined {\n if (isQuestionAnsweredBySource(question.question, source, assertionSource)) return undefined;\n if (!isGroundedCandidate(question.question, source, assertionSource, true)) return undefined;\n const normalizedContext = question.context.trim();\n if (\n normalizedContext.length > 0\n && !isGroundedCandidate(normalizedContext, assertionSource ?? source, undefined, false)\n ) {\n return { ...question, context: \"\" };\n }\n return question;\n}\n\nfunction isRoleGroundedCandidate(\n candidate: string,\n source: string,\n assertionSource: string | undefined,\n roleAssertionSources: ExtractionGroundingRoleSources | undefined,\n): boolean {\n const context = selectGroundingContext(\n candidate,\n resolveGroundingContext(candidate, source, assertionSource, roleAssertionSources),\n );\n return isGroundedCandidate(\n candidate,\n context.source,\n context.assertionSource,\n false,\n context.allowRoleNormalization,\n );\n}\n\nexport function filterExtractionResultBySource(\n result: ExtractionResult,\n source: string,\n assertionSource?: string,\n roleAssertionSources?: ExtractionGroundingRoleSources,\n eventTimeNormalizer?: (eventTime: string) => string,\n spanMode: \"off\" | \"shadow\" | \"on\" = \"off\",\n): ExtractionResult {\n if (source.trim().length === 0) {\n return {\n ...result,\n facts: [],\n profileUpdates: [],\n entities: [],\n questions: [],\n ...(result.relationships !== undefined ? { relationships: [] } : {}),\n identityReflection: undefined,\n };\n }\n\n const facts = result.facts.flatMap((fact) => {\n const grounded = filterGroundedFact(\n fact,\n source,\n assertionSource,\n roleAssertionSources,\n eventTimeNormalizer,\n spanMode,\n );\n return grounded === undefined ? [] : [grounded];\n });\n const profileUpdates = result.profileUpdates.filter((update) =>\n isRoleGroundedCandidate(update, source, assertionSource, roleAssertionSources),\n );\n const entities = result.entities.flatMap((entity) => {\n const grounded = filterGroundedEntity(entity, source, assertionSource);\n return grounded === undefined ? [] : [grounded];\n });\n const questions = result.questions.flatMap((question) => {\n const grounded = groundQuestion(question, source, assertionSource);\n return grounded === undefined ? [] : [grounded];\n });\n const relationships = result.relationships?.filter((relationship) =>\n isGroundedRelationship(relationship, source, assertionSource),\n );\n const identityReflection = result.identityReflection\n && isRoleGroundedCandidate(\n result.identityReflection,\n source,\n assertionSource,\n roleAssertionSources,\n )\n ? result.identityReflection\n : undefined;\n\n return {\n ...result,\n facts,\n profileUpdates,\n entities,\n questions,\n ...(result.relationships !== undefined ? { relationships } : {}),\n ...(identityReflection !== undefined ? { identityReflection } : { identityReflection: undefined }),\n };\n}\n"],"mappings":"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","names":["predicateTokens","sourceIndex"]}
@@ -1,64 +0,0 @@
1
- // src/converge-config.ts
2
- var CONVERGE_CONFLICT_POLICIES = [
3
- "newest-wins",
4
- "manual"
5
- ];
6
- var DEFAULT_CONVERGE_CONFLICT_POLICY = "newest-wins";
7
- var DEFAULT_CONVERGE_PEER_REQUEST_TIMEOUT_MS = 3e4;
8
- var MAX_CONVERGE_PEER_REQUEST_TIMEOUT_MS = 36e5;
9
- function normalizeConvergePeerRequestTimeoutMs(value, label) {
10
- if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) {
11
- throw new Error(`${label} must be a positive integer number of milliseconds; got ${JSON.stringify(value)}`);
12
- }
13
- return Math.min(value, MAX_CONVERGE_PEER_REQUEST_TIMEOUT_MS);
14
- }
15
- function envConvergePeerRequestTimeoutMs() {
16
- const raw = process.env.REMNIC_CONVERGE_PEER_TIMEOUT_MS;
17
- if (raw === void 0 || raw.trim() === "") return DEFAULT_CONVERGE_PEER_REQUEST_TIMEOUT_MS;
18
- return normalizeConvergePeerRequestTimeoutMs(Number(raw), "REMNIC_CONVERGE_PEER_TIMEOUT_MS");
19
- }
20
- function parsePeerRequestTimeoutMs(value, label) {
21
- if (value === void 0) return DEFAULT_CONVERGE_PEER_REQUEST_TIMEOUT_MS;
22
- return normalizeConvergePeerRequestTimeoutMs(value, label);
23
- }
24
- function parseConvergeConfig(block) {
25
- if (block === void 0) {
26
- return { conflictPolicy: DEFAULT_CONVERGE_CONFLICT_POLICY };
27
- }
28
- if (block === null || typeof block !== "object" || Array.isArray(block)) {
29
- throw new Error("converge must be a plain object");
30
- }
31
- const prototype = Object.getPrototypeOf(block);
32
- if (prototype !== Object.prototype && prototype !== null) {
33
- throw new Error("converge must be a plain object");
34
- }
35
- const { conflictPolicy: rawConflictPolicy, peerRequestTimeoutMs, ...unknown } = block;
36
- let conflictPolicy = rawConflictPolicy;
37
- const unknownKey = Object.keys(unknown)[0];
38
- if (unknownKey !== void 0) {
39
- throw new Error(`converge contains unknown key ${JSON.stringify(unknownKey)}`);
40
- }
41
- if (conflictPolicy === void 0) {
42
- conflictPolicy = DEFAULT_CONVERGE_CONFLICT_POLICY;
43
- }
44
- if (typeof conflictPolicy === "string" && CONVERGE_CONFLICT_POLICIES.includes(conflictPolicy)) {
45
- return {
46
- conflictPolicy,
47
- ...peerRequestTimeoutMs !== void 0 ? { peerRequestTimeoutMs: parsePeerRequestTimeoutMs(peerRequestTimeoutMs, "converge.peerRequestTimeoutMs") } : {}
48
- };
49
- }
50
- throw new Error(
51
- `converge.conflictPolicy must be one of ${CONVERGE_CONFLICT_POLICIES.join(", ")}; got ${JSON.stringify(conflictPolicy)}`
52
- );
53
- }
54
-
55
- export {
56
- CONVERGE_CONFLICT_POLICIES,
57
- DEFAULT_CONVERGE_CONFLICT_POLICY,
58
- DEFAULT_CONVERGE_PEER_REQUEST_TIMEOUT_MS,
59
- MAX_CONVERGE_PEER_REQUEST_TIMEOUT_MS,
60
- normalizeConvergePeerRequestTimeoutMs,
61
- envConvergePeerRequestTimeoutMs,
62
- parseConvergeConfig
63
- };
64
- //# sourceMappingURL=chunk-6MINUTGJ.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/converge-config.ts"],"sourcesContent":["import type { ConvergeConfig, ConvergeConflictPolicy } from \"./types.js\";\n\nexport const CONVERGE_CONFLICT_POLICIES = [\n \"newest-wins\",\n \"manual\",\n] as const satisfies readonly ConvergeConflictPolicy[];\n\nexport const DEFAULT_CONVERGE_CONFLICT_POLICY: ConvergeConflictPolicy = \"newest-wins\";\n\n/** Default per-request peer HTTP timeout. Boot-scale corpora (100k+ files in one\n * namespace) can take well over 30s to serve a manifest snapshot. */\nexport const DEFAULT_CONVERGE_PEER_REQUEST_TIMEOUT_MS = 30_000;\n/** Ceiling for the configured timeout — a peer that has not answered in an hour\n * is unreachable, not slow. */\nexport const MAX_CONVERGE_PEER_REQUEST_TIMEOUT_MS = 3_600_000;\n/**\n * ONE normalization policy for every override source (config JSON, env, CLI\n * flag, programmatic options): malformed values are rejected, valid values\n * clamped to the one-hour ceiling. Returns the clamped ms value.\n */\nexport function normalizeConvergePeerRequestTimeoutMs(value: unknown, label: string): number {\n if (typeof value !== \"number\" || !Number.isInteger(value) || value <= 0) {\n throw new Error(`${label} must be a positive integer number of milliseconds; got ${JSON.stringify(value)}`);\n }\n return Math.min(value, MAX_CONVERGE_PEER_REQUEST_TIMEOUT_MS);\n}\n\n/** Env override, evaluated lazily so tests control time. Junk is rejected. */\nexport function envConvergePeerRequestTimeoutMs(): number {\n const raw = process.env.REMNIC_CONVERGE_PEER_TIMEOUT_MS;\n if (raw === undefined || raw.trim() === \"\") return DEFAULT_CONVERGE_PEER_REQUEST_TIMEOUT_MS;\n return normalizeConvergePeerRequestTimeoutMs(Number(raw), \"REMNIC_CONVERGE_PEER_TIMEOUT_MS\");\n}\n\n/** Config-block value: absent -> default, present -> normalized. */\nfunction parsePeerRequestTimeoutMs(value: unknown, label: string): number {\n if (value === undefined) return DEFAULT_CONVERGE_PEER_REQUEST_TIMEOUT_MS;\n return normalizeConvergePeerRequestTimeoutMs(value, label);\n}\n\nexport function parseConvergeConfig(block: unknown): ConvergeConfig {\n if (block === undefined) {\n return { conflictPolicy: DEFAULT_CONVERGE_CONFLICT_POLICY };\n }\n if (block === null || typeof block !== \"object\" || Array.isArray(block)) {\n throw new Error(\"converge must be a plain object\");\n }\n const prototype = Object.getPrototypeOf(block);\n if (prototype !== Object.prototype && prototype !== null) {\n throw new Error(\"converge must be a plain object\");\n }\n const { conflictPolicy: rawConflictPolicy, peerRequestTimeoutMs, ...unknown } = block as Record<string, unknown>;\n let conflictPolicy: unknown = rawConflictPolicy;\n const unknownKey = Object.keys(unknown)[0];\n if (unknownKey !== undefined) {\n throw new Error(`converge contains unknown key ${JSON.stringify(unknownKey)}`);\n }\n if (conflictPolicy === undefined) {\n conflictPolicy = DEFAULT_CONVERGE_CONFLICT_POLICY;\n }\n if (\n typeof conflictPolicy === \"string\" &&\n CONVERGE_CONFLICT_POLICIES.includes(conflictPolicy as ConvergeConflictPolicy)\n ) {\n return {\n conflictPolicy: conflictPolicy as ConvergeConflictPolicy,\n ...(peerRequestTimeoutMs !== undefined\n ? { peerRequestTimeoutMs: parsePeerRequestTimeoutMs(peerRequestTimeoutMs, \"converge.peerRequestTimeoutMs\") }\n : {}),\n };\n }\n\n throw new Error(\n `converge.conflictPolicy must be one of ${CONVERGE_CONFLICT_POLICIES.join(\", \")}; got ${JSON.stringify(conflictPolicy)}`\n );\n}\n"],"mappings":";AAEO,IAAM,6BAA6B;AAAA,EACxC;AAAA,EACA;AACF;AAEO,IAAM,mCAA2D;AAIjE,IAAM,2CAA2C;AAGjD,IAAM,uCAAuC;AAM7C,SAAS,sCAAsC,OAAgB,OAAuB;AAC3F,MAAI,OAAO,UAAU,YAAY,CAAC,OAAO,UAAU,KAAK,KAAK,SAAS,GAAG;AACvE,UAAM,IAAI,MAAM,GAAG,KAAK,2DAA2D,KAAK,UAAU,KAAK,CAAC,EAAE;AAAA,EAC5G;AACA,SAAO,KAAK,IAAI,OAAO,oCAAoC;AAC7D;AAGO,SAAS,kCAA0C;AACxD,QAAM,MAAM,QAAQ,IAAI;AACxB,MAAI,QAAQ,UAAa,IAAI,KAAK,MAAM,GAAI,QAAO;AACnD,SAAO,sCAAsC,OAAO,GAAG,GAAG,iCAAiC;AAC7F;AAGA,SAAS,0BAA0B,OAAgB,OAAuB;AACxE,MAAI,UAAU,OAAW,QAAO;AAChC,SAAO,sCAAsC,OAAO,KAAK;AAC3D;AAEO,SAAS,oBAAoB,OAAgC;AAClE,MAAI,UAAU,QAAW;AACvB,WAAO,EAAE,gBAAgB,iCAAiC;AAAA,EAC5D;AACA,MAAI,UAAU,QAAQ,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAAG;AACvE,UAAM,IAAI,MAAM,iCAAiC;AAAA,EACnD;AACA,QAAM,YAAY,OAAO,eAAe,KAAK;AAC7C,MAAI,cAAc,OAAO,aAAa,cAAc,MAAM;AACxD,UAAM,IAAI,MAAM,iCAAiC;AAAA,EACnD;AACA,QAAM,EAAE,gBAAgB,mBAAmB,sBAAsB,GAAG,QAAQ,IAAI;AAChF,MAAI,iBAA0B;AAC9B,QAAM,aAAa,OAAO,KAAK,OAAO,EAAE,CAAC;AACzC,MAAI,eAAe,QAAW;AAC5B,UAAM,IAAI,MAAM,iCAAiC,KAAK,UAAU,UAAU,CAAC,EAAE;AAAA,EAC/E;AACA,MAAI,mBAAmB,QAAW;AAChC,qBAAiB;AAAA,EACnB;AACA,MACE,OAAO,mBAAmB,YAC1B,2BAA2B,SAAS,cAAwC,GAC5E;AACA,WAAO;AAAA,MACL;AAAA,MACA,GAAI,yBAAyB,SACzB,EAAE,sBAAsB,0BAA0B,sBAAsB,+BAA+B,EAAE,IACzG,CAAC;AAAA,IACP;AAAA,EACF;AAEA,QAAM,IAAI;AAAA,IACR,0CAA0C,2BAA2B,KAAK,IAAI,CAAC,SAAS,KAAK,UAAU,cAAc,CAAC;AAAA,EACxH;AACF;","names":[]}
@@ -1,9 +0,0 @@
1
- // src/utils/sleep.ts
2
- function sleep(ms) {
3
- return new Promise((resolve) => setTimeout(resolve, ms));
4
- }
5
-
6
- export {
7
- sleep
8
- };
9
- //# sourceMappingURL=chunk-7LEQREP2.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/utils/sleep.ts"],"sourcesContent":["/** Wait without cancellation; keep the timer referenced so awaited polling can finish. */\nexport function sleep(ms: number): Promise<void> {\n // Constructor form keeps this reachable utility compatible with ES2022 adapter type graphs.\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n"],"mappings":";AACO,SAAS,MAAM,IAA2B;AAE/C,SAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AACzD;","names":[]}