@remnic/core 9.27.0 → 9.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (515) hide show
  1. package/dist/access-admin-ops-surface.d.ts +13 -10
  2. package/dist/access-admin-ops-surface.js +46 -41
  3. package/dist/access-audit.js +2 -2
  4. package/dist/access-authorization-probe.d.ts +13 -10
  5. package/dist/access-authorization-probe.js +47 -42
  6. package/dist/access-boundary.d.ts +13 -10
  7. package/dist/access-boundary.js +46 -41
  8. package/dist/access-cli.js +105 -96
  9. package/dist/access-cli.js.map +1 -1
  10. package/dist/access-health-types.d.ts +10 -1
  11. package/dist/access-http-lcm-compaction.d.ts +13 -10
  12. package/dist/access-http.d.ts +13 -10
  13. package/dist/access-http.js +56 -51
  14. package/dist/access-identity-continuity-surface.d.ts +9 -8
  15. package/dist/access-identity-continuity-surface.js +46 -41
  16. package/dist/access-lcm-surface.d.ts +13 -10
  17. package/dist/access-lcm-surface.js +46 -41
  18. package/dist/access-mcp.d.ts +13 -10
  19. package/dist/access-mcp.js +51 -46
  20. package/dist/access-memory-search-fanout.d.ts +2 -2
  21. package/dist/access-memory-search-fanout.js +3 -3
  22. package/dist/{access-namespace-preflight-wRSZEO5V.d.ts → access-namespace-preflight-DCXBkDp0.d.ts} +1 -1
  23. package/dist/access-namespace-preflight.d.ts +3 -3
  24. package/dist/access-namespace-preflight.js +46 -41
  25. package/dist/access-observe-write-surface.d.ts +13 -10
  26. package/dist/access-observe-write-surface.js +46 -41
  27. package/dist/access-operations-batch.js +48 -43
  28. package/dist/access-operations.d.ts +16 -13
  29. package/dist/access-operations.js +50 -45
  30. package/dist/access-recall-concurrency.d.ts +13 -10
  31. package/dist/access-recall-concurrency.js +46 -41
  32. package/dist/access-recall-response.d.ts +13 -10
  33. package/dist/access-recall-response.js +46 -41
  34. package/dist/access-recall-surface.d.ts +13 -10
  35. package/dist/access-recall-surface.js +46 -41
  36. package/dist/access-schema.d.ts +80 -80
  37. package/dist/access-schema.js +3 -3
  38. package/dist/{access-service-B4-Fu9x2.d.ts → access-service-DvPW_M5j.d.ts} +12 -8
  39. package/dist/access-service.d.ts +13 -10
  40. package/dist/access-service.js +46 -41
  41. package/dist/access-surface-catalog.d.ts +13 -10
  42. package/dist/access-wearables-meetings-surface.d.ts +4 -3
  43. package/dist/action-confidence.d.ts +1 -1
  44. package/dist/active-memory-bridge.d.ts +1 -1
  45. package/dist/active-memory-bridge.js +3 -3
  46. package/dist/active-recall.d.ts +1 -1
  47. package/dist/active-recall.js +4 -2
  48. package/dist/active-recall.js.map +1 -1
  49. package/dist/adapters/index.js +4 -4
  50. package/dist/adapters/registry.js +2 -2
  51. package/dist/behavior-learner.d.ts +1 -1
  52. package/dist/behavior-signals.d.ts +1 -1
  53. package/dist/bootstrap.d.ts +9 -8
  54. package/dist/briefing.d.ts +3 -2
  55. package/dist/briefing.js +14 -12
  56. package/dist/buffer-surprise-report.d.ts +1 -1
  57. package/dist/buffer.d.ts +3 -2
  58. package/dist/buffer.js +2 -2
  59. package/dist/bulk-import/index.d.ts +3 -3
  60. package/dist/calibration.d.ts +1 -1
  61. package/dist/capabilities.d.ts +3 -2
  62. package/dist/capabilities.js +1 -1
  63. package/dist/{capsule-crypto-YO5QJ6L3.js → capsule-crypto-GWVG7LGC.js} +2 -2
  64. package/dist/{catalog-BLLxZ5L5.d.ts → catalog-BIVgftWu.d.ts} +1 -1
  65. package/dist/causal-behavior.d.ts +1 -1
  66. package/dist/causal-consolidation.d.ts +1 -1
  67. package/dist/causal-consolidation.js +15 -13
  68. package/dist/causal-consolidation.js.map +1 -1
  69. package/dist/causal-trajectory-graph.d.ts +1 -1
  70. package/dist/{chunk-CI26JDZA.js → chunk-2HNUMF5V.js} +6 -4
  71. package/dist/{chunk-CI26JDZA.js.map → chunk-2HNUMF5V.js.map} +1 -1
  72. package/dist/{chunk-NUWMZIYZ.js → chunk-2XC73SHY.js} +61 -43
  73. package/dist/chunk-2XC73SHY.js.map +1 -0
  74. package/dist/{chunk-RDQGLJRR.js → chunk-2XRE6FLM.js} +2 -1
  75. package/dist/{chunk-RDQGLJRR.js.map → chunk-2XRE6FLM.js.map} +1 -1
  76. package/dist/{chunk-2H7OEVPO.js → chunk-3GD2HFR6.js} +2 -2
  77. package/dist/{chunk-4TFIRMTE.js → chunk-4A6YGWQN.js} +2 -2
  78. package/dist/{chunk-JDOJZTFF.js → chunk-4PBVXX7L.js} +2 -2
  79. package/dist/{chunk-IKMAO55B.js → chunk-55MDBZLC.js} +2 -2
  80. package/dist/{chunk-VDX2J7OX.js → chunk-5W7CTZ2E.js} +4 -4
  81. package/dist/{chunk-B7GROTXD.js → chunk-6LKEUCEM.js} +2 -2
  82. package/dist/{chunk-2AJ72VVS.js → chunk-7BZOBA5J.js} +3 -3
  83. package/dist/{chunk-44DUJETW.js → chunk-7HXCF4RE.js} +2 -2
  84. package/dist/{chunk-X3SQYAPP.js → chunk-ACXPX4AG.js} +2 -2
  85. package/dist/{chunk-AJ7QCSIS.js → chunk-ALSGMEJR.js} +5 -5
  86. package/dist/{chunk-JGUXPJUQ.js → chunk-AS7YMSL6.js} +2 -2
  87. package/dist/{chunk-77CNV7DY.js → chunk-BLAKS3CP.js} +4 -4
  88. package/dist/{chunk-5BRT4Z2I.js → chunk-CMRQ34J5.js} +2 -2
  89. package/dist/{chunk-HEXSNYJD.js → chunk-CSMCNOPH.js} +8 -8
  90. package/dist/chunk-CVILPI77.js +432 -0
  91. package/dist/chunk-CVILPI77.js.map +1 -0
  92. package/dist/{chunk-SK3EYPKC.js → chunk-D2ANTDGO.js} +3 -3
  93. package/dist/{chunk-JCVQV6QX.js → chunk-D3LMYTBV.js} +7 -7
  94. package/dist/{chunk-GJJBPI6I.js → chunk-DRBXHRXE.js} +7 -3
  95. package/dist/chunk-DRBXHRXE.js.map +1 -0
  96. package/dist/{chunk-XY7QPJDA.js → chunk-E6EE5B67.js} +2 -2
  97. package/dist/{chunk-LLISELSY.js → chunk-EP5BVCRI.js} +2 -2
  98. package/dist/{chunk-PTN6UAUA.js → chunk-ES36HTSC.js} +4 -4
  99. package/dist/{chunk-WEAO45M4.js → chunk-ESBQWC3U.js} +4 -4
  100. package/dist/{chunk-EUSLKI4X.js → chunk-EVX44I7C.js} +5 -5
  101. package/dist/{chunk-CIQXI47W.js → chunk-FCDWWCLX.js} +1195 -271
  102. package/dist/chunk-FCDWWCLX.js.map +1 -0
  103. package/dist/{chunk-X6ROIHFE.js → chunk-G5R3D5UP.js} +2 -2
  104. package/dist/{chunk-MG6MNSP4.js → chunk-G6LBWZRF.js} +7 -7
  105. package/dist/{chunk-TKBDJTXG.js → chunk-GBJ4RDFR.js} +94 -20
  106. package/dist/chunk-GBJ4RDFR.js.map +1 -0
  107. package/dist/{chunk-FRVTCCGD.js → chunk-GGUBDXRR.js} +2 -2
  108. package/dist/{chunk-QH6CS6XJ.js → chunk-H24WNPA2.js} +2 -2
  109. package/dist/{chunk-V25OWXAC.js → chunk-HUHX2OCX.js} +1 -1
  110. package/dist/chunk-HUHX2OCX.js.map +1 -0
  111. package/dist/{chunk-TGQ2NTWH.js → chunk-IJ6WHMFB.js} +16 -2
  112. package/dist/{chunk-TGQ2NTWH.js.map → chunk-IJ6WHMFB.js.map} +1 -1
  113. package/dist/{chunk-EOLC6EXV.js → chunk-IMA2EWLV.js} +24 -3
  114. package/dist/chunk-IMA2EWLV.js.map +1 -0
  115. package/dist/{chunk-MQVINOJQ.js → chunk-IYZ5K7MU.js} +3 -3
  116. package/dist/{chunk-RPA2RX5P.js → chunk-JDZRYH2N.js} +2 -2
  117. package/dist/{chunk-M5EPMNS4.js → chunk-K5GB36ME.js} +2 -2
  118. package/dist/{chunk-UT3OQPFA.js → chunk-KUJQHXPH.js} +2 -2
  119. package/dist/{chunk-7RZJWZ46.js → chunk-LEPOP46W.js} +5 -5
  120. package/dist/{chunk-EYJSW2RV.js → chunk-NBDCZWP4.js} +4 -4
  121. package/dist/{chunk-XKGPIWGI.js → chunk-OFHFH655.js} +6 -6
  122. package/dist/{chunk-FGBJBYWP.js → chunk-OVRQLAYR.js} +3 -3
  123. package/dist/{chunk-BXLOS5AJ.js → chunk-OWHERGF2.js} +2 -2
  124. package/dist/chunk-P2BM76KT.js +528 -0
  125. package/dist/chunk-P2BM76KT.js.map +1 -0
  126. package/dist/{chunk-U3TH5Q2Q.js → chunk-P3MH72CI.js} +2 -2
  127. package/dist/{chunk-P2OZKKYP.js → chunk-PHWUFPCO.js} +2 -2
  128. package/dist/{chunk-KGTD2KZJ.js → chunk-PKRIQL3V.js} +2 -2
  129. package/dist/{chunk-BNGPHGVZ.js → chunk-Q6VFVAKZ.js} +13 -6
  130. package/dist/{chunk-BNGPHGVZ.js.map → chunk-Q6VFVAKZ.js.map} +1 -1
  131. package/dist/{chunk-4MJZTF42.js → chunk-QAOGGNE3.js} +3 -3
  132. package/dist/{chunk-RGJBM7Z3.js → chunk-QMBNMPQM.js} +84 -84
  133. package/dist/{chunk-RGJBM7Z3.js.map → chunk-QMBNMPQM.js.map} +1 -1
  134. package/dist/{chunk-2QSZNTDO.js → chunk-RKNJBZ55.js} +4 -4
  135. package/dist/chunk-RMMVQQA6.js +70 -0
  136. package/dist/chunk-RMMVQQA6.js.map +1 -0
  137. package/dist/{chunk-FCCMFVS6.js → chunk-RPSYDM6C.js} +2 -2
  138. package/dist/chunk-RPW2NOU6.js +33 -0
  139. package/dist/chunk-RPW2NOU6.js.map +1 -0
  140. package/dist/{chunk-RYHWZ52A.js → chunk-S2BBISHU.js} +4 -4
  141. package/dist/{chunk-RSYJV25N.js → chunk-SG265CVF.js} +10 -10
  142. package/dist/{chunk-UGH6VPPO.js → chunk-SH6YO3LT.js} +3 -3
  143. package/dist/{chunk-2RAC4JIG.js → chunk-T3GCXULH.js} +16 -16
  144. package/dist/chunk-T3GCXULH.js.map +1 -0
  145. package/dist/{chunk-FMLKOL2Z.js → chunk-TC3VNKGX.js} +4 -4
  146. package/dist/{chunk-7K5Q6COX.js → chunk-TVVEYCNW.js} +4 -4
  147. package/dist/{chunk-BJJAX3IZ.js → chunk-UTRO5UJU.js} +2 -2
  148. package/dist/{chunk-DQEMWVMT.js → chunk-UVYI6VIX.js} +1 -1
  149. package/dist/chunk-VNA7W7QF.js +134 -0
  150. package/dist/chunk-VNA7W7QF.js.map +1 -0
  151. package/dist/{chunk-BHLN7L7M.js → chunk-VVIW3PTA.js} +17 -17
  152. package/dist/chunk-WNIUPHWV.js +152 -0
  153. package/dist/chunk-WNIUPHWV.js.map +1 -0
  154. package/dist/chunk-WOCNN776.js +742 -0
  155. package/dist/chunk-WOCNN776.js.map +1 -0
  156. package/dist/{chunk-XQ4EH6DI.js → chunk-WONS4RZ2.js} +3 -3
  157. package/dist/chunk-WRJVB3C2.js +118 -0
  158. package/dist/chunk-WRJVB3C2.js.map +1 -0
  159. package/dist/{chunk-HORJVJ6K.js → chunk-WZ7UB7XQ.js} +42 -37
  160. package/dist/chunk-WZ7UB7XQ.js.map +1 -0
  161. package/dist/{chunk-MEBQFQ26.js → chunk-XEQ7OT7U.js} +8 -6
  162. package/dist/chunk-XEQ7OT7U.js.map +1 -0
  163. package/dist/{chunk-CSXHRAJJ.js → chunk-XOZ4ALGB.js} +3 -3
  164. package/dist/{chunk-XKO7BM2C.js → chunk-YGHMSDLK.js} +187 -26
  165. package/dist/chunk-YGHMSDLK.js.map +1 -0
  166. package/dist/chunk-YXZG5TVN.js +40 -0
  167. package/dist/chunk-YXZG5TVN.js.map +1 -0
  168. package/dist/{chunk-6NNNURLK.js → chunk-Z54EM5YZ.js} +4 -4
  169. package/dist/{chunk-YSGBD3QN.js → chunk-ZGOQTOYA.js} +3 -3
  170. package/dist/{chunk-4DJQYKMN.js → chunk-ZIKENA2C.js} +2 -2
  171. package/dist/chunk-ZIKENA2C.js.map +1 -0
  172. package/dist/{chunk-RNY3BO35.js → chunk-ZXAGJFHJ.js} +4 -4
  173. package/dist/{cli-Bz7X7dGx.d.ts → cli-CxoSOiG0.d.ts} +5 -5
  174. package/dist/cli.d.ts +14 -12
  175. package/dist/cli.js +73 -68
  176. package/dist/compounding/engine.d.ts +3 -2
  177. package/dist/compounding/engine.js +15 -13
  178. package/dist/compounding/preference-consolidator.d.ts +1 -1
  179. package/dist/compression-optimizer.d.ts +1 -1
  180. package/dist/config.d.ts +1 -1
  181. package/dist/config.js +4 -2
  182. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  183. package/dist/connectors/codex-materialize-runner.js +14 -12
  184. package/dist/connectors/codex-materialize.d.ts +1 -1
  185. package/dist/connectors/index.d.ts +1 -1
  186. package/dist/connectors/index.js +15 -13
  187. package/dist/consolidation-provenance-check.d.ts +3 -2
  188. package/dist/consolidation-undo.d.ts +3 -2
  189. package/dist/contradiction/index.d.ts +3 -2
  190. package/dist/contradiction/index.js +6 -6
  191. package/dist/{contradiction-scan-HMF7CNKD.js → contradiction-scan-HYLIRMJ2.js} +3 -3
  192. package/dist/conversation-index/backend.d.ts +1 -1
  193. package/dist/conversation-index/backend.js +2 -2
  194. package/dist/conversation-index/chunker.d.ts +1 -1
  195. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  196. package/dist/conversation-index/indexer.d.ts +1 -1
  197. package/dist/conversation-index/search.d.ts +1 -1
  198. package/dist/corpus-watermark.d.ts +15 -2
  199. package/dist/corpus-watermark.js +27 -23
  200. package/dist/day-summary.d.ts +1 -1
  201. package/dist/day-summary.js +2 -2
  202. package/dist/delinearize.d.ts +1 -1
  203. package/dist/direct-answer-wiring.d.ts +1 -1
  204. package/dist/direct-answer.d.ts +1 -1
  205. package/dist/embedding-fallback.d.ts +1 -1
  206. package/dist/embedding-fallback.js +2 -2
  207. package/dist/enrichment/index.d.ts +1 -1
  208. package/dist/entity-id-normalization.d.ts +4 -0
  209. package/dist/entity-id-normalization.js +10 -0
  210. package/dist/entity-id-normalization.js.map +1 -0
  211. package/dist/entity-retrieval-boundaries.d.ts +3 -0
  212. package/dist/entity-retrieval-boundaries.js +8 -0
  213. package/dist/entity-retrieval-boundaries.js.map +1 -0
  214. package/dist/entity-retrieval.d.ts +3 -2
  215. package/dist/entity-retrieval.js +15 -12
  216. package/dist/entity-schema.d.ts +1 -1
  217. package/dist/entity-schema.js +1 -1
  218. package/dist/explicit-capture.d.ts +9 -8
  219. package/dist/explicit-capture.js +2 -2
  220. package/dist/extraction-error-classification.d.ts +1 -1
  221. package/dist/extraction-faithfulness.d.ts +1 -1
  222. package/dist/extraction-judge-telemetry.d.ts +1 -1
  223. package/dist/extraction-judge-training.d.ts +1 -1
  224. package/dist/extraction-judge.d.ts +1 -1
  225. package/dist/extraction-liveness.d.ts +1 -1
  226. package/dist/extraction-source-grounding-helpers.d.ts +34 -0
  227. package/dist/extraction-source-grounding-helpers.js +62 -0
  228. package/dist/extraction-source-grounding-helpers.js.map +1 -0
  229. package/dist/extraction-source-grounding-rules.d.ts +18 -0
  230. package/dist/extraction-source-grounding-rules.js +12 -0
  231. package/dist/extraction-source-grounding-rules.js.map +1 -0
  232. package/dist/extraction-source-grounding.d.ts +11 -0
  233. package/dist/extraction-source-grounding.js +13 -0
  234. package/dist/extraction-source-grounding.js.map +1 -0
  235. package/dist/extraction.d.ts +3 -1
  236. package/dist/extraction.js +7 -4
  237. package/dist/fallback-llm.d.ts +1 -1
  238. package/dist/{first-start-migration-LEXL3XYL.js → first-start-migration-F2QJD66E.js} +2 -2
  239. package/dist/graph-dashboard-diff.d.ts +1 -1
  240. package/dist/graph-dashboard-key.d.ts +1 -1
  241. package/dist/graph-dashboard-parser.d.ts +1 -1
  242. package/dist/graph-edge-reinforcement.d.ts +1 -1
  243. package/dist/graph-snapshot.d.ts +1 -1
  244. package/dist/graph.d.ts +1 -1
  245. package/dist/importance.d.ts +1 -1
  246. package/dist/importers/index.d.ts +1 -1
  247. package/dist/in-flight-reads.d.ts +1 -1
  248. package/dist/index.d.ts +407 -405
  249. package/dist/index.js +154 -145
  250. package/dist/intent.d.ts +1 -1
  251. package/dist/lcm/engine.d.ts +1 -1
  252. package/dist/lcm/engine.js +2 -2
  253. package/dist/lcm/index.d.ts +1 -1
  254. package/dist/lcm/index.js +2 -2
  255. package/dist/lcm/tools.d.ts +1 -1
  256. package/dist/lifecycle.d.ts +1 -1
  257. package/dist/live-connectors-runner.d.ts +1 -1
  258. package/dist/local-llm.d.ts +1 -1
  259. package/dist/local-llm.js +2 -2
  260. package/dist/local-model-endpoint.d.ts +1 -1
  261. package/dist/maintenance/memory-governance.d.ts +1 -1
  262. package/dist/maintenance/memory-governance.js +14 -12
  263. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +3 -2
  264. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +14 -12
  265. package/dist/maintenance/rebuild-memory-projection.d.ts +3 -2
  266. package/dist/maintenance/rebuild-memory-projection.js +15 -13
  267. package/dist/{maintenance-DgnD2z8S.d.ts → maintenance-Cb-PjxQd.d.ts} +3 -3
  268. package/dist/mcp-memory-inspector-app.d.ts +13 -10
  269. package/dist/memory-action-policy.d.ts +1 -1
  270. package/dist/memory-cache.d.ts +1 -1
  271. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  272. package/dist/memory-projection-mutations.d.ts +4 -0
  273. package/dist/memory-projection-mutations.js +15 -0
  274. package/dist/memory-projection-mutations.js.map +1 -0
  275. package/dist/memory-projection-store.d.ts +1 -1
  276. package/dist/memory-provenance.d.ts +1 -1
  277. package/dist/memory-worth-outcomes.d.ts +3 -2
  278. package/dist/models-json.d.ts +1 -1
  279. package/dist/namespaces/migrate.d.ts +4 -3
  280. package/dist/namespaces/migrate.js +24 -22
  281. package/dist/namespaces/principal.d.ts +1 -1
  282. package/dist/namespaces/principal.js +2 -2
  283. package/dist/namespaces/search.d.ts +1 -1
  284. package/dist/namespaces/search.js +10 -10
  285. package/dist/namespaces/storage.d.ts +4 -3
  286. package/dist/namespaces/storage.js +14 -12
  287. package/dist/native-knowledge.d.ts +1 -1
  288. package/dist/offline-sync-impression-drain.d.ts +1 -1
  289. package/dist/offline-sync-impression-drain.js +7 -7
  290. package/dist/operator-doctor-corpus.d.ts +22 -3
  291. package/dist/operator-doctor-corpus.js +34 -24
  292. package/dist/operator-doctor-replica.d.ts +52 -0
  293. package/dist/operator-doctor-replica.js +15 -0
  294. package/dist/operator-doctor-replica.js.map +1 -0
  295. package/dist/operator-toolkit.d.ts +7 -3
  296. package/dist/operator-toolkit.js +37 -31
  297. package/dist/orchestration/compression-guideline-coordinator.d.ts +3 -2
  298. package/dist/orchestration/compression-guideline-coordinator.js +2 -2
  299. package/dist/orchestration/maintenance.d.ts +5 -4
  300. package/dist/orchestration/maintenance.js +21 -19
  301. package/dist/{orchestrator-rIHmHpv1.d.ts → orchestrator-5GKqb_HL.d.ts} +7 -7
  302. package/dist/orchestrator.d.ts +9 -8
  303. package/dist/orchestrator.js +105 -96
  304. package/dist/patterns-cli.d.ts +1 -1
  305. package/dist/{pipeline-Bq5zU6Bp.d.ts → pipeline-3Qi1TpRo.d.ts} +1 -1
  306. package/dist/policy-runtime.d.ts +1 -1
  307. package/dist/proactive-contention.d.ts +1 -1
  308. package/dist/provenance.d.ts +1 -1
  309. package/dist/{qmd-3ILJkC70.d.ts → qmd-D9JqzzRX.d.ts} +1 -1
  310. package/dist/qmd-preflight.d.ts +2 -2
  311. package/dist/qmd-recall-cache.d.ts +1 -1
  312. package/dist/qmd.d.ts +2 -2
  313. package/dist/recall-concurrency-config.d.ts +1 -1
  314. package/dist/recall-disclosure-escalation.d.ts +1 -1
  315. package/dist/recall-explain-renderer.d.ts +1 -1
  316. package/dist/recall-explain-renderer.js +3 -3
  317. package/dist/recall-memory-map.d.ts +1 -1
  318. package/dist/recall-planner-llm.d.ts +1 -1
  319. package/dist/recall-state.d.ts +1 -1
  320. package/dist/recall-state.js +2 -2
  321. package/dist/recall-tag-filter.d.ts +1 -1
  322. package/dist/recall-timings.d.ts +1 -1
  323. package/dist/recall-xray-cli.d.ts +1 -1
  324. package/dist/recall-xray-cli.js +4 -4
  325. package/dist/recall-xray-renderer.d.ts +1 -1
  326. package/dist/recall-xray-renderer.js +3 -3
  327. package/dist/recall-xray.d.ts +1 -1
  328. package/dist/recall-xray.js +2 -2
  329. package/dist/replay/normalizers/chatgpt.d.ts +1 -1
  330. package/dist/replay/normalizers/claude.d.ts +1 -1
  331. package/dist/replay/normalizers/openclaw.d.ts +1 -1
  332. package/dist/replay/normalizers/shared.d.ts +1 -1
  333. package/dist/replay/runner.d.ts +1 -1
  334. package/dist/replay/types.d.ts +1 -1
  335. package/dist/replica-divergence.d.ts +279 -0
  336. package/dist/replica-divergence.js +28 -0
  337. package/dist/replica-divergence.js.map +1 -0
  338. package/dist/replica-peers-config.d.ts +5 -0
  339. package/dist/replica-peers-config.js +13 -0
  340. package/dist/replica-peers-config.js.map +1 -0
  341. package/dist/resolve-auth-token.d.ts +21 -2
  342. package/dist/resolve-auth-token.js +5 -1
  343. package/dist/resume-bundles.js +5 -3
  344. package/dist/retrieval-agents.d.ts +2 -2
  345. package/dist/retrieval-tiers.d.ts +1 -1
  346. package/dist/routing/engine.d.ts +1 -1
  347. package/dist/routing/store.d.ts +1 -1
  348. package/dist/salvage-envelope.d.ts +1 -1
  349. package/dist/schemas.d.ts +54 -54
  350. package/dist/{scope-profiles-D0-ff4xT.d.ts → scope-profiles-C4g6_UdP.d.ts} +1 -1
  351. package/dist/search/embed-helper.d.ts +1 -1
  352. package/dist/search/embed-helper.js +2 -2
  353. package/dist/search/factory.d.ts +1 -1
  354. package/dist/search/factory.js +9 -9
  355. package/dist/search/index.d.ts +1 -1
  356. package/dist/search/index.js +9 -9
  357. package/dist/search/lancedb-backend.d.ts +1 -1
  358. package/dist/search/lancedb-backend.js +2 -2
  359. package/dist/search/meilisearch-backend.d.ts +1 -1
  360. package/dist/search/meilisearch-backend.js +2 -2
  361. package/dist/search/noop-backend.d.ts +1 -1
  362. package/dist/search/orama-backend.d.ts +1 -1
  363. package/dist/search/orama-backend.js +2 -2
  364. package/dist/search/port.d.ts +1 -1
  365. package/dist/search/remote-backend.d.ts +1 -1
  366. package/dist/{semantic-consolidation-4Tfh7c1g.d.ts → semantic-consolidation-BrxqnzTW.d.ts} +1 -1
  367. package/dist/semantic-consolidation.d.ts +2 -2
  368. package/dist/semantic-consolidation.js +15 -13
  369. package/dist/semantic-rule-promotion.js +14 -12
  370. package/dist/semantic-rule-verifier.d.ts +1 -1
  371. package/dist/semantic-rule-verifier.js +14 -12
  372. package/dist/{service-cTvil7D_.d.ts → service-Bi1JgxdP.d.ts} +2 -2
  373. package/dist/session-observer-bands.d.ts +1 -1
  374. package/dist/session-observer-state.d.ts +1 -1
  375. package/dist/shared-context/manager.d.ts +9 -9
  376. package/dist/shared-context/manager.js +2 -2
  377. package/dist/signal.d.ts +1 -1
  378. package/dist/{storage-C9ibpTme.d.ts → storage-CcH6yPk2.d.ts} +13 -19
  379. package/dist/storage.d.ts +3 -2
  380. package/dist/storage.js +15 -12
  381. package/dist/summarizer.d.ts +1 -1
  382. package/dist/summarizer.js +3 -3
  383. package/dist/summary-snapshot.d.ts +1 -1
  384. package/dist/temporal-supersession.d.ts +3 -2
  385. package/dist/temporal-timeline-recall.d.ts +1 -1
  386. package/dist/temporal-validity.d.ts +1 -1
  387. package/dist/threading.d.ts +1 -1
  388. package/dist/tier-migration.d.ts +3 -2
  389. package/dist/tier-routing.d.ts +1 -1
  390. package/dist/{tier-stats-XKD7SXYY.js → tier-stats-OPTSBNRH.js} +2 -2
  391. package/dist/topics.d.ts +1 -1
  392. package/dist/transcript.d.ts +1 -1
  393. package/dist/transfer/backup.js +2 -2
  394. package/dist/transfer/capsule-export.js +2 -2
  395. package/dist/transfer/capsule-import.js +2 -2
  396. package/dist/transfer/types.d.ts +66 -66
  397. package/dist/trust-score-stage.d.ts +1 -1
  398. package/dist/trust-score.d.ts +1 -1
  399. package/dist/{types-DHBxIF0s.d.ts → types-Dg0w9ADr.d.ts} +54 -4
  400. package/dist/types.d.ts +1 -1
  401. package/dist/types.js +1 -1
  402. package/dist/utility-runtime.d.ts +1 -1
  403. package/dist/verified-recall.js +14 -12
  404. package/dist/write-envelope.d.ts +1 -1
  405. package/package.json +2 -2
  406. package/src/access-health-types.ts +8 -0
  407. package/src/access-http.test.ts +4 -0
  408. package/src/access-service-health.test.ts +23 -0
  409. package/src/access-service.ts +27 -4
  410. package/src/capabilities.test.ts +1 -0
  411. package/src/capabilities.ts +7 -7
  412. package/src/cli.ts +9 -7
  413. package/src/config.test.ts +5 -0
  414. package/src/config.ts +3 -2
  415. package/src/corpus-watermark.test.ts +21 -0
  416. package/src/corpus-watermark.ts +25 -3
  417. package/src/entity-id-normalization.ts +55 -0
  418. package/src/entity-retrieval-boundaries.ts +134 -0
  419. package/src/entity-retrieval.ts +253 -27
  420. package/src/entity-schema.ts +2 -1
  421. package/src/extraction-source-grounding-helpers.ts +603 -0
  422. package/src/extraction-source-grounding-rules.ts +1031 -0
  423. package/src/extraction-source-grounding.test.ts +2337 -0
  424. package/src/extraction-source-grounding.ts +50 -0
  425. package/src/extraction.ts +120 -15
  426. package/src/memory-projection-mutations.ts +132 -0
  427. package/src/namespaces/storage.ts +5 -3
  428. package/src/operator-doctor-corpus.ts +41 -0
  429. package/src/operator-doctor-replica.test.ts +261 -0
  430. package/src/operator-doctor-replica.ts +129 -0
  431. package/src/operator-toolkit.ts +5 -4
  432. package/src/orchestration/orchestrator-init.ts +2 -2
  433. package/src/replica-divergence.test.ts +1475 -0
  434. package/src/replica-divergence.ts +910 -0
  435. package/src/replica-peers-config.ts +250 -0
  436. package/src/resolve-auth-token.ts +38 -0
  437. package/src/storage/entity-canonical-id-migration-adapter.ts +72 -0
  438. package/src/storage/entity-canonical-id-migration-runner.ts +68 -0
  439. package/src/storage/entity-canonical-id-migration.ts +904 -0
  440. package/src/storage/entity-store.ts +44 -0
  441. package/src/storage/memory-frontmatter-metadata.ts +17 -0
  442. package/src/storage/memory-migration-serialization.ts +37 -0
  443. package/src/storage/memory-read-store.ts +3 -2
  444. package/src/storage/profile-header.ts +8 -7
  445. package/src/storage-profile-timestamp.test.ts +68 -0
  446. package/src/storage.ts +68 -69
  447. package/src/types.ts +5 -5
  448. package/dist/chunk-2RAC4JIG.js.map +0 -1
  449. package/dist/chunk-4DJQYKMN.js.map +0 -1
  450. package/dist/chunk-CIQXI47W.js.map +0 -1
  451. package/dist/chunk-EOLC6EXV.js.map +0 -1
  452. package/dist/chunk-GJJBPI6I.js.map +0 -1
  453. package/dist/chunk-HORJVJ6K.js.map +0 -1
  454. package/dist/chunk-MEBQFQ26.js.map +0 -1
  455. package/dist/chunk-NUWMZIYZ.js.map +0 -1
  456. package/dist/chunk-TKBDJTXG.js.map +0 -1
  457. package/dist/chunk-V25OWXAC.js.map +0 -1
  458. package/dist/chunk-XKO7BM2C.js.map +0 -1
  459. /package/dist/{capsule-crypto-YO5QJ6L3.js.map → capsule-crypto-GWVG7LGC.js.map} +0 -0
  460. /package/dist/{chunk-2H7OEVPO.js.map → chunk-3GD2HFR6.js.map} +0 -0
  461. /package/dist/{chunk-4TFIRMTE.js.map → chunk-4A6YGWQN.js.map} +0 -0
  462. /package/dist/{chunk-JDOJZTFF.js.map → chunk-4PBVXX7L.js.map} +0 -0
  463. /package/dist/{chunk-IKMAO55B.js.map → chunk-55MDBZLC.js.map} +0 -0
  464. /package/dist/{chunk-VDX2J7OX.js.map → chunk-5W7CTZ2E.js.map} +0 -0
  465. /package/dist/{chunk-B7GROTXD.js.map → chunk-6LKEUCEM.js.map} +0 -0
  466. /package/dist/{chunk-2AJ72VVS.js.map → chunk-7BZOBA5J.js.map} +0 -0
  467. /package/dist/{chunk-44DUJETW.js.map → chunk-7HXCF4RE.js.map} +0 -0
  468. /package/dist/{chunk-X3SQYAPP.js.map → chunk-ACXPX4AG.js.map} +0 -0
  469. /package/dist/{chunk-AJ7QCSIS.js.map → chunk-ALSGMEJR.js.map} +0 -0
  470. /package/dist/{chunk-JGUXPJUQ.js.map → chunk-AS7YMSL6.js.map} +0 -0
  471. /package/dist/{chunk-77CNV7DY.js.map → chunk-BLAKS3CP.js.map} +0 -0
  472. /package/dist/{chunk-5BRT4Z2I.js.map → chunk-CMRQ34J5.js.map} +0 -0
  473. /package/dist/{chunk-HEXSNYJD.js.map → chunk-CSMCNOPH.js.map} +0 -0
  474. /package/dist/{chunk-SK3EYPKC.js.map → chunk-D2ANTDGO.js.map} +0 -0
  475. /package/dist/{chunk-JCVQV6QX.js.map → chunk-D3LMYTBV.js.map} +0 -0
  476. /package/dist/{chunk-XY7QPJDA.js.map → chunk-E6EE5B67.js.map} +0 -0
  477. /package/dist/{chunk-LLISELSY.js.map → chunk-EP5BVCRI.js.map} +0 -0
  478. /package/dist/{chunk-PTN6UAUA.js.map → chunk-ES36HTSC.js.map} +0 -0
  479. /package/dist/{chunk-WEAO45M4.js.map → chunk-ESBQWC3U.js.map} +0 -0
  480. /package/dist/{chunk-EUSLKI4X.js.map → chunk-EVX44I7C.js.map} +0 -0
  481. /package/dist/{chunk-X6ROIHFE.js.map → chunk-G5R3D5UP.js.map} +0 -0
  482. /package/dist/{chunk-MG6MNSP4.js.map → chunk-G6LBWZRF.js.map} +0 -0
  483. /package/dist/{chunk-FRVTCCGD.js.map → chunk-GGUBDXRR.js.map} +0 -0
  484. /package/dist/{chunk-QH6CS6XJ.js.map → chunk-H24WNPA2.js.map} +0 -0
  485. /package/dist/{chunk-MQVINOJQ.js.map → chunk-IYZ5K7MU.js.map} +0 -0
  486. /package/dist/{chunk-RPA2RX5P.js.map → chunk-JDZRYH2N.js.map} +0 -0
  487. /package/dist/{chunk-M5EPMNS4.js.map → chunk-K5GB36ME.js.map} +0 -0
  488. /package/dist/{chunk-UT3OQPFA.js.map → chunk-KUJQHXPH.js.map} +0 -0
  489. /package/dist/{chunk-7RZJWZ46.js.map → chunk-LEPOP46W.js.map} +0 -0
  490. /package/dist/{chunk-EYJSW2RV.js.map → chunk-NBDCZWP4.js.map} +0 -0
  491. /package/dist/{chunk-XKGPIWGI.js.map → chunk-OFHFH655.js.map} +0 -0
  492. /package/dist/{chunk-FGBJBYWP.js.map → chunk-OVRQLAYR.js.map} +0 -0
  493. /package/dist/{chunk-BXLOS5AJ.js.map → chunk-OWHERGF2.js.map} +0 -0
  494. /package/dist/{chunk-U3TH5Q2Q.js.map → chunk-P3MH72CI.js.map} +0 -0
  495. /package/dist/{chunk-P2OZKKYP.js.map → chunk-PHWUFPCO.js.map} +0 -0
  496. /package/dist/{chunk-KGTD2KZJ.js.map → chunk-PKRIQL3V.js.map} +0 -0
  497. /package/dist/{chunk-4MJZTF42.js.map → chunk-QAOGGNE3.js.map} +0 -0
  498. /package/dist/{chunk-2QSZNTDO.js.map → chunk-RKNJBZ55.js.map} +0 -0
  499. /package/dist/{chunk-FCCMFVS6.js.map → chunk-RPSYDM6C.js.map} +0 -0
  500. /package/dist/{chunk-RYHWZ52A.js.map → chunk-S2BBISHU.js.map} +0 -0
  501. /package/dist/{chunk-RSYJV25N.js.map → chunk-SG265CVF.js.map} +0 -0
  502. /package/dist/{chunk-UGH6VPPO.js.map → chunk-SH6YO3LT.js.map} +0 -0
  503. /package/dist/{chunk-FMLKOL2Z.js.map → chunk-TC3VNKGX.js.map} +0 -0
  504. /package/dist/{chunk-7K5Q6COX.js.map → chunk-TVVEYCNW.js.map} +0 -0
  505. /package/dist/{chunk-BJJAX3IZ.js.map → chunk-UTRO5UJU.js.map} +0 -0
  506. /package/dist/{chunk-DQEMWVMT.js.map → chunk-UVYI6VIX.js.map} +0 -0
  507. /package/dist/{chunk-BHLN7L7M.js.map → chunk-VVIW3PTA.js.map} +0 -0
  508. /package/dist/{chunk-XQ4EH6DI.js.map → chunk-WONS4RZ2.js.map} +0 -0
  509. /package/dist/{chunk-CSXHRAJJ.js.map → chunk-XOZ4ALGB.js.map} +0 -0
  510. /package/dist/{chunk-6NNNURLK.js.map → chunk-Z54EM5YZ.js.map} +0 -0
  511. /package/dist/{chunk-YSGBD3QN.js.map → chunk-ZGOQTOYA.js.map} +0 -0
  512. /package/dist/{chunk-RNY3BO35.js.map → chunk-ZXAGJFHJ.js.map} +0 -0
  513. /package/dist/{contradiction-scan-HMF7CNKD.js.map → contradiction-scan-HYLIRMJ2.js.map} +0 -0
  514. /package/dist/{first-start-migration-LEXL3XYL.js.map → first-start-migration-F2QJD66E.js.map} +0 -0
  515. /package/dist/{tier-stats-XKD7SXYY.js.map → tier-stats-OPTSBNRH.js.map} +0 -0
