@remnic/core 9.48.1 → 9.49.1

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 (616) hide show
  1. package/dist/abstraction-nodes.d.ts +12 -1
  2. package/dist/abstraction-nodes.js +9 -2
  3. package/dist/access-admin-ops-surface.d.ts +11 -10
  4. package/dist/access-admin-ops-surface.js +46 -45
  5. package/dist/access-audit.js +2 -2
  6. package/dist/access-authorization-probe.d.ts +11 -10
  7. package/dist/access-authorization-probe.js +47 -46
  8. package/dist/access-boundary.d.ts +11 -10
  9. package/dist/access-boundary.js +46 -45
  10. package/dist/access-cli.js +127 -121
  11. package/dist/access-cli.js.map +1 -1
  12. package/dist/access-coding-context-resolution.d.ts +1 -1
  13. package/dist/access-extraction-force-flush.d.ts +11 -10
  14. package/dist/access-extraction-force-flush.js +46 -45
  15. package/dist/access-health-types.d.ts +1 -1
  16. package/dist/access-http-lcm-compaction.d.ts +11 -10
  17. package/dist/access-http-lifecycle-flush.d.ts +11 -10
  18. package/dist/access-http-offline-stream.d.ts +11 -10
  19. package/dist/access-http-query.js +46 -45
  20. package/dist/access-http.d.ts +11 -10
  21. package/dist/access-http.js +57 -56
  22. package/dist/access-identity-continuity-surface.d.ts +9 -8
  23. package/dist/access-identity-continuity-surface.js +46 -45
  24. package/dist/access-lcm-surface.d.ts +11 -10
  25. package/dist/access-lcm-surface.js +46 -45
  26. package/dist/access-mcp.d.ts +11 -10
  27. package/dist/access-mcp.js +52 -51
  28. package/dist/access-memory-search-fanout.d.ts +2 -2
  29. package/dist/{access-namespace-preflight--H6HwN85.d.ts → access-namespace-preflight-DuDU301-.d.ts} +1 -1
  30. package/dist/access-namespace-preflight.d.ts +3 -3
  31. package/dist/access-namespace-preflight.js +46 -45
  32. package/dist/access-observe-write-surface.d.ts +11 -10
  33. package/dist/access-observe-write-surface.js +46 -45
  34. package/dist/access-offline-manifest.d.ts +9 -8
  35. package/dist/access-offline-manifest.js +3 -3
  36. package/dist/access-operations-batch.js +48 -47
  37. package/dist/access-operations.d.ts +14 -13
  38. package/dist/access-operations.js +51 -50
  39. package/dist/access-recall-concurrency.d.ts +11 -10
  40. package/dist/access-recall-concurrency.js +46 -45
  41. package/dist/access-recall-response.d.ts +11 -10
  42. package/dist/access-recall-response.js +46 -45
  43. package/dist/access-recall-surface.d.ts +11 -10
  44. package/dist/access-recall-surface.js +46 -45
  45. package/dist/access-schema.d.ts +105 -105
  46. package/dist/access-schema.js +3 -3
  47. package/dist/{access-service-andNjwfD.d.ts → access-service--_3T_v23.d.ts} +7 -7
  48. package/dist/access-service-helpers.d.ts +11 -10
  49. package/dist/access-service.d.ts +11 -10
  50. package/dist/access-service.js +46 -45
  51. package/dist/access-surface-catalog.d.ts +11 -10
  52. package/dist/access-wearables-meetings-surface.d.ts +4 -3
  53. package/dist/action-confidence.d.ts +1 -1
  54. package/dist/active-memory-bridge.d.ts +1 -1
  55. package/dist/active-recall.d.ts +1 -1
  56. package/dist/active-recall.js +3 -2
  57. package/dist/active-recall.js.map +1 -1
  58. package/dist/adapters/index.js +4 -4
  59. package/dist/adapters/registry.js +2 -2
  60. package/dist/ambient-provenance.d.ts +1 -1
  61. package/dist/artifact-search.d.ts +1 -1
  62. package/dist/{auto-sync-7O6RP2RT.js → auto-sync-QFQGOEO2.js} +4 -4
  63. package/dist/behavior-learner.d.ts +1 -1
  64. package/dist/behavior-signals.d.ts +1 -1
  65. package/dist/bootstrap.d.ts +9 -8
  66. package/dist/briefing.d.ts +3 -2
  67. package/dist/briefing.js +15 -14
  68. package/dist/buffer-surprise-report.d.ts +1 -1
  69. package/dist/buffer-turn-helpers.d.ts +1 -1
  70. package/dist/buffer.d.ts +3 -2
  71. package/dist/buffer.js +4 -4
  72. package/dist/bulk-import/index.d.ts +3 -3
  73. package/dist/calibration.d.ts +1 -1
  74. package/dist/calibration.js +1 -1
  75. package/dist/capabilities.d.ts +1 -1
  76. package/dist/{capsule-merge-Q6AR3XL7.js → capsule-merge-KXTRZ23Z.js} +6 -6
  77. package/dist/{catalog-Iwbk9h5E.d.ts → catalog-DjUmUIal.d.ts} +1 -1
  78. package/dist/causal-behavior.d.ts +1 -1
  79. package/dist/causal-behavior.js +3 -3
  80. package/dist/causal-chain.js +3 -3
  81. package/dist/causal-consolidation.d.ts +1 -1
  82. package/dist/causal-consolidation.js +19 -18
  83. package/dist/causal-consolidation.js.map +1 -1
  84. package/dist/causal-retrieval.js +3 -3
  85. package/dist/causal-trajectory-graph.d.ts +1 -1
  86. package/dist/causal-trajectory.d.ts +51 -2
  87. package/dist/causal-trajectory.js +8 -2
  88. package/dist/{chunk-PLCZD3LG.js → chunk-24BKGKGO.js} +91 -45
  89. package/dist/chunk-24BKGKGO.js.map +1 -0
  90. package/dist/{chunk-ICP53SKG.js → chunk-2HIJHXB3.js} +2 -2
  91. package/dist/{chunk-LZGCJSQR.js → chunk-3LD4N2TF.js} +151 -37
  92. package/dist/chunk-3LD4N2TF.js.map +1 -0
  93. package/dist/{chunk-FJ2ND6CZ.js → chunk-47J4EDGR.js} +2 -2
  94. package/dist/{chunk-S55OAS5P.js → chunk-4EABKPZS.js} +4 -4
  95. package/dist/{chunk-GD7UPIBG.js → chunk-4JWJMRPJ.js} +2 -2
  96. package/dist/{chunk-3NDN5P55.js → chunk-4S3ECH3U.js} +2 -2
  97. package/dist/chunk-5GINB5LC.js +13 -0
  98. package/dist/chunk-5GINB5LC.js.map +1 -0
  99. package/dist/{chunk-CGASUJVP.js → chunk-5V6IXHPI.js} +4 -4
  100. package/dist/{chunk-A4JMGKCD.js → chunk-5XCN4XBU.js} +4 -4
  101. package/dist/{chunk-2RPJ4NEE.js → chunk-64BHFFKZ.js} +2 -2
  102. package/dist/{chunk-FQC3DHH2.js → chunk-66SE3BNH.js} +2 -2
  103. package/dist/{chunk-TERNBNJB.js → chunk-6FC3IZ26.js} +2 -2
  104. package/dist/{chunk-53AJILXF.js → chunk-6XGEBQ3R.js} +4 -4
  105. package/dist/{chunk-IP3DHDU2.js → chunk-7BLWBSRL.js} +3 -3
  106. package/dist/{chunk-A2TFK5PG.js → chunk-7NDM2PNK.js} +3 -3
  107. package/dist/{chunk-HRMEYQRO.js → chunk-7VWZ4LRW.js} +2 -2
  108. package/dist/{chunk-RN53QBM4.js → chunk-A4QMKFFO.js} +5 -1
  109. package/dist/chunk-A4QMKFFO.js.map +1 -0
  110. package/dist/chunk-ACPCA4NO.js +321 -0
  111. package/dist/chunk-ACPCA4NO.js.map +1 -0
  112. package/dist/chunk-AMTEYNYK.js +72 -0
  113. package/dist/chunk-AMTEYNYK.js.map +1 -0
  114. package/dist/{chunk-R6YJI3HE.js → chunk-AW4QUFQF.js} +1 -1
  115. package/dist/{chunk-P65YJEEL.js → chunk-AXFWMRKI.js} +2 -2
  116. package/dist/{chunk-WG5HSQ4P.js → chunk-BAKXNQ3C.js} +2 -2
  117. package/dist/{chunk-NM2WP3B7.js → chunk-BJYET5TX.js} +2 -2
  118. package/dist/{chunk-HLKPRWF4.js → chunk-DATDLJAO.js} +6 -6
  119. package/dist/chunk-DJUKBGAD.js +260 -0
  120. package/dist/chunk-DJUKBGAD.js.map +1 -0
  121. package/dist/{chunk-DX3XRGLH.js → chunk-DQTCGVFK.js} +2 -2
  122. package/dist/{chunk-HIDEBEAN.js → chunk-E633OXMH.js} +11 -11
  123. package/dist/{chunk-J7T4MX7P.js → chunk-EEAMSNSG.js} +12 -1
  124. package/dist/chunk-EEAMSNSG.js.map +1 -0
  125. package/dist/{chunk-EZNXW27Q.js → chunk-ELQCS47S.js} +4 -4
  126. package/dist/{chunk-HAYSYUAB.js → chunk-EURCX6PS.js} +2 -2
  127. package/dist/{chunk-RSPSHRZA.js → chunk-FV7YQTN3.js} +2 -2
  128. package/dist/chunk-G73MCJKL.js +20 -0
  129. package/dist/chunk-G73MCJKL.js.map +1 -0
  130. package/dist/{chunk-GWHPQOUC.js → chunk-GGBSF2X7.js} +2 -2
  131. package/dist/{chunk-SYUBB3WM.js → chunk-GKEYXXKX.js} +2 -2
  132. package/dist/{chunk-PELT6ADC.js → chunk-GSEPRIZC.js} +3 -3
  133. package/dist/{chunk-UTVZKHJK.js → chunk-GUKBW4HL.js} +2 -2
  134. package/dist/chunk-GXSOUIA4.js +293 -0
  135. package/dist/chunk-GXSOUIA4.js.map +1 -0
  136. package/dist/{chunk-2F6NP3NT.js → chunk-HDQUQBPW.js} +2 -2
  137. package/dist/{chunk-6HMYUWXR.js → chunk-HTP6XRUI.js} +2 -2
  138. package/dist/{chunk-UYUYZ4WY.js → chunk-IARXXZU4.js} +2 -2
  139. package/dist/{chunk-MNB5RMAY.js → chunk-IIFFC3RL.js} +2 -2
  140. package/dist/{chunk-KQAFEZQX.js → chunk-IPLYGWQF.js} +5 -5
  141. package/dist/{chunk-NZBZ7IS2.js → chunk-JDCQK3C5.js} +2 -2
  142. package/dist/{chunk-ANCC3JJH.js → chunk-JI62YGPI.js} +2 -2
  143. package/dist/{chunk-LULR4IUW.js → chunk-KATEWTQJ.js} +2 -2
  144. package/dist/{chunk-IJ7HK452.js → chunk-KMAP7SNQ.js} +2 -2
  145. package/dist/{chunk-PRVJH7CY.js → chunk-KMWYZTIE.js} +2 -2
  146. package/dist/{chunk-JGSKJHF7.js → chunk-KQS72GCR.js} +2 -2
  147. package/dist/{chunk-3S63QIFQ.js → chunk-LAQ33B5D.js} +1 -1
  148. package/dist/chunk-LAQ33B5D.js.map +1 -0
  149. package/dist/chunk-LNTUXKBT.js +224 -0
  150. package/dist/chunk-LNTUXKBT.js.map +1 -0
  151. package/dist/{chunk-FMCHFSZF.js → chunk-LQKXVQZR.js} +12 -12
  152. package/dist/{chunk-M4DMO67I.js → chunk-LTOAJXZB.js} +4 -4
  153. package/dist/{chunk-NIS256NW.js → chunk-LYMNZZIM.js} +2 -2
  154. package/dist/{chunk-W4FBGYGK.js → chunk-M4MP34AQ.js} +189 -5
  155. package/dist/chunk-M4MP34AQ.js.map +1 -0
  156. package/dist/{chunk-3PY7VHV7.js → chunk-MCA2X4WH.js} +2 -2
  157. package/dist/{chunk-S5NZBKKQ.js → chunk-N3CXAYPJ.js} +3 -3
  158. package/dist/{chunk-WQIHRA5F.js → chunk-N3LL5NEU.js} +2 -2
  159. package/dist/{chunk-G2RBWVFQ.js → chunk-NKL25FCF.js} +2 -2
  160. package/dist/{chunk-LMDRGRJ2.js → chunk-NOB2T2FC.js} +2 -2
  161. package/dist/{chunk-P2OTGMTR.js → chunk-NSGU76YO.js} +2 -2
  162. package/dist/{chunk-D5NGH2EW.js → chunk-O76MWTVS.js} +2 -2
  163. package/dist/{chunk-WZFAPHIK.js → chunk-OIOZ6MOP.js} +3 -3
  164. package/dist/{chunk-DNHVPZOD.js → chunk-P26YHAQH.js} +201 -1
  165. package/dist/chunk-P26YHAQH.js.map +1 -0
  166. package/dist/{chunk-UMOO7IY7.js → chunk-P2KBDJJ6.js} +2 -2
  167. package/dist/{chunk-KVJRXN2E.js → chunk-P4QOYG52.js} +125 -13
  168. package/dist/chunk-P4QOYG52.js.map +1 -0
  169. package/dist/chunk-P77QX3ID.js +332 -0
  170. package/dist/chunk-P77QX3ID.js.map +1 -0
  171. package/dist/{chunk-SXWHN7GC.js → chunk-PDEKQWDV.js} +2 -2
  172. package/dist/{chunk-2EJNXE53.js → chunk-PLCHU56K.js} +3 -3
  173. package/dist/{chunk-45OTV7FZ.js → chunk-PWIMF7LP.js} +38 -38
  174. package/dist/{chunk-7YKVM5H3.js → chunk-PWLB4TRK.js} +3 -3
  175. package/dist/{chunk-RVYVMQK4.js → chunk-QSYL5CXK.js} +3 -3
  176. package/dist/{chunk-NXUJRXSF.js → chunk-QWLW3VQH.js} +2 -2
  177. package/dist/chunk-RBOJCG4T.js +77 -0
  178. package/dist/chunk-RBOJCG4T.js.map +1 -0
  179. package/dist/{chunk-2P3GQVM2.js → chunk-RBPH3GZV.js} +418 -105
  180. package/dist/chunk-RBPH3GZV.js.map +1 -0
  181. package/dist/{chunk-JBPKEARU.js → chunk-RKNJBZ55.js} +4 -4
  182. package/dist/{chunk-QCECHYZL.js → chunk-RVO6TCTU.js} +6 -6
  183. package/dist/{chunk-5L7PTX2Q.js → chunk-S2SJEOTM.js} +2 -2
  184. package/dist/{chunk-52I3YZZ6.js → chunk-S75UQ3T3.js} +3 -3
  185. package/dist/{chunk-LXOM6IQU.js → chunk-SEF4IOFE.js} +2 -2
  186. package/dist/{chunk-DUEEQCTT.js → chunk-SHYIMIX5.js} +2 -2
  187. package/dist/{chunk-KSGEGHYA.js → chunk-T35UJI5R.js} +78 -74
  188. package/dist/chunk-T35UJI5R.js.map +1 -0
  189. package/dist/{chunk-7K5Q6COX.js → chunk-TVVEYCNW.js} +4 -4
  190. package/dist/{chunk-3JUYWPFJ.js → chunk-VFS3MK5F.js} +2 -2
  191. package/dist/chunk-VUDMT5CP.js +86 -0
  192. package/dist/chunk-VUDMT5CP.js.map +1 -0
  193. package/dist/{chunk-CMQZNEIF.js → chunk-WFLBP5GC.js} +8 -1
  194. package/dist/chunk-WFLBP5GC.js.map +1 -0
  195. package/dist/{chunk-WOEVJKKQ.js → chunk-WPZX7MEA.js} +4 -4
  196. package/dist/{chunk-ZRWB5D4H.js → chunk-WT6UL3UA.js} +2 -2
  197. package/dist/{chunk-MC6XO7T4.js → chunk-YLBE6PLR.js} +2 -2
  198. package/dist/{chunk-GF22HWS2.js → chunk-Z54EM5YZ.js} +4 -4
  199. package/dist/{chunk-GVX3NAUU.js → chunk-ZDAYWJV6.js} +2 -2
  200. package/dist/{chunk-4WBGZYZZ.js → chunk-ZJIFYUJI.js} +7 -7
  201. package/dist/chunk-ZJIFYUJI.js.map +1 -0
  202. package/dist/{chunk-JYPO7L3G.js → chunk-ZN4EYMKJ.js} +2 -2
  203. package/dist/{cli-p_WmVo2h.d.ts → cli-BLNmNEMT.d.ts} +16 -14
  204. package/dist/cli.d.ts +14 -13
  205. package/dist/cli.js +90 -87
  206. package/dist/coding/pre-action-gate.d.ts +66 -0
  207. package/dist/coding/pre-action-gate.js +22 -0
  208. package/dist/commitment-ledger.js +2 -2
  209. package/dist/compounding/engine.d.ts +3 -2
  210. package/dist/compounding/engine.js +16 -15
  211. package/dist/compounding/preference-consolidator.d.ts +1 -1
  212. package/dist/compression-optimizer.d.ts +1 -1
  213. package/dist/config.d.ts +1 -1
  214. package/dist/config.js +3 -2
  215. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  216. package/dist/connectors/codex-materialize-runner.js +15 -14
  217. package/dist/connectors/codex-materialize.d.ts +1 -1
  218. package/dist/connectors/index.d.ts +1 -1
  219. package/dist/connectors/index.js +15 -14
  220. package/dist/consolidation-provenance-check.d.ts +3 -2
  221. package/dist/consolidation-provenance-check.js +6 -6
  222. package/dist/consolidation-undo.d.ts +3 -2
  223. package/dist/consolidation-undo.js +5 -5
  224. package/dist/contradiction/index.d.ts +3 -2
  225. package/dist/contradiction/index.js +3 -3
  226. package/dist/converge-config.d.ts +1 -1
  227. package/dist/convergence-refresh.d.ts +3 -2
  228. package/dist/convergence-refresh.js +18 -17
  229. package/dist/conversation-index/backend.d.ts +1 -1
  230. package/dist/conversation-index/chunker.d.ts +1 -1
  231. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  232. package/dist/conversation-index/indexer.d.ts +1 -1
  233. package/dist/conversation-index/search.d.ts +1 -1
  234. package/dist/corpus-read-cancellation.d.ts +38 -0
  235. package/dist/corpus-read-cancellation.js +9 -0
  236. package/dist/corpus-read-cancellation.js.map +1 -0
  237. package/dist/corpus-watermark.d.ts +1 -1
  238. package/dist/corpus-watermark.js +21 -20
  239. package/dist/cue-anchors.d.ts +19 -1
  240. package/dist/cue-anchors.js +10 -2
  241. package/dist/day-summary.d.ts +1 -1
  242. package/dist/delinearize.d.ts +1 -1
  243. package/dist/dependency-propagation-config.d.ts +10 -0
  244. package/dist/dependency-propagation-config.js +10 -0
  245. package/dist/dependency-propagation-config.js.map +1 -0
  246. package/dist/deterministic-order.d.ts +4 -0
  247. package/dist/deterministic-order.js +10 -0
  248. package/dist/deterministic-order.js.map +1 -0
  249. package/dist/direct-answer-wiring.d.ts +1 -1
  250. package/dist/direct-answer.d.ts +1 -1
  251. package/dist/embedding-fallback.d.ts +1 -1
  252. package/dist/enrichment/index.d.ts +1 -1
  253. package/dist/entity-retrieval.d.ts +3 -2
  254. package/dist/entity-retrieval.js +15 -14
  255. package/dist/entity-schema.d.ts +1 -1
  256. package/dist/evals.js +2 -2
  257. package/dist/explicit-capture.d.ts +9 -8
  258. package/dist/explicit-capture.js +6 -6
  259. package/dist/external-wiki-access.d.ts +11 -10
  260. package/dist/external-wiki-access.js +47 -46
  261. package/dist/external-wiki-collection-registration.d.ts +1 -1
  262. package/dist/external-wiki-collection.d.ts +1 -1
  263. package/dist/external-wiki-mcp-tools.d.ts +11 -10
  264. package/dist/extraction-error-classification.d.ts +1 -1
  265. package/dist/extraction-faithfulness.d.ts +1 -1
  266. package/dist/extraction-judge-telemetry.d.ts +1 -1
  267. package/dist/extraction-judge-training.d.ts +1 -1
  268. package/dist/extraction-judge.d.ts +1 -1
  269. package/dist/extraction-liveness.d.ts +1 -1
  270. package/dist/extraction-normalization.d.ts +14 -0
  271. package/dist/extraction-normalization.js +22 -0
  272. package/dist/extraction-normalization.js.map +1 -0
  273. package/dist/extraction-prompt.d.ts +4 -3
  274. package/dist/extraction-prompt.js +3 -1
  275. package/dist/extraction-source-grounding-rules.d.ts +1 -1
  276. package/dist/extraction-source-grounding.d.ts +1 -1
  277. package/dist/extraction.d.ts +18 -1
  278. package/dist/extraction.js +24 -21
  279. package/dist/fallback-llm.d.ts +1 -1
  280. package/dist/{first-start-migration-ZSHEFEI3.js → first-start-migration-626C5554.js} +5 -5
  281. package/dist/{forget-DNAJ66ZD.js → forget-GJ42LCBW.js} +2 -2
  282. package/dist/graph-dashboard-diff.d.ts +1 -1
  283. package/dist/graph-dashboard-key.d.ts +1 -1
  284. package/dist/graph-dashboard-parser.d.ts +1 -1
  285. package/dist/graph-edge-reinforcement.d.ts +1 -1
  286. package/dist/graph-snapshot.d.ts +1 -1
  287. package/dist/graph.d.ts +1 -1
  288. package/dist/harmonic-construction.d.ts +43 -0
  289. package/dist/harmonic-construction.js +26 -0
  290. package/dist/harmonic-construction.js.map +1 -0
  291. package/dist/harmonic-retrieval.d.ts +1 -0
  292. package/dist/harmonic-retrieval.js +10 -4
  293. package/dist/importance.d.ts +1 -1
  294. package/dist/importers/index.d.ts +1 -1
  295. package/dist/in-flight-reads.d.ts +47 -3
  296. package/dist/in-flight-reads.js +5 -3
  297. package/dist/index.d.ts +699 -696
  298. package/dist/index.js +197 -150
  299. package/dist/intent.d.ts +1 -1
  300. package/dist/json-store.d.ts +15 -1
  301. package/dist/json-store.js +11 -3
  302. package/dist/lcm/engine.d.ts +1 -1
  303. package/dist/lcm/engine.js +2 -2
  304. package/dist/lcm/index.d.ts +1 -1
  305. package/dist/lcm/index.js +7 -7
  306. package/dist/lcm/tools.d.ts +1 -1
  307. package/dist/lifecycle.d.ts +1 -1
  308. package/dist/live-connectors-runner.d.ts +1 -1
  309. package/dist/local-llm.d.ts +1 -1
  310. package/dist/local-model-endpoint.d.ts +1 -1
  311. package/dist/maintenance/archive-observations.js +2 -2
  312. package/dist/maintenance/atomic-file.d.ts +5 -0
  313. package/dist/maintenance/atomic-file.js +12 -0
  314. package/dist/maintenance/atomic-file.js.map +1 -0
  315. package/dist/maintenance/memory-governance.d.ts +1 -1
  316. package/dist/maintenance/memory-governance.js +15 -14
  317. package/dist/maintenance/migrate-observations.js +3 -3
  318. package/dist/maintenance/observation-ledger-utils.d.ts +1 -1
  319. package/dist/maintenance/observation-ledger-utils.js +2 -2
  320. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +3 -2
  321. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +16 -15
  322. package/dist/maintenance/rebuild-memory-projection.d.ts +3 -2
  323. package/dist/maintenance/rebuild-memory-projection.js +17 -16
  324. package/dist/maintenance/rebuild-observations.js +3 -3
  325. package/dist/{maintenance-BfcuwfJS.d.ts → maintenance-DKbKZi3u.d.ts} +3 -3
  326. package/dist/mcp-memory-inspector-app.d.ts +11 -10
  327. package/dist/memory-action-policy.d.ts +1 -1
  328. package/dist/memory-cache.d.ts +1 -1
  329. package/dist/memory-corpus-version.js +2 -2
  330. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  331. package/dist/memory-projection-store.d.ts +1 -1
  332. package/dist/memory-provenance.d.ts +1 -1
  333. package/dist/memory-snapshot.d.ts +1 -1
  334. package/dist/memory-worth-outcomes.d.ts +3 -2
  335. package/dist/models-json.d.ts +1 -1
  336. package/dist/namespaces/migrate.d.ts +4 -3
  337. package/dist/namespaces/migrate.js +20 -19
  338. package/dist/namespaces/principal.d.ts +1 -1
  339. package/dist/namespaces/search.d.ts +1 -1
  340. package/dist/namespaces/search.js +4 -4
  341. package/dist/namespaces/storage.d.ts +4 -3
  342. package/dist/namespaces/storage.js +15 -14
  343. package/dist/native-knowledge.d.ts +1 -1
  344. package/dist/objective-state-writers.js +3 -3
  345. package/dist/objective-state.js +2 -2
  346. package/dist/offline-sync-impression-drain.d.ts +1 -1
  347. package/dist/offline-sync-impression-drain.js +2 -2
  348. package/dist/operator-doctor-corpus.d.ts +1 -1
  349. package/dist/operator-doctor-corpus.js +22 -21
  350. package/dist/operator-doctor-replica.d.ts +1 -1
  351. package/dist/operator-toolkit.d.ts +4 -3
  352. package/dist/operator-toolkit.js +31 -29
  353. package/dist/orchestration/compression-guideline-coordinator.d.ts +3 -2
  354. package/dist/orchestration/maintenance.d.ts +5 -4
  355. package/dist/orchestration/maintenance.js +21 -20
  356. package/dist/{orchestrator-B7nLo4z1.d.ts → orchestrator-BRwD7ceU.d.ts} +7 -7
  357. package/dist/orchestrator.d.ts +9 -8
  358. package/dist/orchestrator.js +127 -121
  359. package/dist/page-versioning.js +5 -5
  360. package/dist/patterns-cli.d.ts +1 -1
  361. package/dist/{pipeline-1h2GpiHP.d.ts → pipeline-DC-1C9T8.d.ts} +1 -1
  362. package/dist/policy-runtime.d.ts +1 -1
  363. package/dist/proactive-contention.d.ts +1 -1
  364. package/dist/provenance.d.ts +1 -1
  365. package/dist/{qmd-UdwoF71D.d.ts → qmd-DdeCEZdb.d.ts} +1 -1
  366. package/dist/qmd-preflight.d.ts +2 -2
  367. package/dist/qmd-recall-cache.d.ts +1 -1
  368. package/dist/qmd.d.ts +2 -2
  369. package/dist/qmd.js +4 -4
  370. package/dist/recall-concurrency-config.d.ts +1 -1
  371. package/dist/recall-disclosure-escalation.d.ts +1 -1
  372. package/dist/recall-explain-renderer.d.ts +1 -1
  373. package/dist/recall-explain-renderer.js +3 -3
  374. package/dist/recall-memory-map.d.ts +1 -1
  375. package/dist/recall-planner-llm.d.ts +1 -1
  376. package/dist/recall-state.d.ts +1 -1
  377. package/dist/recall-state.js +2 -2
  378. package/dist/recall-tag-filter.d.ts +1 -1
  379. package/dist/recall-timings.d.ts +1 -1
  380. package/dist/recall-xray-cli.d.ts +1 -1
  381. package/dist/recall-xray-cli.js +4 -4
  382. package/dist/recall-xray-renderer.d.ts +1 -1
  383. package/dist/recall-xray-renderer.js +3 -3
  384. package/dist/recall-xray.d.ts +1 -1
  385. package/dist/recall-xray.js +2 -2
  386. package/dist/reconcile/cursor.d.ts +1 -1
  387. package/dist/reconcile/manifest.d.ts +1 -1
  388. package/dist/reconcile/plan.d.ts +1 -1
  389. package/dist/relevance.js +2 -2
  390. package/dist/replay/normalizers/chatgpt.d.ts +1 -1
  391. package/dist/replay/normalizers/claude.d.ts +1 -1
  392. package/dist/replay/normalizers/openclaw.d.ts +1 -1
  393. package/dist/replay/normalizers/shared.d.ts +1 -1
  394. package/dist/replay/runner.d.ts +1 -1
  395. package/dist/replay/types.d.ts +1 -1
  396. package/dist/replica-divergence.d.ts +1 -1
  397. package/dist/replica-peers-config.d.ts +1 -1
  398. package/dist/{resolution-3K27T4VO.js → resolution-MDPNOEG6.js} +4 -4
  399. package/dist/resolution-MDPNOEG6.js.map +1 -0
  400. package/dist/resolve-auth-token.d.ts +1 -1
  401. package/dist/resume-bundles.js +8 -7
  402. package/dist/retrieval-agents.d.ts +2 -2
  403. package/dist/retrieval-tiers.d.ts +1 -1
  404. package/dist/routing/engine.d.ts +1 -1
  405. package/dist/routing/store.d.ts +1 -1
  406. package/dist/salvage-envelope.d.ts +1 -1
  407. package/dist/salvage-envelope.js +3 -3
  408. package/dist/schemas.d.ts +213 -116
  409. package/dist/schemas.js +1 -1
  410. package/dist/{scope-profiles-APjhSe-w.d.ts → scope-profiles-BXVq4Jv0.d.ts} +1 -1
  411. package/dist/search/embed-helper.d.ts +1 -1
  412. package/dist/search/factory.d.ts +1 -1
  413. package/dist/search/factory.js +3 -3
  414. package/dist/search/index.d.ts +1 -1
  415. package/dist/search/index.js +3 -3
  416. package/dist/search/lancedb-backend.d.ts +1 -1
  417. package/dist/search/meilisearch-backend.d.ts +1 -1
  418. package/dist/search/noop-backend.d.ts +1 -1
  419. package/dist/search/orama-backend.d.ts +1 -1
  420. package/dist/search/port.d.ts +1 -1
  421. package/dist/search/remote-backend.d.ts +1 -1
  422. package/dist/{semantic-consolidation-CrySDbk3.d.ts → semantic-consolidation-CGYxfa8F.d.ts} +1 -1
  423. package/dist/semantic-consolidation.d.ts +2 -2
  424. package/dist/semantic-consolidation.js +16 -15
  425. package/dist/semantic-rule-promotion.js +15 -14
  426. package/dist/semantic-rule-verifier.d.ts +1 -1
  427. package/dist/semantic-rule-verifier.js +15 -14
  428. package/dist/{service-B5W5IYCx.d.ts → service-CBDBQFCN.d.ts} +2 -2
  429. package/dist/session-observer-bands.d.ts +1 -1
  430. package/dist/session-observer-state.d.ts +1 -1
  431. package/dist/shared-context/manager.d.ts +11 -11
  432. package/dist/signal.d.ts +1 -1
  433. package/dist/source-agent-qualifier.d.ts +1 -1
  434. package/dist/source-agent-qualifier.js +19 -18
  435. package/dist/{storage-COL907QF.d.ts → storage-V--MQi7w.d.ts} +5 -4
  436. package/dist/storage.d.ts +3 -2
  437. package/dist/storage.js +14 -13
  438. package/dist/summarizer.d.ts +1 -1
  439. package/dist/summary-snapshot.d.ts +1 -1
  440. package/dist/temporal-supersession.d.ts +14 -2
  441. package/dist/temporal-supersession.js +1 -1
  442. package/dist/temporal-timeline-recall.d.ts +1 -1
  443. package/dist/temporal-validity.d.ts +1 -1
  444. package/dist/threading.d.ts +1 -1
  445. package/dist/tier-migration.d.ts +3 -2
  446. package/dist/tier-routing.d.ts +1 -1
  447. package/dist/{tier-stats-OPTSBNRH.js → tier-stats-2JCZYEF7.js} +5 -5
  448. package/dist/topics.d.ts +1 -1
  449. package/dist/transcript.d.ts +1 -1
  450. package/dist/transfer/autodetect.js +1 -1
  451. package/dist/transfer/backup.js +1 -1
  452. package/dist/transfer/capsule-export.js +2 -2
  453. package/dist/transfer/capsule-import.js +6 -6
  454. package/dist/transfer/types.d.ts +66 -66
  455. package/dist/trust-score-stage.d.ts +1 -1
  456. package/dist/trust-score.d.ts +1 -1
  457. package/dist/trust-zones.js +2 -2
  458. package/dist/{types-D_Au9qJO.d.ts → types-D_a6Sqjz.d.ts} +25 -8
  459. package/dist/types.d.ts +1 -1
  460. package/dist/types.js +1 -1
  461. package/dist/utility-learner.js +3 -3
  462. package/dist/utility-runtime.d.ts +1 -1
  463. package/dist/utility-runtime.js +4 -4
  464. package/dist/utility-telemetry.js +2 -2
  465. package/dist/verified-recall.js +15 -14
  466. package/dist/work-product-ledger.js +2 -2
  467. package/dist/write-envelope.d.ts +1 -1
  468. package/dist/write-envelope.js +2 -2
  469. package/package.json +32 -2
  470. package/src/abstraction-nodes.ts +182 -4
  471. package/src/causal-trajectory.ts +258 -3
  472. package/src/cli/harmonic-search.ts +23 -0
  473. package/src/cli/research-status-commands.ts +2 -1
  474. package/src/cli.ts +1 -24
  475. package/src/coding/pre-action-gate.test.ts +516 -0
  476. package/src/coding/pre-action-gate.ts +320 -0
  477. package/src/config.test.ts +85 -0
  478. package/src/config.ts +2 -0
  479. package/src/corpus-read-cancellation.ts +42 -0
  480. package/src/cue-anchors.test.ts +90 -0
  481. package/src/cue-anchors.ts +264 -11
  482. package/src/dependency-frontmatter.test.ts +83 -0
  483. package/src/dependency-propagation-config.ts +94 -0
  484. package/src/deterministic-order.ts +14 -0
  485. package/src/entity-retrieval.ts +4 -4
  486. package/src/extraction-normalization.ts +71 -0
  487. package/src/extraction-prompt.ts +45 -11
  488. package/src/extraction.ts +48 -32
  489. package/src/faithfulness-graph-guard.test.ts +27 -0
  490. package/src/harmonic-construction.test.ts +1799 -0
  491. package/src/harmonic-construction.ts +367 -0
  492. package/src/harmonic-retrieval.ts +166 -25
  493. package/src/in-flight-reads.ts +119 -6
  494. package/src/index.ts +4 -5
  495. package/src/json-store.ts +354 -12
  496. package/src/orchestration/consolidation-run.ts +192 -0
  497. package/src/orchestration/contradiction-linking-coordinator.ts +35 -1
  498. package/src/orchestration/dependency-propagation-triggers.test.ts +286 -0
  499. package/src/orchestration/dependency-propagation.test.ts +487 -0
  500. package/src/orchestration/dependency-propagation.ts +263 -0
  501. package/src/orchestration/dependency-revalidation.ts +173 -0
  502. package/src/orchestration/extraction-persist-deps.ts +93 -0
  503. package/src/orchestration/extraction-persist.ts +101 -94
  504. package/src/orchestration/harmonic-construction-persist.ts +86 -0
  505. package/src/orchestration/namespace-read-fanout.ts +13 -2
  506. package/src/orchestration/recall-internal-deps.ts +2 -0
  507. package/src/orchestration/recall-internal.ts +5 -1
  508. package/src/orchestration/recall-search-pipeline.ts +2 -0
  509. package/src/orchestration/recall-search-prefilter.ts +5 -1
  510. package/src/orchestrator.ts +7 -6
  511. package/src/schemas.ts +15 -0
  512. package/src/storage/entity-store.ts +9 -2
  513. package/src/storage/memory-read-store.ts +33 -4
  514. package/src/storage-contract/corpus-read-cancellation.test.ts +408 -0
  515. package/src/storage.ts +75 -19
  516. package/src/temporal-supersession.ts +29 -1
  517. package/src/testing/orchestrator-lite.ts +27 -8
  518. package/src/testing/subjects/extraction-lifecycle.test.ts +91 -50
  519. package/src/types.ts +22 -7
  520. package/dist/chunk-2P3GQVM2.js.map +0 -1
  521. package/dist/chunk-3S63QIFQ.js.map +0 -1
  522. package/dist/chunk-4WBGZYZZ.js.map +0 -1
  523. package/dist/chunk-CMQZNEIF.js.map +0 -1
  524. package/dist/chunk-DNHVPZOD.js.map +0 -1
  525. package/dist/chunk-FZZ2QTJI.js +0 -111
  526. package/dist/chunk-FZZ2QTJI.js.map +0 -1
  527. package/dist/chunk-J7T4MX7P.js.map +0 -1
  528. package/dist/chunk-KSGEGHYA.js.map +0 -1
  529. package/dist/chunk-KVJRXN2E.js.map +0 -1
  530. package/dist/chunk-LPSF4OQH.js +0 -47
  531. package/dist/chunk-LPSF4OQH.js.map +0 -1
  532. package/dist/chunk-LZGCJSQR.js.map +0 -1
  533. package/dist/chunk-OADWQ5CR.js +0 -115
  534. package/dist/chunk-OADWQ5CR.js.map +0 -1
  535. package/dist/chunk-PDJTHRAW.js +0 -36
  536. package/dist/chunk-PDJTHRAW.js.map +0 -1
  537. package/dist/chunk-PLCZD3LG.js.map +0 -1
  538. package/dist/chunk-RN53QBM4.js.map +0 -1
  539. package/dist/chunk-W4FBGYGK.js.map +0 -1
  540. /package/dist/{auto-sync-7O6RP2RT.js.map → auto-sync-QFQGOEO2.js.map} +0 -0
  541. /package/dist/{capsule-merge-Q6AR3XL7.js.map → capsule-merge-KXTRZ23Z.js.map} +0 -0
  542. /package/dist/{chunk-ICP53SKG.js.map → chunk-2HIJHXB3.js.map} +0 -0
  543. /package/dist/{chunk-FJ2ND6CZ.js.map → chunk-47J4EDGR.js.map} +0 -0
  544. /package/dist/{chunk-S55OAS5P.js.map → chunk-4EABKPZS.js.map} +0 -0
  545. /package/dist/{chunk-GD7UPIBG.js.map → chunk-4JWJMRPJ.js.map} +0 -0
  546. /package/dist/{chunk-3NDN5P55.js.map → chunk-4S3ECH3U.js.map} +0 -0
  547. /package/dist/{chunk-CGASUJVP.js.map → chunk-5V6IXHPI.js.map} +0 -0
  548. /package/dist/{chunk-A4JMGKCD.js.map → chunk-5XCN4XBU.js.map} +0 -0
  549. /package/dist/{chunk-2RPJ4NEE.js.map → chunk-64BHFFKZ.js.map} +0 -0
  550. /package/dist/{chunk-FQC3DHH2.js.map → chunk-66SE3BNH.js.map} +0 -0
  551. /package/dist/{chunk-TERNBNJB.js.map → chunk-6FC3IZ26.js.map} +0 -0
  552. /package/dist/{chunk-53AJILXF.js.map → chunk-6XGEBQ3R.js.map} +0 -0
  553. /package/dist/{chunk-IP3DHDU2.js.map → chunk-7BLWBSRL.js.map} +0 -0
  554. /package/dist/{chunk-A2TFK5PG.js.map → chunk-7NDM2PNK.js.map} +0 -0
  555. /package/dist/{chunk-HRMEYQRO.js.map → chunk-7VWZ4LRW.js.map} +0 -0
  556. /package/dist/{chunk-R6YJI3HE.js.map → chunk-AW4QUFQF.js.map} +0 -0
  557. /package/dist/{chunk-P65YJEEL.js.map → chunk-AXFWMRKI.js.map} +0 -0
  558. /package/dist/{chunk-WG5HSQ4P.js.map → chunk-BAKXNQ3C.js.map} +0 -0
  559. /package/dist/{chunk-NM2WP3B7.js.map → chunk-BJYET5TX.js.map} +0 -0
  560. /package/dist/{chunk-HLKPRWF4.js.map → chunk-DATDLJAO.js.map} +0 -0
  561. /package/dist/{chunk-DX3XRGLH.js.map → chunk-DQTCGVFK.js.map} +0 -0
  562. /package/dist/{chunk-HIDEBEAN.js.map → chunk-E633OXMH.js.map} +0 -0
  563. /package/dist/{chunk-EZNXW27Q.js.map → chunk-ELQCS47S.js.map} +0 -0
  564. /package/dist/{chunk-HAYSYUAB.js.map → chunk-EURCX6PS.js.map} +0 -0
  565. /package/dist/{chunk-RSPSHRZA.js.map → chunk-FV7YQTN3.js.map} +0 -0
  566. /package/dist/{chunk-GWHPQOUC.js.map → chunk-GGBSF2X7.js.map} +0 -0
  567. /package/dist/{chunk-SYUBB3WM.js.map → chunk-GKEYXXKX.js.map} +0 -0
  568. /package/dist/{chunk-PELT6ADC.js.map → chunk-GSEPRIZC.js.map} +0 -0
  569. /package/dist/{chunk-UTVZKHJK.js.map → chunk-GUKBW4HL.js.map} +0 -0
  570. /package/dist/{chunk-2F6NP3NT.js.map → chunk-HDQUQBPW.js.map} +0 -0
  571. /package/dist/{chunk-6HMYUWXR.js.map → chunk-HTP6XRUI.js.map} +0 -0
  572. /package/dist/{chunk-UYUYZ4WY.js.map → chunk-IARXXZU4.js.map} +0 -0
  573. /package/dist/{chunk-MNB5RMAY.js.map → chunk-IIFFC3RL.js.map} +0 -0
  574. /package/dist/{chunk-KQAFEZQX.js.map → chunk-IPLYGWQF.js.map} +0 -0
  575. /package/dist/{chunk-NZBZ7IS2.js.map → chunk-JDCQK3C5.js.map} +0 -0
  576. /package/dist/{chunk-ANCC3JJH.js.map → chunk-JI62YGPI.js.map} +0 -0
  577. /package/dist/{chunk-LULR4IUW.js.map → chunk-KATEWTQJ.js.map} +0 -0
  578. /package/dist/{chunk-IJ7HK452.js.map → chunk-KMAP7SNQ.js.map} +0 -0
  579. /package/dist/{chunk-PRVJH7CY.js.map → chunk-KMWYZTIE.js.map} +0 -0
  580. /package/dist/{chunk-JGSKJHF7.js.map → chunk-KQS72GCR.js.map} +0 -0
  581. /package/dist/{chunk-FMCHFSZF.js.map → chunk-LQKXVQZR.js.map} +0 -0
  582. /package/dist/{chunk-M4DMO67I.js.map → chunk-LTOAJXZB.js.map} +0 -0
  583. /package/dist/{chunk-NIS256NW.js.map → chunk-LYMNZZIM.js.map} +0 -0
  584. /package/dist/{chunk-3PY7VHV7.js.map → chunk-MCA2X4WH.js.map} +0 -0
  585. /package/dist/{chunk-S5NZBKKQ.js.map → chunk-N3CXAYPJ.js.map} +0 -0
  586. /package/dist/{chunk-WQIHRA5F.js.map → chunk-N3LL5NEU.js.map} +0 -0
  587. /package/dist/{chunk-G2RBWVFQ.js.map → chunk-NKL25FCF.js.map} +0 -0
  588. /package/dist/{chunk-LMDRGRJ2.js.map → chunk-NOB2T2FC.js.map} +0 -0
  589. /package/dist/{chunk-P2OTGMTR.js.map → chunk-NSGU76YO.js.map} +0 -0
  590. /package/dist/{chunk-D5NGH2EW.js.map → chunk-O76MWTVS.js.map} +0 -0
  591. /package/dist/{chunk-WZFAPHIK.js.map → chunk-OIOZ6MOP.js.map} +0 -0
  592. /package/dist/{chunk-UMOO7IY7.js.map → chunk-P2KBDJJ6.js.map} +0 -0
  593. /package/dist/{chunk-SXWHN7GC.js.map → chunk-PDEKQWDV.js.map} +0 -0
  594. /package/dist/{chunk-2EJNXE53.js.map → chunk-PLCHU56K.js.map} +0 -0
  595. /package/dist/{chunk-45OTV7FZ.js.map → chunk-PWIMF7LP.js.map} +0 -0
  596. /package/dist/{chunk-7YKVM5H3.js.map → chunk-PWLB4TRK.js.map} +0 -0
  597. /package/dist/{chunk-RVYVMQK4.js.map → chunk-QSYL5CXK.js.map} +0 -0
  598. /package/dist/{chunk-NXUJRXSF.js.map → chunk-QWLW3VQH.js.map} +0 -0
  599. /package/dist/{chunk-JBPKEARU.js.map → chunk-RKNJBZ55.js.map} +0 -0
  600. /package/dist/{chunk-QCECHYZL.js.map → chunk-RVO6TCTU.js.map} +0 -0
  601. /package/dist/{chunk-5L7PTX2Q.js.map → chunk-S2SJEOTM.js.map} +0 -0
  602. /package/dist/{chunk-52I3YZZ6.js.map → chunk-S75UQ3T3.js.map} +0 -0
  603. /package/dist/{chunk-LXOM6IQU.js.map → chunk-SEF4IOFE.js.map} +0 -0
  604. /package/dist/{chunk-DUEEQCTT.js.map → chunk-SHYIMIX5.js.map} +0 -0
  605. /package/dist/{chunk-7K5Q6COX.js.map → chunk-TVVEYCNW.js.map} +0 -0
  606. /package/dist/{chunk-3JUYWPFJ.js.map → chunk-VFS3MK5F.js.map} +0 -0
  607. /package/dist/{chunk-WOEVJKKQ.js.map → chunk-WPZX7MEA.js.map} +0 -0
  608. /package/dist/{chunk-ZRWB5D4H.js.map → chunk-WT6UL3UA.js.map} +0 -0
  609. /package/dist/{chunk-MC6XO7T4.js.map → chunk-YLBE6PLR.js.map} +0 -0
  610. /package/dist/{chunk-GF22HWS2.js.map → chunk-Z54EM5YZ.js.map} +0 -0
  611. /package/dist/{chunk-GVX3NAUU.js.map → chunk-ZDAYWJV6.js.map} +0 -0
  612. /package/dist/{chunk-JYPO7L3G.js.map → chunk-ZN4EYMKJ.js.map} +0 -0
  613. /package/dist/{resolution-3K27T4VO.js.map → coding/pre-action-gate.js.map} +0 -0
  614. /package/dist/{first-start-migration-ZSHEFEI3.js.map → first-start-migration-626C5554.js.map} +0 -0
  615. /package/dist/{forget-DNAJ66ZD.js.map → forget-GJ42LCBW.js.map} +0 -0
  616. /package/dist/{tier-stats-OPTSBNRH.js.map → tier-stats-2JCZYEF7.js.map} +0 -0
