@remnic/core 9.63.9 → 9.63.10

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 (451) hide show
  1. package/dist/access-admin-ops-surface.d.ts +11 -11
  2. package/dist/access-admin-ops-surface.js +23 -23
  3. package/dist/access-authorization-probe.d.ts +11 -11
  4. package/dist/access-authorization-probe.js +24 -24
  5. package/dist/access-boundary.d.ts +11 -11
  6. package/dist/access-boundary.js +23 -23
  7. package/dist/access-cli.js +84 -82
  8. package/dist/access-cli.js.map +1 -1
  9. package/dist/access-coding-context-resolution.d.ts +1 -1
  10. package/dist/access-extraction-force-flush.d.ts +11 -11
  11. package/dist/access-extraction-force-flush.js +23 -23
  12. package/dist/access-health-types.d.ts +1 -1
  13. package/dist/access-http-lcm-compaction.d.ts +11 -11
  14. package/dist/access-http-lifecycle-flush.d.ts +11 -11
  15. package/dist/access-http-offline-stream.d.ts +11 -11
  16. package/dist/access-http-query.d.ts +2 -2
  17. package/dist/access-http-query.js +25 -25
  18. package/dist/access-http.d.ts +12 -12
  19. package/dist/access-http.js +36 -36
  20. package/dist/access-identity-continuity-surface.d.ts +9 -9
  21. package/dist/access-identity-continuity-surface.js +23 -23
  22. package/dist/access-lcm-surface.d.ts +11 -11
  23. package/dist/access-lcm-surface.js +23 -23
  24. package/dist/access-mcp.d.ts +11 -11
  25. package/dist/access-mcp.js +30 -30
  26. package/dist/access-memory-search-fanout.d.ts +2 -2
  27. package/dist/{access-namespace-preflight-DB0zXFek.d.ts → access-namespace-preflight-CrF0FKaz.d.ts} +1 -1
  28. package/dist/access-namespace-preflight.d.ts +3 -3
  29. package/dist/access-namespace-preflight.js +23 -23
  30. package/dist/access-observe-write-surface.d.ts +11 -11
  31. package/dist/access-observe-write-surface.js +23 -23
  32. package/dist/access-offline-manifest.d.ts +9 -9
  33. package/dist/access-operations-batch.js +25 -25
  34. package/dist/access-operations.d.ts +11 -11
  35. package/dist/access-operations.js +29 -29
  36. package/dist/access-recall-concurrency.d.ts +11 -11
  37. package/dist/access-recall-concurrency.js +23 -23
  38. package/dist/access-recall-response.d.ts +11 -11
  39. package/dist/access-recall-response.js +23 -23
  40. package/dist/access-recall-surface.d.ts +11 -11
  41. package/dist/access-recall-surface.js +23 -23
  42. package/dist/access-schema.js +3 -3
  43. package/dist/{access-service-DwfdjqkZ.d.ts → access-service-C0AE0jLs.d.ts} +7 -7
  44. package/dist/access-service-helpers.d.ts +11 -11
  45. package/dist/access-service.d.ts +11 -11
  46. package/dist/access-service.js +23 -23
  47. package/dist/access-surface-catalog.d.ts +11 -11
  48. package/dist/access-surface-catalog.js +25 -25
  49. package/dist/access-wearables-meetings-surface.d.ts +3 -3
  50. package/dist/action-confidence.d.ts +1 -1
  51. package/dist/active-memory-bridge.d.ts +1 -1
  52. package/dist/active-recall.d.ts +1 -1
  53. package/dist/ambient-provenance.d.ts +1 -1
  54. package/dist/artifact-search.d.ts +1 -1
  55. package/dist/{auto-sync-3SHMZVQS.js → auto-sync-5L7EUZ27.js} +4 -3
  56. package/dist/{auto-sync-3SHMZVQS.js.map → auto-sync-5L7EUZ27.js.map} +1 -1
  57. package/dist/behavior-learner.d.ts +1 -1
  58. package/dist/behavior-signals.d.ts +1 -1
  59. package/dist/bootstrap.d.ts +9 -9
  60. package/dist/briefing-window.d.ts +2 -2
  61. package/dist/briefing.d.ts +5 -3
  62. package/dist/briefing.js +11 -9
  63. package/dist/buffer-surprise-report.d.ts +1 -1
  64. package/dist/buffer-turn-helpers.d.ts +1 -1
  65. package/dist/buffer.d.ts +2 -2
  66. package/dist/bulk-import/index.d.ts +3 -3
  67. package/dist/calibration.d.ts +1 -1
  68. package/dist/capabilities.d.ts +1 -1
  69. package/dist/{capsule-crypto-YO5QJ6L3.js → capsule-crypto-GWVG7LGC.js} +2 -2
  70. package/dist/{catalog-CCzmf8IH.d.ts → catalog-C0KIwZqR.d.ts} +1 -1
  71. package/dist/causal-behavior.d.ts +1 -1
  72. package/dist/causal-consolidation.d.ts +1 -1
  73. package/dist/causal-consolidation.js +10 -10
  74. package/dist/causal-trajectory-graph.d.ts +1 -1
  75. package/dist/{chunk-4POAMKV6.js → chunk-27IOSH2W.js} +5 -2
  76. package/dist/chunk-27IOSH2W.js.map +1 -0
  77. package/dist/{chunk-OQIRBGUU.js → chunk-2Q4UAPLD.js} +4 -4
  78. package/dist/{chunk-3IMYRX3W.js → chunk-34E5NBQI.js} +2 -2
  79. package/dist/{chunk-BRHKW7GY.js → chunk-4IIDTPSK.js} +2 -2
  80. package/dist/{chunk-Q5XKKDFQ.js → chunk-5SZ6CLGJ.js} +2 -2
  81. package/dist/{chunk-VDX2J7OX.js → chunk-5W7CTZ2E.js} +4 -4
  82. package/dist/{chunk-EUYWQ7TS.js → chunk-652S5A5D.js} +2 -2
  83. package/dist/{chunk-ULZFZL7K.js → chunk-6IKXAAJI.js} +17 -28
  84. package/dist/chunk-6IKXAAJI.js.map +1 -0
  85. package/dist/{chunk-3TDAA7VA.js → chunk-6NMZXEJ7.js} +2 -2
  86. package/dist/{chunk-ZOAAY2OE.js → chunk-77E7LLMV.js} +7 -7
  87. package/dist/{chunk-MIUL6AUZ.js → chunk-7ML7STOD.js} +3 -3
  88. package/dist/{chunk-5SCFDQEJ.js → chunk-BPLPGOUJ.js} +2 -2
  89. package/dist/{chunk-RWMSMTQP.js → chunk-BS75WJBH.js} +2 -2
  90. package/dist/{chunk-XE2QCCT2.js → chunk-BTBAHTQ5.js} +2 -2
  91. package/dist/{chunk-42TIIO2M.js → chunk-BTUIHRRR.js} +2 -2
  92. package/dist/chunk-CIO7GCWE.js +29 -0
  93. package/dist/chunk-CIO7GCWE.js.map +1 -0
  94. package/dist/{chunk-SNEUAZ6B.js → chunk-CK3DZ6OE.js} +2 -2
  95. package/dist/{chunk-AJRJDXYR.js → chunk-E7MYSCSL.js} +2 -2
  96. package/dist/{chunk-3T6HIIKA.js → chunk-EHC3FIJ4.js} +2 -2
  97. package/dist/{chunk-EDZNW3HE.js → chunk-EPRBTGLM.js} +6 -6
  98. package/dist/{chunk-YTXNDEUS.js → chunk-FEP45MYY.js} +4 -3
  99. package/dist/{chunk-YTXNDEUS.js.map → chunk-FEP45MYY.js.map} +1 -1
  100. package/dist/{chunk-KFB4YNXM.js → chunk-G5F4MXXC.js} +2 -2
  101. package/dist/{chunk-VANZKHTN.js → chunk-G5OB4XZX.js} +4 -4
  102. package/dist/{chunk-N7V3P4V5.js → chunk-H5VDBZLZ.js} +2 -2
  103. package/dist/{chunk-645WOU5I.js → chunk-H7BZBSP6.js} +4 -4
  104. package/dist/{chunk-SZ4HFZKB.js → chunk-HMKPFW7R.js} +2 -2
  105. package/dist/{chunk-VFZQXYN5.js → chunk-HZXO2CJ6.js} +2 -2
  106. package/dist/{chunk-KXWE62IH.js → chunk-IOE75NA4.js} +2 -2
  107. package/dist/{chunk-PQHNZ63P.js → chunk-JJ45UTNT.js} +18 -5
  108. package/dist/chunk-JJ45UTNT.js.map +1 -0
  109. package/dist/{chunk-5TF5STAV.js → chunk-K477BTF4.js} +4 -4
  110. package/dist/{chunk-ML3U4KPR.js → chunk-K547KS3X.js} +4 -4
  111. package/dist/{chunk-UHGBNIOS.js → chunk-KVDUKH5E.js} +7 -2
  112. package/dist/chunk-KVDUKH5E.js.map +1 -0
  113. package/dist/{chunk-XTMYB2HY.js → chunk-LJQGQUNS.js} +2 -2
  114. package/dist/{chunk-WAS4HV46.js → chunk-LNH76ZJX.js} +87 -3
  115. package/dist/chunk-LNH76ZJX.js.map +1 -0
  116. package/dist/{chunk-VYMICVRA.js → chunk-LQNBQEMC.js} +2 -2
  117. package/dist/{chunk-J6QIAYNR.js → chunk-LVXBC6YB.js} +7 -2
  118. package/dist/{chunk-J6QIAYNR.js.map → chunk-LVXBC6YB.js.map} +1 -1
  119. package/dist/{chunk-IVKIODHO.js → chunk-MB6GLPRY.js} +4 -4
  120. package/dist/{chunk-BPQ7L27U.js → chunk-MIM7QT6H.js} +16 -16
  121. package/dist/chunk-MKYRCCSN.js +145 -0
  122. package/dist/chunk-MKYRCCSN.js.map +1 -0
  123. package/dist/{chunk-WBPD6SBZ.js → chunk-MNI7KB4Q.js} +54 -54
  124. package/dist/{chunk-6433HV72.js → chunk-MVIYRRVJ.js} +5 -5
  125. package/dist/{chunk-BXLOS5AJ.js → chunk-OWHERGF2.js} +2 -2
  126. package/dist/{chunk-QQYHYW2N.js → chunk-PQODT53H.js} +3 -3
  127. package/dist/{chunk-PHKU6BZ2.js → chunk-R7FQQQ23.js} +2 -2
  128. package/dist/{chunk-TOP3FSDW.js → chunk-RFFCBYBD.js} +11 -11
  129. package/dist/{chunk-O52TB5SL.js → chunk-SAWGVTCE.js} +2 -2
  130. package/dist/{chunk-LTYH2L6E.js → chunk-SILX74CP.js} +9 -9
  131. package/dist/{chunk-MYI3RKI6.js → chunk-SYU5JOBQ.js} +2 -2
  132. package/dist/{chunk-SY5JUJ2X.js → chunk-U5XC6DIS.js} +39 -39
  133. package/dist/{chunk-JXS5PDQ7.js → chunk-UOBPK2OS.js} +25 -7
  134. package/dist/chunk-UOBPK2OS.js.map +1 -0
  135. package/dist/{chunk-BOSIHHOH.js → chunk-UUYQWKHO.js} +2 -2
  136. package/dist/{chunk-DQEMWVMT.js → chunk-UVYI6VIX.js} +1 -1
  137. package/dist/{chunk-M4AHBM72.js → chunk-VCBG52MM.js} +4 -4
  138. package/dist/{chunk-62Y5AGCM.js → chunk-VENMDW4U.js} +10 -10
  139. package/dist/{chunk-6NAPOLRO.js → chunk-VY47VI2T.js} +6 -4
  140. package/dist/chunk-VY47VI2T.js.map +1 -0
  141. package/dist/{chunk-QTXNS3HB.js → chunk-WCWIV2JH.js} +2 -2
  142. package/dist/{chunk-6UKSOXAO.js → chunk-WQ6TRWAE.js} +3 -3
  143. package/dist/{chunk-CBY54QYW.js → chunk-X6HNXVXS.js} +4 -4
  144. package/dist/{chunk-DGUVXXAU.js → chunk-XFJUPJD7.js} +2 -2
  145. package/dist/{chunk-JPWSYHLB.js → chunk-YGSDWO3U.js} +2 -2
  146. package/dist/{chunk-GBVRVYF4.js → chunk-YINSSARY.js} +1 -1
  147. package/dist/{chunk-Q6OL23WM.js → chunk-Z4UPRZR6.js} +2 -2
  148. package/dist/{chunk-4F67JJPG.js → chunk-ZPN7W3OP.js} +2 -2
  149. package/dist/{cli-kcUqoV4E.d.ts → cli-xoJTOdMQ.d.ts} +5 -5
  150. package/dist/cli.d.ts +13 -13
  151. package/dist/cli.js +55 -54
  152. package/dist/coding/pre-action-gate.d.ts +1 -1
  153. package/dist/compounding/engine.d.ts +2 -2
  154. package/dist/compounding/engine.js +9 -9
  155. package/dist/compounding/preference-consolidator.d.ts +1 -1
  156. package/dist/compression-optimizer.d.ts +1 -1
  157. package/dist/config.d.ts +1 -1
  158. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  159. package/dist/connectors/codex-materialize-runner.js +9 -9
  160. package/dist/connectors/codex-materialize.d.ts +1 -1
  161. package/dist/connectors/index.d.ts +1 -1
  162. package/dist/connectors/index.js +9 -9
  163. package/dist/consolidation-provenance-check.d.ts +2 -2
  164. package/dist/consolidation-undo.d.ts +2 -2
  165. package/dist/contradiction/index.d.ts +2 -2
  166. package/dist/contradiction/index.js +4 -4
  167. package/dist/converge-config.d.ts +1 -1
  168. package/dist/convergence-refresh.d.ts +2 -2
  169. package/dist/convergence-refresh.js +11 -11
  170. package/dist/conversation-index/backend.d.ts +1 -1
  171. package/dist/conversation-index/chunker.d.ts +1 -1
  172. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  173. package/dist/conversation-index/indexer.d.ts +1 -1
  174. package/dist/conversation-index/search.d.ts +1 -1
  175. package/dist/corpus-watermark.d.ts +1 -1
  176. package/dist/corpus-watermark.js +11 -11
  177. package/dist/day-summary.d.ts +1 -1
  178. package/dist/day-summary.js +1 -1
  179. package/dist/delinearize.d.ts +1 -1
  180. package/dist/dependency-propagation-config.d.ts +1 -1
  181. package/dist/{dependency-propagation-delivery-DiY5T63p.d.ts → dependency-propagation-delivery-Cph4PnBe.d.ts} +1 -1
  182. package/dist/direct-answer-wiring.d.ts +1 -1
  183. package/dist/direct-answer-wiring.js +2 -1
  184. package/dist/direct-answer.d.ts +1 -1
  185. package/dist/embedding-fallback.d.ts +1 -1
  186. package/dist/enrichment/index.d.ts +1 -1
  187. package/dist/entity-origin-fields.d.ts +1 -1
  188. package/dist/entity-retrieval-i18n.d.ts +34 -0
  189. package/dist/entity-retrieval-i18n.js +13 -0
  190. package/dist/entity-retrieval-i18n.js.map +1 -0
  191. package/dist/entity-retrieval.d.ts +2 -2
  192. package/dist/entity-retrieval.js +10 -9
  193. package/dist/entity-schema.d.ts +1 -1
  194. package/dist/episodic-context.d.ts +1 -1
  195. package/dist/event-order-recall.js +2 -2
  196. package/dist/explicit-capture.d.ts +9 -9
  197. package/dist/external-wiki-access.d.ts +11 -11
  198. package/dist/external-wiki-access.js +24 -24
  199. package/dist/external-wiki-collection-registration.d.ts +1 -1
  200. package/dist/external-wiki-collection.d.ts +1 -1
  201. package/dist/external-wiki-mcp-tools.d.ts +11 -11
  202. package/dist/extraction-error-classification.d.ts +1 -1
  203. package/dist/extraction-faithfulness.d.ts +1 -1
  204. package/dist/extraction-judge-telemetry.d.ts +1 -1
  205. package/dist/extraction-judge-training.d.ts +1 -1
  206. package/dist/extraction-judge.d.ts +1 -1
  207. package/dist/extraction-liveness.d.ts +1 -1
  208. package/dist/extraction-normalization.d.ts +1 -1
  209. package/dist/extraction-prompt.d.ts +1 -1
  210. package/dist/extraction-source-grounding-helpers.d.ts +10 -1
  211. package/dist/extraction-source-grounding-helpers.js +3 -1
  212. package/dist/extraction-source-grounding-rules.d.ts +1 -1
  213. package/dist/extraction-source-grounding-rules.js +2 -2
  214. package/dist/extraction-source-grounding.d.ts +1 -1
  215. package/dist/extraction-source-grounding.js +3 -3
  216. package/dist/extraction.d.ts +1 -1
  217. package/dist/extraction.js +18 -18
  218. package/dist/fallback-llm.d.ts +1 -1
  219. package/dist/graph-dashboard-diff.d.ts +1 -1
  220. package/dist/graph-dashboard-key.d.ts +1 -1
  221. package/dist/graph-dashboard-parser.d.ts +1 -1
  222. package/dist/graph-edge-reinforcement.d.ts +1 -1
  223. package/dist/graph-path-reconstruction.d.ts +1 -1
  224. package/dist/graph-path-scoring.d.ts +1 -1
  225. package/dist/graph-snapshot.d.ts +1 -1
  226. package/dist/graph.d.ts +1 -1
  227. package/dist/harmonic-retrieval.js +1 -1
  228. package/dist/importance.d.ts +1 -1
  229. package/dist/importance.js +2 -1
  230. package/dist/importers/index.d.ts +1 -1
  231. package/dist/in-flight-reads.d.ts +1 -1
  232. package/dist/index.d.ts +21 -21
  233. package/dist/index.js +98 -96
  234. package/dist/intent.d.ts +1 -1
  235. package/dist/lcm/engine.d.ts +1 -1
  236. package/dist/lcm/engine.js +2 -2
  237. package/dist/lcm/index.d.ts +1 -1
  238. package/dist/lcm/index.js +4 -4
  239. package/dist/lcm/tools.d.ts +1 -1
  240. package/dist/lifecycle.d.ts +1 -1
  241. package/dist/live-connectors-runner.d.ts +1 -1
  242. package/dist/local-llm.d.ts +1 -1
  243. package/dist/local-llm.js +2 -2
  244. package/dist/local-model-endpoint.d.ts +1 -1
  245. package/dist/maintenance/memory-governance.d.ts +1 -1
  246. package/dist/maintenance/memory-governance.js +9 -9
  247. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
  248. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +9 -9
  249. package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
  250. package/dist/maintenance/rebuild-memory-projection.js +10 -10
  251. package/dist/{maintenance-CaqA4z7V.d.ts → maintenance-BNq31xpo.d.ts} +3 -3
  252. package/dist/mcp-memory-inspector-app.d.ts +11 -11
  253. package/dist/memory-action-policy.d.ts +1 -1
  254. package/dist/memory-cache.d.ts +1 -1
  255. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  256. package/dist/memory-projection-store.d.ts +1 -1
  257. package/dist/memory-provenance.d.ts +1 -1
  258. package/dist/memory-snapshot.d.ts +1 -1
  259. package/dist/memory-worth-outcomes.d.ts +2 -2
  260. package/dist/models-json.d.ts +1 -1
  261. package/dist/namespaces/migrate.d.ts +3 -3
  262. package/dist/namespaces/migrate.js +10 -10
  263. package/dist/namespaces/principal.d.ts +1 -1
  264. package/dist/namespaces/search.d.ts +1 -1
  265. package/dist/namespaces/search.js +7 -7
  266. package/dist/namespaces/storage.d.ts +3 -3
  267. package/dist/namespaces/storage.js +9 -9
  268. package/dist/native-knowledge.d.ts +1 -1
  269. package/dist/offline-sync-impression-drain.d.ts +1 -1
  270. package/dist/operator-doctor-corpus.d.ts +1 -1
  271. package/dist/operator-doctor-corpus.js +12 -12
  272. package/dist/operator-doctor-replica.d.ts +1 -1
  273. package/dist/operator-toolkit.d.ts +3 -3
  274. package/dist/operator-toolkit.js +17 -17
  275. package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
  276. package/dist/orchestration/maintenance.d.ts +4 -4
  277. package/dist/orchestration/maintenance.js +15 -15
  278. package/dist/{orchestrator-Bay_AofR.d.ts → orchestrator-CBuUOP2J.d.ts} +8 -8
  279. package/dist/orchestrator.d.ts +9 -9
  280. package/dist/orchestrator.js +84 -82
  281. package/dist/patterns-cli.d.ts +1 -1
  282. package/dist/{pipeline-X606GdRJ.d.ts → pipeline-CW_Q4WvX.d.ts} +1 -1
  283. package/dist/policy-runtime.d.ts +1 -1
  284. package/dist/proactive-contention.d.ts +1 -1
  285. package/dist/provenance.d.ts +1 -1
  286. package/dist/{public-http-DscQtnCx.d.ts → public-http-DR3sHfwk.d.ts} +1 -1
  287. package/dist/qmd-preflight.d.ts +2 -2
  288. package/dist/{qmd-DCKeR-GX.d.ts → qmd-q-cAzYuC.d.ts} +1 -1
  289. package/dist/qmd-recall-cache.d.ts +1 -1
  290. package/dist/qmd.d.ts +2 -2
  291. package/dist/recall-concurrency-config.d.ts +1 -1
  292. package/dist/recall-disclosure-escalation.d.ts +1 -1
  293. package/dist/recall-explain-renderer.d.ts +1 -1
  294. package/dist/recall-memory-map.d.ts +1 -1
  295. package/dist/recall-planner-llm.d.ts +1 -1
  296. package/dist/recall-state.d.ts +1 -1
  297. package/dist/recall-tag-filter.d.ts +1 -1
  298. package/dist/recall-timings.d.ts +1 -1
  299. package/dist/recall-xray-cli.d.ts +1 -1
  300. package/dist/recall-xray-renderer.d.ts +1 -1
  301. package/dist/recall-xray.d.ts +1 -1
  302. package/dist/reconcile/cursor.d.ts +1 -1
  303. package/dist/reconcile/manifest.d.ts +1 -1
  304. package/dist/reconcile/plan.d.ts +1 -1
  305. package/dist/replay/normalizers/chatgpt.d.ts +1 -1
  306. package/dist/replay/normalizers/claude.d.ts +1 -1
  307. package/dist/replay/normalizers/openclaw.d.ts +1 -1
  308. package/dist/replay/normalizers/shared.d.ts +1 -1
  309. package/dist/replay/runner.d.ts +1 -1
  310. package/dist/replay/types.d.ts +1 -1
  311. package/dist/replica-divergence.d.ts +1 -1
  312. package/dist/replica-peers-config.d.ts +1 -1
  313. package/dist/resolve-auth-token.d.ts +1 -1
  314. package/dist/retrieval-agents.d.ts +2 -2
  315. package/dist/retrieval-tiers.d.ts +1 -1
  316. package/dist/routing/engine.d.ts +1 -1
  317. package/dist/routing/store.d.ts +1 -1
  318. package/dist/salvage-envelope.d.ts +1 -1
  319. package/dist/{scope-profiles-_Y_RHCeE.d.ts → scope-profiles-CIr4mXgp.d.ts} +1 -1
  320. package/dist/search/embed-helper.d.ts +1 -1
  321. package/dist/search/factory.d.ts +1 -1
  322. package/dist/search/factory.js +6 -6
  323. package/dist/search/index.d.ts +1 -1
  324. package/dist/search/index.js +11 -11
  325. package/dist/search/lancedb-backend.d.ts +1 -1
  326. package/dist/search/lancedb-backend.js +2 -2
  327. package/dist/search/meilisearch-backend.d.ts +1 -1
  328. package/dist/search/meilisearch-backend.js +2 -2
  329. package/dist/search/noop-backend.d.ts +1 -1
  330. package/dist/search/orama-backend.d.ts +1 -1
  331. package/dist/search/orama-backend.js +2 -2
  332. package/dist/search/port.d.ts +1 -1
  333. package/dist/search/remote-backend.d.ts +1 -1
  334. package/dist/{semantic-consolidation-DT2VSrU0.d.ts → semantic-consolidation-BZ6J46j-.d.ts} +1 -1
  335. package/dist/semantic-consolidation.d.ts +2 -2
  336. package/dist/semantic-consolidation.js +10 -10
  337. package/dist/semantic-rule-promotion.js +9 -9
  338. package/dist/semantic-rule-verifier.d.ts +1 -1
  339. package/dist/semantic-rule-verifier.js +9 -9
  340. package/dist/{service-BMo-gwDE.d.ts → service-CCl4iyyY.d.ts} +2 -2
  341. package/dist/session-observer-bands.d.ts +1 -1
  342. package/dist/session-observer-state.d.ts +1 -1
  343. package/dist/shared-context/manager.d.ts +1 -1
  344. package/dist/signal.d.ts +1 -1
  345. package/dist/source-agent-qualifier.d.ts +1 -1
  346. package/dist/source-agent-qualifier.js +13 -13
  347. package/dist/{storage-CGzJGUUu.d.ts → storage-BPXmJKIt.d.ts} +1 -1
  348. package/dist/storage.d.ts +2 -2
  349. package/dist/storage.js +8 -8
  350. package/dist/summarizer.d.ts +1 -1
  351. package/dist/summarizer.js +3 -3
  352. package/dist/summary-snapshot.d.ts +1 -1
  353. package/dist/support-passport/index.d.ts +14 -14
  354. package/dist/support-passport/index.js +26 -26
  355. package/dist/temporal-supersession.d.ts +2 -2
  356. package/dist/temporal-timeline-recall.d.ts +1 -1
  357. package/dist/temporal-validity.d.ts +1 -1
  358. package/dist/threading.d.ts +1 -1
  359. package/dist/tier-migration.d.ts +2 -2
  360. package/dist/tier-routing.d.ts +1 -1
  361. package/dist/topics.d.ts +1 -1
  362. package/dist/topics.js +2 -1
  363. package/dist/transcript.d.ts +1 -1
  364. package/dist/transfer/backup.js +2 -2
  365. package/dist/transfer/capsule-export.js +2 -2
  366. package/dist/transfer/capsule-import.js +2 -2
  367. package/dist/trust-score-stage.d.ts +1 -1
  368. package/dist/trust-score.d.ts +1 -1
  369. package/dist/{types-CBEAYU76.d.ts → types-CltSWcND.d.ts} +1 -1
  370. package/dist/types.d.ts +1 -1
  371. package/dist/utility-runtime.d.ts +1 -1
  372. package/dist/verified-recall.js +9 -9
  373. package/dist/write-envelope.d.ts +1 -1
  374. package/package.json +2 -2
  375. package/src/briefing.test.ts +50 -0
  376. package/src/briefing.ts +3 -2
  377. package/src/chat/chat-engine.test.ts +15 -0
  378. package/src/chat/chat-engine.ts +13 -2
  379. package/src/day-summary.test.ts +63 -0
  380. package/src/day-summary.ts +13 -1
  381. package/src/entity-retrieval-i18n.test.ts +115 -0
  382. package/src/entity-retrieval-i18n.ts +161 -0
  383. package/src/entity-retrieval.ts +34 -34
  384. package/src/extraction-source-grounding-helpers.ts +112 -2
  385. package/src/extraction-source-grounding-rules.ts +3 -1
  386. package/src/extraction-source-grounding.test.ts +52 -0
  387. package/src/importance.ts +32 -22
  388. package/src/taxonomy/resolver.ts +7 -7
  389. package/src/topics.ts +5 -2
  390. package/src/utils/script-aware-text.ts +52 -0
  391. package/src/write-classifiers-cjk.test.ts +115 -0
  392. package/dist/chunk-4POAMKV6.js.map +0 -1
  393. package/dist/chunk-6NAPOLRO.js.map +0 -1
  394. package/dist/chunk-JXS5PDQ7.js.map +0 -1
  395. package/dist/chunk-PQHNZ63P.js.map +0 -1
  396. package/dist/chunk-UHGBNIOS.js.map +0 -1
  397. package/dist/chunk-ULZFZL7K.js.map +0 -1
  398. package/dist/chunk-WAS4HV46.js.map +0 -1
  399. /package/dist/{capsule-crypto-YO5QJ6L3.js.map → capsule-crypto-GWVG7LGC.js.map} +0 -0
  400. /package/dist/{chunk-OQIRBGUU.js.map → chunk-2Q4UAPLD.js.map} +0 -0
  401. /package/dist/{chunk-3IMYRX3W.js.map → chunk-34E5NBQI.js.map} +0 -0
  402. /package/dist/{chunk-BRHKW7GY.js.map → chunk-4IIDTPSK.js.map} +0 -0
  403. /package/dist/{chunk-Q5XKKDFQ.js.map → chunk-5SZ6CLGJ.js.map} +0 -0
  404. /package/dist/{chunk-VDX2J7OX.js.map → chunk-5W7CTZ2E.js.map} +0 -0
  405. /package/dist/{chunk-EUYWQ7TS.js.map → chunk-652S5A5D.js.map} +0 -0
  406. /package/dist/{chunk-3TDAA7VA.js.map → chunk-6NMZXEJ7.js.map} +0 -0
  407. /package/dist/{chunk-ZOAAY2OE.js.map → chunk-77E7LLMV.js.map} +0 -0
  408. /package/dist/{chunk-MIUL6AUZ.js.map → chunk-7ML7STOD.js.map} +0 -0
  409. /package/dist/{chunk-5SCFDQEJ.js.map → chunk-BPLPGOUJ.js.map} +0 -0
  410. /package/dist/{chunk-RWMSMTQP.js.map → chunk-BS75WJBH.js.map} +0 -0
  411. /package/dist/{chunk-XE2QCCT2.js.map → chunk-BTBAHTQ5.js.map} +0 -0
  412. /package/dist/{chunk-42TIIO2M.js.map → chunk-BTUIHRRR.js.map} +0 -0
  413. /package/dist/{chunk-SNEUAZ6B.js.map → chunk-CK3DZ6OE.js.map} +0 -0
  414. /package/dist/{chunk-AJRJDXYR.js.map → chunk-E7MYSCSL.js.map} +0 -0
  415. /package/dist/{chunk-3T6HIIKA.js.map → chunk-EHC3FIJ4.js.map} +0 -0
  416. /package/dist/{chunk-EDZNW3HE.js.map → chunk-EPRBTGLM.js.map} +0 -0
  417. /package/dist/{chunk-KFB4YNXM.js.map → chunk-G5F4MXXC.js.map} +0 -0
  418. /package/dist/{chunk-VANZKHTN.js.map → chunk-G5OB4XZX.js.map} +0 -0
  419. /package/dist/{chunk-N7V3P4V5.js.map → chunk-H5VDBZLZ.js.map} +0 -0
  420. /package/dist/{chunk-645WOU5I.js.map → chunk-H7BZBSP6.js.map} +0 -0
  421. /package/dist/{chunk-SZ4HFZKB.js.map → chunk-HMKPFW7R.js.map} +0 -0
  422. /package/dist/{chunk-VFZQXYN5.js.map → chunk-HZXO2CJ6.js.map} +0 -0
  423. /package/dist/{chunk-KXWE62IH.js.map → chunk-IOE75NA4.js.map} +0 -0
  424. /package/dist/{chunk-5TF5STAV.js.map → chunk-K477BTF4.js.map} +0 -0
  425. /package/dist/{chunk-ML3U4KPR.js.map → chunk-K547KS3X.js.map} +0 -0
  426. /package/dist/{chunk-XTMYB2HY.js.map → chunk-LJQGQUNS.js.map} +0 -0
  427. /package/dist/{chunk-VYMICVRA.js.map → chunk-LQNBQEMC.js.map} +0 -0
  428. /package/dist/{chunk-IVKIODHO.js.map → chunk-MB6GLPRY.js.map} +0 -0
  429. /package/dist/{chunk-BPQ7L27U.js.map → chunk-MIM7QT6H.js.map} +0 -0
  430. /package/dist/{chunk-WBPD6SBZ.js.map → chunk-MNI7KB4Q.js.map} +0 -0
  431. /package/dist/{chunk-6433HV72.js.map → chunk-MVIYRRVJ.js.map} +0 -0
  432. /package/dist/{chunk-BXLOS5AJ.js.map → chunk-OWHERGF2.js.map} +0 -0
  433. /package/dist/{chunk-QQYHYW2N.js.map → chunk-PQODT53H.js.map} +0 -0
  434. /package/dist/{chunk-PHKU6BZ2.js.map → chunk-R7FQQQ23.js.map} +0 -0
  435. /package/dist/{chunk-TOP3FSDW.js.map → chunk-RFFCBYBD.js.map} +0 -0
  436. /package/dist/{chunk-O52TB5SL.js.map → chunk-SAWGVTCE.js.map} +0 -0
  437. /package/dist/{chunk-LTYH2L6E.js.map → chunk-SILX74CP.js.map} +0 -0
  438. /package/dist/{chunk-MYI3RKI6.js.map → chunk-SYU5JOBQ.js.map} +0 -0
  439. /package/dist/{chunk-SY5JUJ2X.js.map → chunk-U5XC6DIS.js.map} +0 -0
  440. /package/dist/{chunk-BOSIHHOH.js.map → chunk-UUYQWKHO.js.map} +0 -0
  441. /package/dist/{chunk-DQEMWVMT.js.map → chunk-UVYI6VIX.js.map} +0 -0
  442. /package/dist/{chunk-M4AHBM72.js.map → chunk-VCBG52MM.js.map} +0 -0
  443. /package/dist/{chunk-62Y5AGCM.js.map → chunk-VENMDW4U.js.map} +0 -0
  444. /package/dist/{chunk-QTXNS3HB.js.map → chunk-WCWIV2JH.js.map} +0 -0
  445. /package/dist/{chunk-6UKSOXAO.js.map → chunk-WQ6TRWAE.js.map} +0 -0
  446. /package/dist/{chunk-CBY54QYW.js.map → chunk-X6HNXVXS.js.map} +0 -0
  447. /package/dist/{chunk-DGUVXXAU.js.map → chunk-XFJUPJD7.js.map} +0 -0
  448. /package/dist/{chunk-JPWSYHLB.js.map → chunk-YGSDWO3U.js.map} +0 -0
  449. /package/dist/{chunk-GBVRVYF4.js.map → chunk-YINSSARY.js.map} +0 -0
  450. /package/dist/{chunk-Q6OL23WM.js.map → chunk-Z4UPRZR6.js.map} +0 -0
  451. /package/dist/{chunk-4F67JJPG.js.map → chunk-ZPN7W3OP.js.map} +0 -0