@@ -0,0 +1,1031 @@
1
+ import type { ExtractionResult } from "./types.js";
2
+ import { anchorTemporalExpressions } from "./delinearize.js";
3
+ import {
4
+ GROUNDING_AUXILIARY_TOKENS,
5
+ GROUNDING_COPULAR_FORMS,
6
+ GROUNDING_ENTITY_TYPE_PREFIXES,
7
+ GROUNDING_MIN_COVERAGE,
8
+ GROUNDING_MIN_SHARED_TOKENS,
9
+ GROUNDING_STOPWORDS,
10
+ areGroundingTokensCompatible,
11
+ containsContiguousGroundingTokens,
12
+ containsExactTokenSequence,
13
+ groundingLexemes,
14
+ groundingTokenSequence,
15
+ hasContradictoryPolarity,
16
+ hasExplicitRoleSubjectToken,
17
+ isAttachedNegatedAuxiliary,
18
+ isInterrogativeSourceSentence,
19
+ normalizeForExactMatch,
20
+ normalizedGroundingAlignmentTokenSequence,
21
+ normalizedGroundingTokenSequence,
22
+ sourceSentences,
23
+ splitGroundingClauses,
24
+ stemToken,
25
+ tokenize,
26
+ tokenSequence,
27
+ } from "./extraction-source-grounding-helpers.js";
28
+
29
+ export interface ExtractionSourceGroundingOptions {
30
+ sourceGrounding: boolean;
31
+ anchorTemporalExpressions: boolean;
32
+ }
33
+
34
+ export function applyExtractionSourceGrounding(
35
+ result: ExtractionResult,
36
+ sourceText: string,
37
+ assertionSourceText: string = sourceText,
38
+ roleAssertionSources: ExtractionGroundingRoleSources | undefined,
39
+ messageTimestamp: Date | undefined,
40
+ options: ExtractionSourceGroundingOptions,
41
+ ): ExtractionResult {
42
+ if (!options.sourceGrounding) return result;
43
+ const anchorSource = (source: string): string =>
44
+ options.anchorTemporalExpressions
45
+ ? anchorTemporalExpressions(source, messageTimestamp ?? new Date())
46
+ : source;
47
+ const anchoredRoleSources = roleAssertionSources === undefined
48
+ ? undefined
49
+ : {
50
+ profile: roleAssertionSources.profile === undefined
51
+ ? undefined
52
+ : anchorSource(roleAssertionSources.profile),
53
+ identity: roleAssertionSources.identity === undefined
54
+ ? undefined
55
+ : anchorSource(roleAssertionSources.identity),
56
+ };
57
+ return filterExtractionResultBySource(
58
+ result,
59
+ anchorSource(sourceText),
60
+ anchorSource(assertionSourceText),
61
+ anchoredRoleSources,
62
+ options.anchorTemporalExpressions ? anchorSource : undefined,
63
+ );
64
+ }
65
+
66
+ export interface ExtractionGroundingRoleSources {
67
+ profile?: string;
68
+ identity?: string;
69
+ }
70
+
71
+
72
+
73
+ interface GroundingCopularClaim {
74
+ subject: string;
75
+ predicate: string;
76
+ }
77
+
78
+ function groundingCopularClaim(text: string): GroundingCopularClaim | undefined {
79
+ const lexemes = groundingLexemes(text);
80
+ const copulaIndex = lexemes.findIndex(({ token }) => GROUNDING_COPULAR_FORMS.has(token));
81
+ if (copulaIndex <= 0) return undefined;
82
+
83
+ let subjectIndex = copulaIndex - 1;
84
+ while (
85
+ subjectIndex >= 0
86
+ && GROUNDING_AUXILIARY_TOKENS.has(lexemes[subjectIndex]!.token)
87
+ ) {
88
+ subjectIndex -= 1;
89
+ }
90
+ const subjectLexeme = lexemes[subjectIndex];
91
+ const predicateLexeme = lexemes
92
+ .slice(copulaIndex + 1)
93
+ .find(({ token }) => GROUNDING_STOPWORDS[token] !== true);
94
+ if (subjectLexeme === undefined || predicateLexeme === undefined) return undefined;
95
+
96
+ return {
97
+ subject: stemToken(subjectLexeme.token, subjectLexeme.preserveTerminalS),
98
+ predicate: stemToken(predicateLexeme.token, predicateLexeme.preserveTerminalS),
99
+ };
100
+ }
101
+
102
+ function hasCopularPredicateEvidence(candidate: string, source: string): boolean {
103
+ const candidateClaim = groundingCopularClaim(candidate);
104
+ if (candidateClaim === undefined) return true;
105
+ const sourceClaim = groundingCopularClaim(source);
106
+ return sourceClaim !== undefined
107
+ && areGroundingTokensCompatible(candidateClaim.subject, sourceClaim.subject)
108
+ && areGroundingTokensCompatible(candidateClaim.predicate, sourceClaim.predicate);
109
+ }
110
+ const GROUNDING_ALIGNMENT_MODIFIERS = new Set([
111
+ "actively",
112
+ "again",
113
+ "already",
114
+ "currently",
115
+ "eventually",
116
+ "finally",
117
+ "generally",
118
+ "mainly",
119
+ "newly",
120
+ "now",
121
+ "often",
122
+ "previously",
123
+ "primarily",
124
+ "quickly",
125
+ "recently",
126
+ "repeatedly",
127
+ "simply",
128
+ "slowly",
129
+ "sometimes",
130
+ "still",
131
+ "successfully",
132
+ "typically",
133
+ "usually",
134
+ ]);
135
+
136
+ function isGroundingAlignmentModifier(token: string): boolean {
137
+ return GROUNDING_ALIGNMENT_MODIFIERS.has(token);
138
+ }
139
+
140
+
141
+ function hasAlignedSubjectPredicateOverlap(candidate: string, source: string): boolean {
142
+ const candidateTokens = normalizedGroundingAlignmentTokenSequence(candidate);
143
+ const sourceTokens = normalizedGroundingAlignmentTokenSequence(source);
144
+ if (candidateTokens.length < 3 || sourceTokens.length < 3) {
145
+ return hasCopularPredicateEvidence(candidate, source);
146
+ }
147
+
148
+ const candidateSubject = candidateTokens[0];
149
+ if (candidateSubject === undefined) return false;
150
+ const hasCorrectionReordering = /\b(?:rather\s+than|instead\s+of)\b/iu.test(candidate)
151
+ && /\b(?:not|rather\s+than|instead\s+of)\b/iu.test(source);
152
+ for (let sourceSubjectIndex = 0; sourceSubjectIndex < sourceTokens.length; sourceSubjectIndex += 1) {
153
+ if (!areGroundingTokensCompatible(candidateSubject, sourceTokens[sourceSubjectIndex]!)) continue;
154
+ let sourceCursor = sourceSubjectIndex + 1;
155
+ let foundAlignedToken = false;
156
+ let aligned = true;
157
+ for (let candidateIndex = 1; candidateIndex < candidateTokens.length; candidateIndex += 1) {
158
+ const candidateToken = candidateTokens[candidateIndex]!;
159
+ const sourceIndex = sourceTokens.findIndex(
160
+ (sourceToken, index) =>
161
+ index >= sourceCursor && areGroundingTokensCompatible(candidateToken, sourceToken),
162
+ );
163
+ if (sourceIndex === -1) {
164
+ if (hasCorrectionReordering) continue;
165
+ aligned = false;
166
+ break;
167
+ }
168
+ foundAlignedToken = true;
169
+ const candidateNext = candidateTokens[candidateIndex + 1];
170
+ const sourceNext = sourceTokens[sourceIndex + 1];
171
+ if (
172
+ candidateNext !== undefined
173
+ && sourceNext !== undefined
174
+ && !hasCorrectionReordering
175
+ && !areGroundingTokensCompatible(candidateNext, sourceNext)
176
+ && !isGroundingAlignmentModifier(sourceNext)
177
+ ) {
178
+ aligned = false;
179
+ break;
180
+ }
181
+ sourceCursor = sourceIndex + 1;
182
+ }
183
+ if (aligned && foundAlignedToken) return true;
184
+ }
185
+ return false;
186
+ }
187
+
188
+ function groundedTokenScore(
189
+ candidate: string,
190
+ source: string,
191
+ requireAlignedArguments = true,
192
+ requireAllCandidateTokensGrounded = true,
193
+ ): number {
194
+ const candidateTokens = tokenize(candidate);
195
+ if (candidateTokens.size === 0) return 0;
196
+ const sourceTokens = tokenize(source);
197
+ const allowCorrectionReordering = /\b(?:rather\s+than|instead\s+of)\b/iu.test(candidate);
198
+ let sharedTokens = 0;
199
+ let allCandidateTokensGrounded = true;
200
+ for (const token of candidateTokens) {
201
+ if ([...sourceTokens].some((sourceToken) => areGroundingTokensCompatible(token, sourceToken))) {
202
+ sharedTokens += 1;
203
+ } else if (!allowCorrectionReordering && token !== "rather" && token !== "instead") {
204
+ allCandidateTokensGrounded = false;
205
+ }
206
+ }
207
+ if (
208
+ (requireAllCandidateTokensGrounded && !allCandidateTokensGrounded)
209
+ || sharedTokens < GROUNDING_MIN_SHARED_TOKENS
210
+ || sharedTokens / candidateTokens.size < GROUNDING_MIN_COVERAGE
211
+ ) {
212
+ return 0;
213
+ }
214
+ if (requireAlignedArguments && !hasAlignedSubjectPredicateOverlap(candidate, source)) return 0;
215
+ return sharedTokens / candidateTokens.size;
216
+ }
217
+
218
+ function candidateClauses(candidate: string): string[] {
219
+ return splitGroundingClauses(sourceSentences(candidate));
220
+ }
221
+
222
+ function isSourceGroundedClause(
223
+ candidate: string,
224
+ source: string,
225
+ includeInterrogativeSource = false,
226
+ ): boolean {
227
+ let bestSupportedScore = 0;
228
+ let bestContradictedScore = 0;
229
+ const sentences = sourceSentences(source);
230
+ for (let index = 0; index < sentences.length; index += 1) {
231
+ const sentence = sentences[index];
232
+ if (isYesNoAnswer(sentence)) {
233
+ const precedingSentence = sentences[index - 1];
234
+ const answerToken = tokenSequence(sentence)[0];
235
+ const contradictoryPolarity = precedingSentence !== undefined
236
+ ? hasContradictoryPolarity(candidate, precedingSentence)
237
+ : false;
238
+ if (
239
+ precedingSentence !== undefined
240
+ && isInterrogativeSourceSentence(precedingSentence)
241
+ && groundedTokenScore(candidate, precedingSentence) === 1
242
+ && (
243
+ (answerToken === "yes" && !contradictoryPolarity)
244
+ || (answerToken === "no" && contradictoryPolarity)
245
+ )
246
+ ) {
247
+ return true;
248
+ }
249
+ continue;
250
+ }
251
+ const sentenceText = normalizeForExactMatch(sentence);
252
+ const isExplanatoryLabel = sentenceText.startsWith(`${normalizeForExactMatch(candidate)}:`)
253
+ && !sentence.trim().endsWith("?");
254
+ if (!includeInterrogativeSource && isInterrogativeSourceSentence(sentence) && !isExplanatoryLabel) {
255
+ continue;
256
+ }
257
+ const sourceSpans = /\b(?:rather\s+than|instead\s+of)\b/iu.test(candidate)
258
+ ? [sentence]
259
+ : splitGroundingClauses([sentence]);
260
+ for (const sourceSpan of sourceSpans) {
261
+ const sourceSpanText = normalizeForExactMatch(sourceSpan);
262
+ if (containsExactTokenSequence(candidate, sourceSpanText)) {
263
+ if (!hasContradictoryPolarity(candidate, sourceSpan)) return true;
264
+ bestContradictedScore = Math.max(bestContradictedScore, 1);
265
+ continue;
266
+ }
267
+ const score = groundedTokenScore(
268
+ candidate,
269
+ sourceSpan,
270
+ !includeInterrogativeSource,
271
+ !includeInterrogativeSource,
272
+ );
273
+ if (score === 0) continue;
274
+ if (hasContradictoryPolarity(candidate, sourceSpan)) {
275
+ bestContradictedScore = Math.max(bestContradictedScore, score);
276
+ } else {
277
+ bestSupportedScore = Math.max(bestSupportedScore, score);
278
+ }
279
+ }
280
+ }
281
+ return bestSupportedScore > bestContradictedScore;
282
+ }
283
+ function isSourceGrounded(
284
+ candidate: string,
285
+ source: string,
286
+ includeInterrogativeSource = false,
287
+ ): boolean {
288
+ const candidateText = normalizeForExactMatch(candidate);
289
+ const sourceText = source.normalize("NFKC").trim();
290
+ if (candidateText.length === 0 || sourceText.length === 0) return false;
291
+ const hasSupportedExactMatch = sourceSentences(sourceText).some((sentence) => {
292
+ const sentenceText = normalizeForExactMatch(sentence);
293
+ const isExplanatoryLabel = sentenceText.startsWith(`${candidateText}:`)
294
+ && !sentence.trim().endsWith("?");
295
+ if (!includeInterrogativeSource && isInterrogativeSourceSentence(sentence) && !isExplanatoryLabel) return false;
296
+ return containsExactTokenSequence(candidateText, sentenceText)
297
+ && !hasContradictoryPolarity(candidateText, sentenceText);
298
+ });
299
+ if (hasSupportedExactMatch) return true;
300
+
301
+ const clauses = candidateClauses(candidateText);
302
+ if (clauses.length > 1) {
303
+ return clauses.every((clause) =>
304
+ isSourceGroundedClause(clause, sourceText, includeInterrogativeSource));
305
+ }
306
+ return isSourceGroundedClause(candidateText, sourceText, includeInterrogativeSource);
307
+ }
308
+
309
+ function normalizedEntityIdentifierTokens(name: string): string[] {
310
+ const identifier = normalizeForExactMatch(name).replace(/[-_]+/gu, " ");
311
+ const tokens = groundingLexemes(identifier)
312
+ .filter(({ token }) => GROUNDING_STOPWORDS[token] !== true)
313
+ .map(({ token }) => stemToken(token, true));
314
+ return tokens.length > 1 && GROUNDING_ENTITY_TYPE_PREFIXES.has(tokens[0] ?? "")
315
+ ? tokens.slice(1)
316
+ : tokens;
317
+ }
318
+
319
+ function isGroundedEntityName(name: string, source: string): boolean {
320
+ const nameTokens = normalizedEntityIdentifierTokens(name);
321
+ return nameTokens.length > 0 && sourceSentences(source).some((sentence) => {
322
+ const sentenceTokens = groundingLexemes(sentence)
323
+ .filter(({ token }) => GROUNDING_STOPWORDS[token] !== true)
324
+ .map(({ token, preserveTerminalS }) => stemToken(token, preserveTerminalS));
325
+ return containsContiguousGroundingTokens(nameTokens, sentenceTokens);
326
+ });
327
+ }
328
+ function buildEntitySupportSource(name: string, source: string): string {
329
+ const nameTokens = normalizedEntityIdentifierTokens(name);
330
+ if (nameTokens.length === 0) return "";
331
+ return sourceSentences(source)
332
+ .filter((sentence) => {
333
+ const sentenceTokens = groundingLexemes(sentence)
334
+ .filter(({ token }) => GROUNDING_STOPWORDS[token] !== true)
335
+ .map(({ token, preserveTerminalS }) => stemToken(token, preserveTerminalS));
336
+ return containsContiguousGroundingTokens(nameTokens, sentenceTokens);
337
+ })
338
+ .join(" ");
339
+ }
340
+
341
+ function hasGroundedPredicateAnchor(candidate: string, sentence: string): boolean {
342
+ const candidateTokens = normalizedGroundingTokenSequence(candidate);
343
+ const sourceTokens = normalizedGroundingTokenSequence(sentence);
344
+ const comparableCandidateTokens = GROUNDING_ROLE_SUBJECT_TOKENS.has(candidateTokens[0] ?? "")
345
+ ? candidateTokens.slice(1)
346
+ : candidateTokens;
347
+ if (comparableCandidateTokens.length < 2) return false;
348
+ const subjectToken = comparableCandidateTokens[0];
349
+ if (subjectToken === undefined || !sourceTokens.includes(subjectToken)) {
350
+ return false;
351
+ }
352
+ const candidatePredicateTokens = comparableCandidateTokens.slice(1);
353
+ const sourceTokenSet = new Set(sourceTokens);
354
+ const sharedPredicateTokens = candidatePredicateTokens.filter((token) => sourceTokenSet.has(token));
355
+ const requiredSharedTokens = Math.min(2, candidatePredicateTokens.length);
356
+ return sharedPredicateTokens.length >= requiredSharedTokens;
357
+ }
358
+ function hasGroundingAnchor(
359
+ candidate: string,
360
+ assertionSource: string,
361
+ includeInterrogativeSource = false,
362
+ requirePredicateSupport = false,
363
+ ): boolean {
364
+ return sourceSentences(assertionSource).some((sentence) => {
365
+ if (!includeInterrogativeSource && isInterrogativeSourceSentence(sentence)) return false;
366
+ const sourceSpans = /\b(?:rather\s+than|instead\s+of)\b/iu.test(candidate)
367
+ ? [sentence]
368
+ : splitGroundingClauses([sentence]);
369
+ return sourceSpans.some((sourceSpan) => {
370
+ const exactMatch = containsExactTokenSequence(candidate, sourceSpan)
371
+ && !hasContradictoryPolarity(candidate, sourceSpan);
372
+ if (exactMatch) return true;
373
+ if (requirePredicateSupport && !hasGroundedPredicateAnchor(candidate, sourceSpan)) return false;
374
+ return groundedTokenScore(candidate, sourceSpan) > 0
375
+ || hasRoleNormalizedGrounding(candidate, sourceSpan);
376
+ });
377
+ });
378
+ }
379
+
380
+ function hasAnswerSupport(
381
+ candidate: string,
382
+ source: string,
383
+ assertionSource: string,
384
+ ): boolean {
385
+ const assertedAnswerSentences = new Set(
386
+ sourceSentences(assertionSource)
387
+ .filter((sentence) => {
388
+ const answerToken = tokenSequence(sentence)[0];
389
+ return answerToken === "yes" || answerToken === "no";
390
+ })
391
+ .map((sentence) => normalizeForExactMatch(sentence)),
392
+ );
393
+ if (assertedAnswerSentences.size === 0) return false;
394
+ const sentences = sourceSentences(source);
395
+ return sentences.some((sentence, index) => {
396
+ const answerToken = tokenSequence(sentence)[0];
397
+ if (answerToken !== "yes" && answerToken !== "no") return false;
398
+ if (!assertedAnswerSentences.has(normalizeForExactMatch(sentence))) return false;
399
+ const precedingSentence = sentences[index - 1];
400
+ if (
401
+ precedingSentence === undefined
402
+ || !isInterrogativeSourceSentence(precedingSentence)
403
+ || groundedTokenScore(candidate, precedingSentence) !== 1
404
+ ) {
405
+ return false;
406
+ }
407
+ const contradictoryPolarity = hasContradictoryPolarity(candidate, precedingSentence);
408
+ return answerToken === "yes" ? !contradictoryPolarity : contradictoryPolarity;
409
+ });
410
+ }
411
+
412
+ const GROUNDING_ROLE_SUBJECT_TOKENS = new Set(["assistant", "user"]);
413
+
414
+ function hasRoleNormalizedGrounding(candidate: string, source: string): boolean {
415
+ const candidateTokens = groundingTokenSequence(candidate);
416
+ if (!GROUNDING_ROLE_SUBJECT_TOKENS.has(candidateTokens[0] ?? "")) return false;
417
+ const claimTokens = candidateTokens.slice(1);
418
+ if (claimTokens.length === 0) return false;
419
+
420
+ return sourceSentences(source).some((sentence) => {
421
+ if (isInterrogativeSourceSentence(sentence)) return false;
422
+ const sourceTokens = groundingTokenSequence(sentence);
423
+ const requiredSharedTokens = Math.min(GROUNDING_MIN_SHARED_TOKENS, claimTokens.length);
424
+ let sourceIndex = 0;
425
+ let sharedTokens = 0;
426
+ for (const claimToken of claimTokens) {
427
+ const matchingIndex = sourceTokens.indexOf(claimToken, sourceIndex);
428
+ if (matchingIndex === -1) continue;
429
+ sharedTokens += 1;
430
+ sourceIndex = matchingIndex + 1;
431
+ }
432
+ return sharedTokens >= requiredSharedTokens
433
+ && !hasContradictoryPolarity(candidate, sentence);
434
+ });
435
+ }
436
+
437
+ interface GroundingContext {
438
+ source: string;
439
+ assertionSource: string | undefined;
440
+ allowRoleNormalization: boolean;
441
+ fallbackSource?: string;
442
+ fallbackAssertionSource?: string;
443
+ }
444
+
445
+ function resolveGroundingContext(
446
+ candidate: string,
447
+ source: string,
448
+ assertionSource: string | undefined,
449
+ roleAssertionSources: ExtractionGroundingRoleSources | undefined,
450
+ ): GroundingContext {
451
+ const candidateRole = groundingTokenSequence(candidate)[0];
452
+ if (!GROUNDING_ROLE_SUBJECT_TOKENS.has(candidateRole ?? "")) {
453
+ return { source, assertionSource, allowRoleNormalization: false };
454
+ }
455
+ if (roleAssertionSources === undefined) {
456
+ return { source, assertionSource, allowRoleNormalization: true };
457
+ }
458
+ const roleSource = candidateRole === "user"
459
+ ? roleAssertionSources.profile
460
+ : roleAssertionSources.identity;
461
+ return {
462
+ source: roleSource ?? "",
463
+ assertionSource: roleSource ?? "",
464
+ allowRoleNormalization: true,
465
+ fallbackSource: source,
466
+ fallbackAssertionSource: assertionSource,
467
+ };
468
+ }
469
+
470
+ function selectGroundingContext(candidate: string, context: GroundingContext): GroundingContext {
471
+ if (isGroundedCandidate(
472
+ candidate,
473
+ context.source,
474
+ context.assertionSource,
475
+ false,
476
+ context.allowRoleNormalization,
477
+ )) {
478
+ return context;
479
+ }
480
+ if (
481
+ context.fallbackSource === undefined
482
+ || !hasExplicitRoleSubjectToken(
483
+ groundingTokenSequence(candidate)[0],
484
+ sourceSentences(context.fallbackSource).map((sentence) => groundingTokenSequence(sentence)),
485
+ )
486
+ ) return context;
487
+ const fallbackContext: GroundingContext = {
488
+ source: context.fallbackSource,
489
+ assertionSource: context.fallbackAssertionSource,
490
+ allowRoleNormalization: false,
491
+ };
492
+ return isGroundedCandidate(
493
+ candidate,
494
+ fallbackContext.source,
495
+ fallbackContext.assertionSource,
496
+ false,
497
+ fallbackContext.allowRoleNormalization,
498
+ )
499
+ ? fallbackContext
500
+ : context;
501
+ }
502
+
503
+ function isGroundedCandidate(
504
+ candidate: string,
505
+ source: string,
506
+ assertionSource: string | undefined,
507
+ includeInterrogativeSource = false,
508
+ allowRoleNormalization = false,
509
+ ): boolean {
510
+ const allowInterrogativeSource = includeInterrogativeSource
511
+ || (
512
+ assertionSource !== undefined
513
+ && normalizeForExactMatch(assertionSource) !== normalizeForExactMatch(source)
514
+ );
515
+ const sourceGrounded = isSourceGrounded(candidate, source, allowInterrogativeSource);
516
+ const roleGrounded = allowRoleNormalization && hasRoleNormalizedGrounding(candidate, source);
517
+ const candidateTokens = groundingTokenSequence(candidate);
518
+ const roleNormalizedCandidate = allowRoleNormalization
519
+ && GROUNDING_ROLE_SUBJECT_TOKENS.has(candidateTokens[0] ?? "");
520
+ if (roleNormalizedCandidate && !roleGrounded) return false;
521
+ if (!sourceGrounded && !roleGrounded) return false;
522
+ if (assertionSource === undefined) return true;
523
+ const clauses = candidateClauses(candidate);
524
+ const requirePredicateSupport = !includeInterrogativeSource
525
+ && assertionSource !== undefined
526
+ && normalizeForExactMatch(assertionSource) !== normalizeForExactMatch(source);
527
+ return clauses.length > 0
528
+ && (
529
+ clauses.every((clause) =>
530
+ hasGroundingAnchor(clause, assertionSource, includeInterrogativeSource, requirePredicateSupport))
531
+ || hasAnswerSupport(candidate, source, assertionSource)
532
+ );
533
+ }
534
+
535
+ function buildFactSupportSource(
536
+ source: string,
537
+ supportingSentences: ReadonlyArray<string>,
538
+ ): string {
539
+ const sentences = sourceSentences(source);
540
+ const selectedIndices = new Set<number>();
541
+ for (const supportingSentence of supportingSentences) {
542
+ const supportIndex = sentences.indexOf(supportingSentence);
543
+ if (supportIndex < 0) continue;
544
+ let endIndex = supportIndex;
545
+ while (
546
+ endIndex < sentences.length - 1
547
+ && sentences[endIndex]!.trimEnd().endsWith(";")
548
+ && /^(?:its|their|this|that|these|those)\b/iu.test(
549
+ sentences[endIndex + 1]!.trimStart(),
550
+ )
551
+ ) {
552
+ endIndex += 1;
553
+ }
554
+ for (let index = supportIndex; index <= endIndex; index += 1) {
555
+ selectedIndices.add(index);
556
+ }
557
+ }
558
+ return [...selectedIndices]
559
+ .sort((left, right) => left - right)
560
+ .map((index) => sentences[index]!)
561
+ .join(" ");
562
+ }
563
+ function buildProcedureSupportSource(
564
+ fact: ExtractionResult["facts"][number],
565
+ source: string,
566
+ factSupportSource: string,
567
+ ): string {
568
+ if (fact.category !== "procedure" || fact.procedureSteps === undefined) return factSupportSource;
569
+ const parentSupportSentences = new Set(
570
+ sourceSentences(factSupportSource).map((sentence) => normalizeForExactMatch(sentence)),
571
+ );
572
+ const parentGroundedSteps = fact.procedureSteps.filter((step) =>
573
+ isGroundedCandidate(step.intent, factSupportSource, undefined, false),
574
+ );
575
+ if (parentGroundedSteps.length === 0) return factSupportSource;
576
+ return sourceSentences(source)
577
+ .filter((sentence) => {
578
+ if (parentSupportSentences.has(normalizeForExactMatch(sentence))) return true;
579
+ const sentenceTokens = tokenize(sentence);
580
+ return parentGroundedSteps.some((step) =>
581
+ [...tokenize(step.intent)].some((token) =>
582
+ [...sentenceTokens].some((sourceToken) => areGroundingTokensCompatible(token, sourceToken)),
583
+ ),
584
+ );
585
+ })
586
+ .join(" ");
587
+ }
588
+ function filterGroundedFact(
589
+ fact: ExtractionResult["facts"][number],
590
+ source: string,
591
+ assertionSource: string | undefined,
592
+ roleAssertionSources: ExtractionGroundingRoleSources | undefined,
593
+ eventTimeNormalizer: ((eventTime: string) => string) | undefined,
594
+ ): ExtractionResult["facts"][number] | undefined {
595
+ const factContext = selectGroundingContext(
596
+ fact.content,
597
+ resolveGroundingContext(fact.content, source, assertionSource, roleAssertionSources),
598
+ );
599
+ if (!isGroundedCandidate(
600
+ fact.content,
601
+ factContext.source,
602
+ factContext.assertionSource,
603
+ false,
604
+ factContext.allowRoleNormalization,
605
+ )) return undefined;
606
+ const factEventTime = fact.eventTime;
607
+ const groundedFactEventTime = factEventTime === undefined
608
+ ? undefined
609
+ : eventTimeNormalizer?.(factEventTime) ?? factEventTime;
610
+ const factSupportingSentences = sourceSentences(factContext.assertionSource ?? factContext.source).filter(
611
+ (sentence) =>
612
+ isGroundedCandidate(
613
+ fact.content,
614
+ sentence,
615
+ undefined,
616
+ false,
617
+ factContext.allowRoleNormalization,
618
+ ),
619
+ );
620
+ const factSupportingSource = factEventTime === undefined
621
+ ? factSupportingSentences[0]
622
+ : factSupportingSentences.find((sentence) =>
623
+ isGroundedCandidate(
624
+ groundedFactEventTime ?? factEventTime,
625
+ sentence,
626
+ undefined,
627
+ false,
628
+ factContext.allowRoleNormalization,
629
+ ),
630
+ ) ?? factSupportingSentences[0];
631
+ const eventTimeSource = factSupportingSource ?? factContext.source;
632
+ const eventTimeAssertionSource = factSupportingSource === undefined
633
+ ? factContext.assertionSource
634
+ : undefined;
635
+
636
+ const factSupportSource = buildFactSupportSource(
637
+ factContext.assertionSource ?? factContext.source,
638
+ factSupportingSentences,
639
+ );
640
+ const groundedAttributes = fact.structuredAttributes
641
+ ? Object.fromEntries(
642
+ Object.entries(fact.structuredAttributes)
643
+ .filter(([key, value]) =>
644
+ isGroundedCandidate(
645
+ `${key}: ${value}`,
646
+ factSupportSource,
647
+ undefined,
648
+ false,
649
+ factContext.allowRoleNormalization,
650
+ ),
651
+ ),
652
+ )
653
+ : undefined;
654
+ const procedureGroundingSource = buildProcedureSupportSource(
655
+ fact,
656
+ factContext.assertionSource ?? factContext.source,
657
+ factSupportSource,
658
+ );
659
+ const groundedProcedureSteps = fact.procedureSteps
660
+ ? fact.procedureSteps.flatMap((step) => {
661
+ if (!isGroundedCandidate(step.intent, procedureGroundingSource, undefined, false)) return [];
662
+ const expectedOutcome = step.expectedOutcome
663
+ && isGroundedCandidate(step.expectedOutcome, procedureGroundingSource, undefined, false)
664
+ ? step.expectedOutcome
665
+ : undefined;
666
+ const toolCall = step.toolCall
667
+ && isGroundedCandidate(step.toolCall.signature, procedureGroundingSource, undefined, false)
668
+ ? step.toolCall
669
+ : undefined;
670
+ const {
671
+ expectedOutcome: _expectedOutcome,
672
+ toolCall: _toolCall,
673
+ ...stepWithoutOptionalFields
674
+ } = step;
675
+ return [{
676
+ ...stepWithoutOptionalFields,
677
+ ...(expectedOutcome !== undefined ? { expectedOutcome } : {}),
678
+ ...(toolCall !== undefined ? { toolCall } : {}),
679
+ }];
680
+ })
681
+ : undefined;
682
+ const groundedReasoningTrace = fact.reasoningTrace
683
+ && fact.reasoningTrace.steps.length > 0
684
+ && isGroundedCandidate(
685
+ fact.reasoningTrace.finalAnswer,
686
+ factContext.source,
687
+ factContext.assertionSource,
688
+ false,
689
+ factContext.allowRoleNormalization,
690
+ )
691
+ && fact.reasoningTrace.steps.every((step) =>
692
+ isGroundedCandidate(
693
+ step.description,
694
+ factContext.source,
695
+ factContext.assertionSource,
696
+ false,
697
+ factContext.allowRoleNormalization,
698
+ ),
699
+ )
700
+ ? {
701
+ steps: fact.reasoningTrace.steps,
702
+ finalAnswer: fact.reasoningTrace.finalAnswer,
703
+ ...(fact.reasoningTrace.observedOutcome
704
+ && isGroundedCandidate(
705
+ fact.reasoningTrace.observedOutcome,
706
+ factContext.source,
707
+ factContext.assertionSource,
708
+ false,
709
+ factContext.allowRoleNormalization,
710
+ )
711
+ ? { observedOutcome: fact.reasoningTrace.observedOutcome }
712
+ : {}),
713
+ }
714
+ : undefined;
715
+ const groundedEventTime = groundedFactEventTime
716
+ && isGroundedCandidate(groundedFactEventTime, eventTimeSource, eventTimeAssertionSource)
717
+ ? factEventTime
718
+ : undefined;
719
+ const groundedEntityRef = fact.entityRef !== undefined
720
+ && isGroundedEntityName(fact.entityRef, factSupportSource)
721
+ ? fact.entityRef
722
+ : undefined;
723
+ const {
724
+ entityRef: _entityRef,
725
+ structuredAttributes: _structuredAttributes,
726
+ procedureSteps: _procedureSteps,
727
+ reasoningTrace: _reasoningTrace,
728
+ eventTime: _eventTime,
729
+ ...factWithoutGroundingFields
730
+ } = fact;
731
+ return {
732
+ ...factWithoutGroundingFields,
733
+ ...(groundedEntityRef !== undefined ? { entityRef: groundedEntityRef } : {}),
734
+ ...(groundedAttributes && Object.keys(groundedAttributes).length > 0
735
+ ? { structuredAttributes: groundedAttributes }
736
+ : {}),
737
+ ...(groundedProcedureSteps && groundedProcedureSteps.length > 0
738
+ ? { procedureSteps: groundedProcedureSteps }
739
+ : {}),
740
+ ...(groundedReasoningTrace !== undefined ? { reasoningTrace: groundedReasoningTrace } : {}),
741
+ ...(groundedEventTime !== undefined ? { eventTime: groundedEventTime } : {}),
742
+ };
743
+ }
744
+
745
+ function filterGroundedEntity(
746
+ entity: ExtractionResult["entities"][number],
747
+ source: string,
748
+ assertionSource: string | undefined,
749
+ ): ExtractionResult["entities"][number] | undefined {
750
+ if (!isGroundedEntityName(entity.name, source)) return undefined;
751
+ const entitySource = buildEntitySupportSource(entity.name, source);
752
+ const entityAssertionSource = assertionSource === undefined
753
+ ? undefined
754
+ : buildEntitySupportSource(entity.name, assertionSource);
755
+ const facts = entity.facts.filter((fact) =>
756
+ isGroundedCandidate(fact, entitySource, entityAssertionSource),
757
+ );
758
+ const structuredSections = entity.structuredSections
759
+ ?.flatMap((section) => {
760
+ const groundedFacts = section.facts.filter((fact) =>
761
+ isGroundedCandidate(fact, entitySource, entityAssertionSource),
762
+ );
763
+ return groundedFacts.length > 0
764
+ ? [{ ...section, facts: groundedFacts }]
765
+ : [];
766
+ });
767
+ if (facts.length === 0 && (structuredSections === undefined || structuredSections.length === 0)) {
768
+ return undefined;
769
+ }
770
+ const { structuredSections: _structuredSections, ...entityWithoutSections } = entity;
771
+ return {
772
+ ...entityWithoutSections,
773
+ facts,
774
+ ...(structuredSections && structuredSections.length > 0 ? { structuredSections } : {}),
775
+ };
776
+ }
777
+
778
+ function normalizedEntitySourceText(name: string): string {
779
+ return normalizedEntityIdentifierTokens(name).join(" ");
780
+ }
781
+
782
+ function isGroundedRelationship(
783
+ relationship: NonNullable<ExtractionResult["relationships"]>[number],
784
+ source: string,
785
+ assertionSource: string | undefined,
786
+ ): boolean {
787
+ const sourceName = normalizedEntitySourceText(relationship.source);
788
+ const targetName = normalizedEntitySourceText(relationship.target);
789
+ const labelTokens = tokenize(relationship.label);
790
+ if (sourceName.length === 0 || targetName.length === 0 || labelTokens.size === 0) return false;
791
+ const relationText = `${sourceName} ${relationship.label} ${targetName}`;
792
+ const hasCoherentSourceSpan = sourceSentences(source).some((sentence) => {
793
+ if (isInterrogativeSourceSentence(sentence)) return false;
794
+ return groundedTokenScore(relationText, sentence) === 1
795
+ && !hasContradictoryPolarity(relationText, sentence);
796
+ });
797
+ return hasCoherentSourceSpan
798
+ && isGroundedCandidate(relationText, source, assertionSource);
799
+ }
800
+ const GROUNDING_TEMPORAL_WORDS = new Set([
801
+ "today",
802
+ "yesterday",
803
+ "tomorrow",
804
+ "now",
805
+ "recently",
806
+ "earlier",
807
+ "later",
808
+ "soon",
809
+ "morning",
810
+ "afternoon",
811
+ "evening",
812
+ "tonight",
813
+ "night",
814
+ "noon",
815
+ "midnight",
816
+ "monday",
817
+ "tuesday",
818
+ "wednesday",
819
+ "thursday",
820
+ "friday",
821
+ "saturday",
822
+ "sunday",
823
+ "january",
824
+ "february",
825
+ "march",
826
+ "april",
827
+ "may",
828
+ "june",
829
+ "july",
830
+ "august",
831
+ "september",
832
+ "october",
833
+ "november",
834
+ "december",
835
+ "q1",
836
+ "q2",
837
+ "q3",
838
+ "q4",
839
+ ]);
840
+ const GROUNDING_TEMPORAL_CLOCK_PATTERN = /\b\d{1,2}:\d{2}(?:\s*[ap]\.?m\.?)?\b/iu;
841
+ const GROUNDING_TEMPORAL_DURATION_PATTERN = new RegExp(
842
+ "\\b(?:\\d+|one|two|three|four|five|six|seven|eight|nine|ten)\\s+"
843
+ + "(?:seconds?|minutes?|hours?|days?|weeks?|months?|quarters?|years?)\\b",
844
+ "iu",
845
+ );
846
+
847
+ function isWhenQuestion(question: string): boolean {
848
+ return /^(?:when|what\s+(?:time|date)|which\s+day)\b/iu.test(question.trim());
849
+ }
850
+ function isWhyQuestion(question: string): boolean {
851
+ return /^why\b/iu.test(question.trim());
852
+ }
853
+
854
+ function hasCausalAnswerEvidence(question: string, sentence: string): boolean {
855
+ if (!isWhyQuestion(question)) return true;
856
+ return /\b(?:because|since|due\s+to|owing\s+to|thanks\s+to|therefore|thus|hence|so)\b/iu.test(
857
+ sentence,
858
+ );
859
+ }
860
+
861
+ function hasTemporalAnswerEvidence(question: string, sentence: string): boolean {
862
+ if (!isWhenQuestion(question)) return true;
863
+ return groundingLexemes(sentence).some(({ token }) =>
864
+ GROUNDING_TEMPORAL_WORDS.has(token) || /^(?:19|20)\d{2}$/u.test(token),
865
+ )
866
+ || GROUNDING_TEMPORAL_CLOCK_PATTERN.test(sentence)
867
+ || GROUNDING_TEMPORAL_DURATION_PATTERN.test(sentence);
868
+ }
869
+
870
+
871
+ function isUnknownAnswerSentence(sentence: string): boolean {
872
+ 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
873
+ .test(sentence);
874
+ }
875
+
876
+ function isYesNoAnswer(sentence: string): boolean {
877
+ return /^(?:yes|no)(?:[.!?]|,\s*(?:absolutely|definitely|indeed|exactly|correct|of\s+course|use\s+that|do\s+that)[.!?]?)?$/iu
878
+ .test(sentence.trim());
879
+ }
880
+
881
+ function hasWhAnswerRoleAlignment(question: string, sentence: string): boolean {
882
+ const normalizedQuestion = question.trim();
883
+ const objectQuestionMatch = /^(?:what|which)\s+.+?\s+(?:is|are|was|were|do|does|did|can|could|will|would|should|has|have|had)\s+(.+?)\s+([^\s?]+)\??$/iu
884
+ .exec(normalizedQuestion);
885
+ const sourceTokens = normalizedGroundingTokenSequence(sentence);
886
+ if (objectQuestionMatch !== null) {
887
+ const subjectTokens = groundingTokenSequence(objectQuestionMatch[1] ?? "");
888
+ const predicateTokens = groundingTokenSequence(objectQuestionMatch[2] ?? "");
889
+ if (subjectTokens.length === 0 || predicateTokens.length === 0) return true;
890
+ let sourceIndex = 0;
891
+ for (const token of [...subjectTokens, ...predicateTokens]) {
892
+ const matchedIndex = sourceTokens.indexOf(token, sourceIndex);
893
+ if (matchedIndex === -1) return false;
894
+ sourceIndex = matchedIndex + 1;
895
+ }
896
+ return true;
897
+ }
898
+
899
+ const subjectQuestionMatch = /^(?:who|what)\s+([^\s?]+)\s+(.+?)\??$/iu.exec(normalizedQuestion);
900
+ if (subjectQuestionMatch === null) return true;
901
+ const predicateTokens = groundingTokenSequence(subjectQuestionMatch[1] ?? "");
902
+ const objectTokens = groundingTokenSequence(subjectQuestionMatch[2] ?? "");
903
+ if (predicateTokens.length === 0 || objectTokens.length === 0) return true;
904
+ const predicateStart = sourceTokens.indexOf(predicateTokens[0]!);
905
+ if (predicateStart === -1) return false;
906
+ let sourceIndex = predicateStart + predicateTokens.length;
907
+ for (const objectToken of objectTokens) {
908
+ const objectIndex = sourceTokens.indexOf(objectToken, sourceIndex);
909
+ if (objectIndex === -1) return false;
910
+ sourceIndex = objectIndex + 1;
911
+ }
912
+ return true;
913
+ }
914
+
915
+ function isQuestionAnsweredBySource(
916
+ question: string,
917
+ source: string,
918
+ assertionSource: string | undefined,
919
+ ): boolean {
920
+ const questionTokens = tokenize(question);
921
+ if (questionTokens.size === 0) return false;
922
+ const isYesNoQuestion = /^(?:is|are|am|was|were|do|does|did|can|could|will|would|should|has|have|had)\b/iu
923
+ .test(question.trim());
924
+ const assertedSentences = new Set(sourceSentences(assertionSource ?? source).map((sentence) => normalizeForExactMatch(sentence)));
925
+ const sentences = sourceSentences(source);
926
+ return sentences.some((sentence, index) => {
927
+ if (!assertedSentences.has(normalizeForExactMatch(sentence))) return false;
928
+ if (isInterrogativeSourceSentence(sentence)) return false;
929
+ if (isYesNoAnswer(sentence)) {
930
+ const precedingSentence = sentences[index - 1];
931
+ return precedingSentence !== undefined
932
+ && isInterrogativeSourceSentence(precedingSentence)
933
+ && groundedTokenScore(question, precedingSentence) === 1;
934
+ }
935
+ if (isUnknownAnswerSentence(sentence)) return false;
936
+ const score = groundedTokenScore(question, sentence, false);
937
+ if (score !== 1) return false;
938
+ const sentenceTokens = tokenize(sentence);
939
+ const hasAnswerToken = [...sentenceTokens].some((token) => !questionTokens.has(token));
940
+ return (isYesNoQuestion || hasAnswerToken)
941
+ && hasTemporalAnswerEvidence(question, sentence)
942
+ && hasCausalAnswerEvidence(question, sentence)
943
+ && hasWhAnswerRoleAlignment(question, sentence);
944
+ });
945
+ }
946
+
947
+ function groundQuestion(
948
+ question: ExtractionResult["questions"][number],
949
+ source: string,
950
+ assertionSource: string | undefined,
951
+ ): ExtractionResult["questions"][number] | undefined {
952
+ if (isQuestionAnsweredBySource(question.question, source, assertionSource)) return undefined;
953
+ if (!isGroundedCandidate(question.question, source, assertionSource, true)) return undefined;
954
+ const normalizedContext = question.context.trim();
955
+ if (
956
+ normalizedContext.length > 0
957
+ && !isGroundedCandidate(normalizedContext, assertionSource ?? source, undefined, false)
958
+ ) {
959
+ return { ...question, context: "" };
960
+ }
961
+ return question;
962
+ }
963
+
964
+ export function filterExtractionResultBySource(
965
+ result: ExtractionResult,
966
+ source: string,
967
+ assertionSource?: string,
968
+ roleAssertionSources?: ExtractionGroundingRoleSources,
969
+ eventTimeNormalizer?: (eventTime: string) => string,
970
+ ): ExtractionResult {
971
+ if (source.trim().length === 0) {
972
+ return {
973
+ ...result,
974
+ facts: [],
975
+ profileUpdates: [],
976
+ entities: [],
977
+ questions: [],
978
+ ...(result.relationships !== undefined ? { relationships: [] } : {}),
979
+ identityReflection: undefined,
980
+ };
981
+ }
982
+
983
+ const facts = result.facts.flatMap((fact) => {
984
+ const grounded = filterGroundedFact(
985
+ fact,
986
+ source,
987
+ assertionSource,
988
+ roleAssertionSources,
989
+ eventTimeNormalizer,
990
+ );
991
+ return grounded === undefined ? [] : [grounded];
992
+ });
993
+ const profileGroundingSource = roleAssertionSources?.profile ?? source;
994
+ const profileAssertionSource = roleAssertionSources?.profile ?? assertionSource;
995
+ const profileUpdates = result.profileUpdates.filter((update) =>
996
+ isGroundedCandidate(update, profileGroundingSource, profileAssertionSource, false, true),
997
+ );
998
+ const entities = result.entities.flatMap((entity) => {
999
+ const grounded = filterGroundedEntity(entity, source, assertionSource);
1000
+ return grounded === undefined ? [] : [grounded];
1001
+ });
1002
+ const questions = result.questions.flatMap((question) => {
1003
+ const grounded = groundQuestion(question, source, assertionSource);
1004
+ return grounded === undefined ? [] : [grounded];
1005
+ });
1006
+ const relationships = result.relationships?.filter((relationship) =>
1007
+ isGroundedRelationship(relationship, source, assertionSource),
1008
+ );
1009
+ const identityGroundingSource = roleAssertionSources?.identity ?? source;
1010
+ const identityAssertionSource = roleAssertionSources?.identity ?? assertionSource;
1011
+ const identityReflection = result.identityReflection
1012
+ && isGroundedCandidate(
1013
+ result.identityReflection,
1014
+ identityGroundingSource,
1015
+ identityAssertionSource,
1016
+ false,
1017
+ true,
1018
+ )
1019
+ ? result.identityReflection
1020
+ : undefined;
1021
+
1022
+ return {
1023
+ ...result,
1024
+ facts,
1025
+ profileUpdates,
1026
+ entities,
1027
+ questions,
1028
+ ...(result.relationships !== undefined ? { relationships } : {}),
1029
+ ...(identityReflection !== undefined ? { identityReflection } : { identityReflection: undefined }),
1030
+ };
1031
+ }