@@ -0,0 +1,367 @@
1
+ import { createHash } from "node:crypto";
2
+ import {
3
+ type AbstractionNode,
4
+ HARMONIC_SOURCE_MEMORY_INSERTED_AT_KEY,
5
+ upsertAbstractionNodes,
6
+ } from "./abstraction-nodes.js";
7
+ import { type CueAnchor, type CueAnchorType, upsertCueAnchors } from "./cue-anchors.js";
8
+ import { compareDeterministicStrings } from "./deterministic-order.js";
9
+ import { normalizeRecallTokens } from "./recall-tokenization.js";
10
+ import { sanitizeMemoryContent } from "./sanitize.js";
11
+
12
+ export interface HarmonicCueAnchorInput {
13
+ type: CueAnchorType;
14
+ value: string;
15
+ }
16
+
17
+ export interface HarmonicConstructionInput {
18
+ sessionKey: string;
19
+ recordedAt: string;
20
+ episodeTitle?: string | null;
21
+ persistedFacts: Array<{
22
+ memoryId: string;
23
+ content: string;
24
+ category: string;
25
+ tags: string[];
26
+ insertedAt?: string;
27
+ entityRef?: string | null;
28
+ cueAnchors?: HarmonicCueAnchorInput[] | null;
29
+ validAt?: string | null;
30
+ }>;
31
+ entityMentions: Array<{
32
+ name: string;
33
+ type: string;
34
+ facts?: string[];
35
+ }>;
36
+ }
37
+
38
+ const CUE_ANCHOR_TYPES: Record<CueAnchorType, true> = {
39
+ entity: true,
40
+ file: true,
41
+ tool: true,
42
+ outcome: true,
43
+ constraint: true,
44
+ date: true,
45
+ };
46
+
47
+ function safeHarmonicDisplayText(value: unknown): string | undefined {
48
+ if (typeof value !== "string") return undefined;
49
+ const candidate = value.trim();
50
+ if (candidate.length === 0) return undefined;
51
+ const sanitized = sanitizeMemoryContent(candidate);
52
+ if (!sanitized.clean) return undefined;
53
+ const clean = sanitized.text.trim();
54
+ return clean.length > 0 ? clean : undefined;
55
+ }
56
+ function hashId(prefix: string, value: string): string {
57
+ return `${prefix}${createHash("sha256").update(value).digest("hex").slice(0, 16)}`;
58
+ }
59
+
60
+ function truncate(value: string, maxChars: number): string {
61
+ return value.length <= maxChars ? value : value.slice(0, maxChars);
62
+ }
63
+
64
+ function sortedUnique(values: Iterable<string>): string[] {
65
+ return [...new Set(values)].sort(compareDeterministicStrings);
66
+ }
67
+
68
+ export function harmonicEntitySegment(name: string): string {
69
+ const normalized = name.toLowerCase().replace(/[^a-z0-9]+/g, "-");
70
+ const start = normalized.startsWith("-") ? 1 : 0;
71
+ const end = normalized.endsWith("-") ? normalized.length - 1 : normalized.length;
72
+ const segment = normalized.slice(start, end);
73
+ return segment || hashId("entity-", name).slice(0, 23);
74
+ }
75
+
76
+ export function normalizedHarmonicEntityIdentity(name: string): string {
77
+ return name.trim().toLowerCase().replace(/\s+/g, " ");
78
+ }
79
+ export function harmonicEntityReferenceMatches(
80
+ entityRef: string,
81
+ entityName: string,
82
+ allowSegmentFallback: boolean
83
+ ): boolean {
84
+ if (normalizedHarmonicEntityIdentity(entityRef) === normalizedHarmonicEntityIdentity(entityName)) {
85
+ return true;
86
+ }
87
+ return allowSegmentFallback && harmonicEntitySegment(entityRef) === harmonicEntitySegment(entityName);
88
+ }
89
+
90
+ export function normalizeCueAnchorInputs(value: unknown, maxAnchors = 3): HarmonicCueAnchorInput[] {
91
+ if (!Array.isArray(value) || maxAnchors <= 0) return [];
92
+ const byIdentity = new Map<string, HarmonicCueAnchorInput>();
93
+ for (const candidate of value) {
94
+ if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) continue;
95
+ const record = candidate as Record<string, unknown>;
96
+ if (typeof record.type !== "string" || !Object.hasOwn(CUE_ANCHOR_TYPES, record.type)) {
97
+ continue;
98
+ }
99
+ const anchorValue = safeHarmonicDisplayText(record.value);
100
+ if (anchorValue === undefined || anchorValue.length > 120) continue;
101
+ const type = record.type as CueAnchorType;
102
+ const normalizedCue = normalizeRecallTokens(anchorValue).join(" ");
103
+ if (normalizedCue.length === 0) continue;
104
+ const identity = `${type}:${normalizedCue}`;
105
+ const existing = byIdentity.get(identity);
106
+ if (!existing || compareDeterministicStrings(anchorValue, existing.value) < 0) {
107
+ byIdentity.set(identity, { type, value: anchorValue });
108
+ }
109
+ }
110
+ return [...byIdentity.entries()]
111
+ .sort(([left], [right]) => compareDeterministicStrings(left, right))
112
+ .slice(0, maxAnchors)
113
+ .map(([, anchor]) => anchor);
114
+ }
115
+
116
+ function validAtDate(validAt: string | null | undefined): string | undefined {
117
+ if (typeof validAt !== "string") return undefined;
118
+ const match = /^(\d{4})-(\d{2})-(\d{2})/.exec(validAt);
119
+ if (!match) return undefined;
120
+ const year = Number(match[1]);
121
+ const month = Number(match[2]);
122
+ const day = Number(match[3]);
123
+ const date = new Date(0);
124
+ date.setUTCFullYear(year, month - 1, day);
125
+ if (
126
+ !Number.isFinite(date.getTime()) ||
127
+ date.getUTCFullYear() !== year ||
128
+ date.getUTCMonth() !== month - 1 ||
129
+ date.getUTCDate() !== day
130
+ ) {
131
+ return undefined;
132
+ }
133
+ return match[0];
134
+ }
135
+
136
+ function sourceMemoryInsertedAtMetadata(
137
+ facts: Array<{ memoryId: string; insertedAt: string }>
138
+ ): Record<string, string> {
139
+ const insertedAtById = Object.fromEntries(
140
+ facts
141
+ .map((fact) => [fact.memoryId, fact.insertedAt] as const)
142
+ .sort(([left], [right]) => compareDeterministicStrings(left, right))
143
+ );
144
+ return {
145
+ [HARMONIC_SOURCE_MEMORY_INSERTED_AT_KEY]: JSON.stringify(insertedAtById),
146
+ };
147
+ }
148
+
149
+ export function deriveHarmonicRecords(input: HarmonicConstructionInput): {
150
+ nodes: AbstractionNode[];
151
+ anchors: CueAnchor[];
152
+ } {
153
+ const persistedFacts = input.persistedFacts
154
+ .map((fact) => ({
155
+ ...fact,
156
+ memoryId: fact.memoryId.trim(),
157
+ content: safeHarmonicDisplayText(fact.content) ?? "",
158
+ insertedAt:
159
+ fact.insertedAt && Number.isFinite(Date.parse(fact.insertedAt))
160
+ ? new Date(fact.insertedAt).toISOString()
161
+ : input.recordedAt,
162
+ tags: sortedUnique(
163
+ fact.tags.flatMap((tag) => {
164
+ const safeTag = safeHarmonicDisplayText(tag);
165
+ return safeTag ? [safeTag] : [];
166
+ })
167
+ ),
168
+ entityRef: safeHarmonicDisplayText(fact.entityRef),
169
+ cueAnchors: normalizeCueAnchorInputs(fact.cueAnchors),
170
+ }))
171
+ .filter((fact) => fact.memoryId.length > 0 && fact.content.length > 0)
172
+ .sort(
173
+ (left, right) =>
174
+ compareDeterministicStrings(left.memoryId, right.memoryId) ||
175
+ compareDeterministicStrings(left.content, right.content)
176
+ );
177
+
178
+ if (persistedFacts.length === 0) return { nodes: [], anchors: [] };
179
+
180
+ const sourceMemoryIds = sortedUnique(persistedFacts.map((fact) => fact.memoryId));
181
+ const episodeNodeId = hashId("ep-", `${input.sessionKey}|${input.recordedAt}|${sourceMemoryIds.join("|")}`);
182
+ const episodeTitle = safeHarmonicDisplayText(input.episodeTitle) ?? persistedFacts[0]?.content ?? "Memory episode";
183
+ const episodeNode: AbstractionNode = {
184
+ schemaVersion: 1,
185
+ nodeId: episodeNodeId,
186
+ recordedAt: input.recordedAt,
187
+ sessionKey: input.sessionKey,
188
+ kind: "episode",
189
+ abstractionLevel: "micro",
190
+ title: truncate(episodeTitle, 80),
191
+ summary: truncate(
192
+ persistedFacts
193
+ .slice(0, 3)
194
+ .map((fact) => fact.content)
195
+ .join("; "),
196
+ 400
197
+ ),
198
+ sourceMemoryIds,
199
+ entityRefs: sortedUnique(persistedFacts.flatMap((fact) => (fact.entityRef ? [fact.entityRef] : []))),
200
+ tags: sortedUnique(persistedFacts.flatMap((fact) => fact.tags)),
201
+ metadata: sourceMemoryInsertedAtMetadata(persistedFacts),
202
+ };
203
+
204
+ const mentionGroups = new Map<string, { names: string[]; types: string[]; facts: string[]; segment: string }>();
205
+ for (const mention of input.entityMentions) {
206
+ const name = safeHarmonicDisplayText(mention.name);
207
+ if (!name) continue;
208
+ const identity = normalizedHarmonicEntityIdentity(name);
209
+ const group = mentionGroups.get(identity) ?? {
210
+ names: [],
211
+ types: [],
212
+ facts: [],
213
+ segment: harmonicEntitySegment(name),
214
+ };
215
+ group.names.push(name);
216
+ group.types.push(mention.type.trim().toLowerCase());
217
+ group.facts.push(
218
+ ...(mention.facts ?? []).flatMap((fact) => {
219
+ const safeFact = safeHarmonicDisplayText(fact);
220
+ return safeFact ? [safeFact] : [];
221
+ })
222
+ );
223
+ mentionGroups.set(identity, group);
224
+ }
225
+ const groupsPerSegment = new Map<string, number>();
226
+ for (const group of mentionGroups.values()) {
227
+ groupsPerSegment.set(group.segment, (groupsPerSegment.get(group.segment) ?? 0) + 1);
228
+ }
229
+
230
+ const topicEntries = [...mentionGroups.entries()]
231
+ .sort(([left], [right]) => compareDeterministicStrings(left, right))
232
+ .flatMap(([identity, group]) => {
233
+ const matchingFacts = persistedFacts.filter((fact) => {
234
+ if (!fact.entityRef) return false;
235
+ return harmonicEntityReferenceMatches(
236
+ fact.entityRef,
237
+ sortedUnique(group.names)[0] ?? identity,
238
+ groupsPerSegment.get(group.segment) === 1
239
+ );
240
+ });
241
+ const nodeSegment = `${group.segment}-${hashId("", identity)}`;
242
+ const mentionSummary = sortedUnique(group.facts).join("; ");
243
+ const node: AbstractionNode = {
244
+ schemaVersion: 1,
245
+ nodeId: `topic-${nodeSegment}`,
246
+ recordedAt: input.recordedAt,
247
+ sessionKey: input.sessionKey,
248
+ kind: group.types.includes("project") ? "project" : "topic",
249
+ abstractionLevel: "meso",
250
+ title: sortedUnique(group.names)[0] ?? group.segment,
251
+ summary: truncate(
252
+ mentionSummary ||
253
+ matchingFacts
254
+ .slice(0, 3)
255
+ .map((fact) => fact.content)
256
+ .join("; ") ||
257
+ sortedUnique(group.names)[0] ||
258
+ group.segment,
259
+ 400
260
+ ),
261
+ sourceMemoryIds: sortedUnique(matchingFacts.map((fact) => fact.memoryId)),
262
+ entityRefs: sortedUnique(group.names),
263
+ tags: sortedUnique(matchingFacts.flatMap((fact) => fact.tags)),
264
+ metadata: sourceMemoryInsertedAtMetadata(matchingFacts),
265
+ };
266
+ return [{ identity, segment: group.segment, node }];
267
+ });
268
+ const topicNodes = topicEntries.map((entry) => entry.node);
269
+ const topicNodeIdByIdentity = new Map(topicEntries.map((entry) => [entry.identity, entry.node.nodeId]));
270
+ const topicEntriesBySegment = new Map<string, typeof topicEntries>();
271
+ for (const entry of topicEntries) {
272
+ const entries = topicEntriesBySegment.get(entry.segment) ?? [];
273
+ entries.push(entry);
274
+ topicEntriesBySegment.set(entry.segment, entries);
275
+ }
276
+ const topicNodeIdForEntityRef = (entityRef: string): string | undefined => {
277
+ const exact = topicNodeIdByIdentity.get(normalizedHarmonicEntityIdentity(entityRef));
278
+ if (exact) return exact;
279
+ const segmentEntries = topicEntriesBySegment.get(harmonicEntitySegment(entityRef));
280
+ return segmentEntries?.length === 1 ? segmentEntries[0]?.node.nodeId : undefined;
281
+ };
282
+ const anchorsById = new Map<string, CueAnchor>();
283
+ for (const fact of persistedFacts) {
284
+ const deterministicAnchors: HarmonicCueAnchorInput[] = [];
285
+ if (fact.entityRef) {
286
+ deterministicAnchors.push({ type: "entity", value: fact.entityRef });
287
+ }
288
+ const date = validAtDate(fact.validAt);
289
+ if (date) deterministicAnchors.push({ type: "date", value: date });
290
+
291
+ for (const anchorInput of [...fact.cueAnchors, ...deterministicAnchors]) {
292
+ const anchorValue = safeHarmonicDisplayText(anchorInput.value);
293
+ if (anchorValue === undefined) continue;
294
+ const normalizedCue = normalizeRecallTokens(anchorValue).join(" ");
295
+ if (normalizedCue.length === 0) continue;
296
+ const anchorId = hashId("cue-", `${anchorInput.type}:${normalizedCue}`);
297
+ const topicNodeId = fact.entityRef ? topicNodeIdForEntityRef(fact.entityRef) : undefined;
298
+ const nodeRefs = sortedUnique(topicNodeId ? [episodeNodeId, topicNodeId] : [episodeNodeId]);
299
+ const existing = anchorsById.get(anchorId);
300
+ const mergedNodeRefs = sortedUnique([...(existing?.nodeRefs ?? []), ...nodeRefs]);
301
+ const sourceMemoryIdsByNodeRef = Object.fromEntries(
302
+ mergedNodeRefs.map((nodeRef) => [
303
+ nodeRef,
304
+ sortedUnique([
305
+ ...(existing?.sourceMemoryIdsByNodeRef?.[nodeRef] ?? []),
306
+ ...(nodeRefs.includes(nodeRef) ? [fact.memoryId] : []),
307
+ ]),
308
+ ])
309
+ );
310
+ anchorsById.set(anchorId, {
311
+ schemaVersion: 1,
312
+ anchorId,
313
+ anchorType: anchorInput.type,
314
+ anchorValue:
315
+ existing && compareDeterministicStrings(existing.anchorValue, anchorValue) < 0
316
+ ? existing.anchorValue
317
+ : anchorValue,
318
+ normalizedCue,
319
+ recordedAt: input.recordedAt,
320
+ sessionKey: input.sessionKey,
321
+ nodeRefs: mergedNodeRefs,
322
+ sourceMemoryIdsByNodeRef,
323
+ tags: sortedUnique([...(existing?.tags ?? []), ...fact.tags]),
324
+ });
325
+ }
326
+ }
327
+
328
+ return {
329
+ nodes: [episodeNode, ...topicNodes]
330
+ .map((node) => ({
331
+ ...node,
332
+ sourceMemoryIds: sortedUnique(node.sourceMemoryIds ?? []),
333
+ entityRefs: sortedUnique(node.entityRefs ?? []),
334
+ tags: sortedUnique(node.tags ?? []),
335
+ }))
336
+ .sort((left, right) => compareDeterministicStrings(left.nodeId, right.nodeId)),
337
+ anchors: [...anchorsById.values()]
338
+ .map((anchor) => ({
339
+ ...anchor,
340
+ nodeRefs: sortedUnique(anchor.nodeRefs),
341
+ tags: sortedUnique(anchor.tags ?? []),
342
+ }))
343
+ .sort((left, right) => compareDeterministicStrings(left.anchorId, right.anchorId)),
344
+ };
345
+ }
346
+
347
+ export async function persistHarmonicRecords(options: {
348
+ memoryDir: string;
349
+ abstractionNodeStoreDir?: string;
350
+ nodes: AbstractionNode[];
351
+ anchors: CueAnchor[];
352
+ }): Promise<void> {
353
+ if (options.nodes.length > 0) {
354
+ await upsertAbstractionNodes({
355
+ memoryDir: options.memoryDir,
356
+ abstractionNodeStoreDir: options.abstractionNodeStoreDir,
357
+ nodes: options.nodes,
358
+ });
359
+ }
360
+ if (options.anchors.length > 0) {
361
+ await upsertCueAnchors({
362
+ memoryDir: options.memoryDir,
363
+ abstractionNodeStoreDir: options.abstractionNodeStoreDir,
364
+ anchors: options.anchors,
365
+ });
366
+ }
367
+ }
@@ -1,18 +1,122 @@
1
1
  import path from "node:path";