@@ -2665,3 +2665,55 @@ test("grounding preserves plural identifiers after a proper-name copular subject
2665
2665
  assert.deepEqual(result.facts, []);
2666
2666
  }
2667
2667
  });
2668
+
2669
+ const JAPANESE_OBSERVED_TURN = {
2670
+ role: "user" as const,
2671
+ content: "田中さんは東京に住んでいます。毎日電車で会社に行きます。",
2672
+ timestamp: "2026-07-25T12:00:00.000Z",
2673
+ };
2674
+
2675
+ test("script-aware grounding keeps CJK paraphrased facts and embedded entity names", async () => {
2676
+ const engine = fixtureEngine({
2677
+ localLlmEnabled: true,
2678
+ localLlmModel: "fixture-local",
2679
+ localLlmFallback: false,
2680
+ });
2681
+ Object.assign(engine, {
2682
+ localLlm: {
2683
+ async chatCompletion() {
2684
+ return {
2685
+ content: JSON.stringify({
2686
+ facts: [
2687
+ {
2688
+ category: "fact",
2689
+ content: "田中さんは東京に住んでいる",
2690
+ confidence: 0.9,
2691
+ tags: [],
2692
+ },
2693
+ {
2694
+ category: "fact",
2695
+ content: "田中さんは大阪に住んでいる",
2696
+ confidence: 0.9,
2697
+ tags: [],
2698
+ },
2699
+ ],
2700
+ profileUpdates: [],
2701
+ entities: [{
2702
+ name: "田中",
2703
+ type: "person",
2704
+ facts: ["東京に住んでいる"],
2705
+ }],
2706
+ questions: [],
2707
+ }),
2708
+ };
2709
+ },
2710
+ },
2711
+ });
2712
+
2713
+ const result = await engine.extract([JAPANESE_OBSERVED_TURN]);
2714
+
2715
+ assert.deepEqual(result.facts.map((fact) => fact.content), ["田中さんは東京に住んでいる"]);
2716
+ assert.equal(result.entities.length, 1);
2717
+ assert.equal(result.entities[0]?.name, "田中");
2718
+ assert.deepEqual(result.entities[0]?.facts, ["東京に住んでいる"]);
2719
+ });
package/src/importance.ts CHANGED
@@ -7,6 +7,7 @@
7
7
  */