2
- import { listJsonFiles, readJsonFile } from "./json-store.js";
2
+ import { listJsonFilesStrict, readJsonFile } from "./json-store.js";
3
3
  import { throwIfAborted } from "./abort-error.js";
4
- import {
5
- resolveAbstractionNodeStoreDir,
6
- validateAbstractionNode,
7
- type AbstractionNode,
8
- } from "./abstraction-nodes.js";
9
- import {
10
- resolveCueAnchorStoreDir,
11
- validateCueAnchor,
12
- type CueAnchor,
13
- type CueAnchorType,
14
- } from "./cue-anchors.js";
4
+ import { inferMemoryStatus, toMemoryPathRel } from "./memory-lifecycle-ledger-utils.js";
5
+ import {
6
+ HARMONIC_SOURCE_MEMORY_INSERTED_AT_KEY,
7
+ resolveAbstractionNodeStoreDir,
8
+ validateAbstractionNode,
9
+ type AbstractionNode,
10
+ } from "./abstraction-nodes.js";
11
+ import { resolveCueAnchorStoreDir, validateCueAnchor, type CueAnchor, type CueAnchorType } from "./cue-anchors.js";
12
+ import { compareDeterministicStrings } from "./deterministic-order.js";
15
13
  import { countRecallTokenOverlap, normalizeRecallTokens } from "./recall-tokenization.js";
14
+ import { stripAttributesSuffix } from "./structured-attributes.js";
15
+ import { isValidityExpiredNow } from "./temporal-validity.js";
16
+ import type { MemoryFile } from "./types.js";
17
+
18
+ type SourceMemoryMap = Map<string, MemoryFile>;
19
+
20
+ async function readSourceMemories(options: {
21
+ memoryDir: string;
22
+ abortSignal?: AbortSignal;
23
+ }): Promise<SourceMemoryMap> {
24
+ const sourceMemories: SourceMemoryMap = new Map();
25
+ try {
26
+ const { StorageManager } = await import("./storage.js");
27
+ const storage = new StorageManager(options.memoryDir);
28
+ const [hotMemories, coldMemories] = await Promise.all([
29
+ storage.readAllMemories({ abortSignal: options.abortSignal }),
30
+ storage.readAllColdMemories(),
31
+ ]);
32
+ for (const memory of [...hotMemories, ...coldMemories]) {
33
+ throwIfAborted(options.abortSignal, "harmonic retrieval aborted");
34
+ sourceMemories.set(memory.frontmatter.id, memory);
35
+ }
36
+ } catch {
37
+ throwIfAborted(options.abortSignal, "harmonic retrieval aborted");
38
+ // Source validation fails closed when the authorized memory directory is
39
+ // unreadable. Source-less nodes remain eligible for retrieval.
40
+ sourceMemories.clear();
41
+ }
42
+ return sourceMemories;
43
+ }
44
+
45
+ function projectSourceBackedNode(
46
+ node: AbstractionNode,
47
+ sourceMemories: SourceMemoryMap,
48
+ memoryDir: string,
49
+ temporalExpiredInInjection: boolean,
50
+ nowMs: number
51
+ ): AbstractionNode | null {
52
+ const sourceMemoryIds = node.sourceMemoryIds ?? [];
53
+ if (sourceMemoryIds.length === 0) return node;
54
+
55
+ const activeSourceMemoryIds = sourceMemoryIds.filter((memoryId) => {
56
+ const memory = sourceMemories.get(memoryId);
57
+ return (
58
+ memory !== undefined &&
59
+ inferMemoryStatus(memory.frontmatter, toMemoryPathRel(memoryDir, memory.path)) === "active" &&
60
+ (temporalExpiredInInjection || !isValidityExpiredNow(memory.frontmatter, nowMs))
61
+ );
62
+ });
63
+ if (activeSourceMemoryIds.length === 0) return null;
64
+
65
+ const activeMemories = activeSourceMemoryIds.flatMap((memoryId) => {
66
+ const memory = sourceMemories.get(memoryId);
67
+ return memory ? [memory] : [];
68
+ });
69
+ const activeContents = activeMemories.map((memory) =>
70
+ memory.frontmatter.structuredAttributes ? stripAttributesSuffix(memory.content) : memory.content
71
+ );
72
+ let metadata: Record<string, string> | undefined;
73
+ const insertedAtRaw = node.metadata?.[HARMONIC_SOURCE_MEMORY_INSERTED_AT_KEY];
74
+ if (insertedAtRaw) {
75
+ try {
76
+ const insertedAt = JSON.parse(insertedAtRaw) as Record<string, unknown>;
77
+ const activeInsertedAt = activeSourceMemoryIds.flatMap((memoryId) => {
78
+ const value = insertedAt[memoryId];
79
+ return typeof value === "string" ? [[memoryId, value] as const] : [];
80
+ });
81
+ if (activeInsertedAt.length > 0) {
82
+ metadata = {
83
+ [HARMONIC_SOURCE_MEMORY_INSERTED_AT_KEY]: JSON.stringify(Object.fromEntries(activeInsertedAt)),
84
+ };
85
+ }
86
+ } catch {
87
+ metadata = undefined;
88
+ }
89
+ }
90
+
91
+ return {
92
+ ...node,
93
+ sourceMemoryIds: activeSourceMemoryIds,
94
+ title: activeContents[0]?.slice(0, 80) ?? node.title,
95
+ summary: activeContents.slice(0, 3).join("; ").slice(0, 400),
96
+ tags: [...new Set(activeMemories.flatMap((memory) => memory.frontmatter.tags))].sort(compareDeterministicStrings),
97
+ entityRefs: [
98
+ ...new Set(
99
+ activeMemories.flatMap((memory) =>
100
+ typeof memory.frontmatter.entityRef === "string" ? [memory.frontmatter.entityRef] : []
101
+ )
102
+ ),
103
+ ].sort(compareDeterministicStrings),
104
+ metadata,
105
+ };
106
+ }
107
+
108
+ function anchorMatchesProjectedNode(
109
+ anchor: CueAnchor,
110
+ nodeRef: string,
111
+ node: AbstractionNode,
112
+ allowLegacyAttribution: boolean
113
+ ): boolean {
114
+ const activeSourceMemoryIds = node.sourceMemoryIds ?? [];
115
+ if (activeSourceMemoryIds.length === 0) return true;
116
+ if (!anchor.sourceMemoryIdsByNodeRef) return allowLegacyAttribution;
117
+ const anchorSourceMemoryIds = anchor.sourceMemoryIdsByNodeRef[nodeRef] ?? [];
118
+ return anchorSourceMemoryIds.some((sourceMemoryId) => activeSourceMemoryIds.includes(sourceMemoryId));
119
+ }
16
120
 