8
8
 
9
9
  import type { ImportanceLevel, ImportanceScore, MemoryCategory, MemoryFile } from "./types.js";
10
+ import { cjkBigrams, hasLatinWord, informationalLength } from "./utils/script-aware-text.js";
10
11
 
11
12
  // ---------------------------------------------------------------------------
12
13
  // Marker patterns for each tier
@@ -48,18 +49,6 @@ const HIGH_PATTERNS = [
48
49
  /\b(scheduled|appointment|meeting|call)\b/i,
49
50
  ];
50
51
 
51
- /** Normal importance markers (0.4-0.7) */
52
- const NORMAL_PATTERNS = [
53
- // Factual content
54
- /\b(is|are|was|were|has|have|does|do)\b/i,
55
- /\b(because|since|therefore|thus|so)\b/i,
56
- // Emotional content
57
- /\b(happy|sad|frustrated|excited|worried|anxious)\b/i,
58
- /\b(feel|feeling|felt)\b/i,
59
- // Technical details
60
- /\b(version|api|endpoint|database|server|config)\b/i,
61
- /\b(function|class|method|variable|parameter)\b/i,
62
- ];
63
52
 
64
53
  /** Low importance markers (0.2-0.4) */
65
54
  const LOW_PATTERNS = [
@@ -82,8 +71,6 @@ const TRIVIAL_PATTERNS = [
82
71
  /^(bye|goodbye|later|see ya|ttyl)[.!]?\s*$/i,
83
72
  /^(lol|haha|hehe|lmao|rofl)[.!]?\s*$/i,
84
73
  /^(hmm+|uhh*|ahh*|err*|umm*)[.!]?\s*$/i,
85
- // Very short content
86
- /^.{1,10}$/,
87
74
  ];
88
75
 
89
76
  // ---------------------------------------------------------------------------
@@ -134,16 +121,20 @@ const STOP_WORDS = new Set([
134
121
  * Returns top N keywords sorted by relevance.
135
122
  */
136
123
  function extractKeywords(content: string, maxKeywords: number = 5): string[] {
137
- // Tokenize and normalize
138
- const words = content
139
- .toLowerCase()
140
- .replace(/[^a-z0-9\s-]/g, " ")
141
- .split(/\s+/)
142
- .filter((w) => w.length >= 3 && !STOP_WORDS.has(w));
124
+ // Latin words plus CJK bigrams, so non-Latin content still yields
125
+ // keywords (pure-CJK prose returned none before #2192).
126
+ const candidates = [
127
+ ...content
128
+ .toLowerCase()
129
+ .replace(/[^a-z0-9\s-]/g, " ")
130
+ .split(/\s+/)
131
+ .filter((w) => w.length >= 3 && !STOP_WORDS.has(w)),
132
+ ...cjkBigrams(content),
133
+ ];
143
134
 
144
135
  // Count frequencies
145
136
  const freq = new Map<string, number>();
146
- for (const word of words) {
137
+ for (const word of candidates) {
147
138
  freq.set(word, (freq.get(word) ?? 0) + 1);
148
139
  }
149
140
 
@@ -170,7 +161,6 @@ export function scoreImportance(
170
161
  const reasons: string[] = [];
171
162
  let score = 0.5; // Start at normal baseline
172
163
 
173
- const lowerContent = content.toLowerCase();
174
164
  const contentLength = content.length;
175
165
 
176
166
  // Check for trivial content first (short-circuit)
@@ -185,6 +175,26 @@ export function scoreImportance(
185
175
  }
186
176
  }
187
177
 
178
+ // Very short content. informationalLength weights CJK/Hangul 3:1, so a
179
+ // dense non-Latin sentence ("予約しました") is not trivial for being
180
+ // under 10 raw characters while its English equivalent is not (#2192).
181
+ const weightedLength = informationalLength(content);
182
+ if (weightedLength >= 1 && weightedLength <= 10) {
183
+ return {
184
+ score: 0.1,
185
+ level: "trivial",
186
+ reasons: ["Trivial content (greeting, filler, or very short)"],
187
+ keywords: [],
188
+ };
189
+ }
190
+
191
+ // Documented non-Latin fallback (#2192): the English keyword tiers below
192
+ // cannot fire without Latin words, so the score rests on the 0.5 baseline
193
+ // plus script-agnostic signals (category boost, length, digits, tags).
194
+ if (!hasLatinWord(content)) {
195
+ reasons.push("Non-Latin script: keyword tiers not applicable; script-agnostic signals only");
196
+ }
197
+
188
198
  // Check critical patterns
189
199
  for (const pattern of CRITICAL_PATTERNS) {
190
200
  if (pattern.test(content)) {
@@ -7,6 +7,7 @@
7
7
 
8
8
  import type { MemoryCategory } from "../types.js";
9
9
  import type { ResolverDecision, Taxonomy, TaxonomyCategory } from "./types.js";
10
+ import { cjkBigrams } from "../utils/script-aware-text.js";
10
11
 
11
12
  const DEFAULT_CATEGORY_ID = "facts";
12
13
 
@@ -148,13 +149,12 @@ function computeKeywordScoreForTokens(contentTokens: Set<string>, cat: TaxonomyC
148
149
  }
149
150
 
150
151
  function tokenizeKeywordText(value: string): Set<string> {
151
- return new Set(
152
- value
153
- .toLowerCase()
154
- .split(/[^a-z0-9]+/)
155
- .map((word) => word.trim())
156
- .filter((word) => word.length >= 3 && !TAXONOMY_KEYWORD_STOPWORDS.has(word)),
157
- );
152
+ // CJK bigrams tokenize BOTH sides (content and filing rules), so a
153
+ // taxonomy written in a CJK language matches CJK content; Latin-only
154
+ // taxonomies see no change (issue #2192).
155
+ const latin = (value.toLowerCase().match(/[a-z0-9]+/g) ?? [])
156
+ .filter((word) => word.length >= 3 && !TAXONOMY_KEYWORD_STOPWORDS.has(word));
157
+ return new Set([...latin, ...cjkBigrams(value)]);
158
158
  }
159
159
 
160
160
  function selectFallbackCategory(
package/src/topics.ts CHANGED
@@ -6,6 +6,7 @@
6
6
  */
7
7
 
8
8
  import type { MemoryFile, TopicScore } from "./types.js";
9
+ import { cjkBigrams } from "./utils/script-aware-text.js";
9
10
 
10
11
  /** Stop words to exclude from topic extraction */
11
12
  const STOP_WORDS = new Set([
@@ -28,14 +29,16 @@ const STOP_WORDS = new Set([
28
29
 
29
30
  /**
30
31
  * Extract terms from content.
31
- * Returns normalized lowercase terms >= 3 chars.
32
+ * Returns normalized lowercase terms >= 3 chars, plus CJK bigrams so
33
+ * non-Latin memories contribute topics instead of none (issue #2192).
32
34
  */
33
35
  function extractTerms(content: string): string[] {
34
- return content
36
+ const latin = content
35
37
  .toLowerCase()
36
38
  .replace(/[^a-z0-9\s-]/g, " ")
37
39
  .split(/\s+/)
38
40
  .filter((w) => w.length >= 3 && !STOP_WORDS.has(w));
41
+ return [...latin, ...cjkBigrams(content)];
39
42
  }
40
43
 
41
44
  /**
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Script-aware text primitives for write-path classifiers (issue #2192).
3
+ *
4
+ * The local classifiers (importance, topics, taxonomy) grew around English
5
+ * keyword regexes and Latin-oriented tokenizers. Non-Latin prose matched no
6
+ * tier and lost every token: a Japanese sentence as dense as a full English
7
+ * clause was scored by raw character count and filed with zero keyword
8
+ * overlap. These helpers provide script-agnostic signals — weighted length,
9
+ * Latin-word detection, CJK bigram tokenization — without language detection.
10
+ */
11
+
12
+ /** CJK + Hangul: kana (incl. halfwidth), Hangul jamo/syllables, ext A, unified + compat ideographs, ext B. */
13
+ const CJK_CHAR =
14
+ /[\u3040-\u30ff\u3130-\u318f\u3400-\u4dbf\u4e00-\u9fff\uac00-\ud7af\uf900-\ufaff\uff66-\uff9f\u{20000}-\u{2a6df}]/u;
15
+
16
+ const CJK_RUN =
17
+ /[\u3040-\u30ff\u3130-\u318f\u3400-\u4dbf\u4e00-\u9fff\uac00-\ud7af\uf900-\ufaff\uff66-\uff9f\u{20000}-\u{2a6df}]+/gu;
18
+
19
+ /** True when the text contains a Latin word of two or more letters. */
20
+ export function hasLatinWord(text: string): boolean {
21
+ return /[a-z]{2,}/i.test(text);
22
+ }
23
+
24
+ /**
25
+ * Length in Latin-equivalent characters: every code point counts 1,
26
+ * CJK/Hangul code points count 3. One han/kana glyph typically carries a
27
+ * whole Latin word of information ("予約しました" ≈ "made a reservation"),
28
+ * so length cutoffs calibrated on English must weight dense scripts up, or
29
+ * short non-Latin sentences are systematically dumped into trivial buckets.
30
+ */
31
+ export function informationalLength(text: string): number {
32
+ let weight = 0;
33
+ for (const ch of text) {
34
+ weight += CJK_CHAR.test(ch) ? 3 : 1;
35
+ }
36
+ return weight;
37
+ }
38
+
39
+ /**
40
+ * Sliding bigrams over contiguous CJK runs — the standard script-agnostic
41
+ * substitute for word tokenization in unsegmented scripts. Runs shorter
42
+ * than two characters yield nothing (a lone glyph is too generic a token).
43
+ */
44
+ export function cjkBigrams(text: string): string[] {
45
+ const bigrams: string[] = [];
46
+ for (const run of text.match(CJK_RUN) ?? []) {
47
+ for (let i = 0; i + 1 < run.length; i++) {
48
+ bigrams.push(run.slice(i, i + 2));
49
+ }
50
+ }
51
+ return bigrams;
52
+ }
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Issue #2192: write-path classifiers must not dump non-English content
3
+ * into the lowest importance/taxonomy bucket merely for lacking English
4
+ * tokens. Script-agnostic signals (weighted length, CJK bigrams) carry the
5
+ * decision instead of English keywords.
6
+ */
7
+ import test from "node:test";
8
+ import assert from "node:assert/strict";
9
+
10
+ import { scoreImportance } from "./importance.js";
11
+ import { extractTopics } from "./topics.js";
12
+ import { DEFAULT_TAXONOMY } from "./taxonomy/default-taxonomy.js";
13
+ import { resolveCategory } from "./taxonomy/resolver.js";
14
+ import type { Taxonomy } from "./taxonomy/types.js";
15
+ import type { MemoryFile, MemoryFrontmatter } from "./types.js";
16
+
17
+ function makeMemory(id: string, content: string): MemoryFile {
18
+ const frontmatter: MemoryFrontmatter = {
19
+ id,
20
+ category: "fact",
21
+ created: "2026-08-17T00:00:00.000Z",
22
+ updated: "2026-08-17T00:00:00.000Z",
23
+ source: "extraction",
24
+ confidence: 0.8,
25
+ confidenceTier: "explicit",
26
+ tags: [],
27
+ };
28
+ return { path: `/memories/facts/2026-08-17/${id}.md`, frontmatter, content };
29
+ }
30
+
31
+ test("importance: dense Japanese/Chinese facts stay out of the trivial/low buckets", () => {
32
+ // 12 CJK chars ≈ a full English clause ("I will move to Tokyo next month").
33
+ // Before #2192 this matched the raw `^.{1,10}$` short-content rule and was
34
+ // scored trivial — dropping it at the write gate.
35
+ const japanese = scoreImportance("来月、東京に引っ越します。", "commitment");
36
+ assert.ok(
37
+ japanese.score >= 0.4,
38
+ `Japanese commitment scored ${japanese.score} (${japanese.level})`,
39
+ );
40
+ assert.notEqual(japanese.level, "trivial");
41
+ assert.notEqual(japanese.level, "low");
42
+
43
+ const chinese = scoreImportance("会议定在周五下午两点,请准时参加。", "fact");
44
+ assert.ok(
45
+ chinese.score >= 0.4,
46
+ `Chinese meeting fact scored ${chinese.score} (${chinese.level})`,
47
+ );
48
+ assert.notEqual(chinese.level, "trivial");
49
+ assert.notEqual(chinese.level, "low");
50
+
51
+ // Keywords must not be empty for non-Latin content (CJK bigram fallback).
52
+ assert.ok(
53
+ japanese.keywords.length > 0,
54
+ `expected CJK bigram keywords, got ${JSON.stringify(japanese.keywords)}`,
55
+ );
56
+ });
57
+
58
+ test("importance: genuinely trivial CJK interjections stay trivial", () => {
59
+ // "はい" ≈ "yes" — 2 glyphs, weighted length 6, still under the cutoff.
60
+ assert.equal(scoreImportance("はい", "fact").level, "trivial");
61
+ assert.equal(scoreImportance("嗯", "fact").level, "trivial");
62
+ });
63
+
64
+ test("taxonomy: CJK filing rules match CJK content instead of the fallback pick", () => {
65
+ const taxonomy: Taxonomy = {
66
+ version: 1,
67
+ categories: [
68
+ {
69
+ id: "paris-notes",
70
+ name: "Paris Notes",
71
+ description: "Statements about Paris",
72
+ filingRules: ["paris seine arrondissement"],
73
+ // Lower priority wins the pre-fix keyword-less tie-break, so this
74
+ // fixture fails unless CJK content actually matches CJK filing rules.
75
+ priority: 10,
76
+ memoryCategories: ["fact"],
77
+ },
78
+ {
79
+ id: "tokyo-notes",
80
+ name: "Tokyo Notes",
81
+ description: "東京に関する事実",
82
+ filingRules: ["東京 についての記録"],
83
+ priority: 40,
84
+ memoryCategories: ["fact"],
85
+ },
86
+ ],
87
+ };
88
+
89
+ const decision = resolveCategory("東京に住んでいます。", "fact", taxonomy);
90
+ assert.equal(decision.categoryId, "tokyo-notes");
91
+ assert.ok(decision.confidence >= 0.9, `confidence ${decision.confidence}`);
92
+ });
93
+
94
+ test("taxonomy: default taxonomy resolution is unchanged for non-Latin facts", () => {
95
+ const decision = resolveCategory("会議は金曜日の午後です。", "fact", DEFAULT_TAXONOMY);
96
+ assert.equal(decision.categoryId, "facts");
97
+ assert.equal(decision.confidence, 1.0);
98
+ });
99
+
100
+ test("topics: CJK memories contribute topics via bigrams", () => {
101
+ const topics = extractTopics(
102
+ [
103
+ makeMemory(
104
+ "fact-cjk",
105
+ "東京に住んでいます。東京の会社で働いています。",
106
+ ),
107
+ makeMemory("fact-en", "Deployed the api server to production."),
108
+ ],
109
+ 20,
110
+ );
111
+
112
+ const tokyo = topics.find((t) => t.term === "東京");
113
+ assert.ok(tokyo, `expected 東京 in topics: ${JSON.stringify(topics)}`);
114
+ assert.ok(tokyo.count >= 2, `expected 東京 twice, got ${tokyo.count}`);
115
+ });
@@ -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 isAttachedNegatedAuxiliary,\n isInterrogativeSourceSentence,\n normalizeForExactMatch,\n normalizedGroundingAlignmentTokenSequence,\n normalizedGroundingTokenSequence,\n sourceSentences,\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}\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 );\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 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): ExtractionResult[\"facts\"][number] | undefined {\n const factContext = selectGroundingContext(\n fact.content,\n resolveGroundingContext(fact.content, source, assertionSource, roleAssertionSources),\n );\n if (!isGroundedCandidate(\n fact.content,\n factContext.source,\n factContext.assertionSource,\n false,\n factContext.allowRoleNormalization,\n )) return undefined;\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 fact.content,\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): 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 );\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 +0,0 @@
1
- {"version":3,"sources":["../src/taxonomy/resolver.ts","../src/direct-answer-wiring.ts"],"sourcesContent":["/**\n * Resolver decision tree for the MECE taxonomy.\n *\n * Given extracted content and its MemoryCategory, determines which\n * taxonomy category the knowledge should be filed under.\n */\n\nimport type { MemoryCategory } from \"../types.js\";\nimport type { ResolverDecision, Taxonomy, TaxonomyCategory } from \"./types.js\";\n\nconst DEFAULT_CATEGORY_ID = \"facts\";\n\n/**\n * Resolve a piece of content to a taxonomy category.\n *\n * Algorithm:\n * 1. Find all taxonomy categories whose `memoryCategories` include\n * the given `memoryCategory`.\n * 2. If exactly one match, return it with confidence 1.0.\n * 3. If multiple matches, prefer the strongest exact-token keyword\n * overlap from filing rules. Use priority only as a tie-breaker.\n * If no filing rules match, choose the explicit/default fallback\n * category instead of letting low-priority generic terms win.\n * 4. If no match, fall back to the \"facts\" category (or first\n * category if \"facts\" is absent) with low confidence.\n * 5. Always populate `alternatives` with other plausible categories.\n */\nexport function resolveCategory(\n content: string,\n memoryCategory: MemoryCategory,\n taxonomy: Taxonomy,\n): ResolverDecision {\n const contentTokens = tokenizeKeywordText(content);\n\n // Step 1: find matching categories\n const matches = taxonomy.categories.filter((cat) =>\n cat.memoryCategories.includes(memoryCategory),\n );\n\n if (matches.length === 0) {\n // No taxonomy category accepts this MemoryCategory — fall back\n const fallback =\n taxonomy.categories.find((c) => c.id === DEFAULT_CATEGORY_ID) ??\n taxonomy.categories[0];\n if (!fallback) {\n return {\n categoryId: DEFAULT_CATEGORY_ID,\n confidence: 0,\n reason: \"Taxonomy is empty; using default category\",\n alternatives: [],\n };\n }\n const alternatives = taxonomy.categories\n .filter((c) => c.id !== fallback.id)\n .map((c) => ({\n categoryId: c.id,\n reason: c.description,\n }));\n return {\n categoryId: fallback.id,\n confidence: 0.3,\n reason: `No taxonomy category maps to MemoryCategory \"${memoryCategory}\"; falling back to \"${fallback.name}\"`,\n alternatives,\n };\n }\n\n if (matches.length === 1) {\n const match = matches[0]!;\n const alternatives = taxonomy.categories\n .filter((c) => c.id !== match.id)\n .map((c) => ({\n categoryId: c.id,\n reason: c.description,\n }));\n return {\n categoryId: match.id,\n confidence: 1.0,\n reason: `Unique match: MemoryCategory \"${memoryCategory}\" maps to \"${match.name}\"`,\n alternatives,\n };\n }\n\n // Multiple matches — use filing rule keyword heuristics + priority\n const scored = matches.map((cat) => ({\n cat,\n keywordScore: computeKeywordScoreForTokens(contentTokens, cat),\n }));\n\n // Sort by keyword score descending, then priority ascending (lower wins)\n scored.sort((a, b) => {\n if (b.keywordScore !== a.keywordScore) return b.keywordScore - a.keywordScore;\n return a.cat.priority - b.cat.priority;\n });\n\n const topScored = scored[0]!;\n const best = topScored.keywordScore > 0\n ? topScored\n : {\n cat: selectFallbackCategory(matches) ?? topScored.cat,\n keywordScore: 0,\n };\n const runnerUp = scored[1];\n\n // Confidence is higher when keyword match clearly differentiates\n const confidence =\n best.keywordScore > 0 && (!runnerUp || best.keywordScore > runnerUp.keywordScore)\n ? 0.9\n : 0.7;\n\n const alternatives = taxonomy.categories\n .filter((c) => c.id !== best.cat.id)\n .map((c) => ({\n categoryId: c.id,\n reason: c.description,\n }));\n\n const reason =\n best.keywordScore > 0\n ? `Filing rules for \"${best.cat.name}\" matched content keywords (priority ${best.cat.priority})`\n : `No filing rules matched content keywords; using fallback category \"${best.cat.name}\"`;\n\n return {\n categoryId: best.cat.id,\n confidence,\n reason,\n alternatives,\n };\n}\n\n/**\n * Compute a simple keyword overlap score between content and\n * a category's filing rules + description.\n */\nfunction computeKeywordScoreForTokens(contentTokens: Set<string>, cat: TaxonomyCategory): number {\n let score = 0;\n const ruleText = [...cat.filingRules, cat.description]\n .join(\" \")\n .toLowerCase();\n\n const keywords = tokenizeKeywordText(ruleText);\n\n for (const kw of keywords) {\n if (contentTokens.has(kw)) {\n score += 1;\n }\n }\n return score;\n}\n\nfunction tokenizeKeywordText(value: string): Set<string> {\n return new Set(\n value\n .toLowerCase()\n .split(/[^a-z0-9]+/)\n .map((word) => word.trim())\n .filter((word) => word.length >= 3 && !TAXONOMY_KEYWORD_STOPWORDS.has(word)),\n );\n}\n\nfunction selectFallbackCategory(\n categories: readonly TaxonomyCategory[],\n): TaxonomyCategory | undefined {\n return categories.find((cat) => cat.id === DEFAULT_CATEGORY_ID) ??\n categories.find((cat) => {\n const text = `${cat.id} ${cat.name} ${cat.description} ${cat.filingRules.join(\" \")}`.toLowerCase();\n return /\\b(general|fallback)\\b/.test(text);\n });\n}\n\nconst TAXONOMY_KEYWORD_STOPWORDS = new Set([\n \"about\",\n \"all\",\n \"and\",\n \"are\",\n \"for\",\n \"from\",\n \"has\",\n \"into\",\n \"not\",\n \"the\",\n \"this\",\n \"was\",\n \"with\",\n]);\n","/**\n * Direct-answer wiring (issue #518 slice 3).\n *\n * Binds the pure eligibility decision (`direct-answer.ts`) to the data\n * sources needed to build candidates: storage, trust-zones, taxonomy,\n * and importance scoring. Kept as a separate module so that:\n *\n * - The eligibility layer stays pure and unit-testable without stores.\n * - Each caller injects its own source accessors. The orchestrator\n * binding is a follow-on slice; tests here use mock sources.\n * - The wiring is safe to ship alone — nothing calls `tryDirectAnswer`\n * yet, so enabling this module's presence does not change recall\n * behavior. The next slice adds exactly one call site before QMD.\n *\n * Short-circuit contract:\n *\n * - When the resolved gate (`input.enabled`, projected from\n * `caps.recallDirectAnswer` at the recall-operation entry) is `false`, the\n * function returns the\n * eligibility verdict with reason `\"disabled\"` without touching any source\n * accessor. This is the documented default.\n * - When enabled, the wiring cheaply drops non-trusted-zone memories\n * and ineligible taxonomy buckets before computing importance, so\n * the eligibility module sees a pre-filtered candidate set. The\n * eligibility module still performs the same checks itself — this\n * module is purely an I/O and prefiltering layer.\n */\n\nimport type { MemoryFile, PluginConfig } from \"./types.js\";\nimport type { TrustZoneName } from \"./trust-zones.js\";\nimport type { Taxonomy } from \"./taxonomy/types.js\";\nimport { resolveCategory } from \"./taxonomy/resolver.js\";\nimport { normalizeRecallTokens } from \"./recall-tokenization.js\";\nimport { throwIfAborted } from \"./abort-error.js\";\nimport {\n isDirectAnswerEligible,\n type DirectAnswerCandidate,\n type DirectAnswerConfig,\n type DirectAnswerResult,\n} from \"./direct-answer.js\";\n\n/**\n * Caller-provided accessors for candidate sourcing. Decouples the\n * wiring from any specific storage / trust-zone / importance backend.\n */\nexport interface DirectAnswerSources {\n /**\n * List memories eligible to be considered for direct-answer.\n * Callers are expected to return only active, non-superseded memories\n * in the requested namespace; the wiring will cheaply re-filter on\n * trust zone and taxonomy bucket and hand the rest to the eligibility\n * module, which applies the full gate ladder.\n */\n listCandidateMemories(options: {\n namespace: string;\n abortSignal?: AbortSignal;\n }): Promise<MemoryFile[]>;\n /**\n * Resolve the trust-zone record for a memory. Returns `null` when\n * the memory has no trust-zone record (treated as not trusted).\n */\n trustZoneFor(memoryId: string): Promise<TrustZoneName | null>;\n /**\n * Resolve a calibrated importance score in [0, 1] for a memory.\n */\n importanceFor(memory: MemoryFile): number;\n /**\n * Taxonomy used to classify memories into direct-answer buckets.\n */\n taxonomy: Taxonomy;\n}\n\nexport interface DirectAnswerWiringInput {\n query: string;\n namespace: string;\n config: Pick<\n PluginConfig,\n | \"recallDirectAnswerTokenOverlapFloor\"\n | \"recallDirectAnswerImportanceFloor\"\n | \"recallDirectAnswerAmbiguityMargin\"\n | \"recallDirectAnswerEligibleTaxonomyBuckets\"\n >;\n /**\n * Direct-answer capability gate, resolved once at the recall-operation entry\n * via `resolveCapabilities(config).recallDirectAnswer` (issue #1523). This\n * is the sole gate — the function no longer reads the config flag directly.\n * Callers MUST pass the resolved capability so the whole operation agrees on\n * a single gate value.\n */\n enabled: boolean;\n sources: DirectAnswerSources;\n queryEntityRefs?: string[];\n abortSignal?: AbortSignal;\n}\n\n/**\n * Attempt direct-answer resolution. Returns the eligibility verdict\n * produced by `isDirectAnswerEligible` with candidates materialized\n * from the caller-supplied sources.\n */\nexport async function tryDirectAnswer(\n input: DirectAnswerWiringInput,\n): Promise<DirectAnswerResult> {\n const { query, namespace, config, enabled, sources, queryEntityRefs, abortSignal } = input;\n\n const eligibilityConfig: DirectAnswerConfig = {\n enabled,\n tokenOverlapFloor: config.recallDirectAnswerTokenOverlapFloor,\n importanceFloor: config.recallDirectAnswerImportanceFloor,\n ambiguityMargin: config.recallDirectAnswerAmbiguityMargin,\n eligibleTaxonomyBuckets: config.recallDirectAnswerEligibleTaxonomyBuckets,\n };\n\n // Short-circuit disabled case before touching any I/O.\n if (!eligibilityConfig.enabled) {\n return isDirectAnswerEligible({\n query,\n candidates: [],\n config: eligibilityConfig,\n queryEntityRefs,\n });\n }\n\n // Short-circuit empty-query case before any I/O. isDirectAnswerEligible\n // deterministically returns reason \"empty-query\" when the query\n // normalizes to zero searchable tokens; there's no point materializing\n // candidates just to reach the same verdict, and doing so would\n // surface avoidable upstream errors for requests that should exit\n // immediately.\n if (normalizeRecallTokens(query).length === 0) {\n return isDirectAnswerEligible({\n query,\n candidates: [],\n config: eligibilityConfig,\n queryEntityRefs,\n });\n }\n\n throwIfAborted(abortSignal, \"direct-answer wiring aborted\");\n const memories = await sources.listCandidateMemories({ namespace, abortSignal });\n throwIfAborted(abortSignal, \"direct-answer wiring aborted\");\n const candidates: DirectAnswerCandidate[] = [];\n\n for (const memory of memories) {\n // Throw rather than returning a partial verdict — a mid-loop abort\n // that left competing candidates unprocessed could otherwise surface\n // a spurious \"eligible\" result that the ambiguity gate never got a\n // chance to reject. The check repeats after every await so an\n // abort that lands during the in-flight I/O on the final memory\n // (after which no further iteration would exist) still stops us.\n throwIfAborted(abortSignal, \"direct-answer wiring aborted\");\n\n const trustZone = await sources.trustZoneFor(memory.frontmatter.id);\n throwIfAborted(abortSignal, \"direct-answer wiring aborted\");\n\n // Cheap pre-filter: non-trusted memories can't qualify, so skip\n // taxonomy and importance resolution for them.\n if (trustZone !== \"trusted\") continue;\n\n const decision = resolveCategory(\n memory.content,\n memory.frontmatter.category,\n sources.taxonomy,\n );\n const taxonomyBucket = decision.categoryId;\n if (!eligibilityConfig.eligibleTaxonomyBuckets.includes(taxonomyBucket)) continue;\n\n const importanceScore = sources.importanceFor(memory);\n\n candidates.push({\n memory,\n trustZone,\n taxonomyBucket,\n importanceScore,\n });\n }\n\n // Final check — if abort landed during the trust-zone await for the\n // last memory, the loop condition no longer fires. Guard before we\n // hand candidates to the eligibility gate.\n throwIfAborted(abortSignal, \"direct-answer wiring aborted\");\n\n return isDirectAnswerEligible({\n query,\n candidates,\n config: eligibilityConfig,\n queryEntityRefs,\n });\n}\n"],"mappings":";;;;;;;;;;;AAUA,IAAM,sBAAsB;AAiBrB,SAAS,gBACd,SACA,gBACA,UACkB;AAClB,QAAM,gBAAgB,oBAAoB,OAAO;AAGjD,QAAM,UAAU,SAAS,WAAW;AAAA,IAAO,CAAC,QAC1C,IAAI,iBAAiB,SAAS,cAAc;AAAA,EAC9C;AAEA,MAAI,QAAQ,WAAW,GAAG;AAExB,UAAM,WACJ,SAAS,WAAW,KAAK,CAAC,MAAM,EAAE,OAAO,mBAAmB,KAC5D,SAAS,WAAW,CAAC;AACvB,QAAI,CAAC,UAAU;AACb,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,cAAc,CAAC;AAAA,MACjB;AAAA,IACF;AACA,UAAMA,gBAAe,SAAS,WAC3B,OAAO,CAAC,MAAM,EAAE,OAAO,SAAS,EAAE,EAClC,IAAI,CAAC,OAAO;AAAA,MACX,YAAY,EAAE;AAAA,MACd,QAAQ,EAAE;AAAA,IACZ,EAAE;AACJ,WAAO;AAAA,MACL,YAAY,SAAS;AAAA,MACrB,YAAY;AAAA,MACZ,QAAQ,gDAAgD,cAAc,uBAAuB,SAAS,IAAI;AAAA,MAC1G,cAAAA;AAAA,IACF;AAAA,EACF;AAEA,MAAI,QAAQ,WAAW,GAAG;AACxB,UAAM,QAAQ,QAAQ,CAAC;AACvB,UAAMA,gBAAe,SAAS,WAC3B,OAAO,CAAC,MAAM,EAAE,OAAO,MAAM,EAAE,EAC/B,IAAI,CAAC,OAAO;AAAA,MACX,YAAY,EAAE;AAAA,MACd,QAAQ,EAAE;AAAA,IACZ,EAAE;AACJ,WAAO;AAAA,MACL,YAAY,MAAM;AAAA,MAClB,YAAY;AAAA,MACZ,QAAQ,iCAAiC,cAAc,cAAc,MAAM,IAAI;AAAA,MAC/E,cAAAA;AAAA,IACF;AAAA,EACF;AAGA,QAAM,SAAS,QAAQ,IAAI,CAAC,SAAS;AAAA,IACnC;AAAA,IACA,cAAc,6BAA6B,eAAe,GAAG;AAAA,EAC/D,EAAE;AAGF,SAAO,KAAK,CAAC,GAAG,MAAM;AACpB,QAAI,EAAE,iBAAiB,EAAE,aAAc,QAAO,EAAE,eAAe,EAAE;AACjE,WAAO,EAAE,IAAI,WAAW,EAAE,IAAI;AAAA,EAChC,CAAC;AAED,QAAM,YAAY,OAAO,CAAC;AAC1B,QAAM,OAAO,UAAU,eAAe,IAClC,YACA;AAAA,IACE,KAAK,uBAAuB,OAAO,KAAK,UAAU;AAAA,IAClD,cAAc;AAAA,EAChB;AACJ,QAAM,WAAW,OAAO,CAAC;AAGzB,QAAM,aACJ,KAAK,eAAe,MAAM,CAAC,YAAY,KAAK,eAAe,SAAS,gBAChE,MACA;AAEN,QAAM,eAAe,SAAS,WAC3B,OAAO,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,EAAE,EAClC,IAAI,CAAC,OAAO;AAAA,IACX,YAAY,EAAE;AAAA,IACd,QAAQ,EAAE;AAAA,EACZ,EAAE;AAEJ,QAAM,SACJ,KAAK,eAAe,IAChB,qBAAqB,KAAK,IAAI,IAAI,wCAAwC,KAAK,IAAI,QAAQ,MAC3F,sEAAsE,KAAK,IAAI,IAAI;AAEzF,SAAO;AAAA,IACL,YAAY,KAAK,IAAI;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAMA,SAAS,6BAA6B,eAA4B,KAA+B;AAC/F,MAAI,QAAQ;AACZ,QAAM,WAAW,CAAC,GAAG,IAAI,aAAa,IAAI,WAAW,EAClD,KAAK,GAAG,EACR,YAAY;AAEf,QAAM,WAAW,oBAAoB,QAAQ;AAE7C,aAAW,MAAM,UAAU;AACzB,QAAI,cAAc,IAAI,EAAE,GAAG;AACzB,eAAS;AAAA,IACX;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,oBAAoB,OAA4B;AACvD,SAAO,IAAI;AAAA,IACT,MACG,YAAY,EACZ,MAAM,YAAY,EAClB,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,EACzB,OAAO,CAAC,SAAS,KAAK,UAAU,KAAK,CAAC,2BAA2B,IAAI,IAAI,CAAC;AAAA,EAC/E;AACF;AAEA,SAAS,uBACP,YAC8B;AAC9B,SAAO,WAAW,KAAK,CAAC,QAAQ,IAAI,OAAO,mBAAmB,KAC5D,WAAW,KAAK,CAAC,QAAQ;AACvB,UAAM,OAAO,GAAG,IAAI,EAAE,IAAI,IAAI,IAAI,IAAI,IAAI,WAAW,IAAI,IAAI,YAAY,KAAK,GAAG,CAAC,GAAG,YAAY;AACjG,WAAO,yBAAyB,KAAK,IAAI;AAAA,EAC3C,CAAC;AACL;AAEA,IAAM,6BAA6B,oBAAI,IAAI;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;;;ACnFD,eAAsB,gBACpB,OAC6B;AAC7B,QAAM,EAAE,OAAO,WAAW,QAAQ,SAAS,SAAS,iBAAiB,YAAY,IAAI;AAErF,QAAM,oBAAwC;AAAA,IAC5C;AAAA,IACA,mBAAmB,OAAO;AAAA,IAC1B,iBAAiB,OAAO;AAAA,IACxB,iBAAiB,OAAO;AAAA,IACxB,yBAAyB,OAAO;AAAA,EAClC;AAGA,MAAI,CAAC,kBAAkB,SAAS;AAC9B,WAAO,uBAAuB;AAAA,MAC5B;AAAA,MACA,YAAY,CAAC;AAAA,MACb,QAAQ;AAAA,MACR;AAAA,IACF,CAAC;AAAA,EACH;AAQA,MAAI,sBAAsB,KAAK,EAAE,WAAW,GAAG;AAC7C,WAAO,uBAAuB;AAAA,MAC5B;AAAA,MACA,YAAY,CAAC;AAAA,MACb,QAAQ;AAAA,MACR;AAAA,IACF,CAAC;AAAA,EACH;AAEA,iBAAe,aAAa,8BAA8B;AAC1D,QAAM,WAAW,MAAM,QAAQ,sBAAsB,EAAE,WAAW,YAAY,CAAC;AAC/E,iBAAe,aAAa,8BAA8B;AAC1D,QAAM,aAAsC,CAAC;AAE7C,aAAW,UAAU,UAAU;AAO7B,mBAAe,aAAa,8BAA8B;AAE1D,UAAM,YAAY,MAAM,QAAQ,aAAa,OAAO,YAAY,EAAE;AAClE,mBAAe,aAAa,8BAA8B;AAI1D,QAAI,cAAc,UAAW;AAE7B,UAAM,WAAW;AAAA,MACf,OAAO;AAAA,MACP,OAAO,YAAY;AAAA,MACnB,QAAQ;AAAA,IACV;AACA,UAAM,iBAAiB,SAAS;AAChC,QAAI,CAAC,kBAAkB,wBAAwB,SAAS,cAAc,EAAG;AAEzE,UAAM,kBAAkB,QAAQ,cAAc,MAAM;AAEpD,eAAW,KAAK;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAKA,iBAAe,aAAa,8BAA8B;AAE1D,SAAO,uBAAuB;AAAA,IAC5B;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,EACF,CAAC;AACH;","names":["alternatives"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/importance.ts"],"sourcesContent":["/**\n * Local Importance Scoring (Phase 1B)\n *\n * Zero-LLM heuristic system that evaluates each memory's significance.\n * Analyzes content for markers like explicit importance statements,\n * personal information, instructions, emotional content, and factual density.\n */\n\nimport type { ImportanceLevel, ImportanceScore, MemoryCategory, MemoryFile } from \"./types.js\";\n\n// ---------------------------------------------------------------------------\n// Marker patterns for each tier\n// ---------------------------------------------------------------------------\n\n/** Critical importance markers (0.9-1.0) */\nconst CRITICAL_PATTERNS = [\n // Explicit importance\n /\\b(critical|crucial|essential|must|always|never)\\b/i,\n /\\b(important|remember this|don't forget)\\b/i,\n // Personal identity\n /\\b(my name is|i am|i'm called)\\b/i,\n /\\b(my (birthday|phone|email|address|ssn|password))\\b/i,\n // Strong preferences\n /\\b(i (hate|love|despise|adore))\\b/i,\n /\\b(absolutely|definitely|certainly) (not|must|should)\\b/i,\n // Corrections (high weight)\n /\\b(actually|no,? that's wrong|correction:?|let me correct)\\b/i,\n /\\b(i said|i meant|i was wrong)\\b/i,\n];\n\n/** High importance markers (0.7-0.9) */\nconst HIGH_PATTERNS = [\n // Decisions\n /\\b(decided|decision|chose|choosing|picked|selected)\\b/i,\n /\\b(we('ll| will) (go with|use|implement))\\b/i,\n // Instructions\n /\\b(make sure|ensure|always|don't|do not|never|avoid)\\b/i,\n /\\b(you (should|must|need to))\\b/i,\n // Temporal references (deadlines, schedules)\n /\\b(by (monday|tuesday|wednesday|thursday|friday|saturday|sunday))\\b/i,\n /\\b(deadline|due (date|by)|by (end of|next))\\b/i,\n /\\b(tomorrow|next week|this week|today)\\b/i,\n // Preferences\n /\\b(i (prefer|like|want|need|dislike))\\b/i,\n /\\b(my (preference|style|approach|way))\\b/i,\n // Commitments\n /\\b(i('ll| will)|promise|commit|guarantee)\\b/i,\n /\\b(scheduled|appointment|meeting|call)\\b/i,\n];\n\n/** Normal importance markers (0.4-0.7) */\nconst NORMAL_PATTERNS = [\n // Factual content\n /\\b(is|are|was|were|has|have|does|do)\\b/i,\n /\\b(because|since|therefore|thus|so)\\b/i,\n // Emotional content\n /\\b(happy|sad|frustrated|excited|worried|anxious)\\b/i,\n /\\b(feel|feeling|felt)\\b/i,\n // Technical details\n /\\b(version|api|endpoint|database|server|config)\\b/i,\n /\\b(function|class|method|variable|parameter)\\b/i,\n];\n\n/** Low importance markers (0.2-0.4) */\nconst LOW_PATTERNS = [\n // Uncertainty\n /\\b(maybe|perhaps|possibly|might|could be)\\b/i,\n /\\b(i think|i guess|not sure|uncertain)\\b/i,\n /\\b(probably|likely|seems like)\\b/i,\n // Hedging\n /\\b(kind of|sort of|somewhat|a bit)\\b/i,\n /\\b(in a way|to some extent)\\b/i,\n];\n\n/** Trivial content markers (0.0-0.2) */\nconst TRIVIAL_PATTERNS = [\n // Greetings and filler\n /^(hi|hello|hey|yo|sup|greetings)[.!,]?\\s*$/i,\n /^(ok|okay|k|sure|yes|no|yep|nope|yeah|nah)[.!]?\\s*$/i,\n /^(thanks|thank you|thx|ty|cheers)[.!]?\\s*$/i,\n /^(got it|understood|roger|copy|noted)[.!]?\\s*$/i,\n /^(bye|goodbye|later|see ya|ttyl)[.!]?\\s*$/i,\n /^(lol|haha|hehe|lmao|rofl)[.!]?\\s*$/i,\n /^(hmm+|uhh*|ahh*|err*|umm*)[.!]?\\s*$/i,\n // Very short content\n /^.{1,10}$/,\n];\n\n// ---------------------------------------------------------------------------\n// Category-based importance boosts\n// ---------------------------------------------------------------------------\n\nconst CATEGORY_BOOSTS: Record<MemoryCategory, number> = {\n correction: 0.15, // Corrections are always important\n principle: 0.12, // Durable rules/values\n rule: 0.11, // Causal IF→THEN rules\n procedure: 0.10, // Repeatable workflows (issue #519)\n preference: 0.10, // User preferences matter\n commitment: 0.10, // Promises/obligations\n reasoning_trace: 0.09, // Stored reasoning chains (issue #564)\n decision: 0.08, // Decisions with rationale\n relationship: 0.05, // Entity relationships\n skill: 0.05, // Capabilities\n moment: 0.03, // Emotional milestones\n entity: 0.02, // Entity facts\n fact: 0.00, // Base facts, no boost\n};\n\n// ---------------------------------------------------------------------------\n// Keyword extraction\n// ---------------------------------------------------------------------------\n\n/** Common stop words to filter out */\nconst STOP_WORDS = new Set([\n \"a\", \"an\", \"the\", \"is\", \"are\", \"was\", \"were\", \"be\", \"been\", \"being\",\n \"have\", \"has\", \"had\", \"do\", \"does\", \"did\", \"will\", \"would\", \"could\",\n \"should\", \"may\", \"might\", \"must\", \"shall\", \"can\", \"need\", \"dare\",\n \"ought\", \"used\", \"to\", \"of\", \"in\", \"for\", \"on\", \"with\", \"at\", \"by\",\n \"from\", \"as\", \"into\", \"through\", \"during\", \"before\", \"after\", \"above\",\n \"below\", \"between\", \"under\", \"again\", \"further\", \"then\", \"once\",\n \"here\", \"there\", \"when\", \"where\", \"why\", \"how\", \"all\", \"each\", \"few\",\n \"more\", \"most\", \"other\", \"some\", \"such\", \"no\", \"nor\", \"not\", \"only\",\n \"own\", \"same\", \"so\", \"than\", \"too\", \"very\", \"just\", \"and\", \"but\",\n \"or\", \"if\", \"because\", \"until\", \"while\", \"this\", \"that\", \"these\",\n \"those\", \"i\", \"me\", \"my\", \"myself\", \"we\", \"our\", \"ours\", \"ourselves\",\n \"you\", \"your\", \"yours\", \"yourself\", \"yourselves\", \"he\", \"him\", \"his\",\n \"himself\", \"she\", \"her\", \"hers\", \"herself\", \"it\", \"its\", \"itself\",\n \"they\", \"them\", \"their\", \"theirs\", \"themselves\", \"what\", \"which\",\n \"who\", \"whom\", \"whose\", \"am\", \"been\", \"being\", \"about\", \"against\",\n]);\n\n/**\n * Extract salient keywords from content.\n * Returns top N keywords sorted by relevance.\n */\nfunction extractKeywords(content: string, maxKeywords: number = 5): string[] {\n // Tokenize and normalize\n const words = content\n .toLowerCase()\n .replace(/[^a-z0-9\\s-]/g, \" \")\n .split(/\\s+/)\n .filter((w) => w.length >= 3 && !STOP_WORDS.has(w));\n\n // Count frequencies\n const freq = new Map<string, number>();\n for (const word of words) {\n freq.set(word, (freq.get(word) ?? 0) + 1);\n }\n\n // Sort by frequency, take top N\n return [...freq.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, maxKeywords)\n .map(([word]) => word);\n}\n\n// ---------------------------------------------------------------------------\n// Main scoring function\n// ---------------------------------------------------------------------------\n\n/**\n * Calculate importance score for a memory.\n * Pure local heuristics, zero LLM calls.\n */\nexport function scoreImportance(\n content: string,\n category: MemoryCategory,\n tags: string[] = [],\n): ImportanceScore {\n const reasons: string[] = [];\n let score = 0.5; // Start at normal baseline\n\n const lowerContent = content.toLowerCase();\n const contentLength = content.length;\n\n // Check for trivial content first (short-circuit)\n for (const pattern of TRIVIAL_PATTERNS) {\n if (pattern.test(content)) {\n return {\n score: 0.1,\n level: \"trivial\",\n reasons: [\"Trivial content (greeting, filler, or very short)\"],\n keywords: [],\n };\n }\n }\n\n // Check critical patterns\n for (const pattern of CRITICAL_PATTERNS) {\n if (pattern.test(content)) {\n score += 0.20;\n reasons.push(`Critical marker: ${pattern.source.slice(0, 30)}`);\n break; // Only count once per tier\n }\n }\n\n // Check high patterns\n for (const pattern of HIGH_PATTERNS) {\n if (pattern.test(content)) {\n score += 0.12;\n reasons.push(`High importance marker detected`);\n break;\n }\n }\n\n // Check low patterns (reduces score)\n for (const pattern of LOW_PATTERNS) {\n if (pattern.test(content)) {\n score -= 0.15;\n reasons.push(`Uncertainty/hedging detected`);\n break;\n }\n }\n\n // Category boost\n const categoryBoost = CATEGORY_BOOSTS[category] ?? 0;\n if (categoryBoost > 0) {\n score += categoryBoost;\n reasons.push(`Category boost: ${category}`);\n }\n\n // Length bonus (longer = more substance, capped)\n if (contentLength > 200) {\n const lengthBonus = Math.min((contentLength - 200) / 1000, 0.1);\n score += lengthBonus;\n if (lengthBonus > 0.05) {\n reasons.push(\"Substantial content length\");\n }\n }\n\n // Check for personal pronouns (signals personal relevance)\n if (/\\b(my|mine|i|i'm|i've|i'd|i'll)\\b/i.test(content)) {\n score += 0.05;\n reasons.push(\"Personal reference\");\n }\n\n // Check for numbers/specifics (concrete details)\n if (/\\b\\d{2,}\\b/.test(content) || /\\b(version|v\\d|api|config)\\b/i.test(content)) {\n score += 0.03;\n reasons.push(\"Contains specific details\");\n }\n\n // Tag-based boosts\n const importantTags = tags.filter((t) =>\n [\"important\", \"critical\", \"preference\", \"decision\", \"rule\", \"principle\"].includes(t.toLowerCase())\n );\n if (importantTags.length > 0) {\n score += 0.05 * importantTags.length;\n reasons.push(`Important tags: ${importantTags.join(\", \")}`);\n }\n\n // Clamp score to 0-1 range\n score = Math.max(0, Math.min(1, score));\n\n // Determine level from score\n let level: ImportanceLevel;\n if (score >= 0.9) {\n level = \"critical\";\n } else if (score >= 0.7) {\n level = \"high\";\n } else if (score >= 0.4) {\n level = \"normal\";\n } else if (score >= 0.2) {\n level = \"low\";\n } else {\n level = \"trivial\";\n }\n\n // Extract keywords\n const keywords = extractKeywords(content);\n\n return {\n score: Math.round(score * 100) / 100, // Round to 2 decimal places\n level,\n reasons: reasons.slice(0, 5), // Cap at 5 reasons\n keywords,\n };\n}\n\n/**\n * Recompute importance for an existing memory file using current local heuristics.\n */\nexport function rescoreMemoryImportance(memory: MemoryFile): ImportanceScore {\n return scoreImportance(memory.content, memory.frontmatter.category, memory.frontmatter.tags ?? []);\n}\n\n/**\n * Get importance level from numeric score.\n */\nexport function importanceLevel(score: number): ImportanceLevel {\n if (score >= 0.9) return \"critical\";\n if (score >= 0.7) return \"high\";\n if (score >= 0.4) return \"normal\";\n if (score >= 0.2) return \"low\";\n return \"trivial\";\n}\n\n// ---------------------------------------------------------------------------\n// Importance threshold helper (issue #372)\n// ---------------------------------------------------------------------------\n\n/**\n * Ordering for importance levels used by the extraction write gate.\n * Higher indices mean more important.\n */\nconst IMPORTANCE_LEVEL_RANK: Record<ImportanceLevel, number> = {\n trivial: 0,\n low: 1,\n normal: 2,\n high: 3,\n critical: 4,\n};\n\n/**\n * Return true if `candidate` meets or exceeds `threshold`. Used by the\n * extraction write gate in orchestrator.persistExtraction() to drop trivial\n * content before it is written to the memory store.\n *\n * Note: callers should pass the ALREADY-BOOSTED level returned by\n * scoreImportance(), because category boosts (e.g. corrections) are applied\n * inside scoreImportance() before the level is derived.\n */\nexport function isAboveImportanceThreshold(\n candidate: ImportanceLevel,\n threshold: ImportanceLevel,\n): boolean {\n return IMPORTANCE_LEVEL_RANK[candidate] >= IMPORTANCE_LEVEL_RANK[threshold];\n}\n"],"mappings":"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","names":[]}