17
121
  export interface HarmonicMatchedAnchor {
18
122
  anchorId: string;
@@ -74,7 +178,11 @@ function scoreNode(node: AbstractionNode, queryTokens: Set<string>): { score: nu
74
178
  return { score, matchedFields };
75
179
  }
76
180
 
77
- function scoreAnchor(anchor: CueAnchor, queryTokens: Set<string>): { score: number; matchedFields: string[] } {
181
+ function scoreAnchor(
182
+ anchor: CueAnchor,
183
+ queryTokens: Set<string>,
184
+ eligibleNodeTags: readonly string[]
185
+ ): { score: number; matchedFields: string[] } {
78
186
  const matchedFields: string[] = [];
79
187
  let score = 0;
80
188
 
@@ -93,7 +201,7 @@ function scoreAnchor(anchor: CueAnchor, queryTokens: Set<string>): { score: numb
93
201
  matchedFields.push("anchorType");
94
202
  }
95
203
 
96
- const tagMatches = countRecallTokenOverlap(queryTokens, anchor.tags?.join(" "));
204
+ const tagMatches = countRecallTokenOverlap(queryTokens, eligibleNodeTags.join(" "));
97
205
  if (tagMatches > 0) {
98
206
  score += tagMatches * 2;
99
207
  matchedFields.push("anchorTags");
@@ -107,7 +215,7 @@ async function readAbstractionNodes(options: {
107
215
  abstractionNodeStoreDir?: string;
108
216
  }): Promise<AbstractionNode[]> {
109
217
  const rootDir = resolveAbstractionNodeStoreDir(options.memoryDir, options.abstractionNodeStoreDir);
110
- const files = await listJsonFiles(path.join(rootDir, "nodes"));
218
+ const files = await listJsonFilesStrict(path.join(rootDir, "nodes"), { allowMissingDirectory: true });
111
219
  const nodes: AbstractionNode[] = [];
112
220
  for (const filePath of files) {
113
221
  try {
@@ -125,7 +233,7 @@ async function readCueAnchors(options: {
125
233
  }): Promise<CueAnchor[]> {
126
234
  const abstractionRoot = resolveAbstractionNodeStoreDir(options.memoryDir, options.abstractionNodeStoreDir);
127
235
  const rootDir = resolveCueAnchorStoreDir(abstractionRoot);
128
- const files = await listJsonFiles(rootDir);
236
+ const files = await listJsonFilesStrict(rootDir, { allowMissingDirectory: true });
129
237
  const anchors: CueAnchor[] = [];
130
238
  for (const filePath of files) {
131
239
  try {
@@ -145,15 +253,38 @@ export async function searchHarmonicRetrieval(options: {
145
253
  sessionKey?: string;
146
254
  anchorsEnabled: boolean;
147
255
  abortSignal?: AbortSignal;
256
+ temporalExpiredInInjection?: boolean;
148
257
  }): Promise<HarmonicRetrievalResult[]> {
149
258
  throwIfAborted(options.abortSignal, "harmonic retrieval aborted");
150
259
  const queryTokens = new Set(normalizeRecallTokens(options.query, ["what", "which"]));
151
260
  if (queryTokens.size === 0 || options.maxResults <= 0) return [];
152
261
 
153
262
  const nodes = await readAbstractionNodes(options);
263
+ const sourceBackedNodes = nodes.filter((node) => (node.sourceMemoryIds?.length ?? 0) > 0);
264
+ const sourceMemories: SourceMemoryMap =
265
+ sourceBackedNodes.length > 0 ? await readSourceMemories(options) : new Map<string, MemoryFile>();
266
+ const legacyCompatibleNodeRefs = new Set<string>();
267
+ const nowMs = Date.now();
268
+ const eligibleNodes = nodes.flatMap((node) => {
269
+ const projected = projectSourceBackedNode(
270
+ node,
271
+ sourceMemories,
272
+ options.memoryDir,
273
+ options.temporalExpiredInInjection === true,
274
+ nowMs
275
+ );
276
+ if (
277
+ projected &&
278
+ (node.sourceMemoryIds?.length ?? 0) > 0 &&
279
+ projected.sourceMemoryIds?.length === node.sourceMemoryIds?.length
280
+ ) {
281
+ legacyCompatibleNodeRefs.add(node.nodeId);
282
+ }
283
+ return projected ? [projected] : [];
284
+ });
154
285
  const candidates = new Map<string, HarmonicCandidate>();
155
286
 
156
- for (const node of nodes) {
287
+ for (const node of eligibleNodes) {
157
288
  throwIfAborted(options.abortSignal, "harmonic retrieval aborted");
158
289
  const { score, matchedFields } = scoreNode(node, queryTokens);
159
290
  if (score <= 0) continue;
@@ -169,12 +300,21 @@ export async function searchHarmonicRetrieval(options: {
169
300
  if (options.anchorsEnabled) {
170
301
  throwIfAborted(options.abortSignal, "harmonic retrieval aborted");
171
302
  const anchors = await readCueAnchors(options);
172
- const nodeIndex = new Map(nodes.map((node) => [node.nodeId, node]));
303
+ const nodeIndex = new Map(eligibleNodes.map((node) => [node.nodeId, node]));
173
304
  for (const anchor of anchors) {
174
305
  throwIfAborted(options.abortSignal, "harmonic retrieval aborted");
175
- const { score, matchedFields } = scoreAnchor(anchor, queryTokens);
306
+ const eligibleNodeRefs = anchor.nodeRefs.filter((nodeRef) => {
307
+ const node = nodeIndex.get(nodeRef);
308
+ return (
309
+ node !== undefined &&
310
+ anchorMatchesProjectedNode(anchor, nodeRef, node, legacyCompatibleNodeRefs.has(nodeRef))
311
+ );
312
+ });
313
+ const eligibleNodeTags = new Set(eligibleNodeRefs.flatMap((nodeRef) => nodeIndex.get(nodeRef)?.tags ?? []));
314
+ const eligibleAnchorTags = anchor.tags?.filter((tag) => eligibleNodeTags.has(tag)) ?? [];
315
+ const { score, matchedFields } = scoreAnchor(anchor, queryTokens, eligibleAnchorTags);
176
316
  if (score <= 0) continue;
177
- for (const nodeRef of anchor.nodeRefs) {
317
+ for (const nodeRef of eligibleNodeRefs) {
178
318
  const node = nodeIndex.get(nodeRef);
179
319
  if (!node) continue;
180
320
  const existing = candidates.get(nodeRef) ?? {
@@ -207,17 +347,18 @@ export async function searchHarmonicRetrieval(options: {
207
347
  nodeScore: candidate.nodeScore,
208
348
  anchorScore: candidate.anchorScore,
209
349
  matchedFields: [...candidate.matchedFields].sort(),
210
- matchedAnchors: [...candidate.matchedAnchors.values()].sort((left, right) =>
211
- left.anchorType.localeCompare(right.anchorType) || left.anchorValue.localeCompare(right.anchorValue)
350
+ matchedAnchors: [...candidate.matchedAnchors.values()].sort(
351
+ (left, right) =>
352
+ left.anchorType.localeCompare(right.anchorType) || left.anchorValue.localeCompare(right.anchorValue)
212
353
  ),
213
354
  };
214
355
  })
215
356
  .filter((result) => result.nodeScore > 0 || result.anchorScore > 0)
216
357
  .sort(
217
358
  (left, right) =>
218
- right.score - left.score
219
- || right.anchorScore - left.anchorScore
220
- || right.node.recordedAt.localeCompare(left.node.recordedAt),
359
+ right.score - left.score ||
360
+ right.anchorScore - left.anchorScore ||
361
+ right.node.recordedAt.localeCompare(left.node.recordedAt)
221
362
  )
222
363
  .slice(0, options.maxResults);
223
364
  }