@remnic/core 9.49.0 → 9.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (606) 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 +10 -10
  4. package/dist/access-admin-ops-surface.js +48 -48
  5. package/dist/access-authorization-probe.d.ts +10 -10
  6. package/dist/access-authorization-probe.js +49 -49
  7. package/dist/access-boundary.d.ts +10 -10
  8. package/dist/access-boundary.js +48 -48
  9. package/dist/access-cli.js +132 -127
  10. package/dist/access-cli.js.map +1 -1
  11. package/dist/access-coding-context-resolution.d.ts +1 -1
  12. package/dist/access-extraction-force-flush.d.ts +10 -10
  13. package/dist/access-extraction-force-flush.js +48 -48
  14. package/dist/access-health-types.d.ts +1 -1
  15. package/dist/access-http-lcm-compaction.d.ts +10 -10
  16. package/dist/access-http-lifecycle-flush.d.ts +10 -10
  17. package/dist/access-http-offline-stream.d.ts +10 -10
  18. package/dist/access-http-query.js +48 -48
  19. package/dist/access-http.d.ts +10 -10
  20. package/dist/access-http.js +60 -60
  21. package/dist/access-identity-continuity-surface.d.ts +8 -8
  22. package/dist/access-identity-continuity-surface.js +48 -48
  23. package/dist/access-lcm-surface.d.ts +10 -10
  24. package/dist/access-lcm-surface.js +48 -48
  25. package/dist/access-mcp.d.ts +10 -10
  26. package/dist/access-mcp.js +55 -55
  27. package/dist/access-memory-search-fanout.d.ts +2 -2
  28. package/dist/{access-namespace-preflight--H6HwN85.d.ts → access-namespace-preflight-DuDU301-.d.ts} +1 -1
  29. package/dist/access-namespace-preflight.d.ts +3 -3
  30. package/dist/access-namespace-preflight.js +48 -48
  31. package/dist/access-observe-write-surface.d.ts +10 -10
  32. package/dist/access-observe-write-surface.js +48 -48
  33. package/dist/access-offline-manifest.d.ts +8 -8
  34. package/dist/access-offline-manifest.js +3 -3
  35. package/dist/access-operations-batch.js +51 -51
  36. package/dist/access-operations.d.ts +13 -13
  37. package/dist/access-operations.js +54 -54
  38. package/dist/access-recall-concurrency.d.ts +10 -10
  39. package/dist/access-recall-concurrency.js +48 -48
  40. package/dist/access-recall-response.d.ts +10 -10
  41. package/dist/access-recall-response.js +48 -48
  42. package/dist/access-recall-surface.d.ts +10 -10
  43. package/dist/access-recall-surface.js +48 -48
  44. package/dist/access-schema.d.ts +105 -105
  45. package/dist/access-schema.js +4 -4
  46. package/dist/{access-service-DvXOzCrM.d.ts → access-service--_3T_v23.d.ts} +7 -7
  47. package/dist/access-service-helpers.d.ts +10 -10
  48. package/dist/access-service.d.ts +10 -10
  49. package/dist/access-service.js +48 -48
  50. package/dist/access-surface-catalog.d.ts +10 -10
  51. package/dist/access-wearables-meetings-surface.d.ts +3 -3
  52. package/dist/action-confidence.d.ts +1 -1
  53. package/dist/active-memory-bridge.d.ts +1 -1
  54. package/dist/active-recall.d.ts +1 -1
  55. package/dist/active-recall.js +3 -2
  56. package/dist/active-recall.js.map +1 -1
  57. package/dist/adapters/index.js +4 -4
  58. package/dist/adapters/registry.js +2 -2
  59. package/dist/ambient-provenance.d.ts +1 -1
  60. package/dist/artifact-search.d.ts +1 -1
  61. package/dist/{auto-sync-7O6RP2RT.js → auto-sync-QFQGOEO2.js} +4 -4
  62. package/dist/behavior-learner.d.ts +1 -1
  63. package/dist/behavior-signals.d.ts +1 -1
  64. package/dist/bootstrap.d.ts +8 -8
  65. package/dist/briefing.d.ts +2 -2
  66. package/dist/briefing.js +12 -12
  67. package/dist/buffer-surprise-report.d.ts +1 -1
  68. package/dist/buffer-turn-helpers.d.ts +1 -1
  69. package/dist/buffer.d.ts +2 -2
  70. package/dist/buffer.js +4 -4
  71. package/dist/bulk-import/index.d.ts +3 -3
  72. package/dist/calibration.d.ts +1 -1
  73. package/dist/calibration.js +1 -1
  74. package/dist/capabilities.d.ts +1 -1
  75. package/dist/{capsule-crypto-YO5QJ6L3.js → capsule-crypto-7FJQINUR.js} +2 -2
  76. package/dist/{capsule-merge-6GFHWECG.js → capsule-merge-KXTRZ23Z.js} +4 -4
  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 +16 -16
  83. package/dist/causal-retrieval.js +3 -3
  84. package/dist/causal-trajectory-graph.d.ts +1 -1
  85. package/dist/causal-trajectory.d.ts +51 -2
  86. package/dist/causal-trajectory.js +8 -2
  87. package/dist/{chunk-EY64JLOM.js → chunk-24BKGKGO.js} +30 -19
  88. package/dist/chunk-24BKGKGO.js.map +1 -0
  89. package/dist/{chunk-ICP53SKG.js → chunk-2HIJHXB3.js} +2 -2
  90. package/dist/{chunk-BXLOS5AJ.js → chunk-2NLLXCJG.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-5JRC6BYS.js → chunk-47J4EDGR.js} +11 -11
  94. package/dist/{chunk-2VHLLPTX.js → chunk-4EABKPZS.js} +4 -4
  95. package/dist/{chunk-RJV6Q2FT.js → chunk-4JWJMRPJ.js} +2 -2
  96. package/dist/{chunk-MXPB6PJQ.js → chunk-4S3ECH3U.js} +2 -2
  97. package/dist/{chunk-CGASUJVP.js → chunk-5V6IXHPI.js} +4 -4
  98. package/dist/{chunk-R5IGA2NH.js → chunk-5XCN4XBU.js} +4 -4
  99. package/dist/{chunk-2RPJ4NEE.js → chunk-64BHFFKZ.js} +2 -2
  100. package/dist/{chunk-FQC3DHH2.js → chunk-66SE3BNH.js} +2 -2
  101. package/dist/{chunk-TERNBNJB.js → chunk-6FC3IZ26.js} +2 -2
  102. package/dist/{chunk-K7VKAHFE.js → chunk-6XGEBQ3R.js} +4 -4
  103. package/dist/{chunk-JFLOOTXU.js → chunk-7BLWBSRL.js} +3 -3
  104. package/dist/{chunk-ABR2HEJO.js → chunk-7NDM2PNK.js} +3 -3
  105. package/dist/{chunk-JXZ7NLYH.js → chunk-7VWZ4LRW.js} +2 -2
  106. package/dist/{chunk-RN53QBM4.js → chunk-A4QMKFFO.js} +5 -1
  107. package/dist/chunk-A4QMKFFO.js.map +1 -0
  108. package/dist/chunk-ACPCA4NO.js +321 -0
  109. package/dist/chunk-ACPCA4NO.js.map +1 -0
  110. package/dist/chunk-AMTEYNYK.js +72 -0
  111. package/dist/chunk-AMTEYNYK.js.map +1 -0
  112. package/dist/{chunk-R6YJI3HE.js → chunk-AW4QUFQF.js} +1 -1
  113. package/dist/{chunk-P65YJEEL.js → chunk-AXFWMRKI.js} +2 -2
  114. package/dist/{chunk-WG5HSQ4P.js → chunk-BAKXNQ3C.js} +2 -2
  115. package/dist/{chunk-NM2WP3B7.js → chunk-BJYET5TX.js} +2 -2
  116. package/dist/{chunk-HLKPRWF4.js → chunk-DATDLJAO.js} +6 -6
  117. package/dist/chunk-DJUKBGAD.js +260 -0
  118. package/dist/chunk-DJUKBGAD.js.map +1 -0
  119. package/dist/{chunk-DX3XRGLH.js → chunk-DQTCGVFK.js} +2 -2
  120. package/dist/{chunk-IPBNC77A.js → chunk-E633OXMH.js} +11 -11
  121. package/dist/{chunk-J7T4MX7P.js → chunk-EEAMSNSG.js} +12 -1
  122. package/dist/chunk-EEAMSNSG.js.map +1 -0
  123. package/dist/{chunk-Z5UC3OKB.js → chunk-ELQCS47S.js} +7 -7
  124. package/dist/{chunk-FMXJ555A.js → chunk-EURCX6PS.js} +2 -2
  125. package/dist/{chunk-MZZR3J6M.js → chunk-FV7YQTN3.js} +2 -2
  126. package/dist/chunk-G73MCJKL.js +20 -0
  127. package/dist/chunk-G73MCJKL.js.map +1 -0
  128. package/dist/{chunk-3R6D33UF.js → chunk-GGBSF2X7.js} +2 -2
  129. package/dist/{chunk-SYUBB3WM.js → chunk-GKEYXXKX.js} +2 -2
  130. package/dist/{chunk-5AGR7SAI.js → chunk-GSEPRIZC.js} +3 -3
  131. package/dist/{chunk-UTVZKHJK.js → chunk-GUKBW4HL.js} +2 -2
  132. package/dist/chunk-GXSOUIA4.js +293 -0
  133. package/dist/chunk-GXSOUIA4.js.map +1 -0
  134. package/dist/{chunk-2F6NP3NT.js → chunk-HDQUQBPW.js} +2 -2
  135. package/dist/{chunk-6HMYUWXR.js → chunk-HTP6XRUI.js} +2 -2
  136. package/dist/{chunk-UYUYZ4WY.js → chunk-IARXXZU4.js} +2 -2
  137. package/dist/{chunk-MNB5RMAY.js → chunk-IIFFC3RL.js} +2 -2
  138. package/dist/{chunk-VDX2J7OX.js → chunk-IPLYGWQF.js} +6 -6
  139. package/dist/{chunk-NZBZ7IS2.js → chunk-JDCQK3C5.js} +2 -2
  140. package/dist/{chunk-C3KVFJH5.js → chunk-JI62YGPI.js} +2 -2
  141. package/dist/{chunk-LULR4IUW.js → chunk-KATEWTQJ.js} +2 -2
  142. package/dist/{chunk-BMCHFWGX.js → chunk-KMWYZTIE.js} +2 -2
  143. package/dist/{chunk-JGSKJHF7.js → chunk-KQS72GCR.js} +2 -2
  144. package/dist/{chunk-3S63QIFQ.js → chunk-LAQ33B5D.js} +1 -1
  145. package/dist/chunk-LAQ33B5D.js.map +1 -0
  146. package/dist/chunk-LNTUXKBT.js +224 -0
  147. package/dist/chunk-LNTUXKBT.js.map +1 -0
  148. package/dist/{chunk-2RIWJUSQ.js → chunk-LQKXVQZR.js} +12 -12
  149. package/dist/{chunk-LQL7ARIC.js → chunk-LTOAJXZB.js} +4 -4
  150. package/dist/{chunk-QKD65RGL.js → chunk-LYMNZZIM.js} +2 -2
  151. package/dist/{chunk-W4FBGYGK.js → chunk-M4MP34AQ.js} +189 -5
  152. package/dist/chunk-M4MP34AQ.js.map +1 -0
  153. package/dist/{chunk-3PY7VHV7.js → chunk-MCA2X4WH.js} +2 -2
  154. package/dist/{chunk-S5NZBKKQ.js → chunk-N3CXAYPJ.js} +3 -3
  155. package/dist/{chunk-WQIHRA5F.js → chunk-N3LL5NEU.js} +2 -2
  156. package/dist/{chunk-Z4U6U3M3.js → chunk-NKL25FCF.js} +2 -2
  157. package/dist/{chunk-LMDRGRJ2.js → chunk-NOB2T2FC.js} +2 -2
  158. package/dist/{chunk-P2OTGMTR.js → chunk-NSGU76YO.js} +2 -2
  159. package/dist/{chunk-L6DCVUCA.js → chunk-O76MWTVS.js} +2 -2
  160. package/dist/{chunk-WZFAPHIK.js → chunk-OIOZ6MOP.js} +3 -3
  161. package/dist/{chunk-DNHVPZOD.js → chunk-P26YHAQH.js} +201 -1
  162. package/dist/chunk-P26YHAQH.js.map +1 -0
  163. package/dist/{chunk-UMOO7IY7.js → chunk-P2KBDJJ6.js} +2 -2
  164. package/dist/{chunk-KVJRXN2E.js → chunk-P4QOYG52.js} +125 -13
  165. package/dist/chunk-P4QOYG52.js.map +1 -0
  166. package/dist/chunk-P77QX3ID.js +332 -0
  167. package/dist/chunk-P77QX3ID.js.map +1 -0
  168. package/dist/{chunk-SXWHN7GC.js → chunk-PDEKQWDV.js} +2 -2
  169. package/dist/{chunk-ENEA47UC.js → chunk-PLCHU56K.js} +3 -3
  170. package/dist/{chunk-IXPKESVP.js → chunk-PWIMF7LP.js} +37 -37
  171. package/dist/{chunk-RHTO4HTL.js → chunk-PWLB4TRK.js} +2 -2
  172. package/dist/{chunk-RVYVMQK4.js → chunk-QSYL5CXK.js} +3 -3
  173. package/dist/{chunk-B6KGGRUL.js → chunk-QWLW3VQH.js} +2 -2
  174. package/dist/{chunk-YQIVWS7Y.js → chunk-RBPH3GZV.js} +405 -101
  175. package/dist/chunk-RBPH3GZV.js.map +1 -0
  176. package/dist/{chunk-JBPKEARU.js → chunk-RKNJBZ55.js} +4 -4
  177. package/dist/{chunk-QCECHYZL.js → chunk-RVO6TCTU.js} +6 -6
  178. package/dist/{chunk-SHDZNSK4.js → chunk-S2SJEOTM.js} +2 -2
  179. package/dist/{chunk-ULWHRQEQ.js → chunk-S75UQ3T3.js} +3 -3
  180. package/dist/{chunk-LXOM6IQU.js → chunk-SEF4IOFE.js} +2 -2
  181. package/dist/{chunk-I3YHVVT4.js → chunk-SHYIMIX5.js} +2 -2
  182. package/dist/{chunk-IZANPXMV.js → chunk-T35UJI5R.js} +86 -82
  183. package/dist/chunk-T35UJI5R.js.map +1 -0
  184. package/dist/{chunk-G5OB4XZX.js → chunk-VANZKHTN.js} +4 -4
  185. package/dist/{chunk-I4TQST3L.js → chunk-VFS3MK5F.js} +2 -2
  186. package/dist/chunk-VUDMT5CP.js +86 -0
  187. package/dist/chunk-VUDMT5CP.js.map +1 -0
  188. package/dist/{chunk-CMQZNEIF.js → chunk-WFLBP5GC.js} +8 -1
  189. package/dist/chunk-WFLBP5GC.js.map +1 -0
  190. package/dist/{chunk-SMPVHGHG.js → chunk-WPZX7MEA.js} +3 -3
  191. package/dist/{chunk-ZRWB5D4H.js → chunk-WT6UL3UA.js} +2 -2
  192. package/dist/{chunk-DQEMWVMT.js → chunk-X7Y7WX73.js} +1 -1
  193. package/dist/{chunk-JHMAYABJ.js → chunk-XL3TATMJ.js} +4 -4
  194. package/dist/{chunk-MC6XO7T4.js → chunk-YLBE6PLR.js} +2 -2
  195. package/dist/{chunk-OLX2HJFW.js → chunk-YLHM5BQQ.js} +4 -4
  196. package/dist/{chunk-EZ25VE3G.js → chunk-YNDLCWXS.js} +4 -4
  197. package/dist/{chunk-GF22HWS2.js → chunk-Z54EM5YZ.js} +4 -4
  198. package/dist/{chunk-GVX3NAUU.js → chunk-ZDAYWJV6.js} +2 -2
  199. package/dist/{chunk-EYAIZBLM.js → chunk-ZJIFYUJI.js} +5 -5
  200. package/dist/{chunk-CNQQMB67.js → chunk-ZN4EYMKJ.js} +2 -2
  201. package/dist/{cli-PyAUaozE.d.ts → cli-BLNmNEMT.d.ts} +16 -14
  202. package/dist/cli.d.ts +13 -13
  203. package/dist/cli.js +96 -94
  204. package/dist/coding/pre-action-gate.d.ts +66 -0
  205. package/dist/coding/pre-action-gate.js +22 -0
  206. package/dist/commitment-ledger.js +2 -2
  207. package/dist/compounding/engine.d.ts +2 -2
  208. package/dist/compounding/engine.js +13 -13
  209. package/dist/compounding/preference-consolidator.d.ts +1 -1
  210. package/dist/compression-optimizer.d.ts +1 -1
  211. package/dist/config.d.ts +1 -1
  212. package/dist/config.js +3 -2
  213. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  214. package/dist/connectors/codex-materialize-runner.js +12 -12
  215. package/dist/connectors/codex-materialize.d.ts +1 -1
  216. package/dist/connectors/index.d.ts +1 -1
  217. package/dist/connectors/index.js +12 -12
  218. package/dist/consolidation-provenance-check.d.ts +2 -2
  219. package/dist/consolidation-provenance-check.js +4 -4
  220. package/dist/consolidation-undo.d.ts +2 -2
  221. package/dist/consolidation-undo.js +3 -3
  222. package/dist/contradiction/index.d.ts +2 -2
  223. package/dist/contradiction/index.js +3 -3
  224. package/dist/converge-config.d.ts +1 -1
  225. package/dist/convergence-refresh.d.ts +2 -2
  226. package/dist/convergence-refresh.js +15 -15
  227. package/dist/conversation-index/backend.d.ts +1 -1
  228. package/dist/conversation-index/chunker.d.ts +1 -1
  229. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  230. package/dist/conversation-index/indexer.d.ts +1 -1
  231. package/dist/conversation-index/search.d.ts +1 -1
  232. package/dist/corpus-watermark.d.ts +1 -1
  233. package/dist/corpus-watermark.js +23 -23
  234. package/dist/cue-anchors.d.ts +19 -1
  235. package/dist/cue-anchors.js +10 -2
  236. package/dist/dashboard-runtime.js +2 -2
  237. package/dist/day-summary.d.ts +1 -1
  238. package/dist/delinearize.d.ts +1 -1
  239. package/dist/dependency-propagation-config.d.ts +10 -0
  240. package/dist/dependency-propagation-config.js +10 -0
  241. package/dist/dependency-propagation-config.js.map +1 -0
  242. package/dist/deterministic-order.d.ts +4 -0
  243. package/dist/deterministic-order.js +10 -0
  244. package/dist/deterministic-order.js.map +1 -0
  245. package/dist/direct-answer-wiring.d.ts +1 -1
  246. package/dist/direct-answer.d.ts +1 -1
  247. package/dist/embedding-fallback.d.ts +1 -1
  248. package/dist/enrichment/index.d.ts +1 -1
  249. package/dist/entity-retrieval.d.ts +2 -2
  250. package/dist/entity-retrieval.js +12 -12
  251. package/dist/entity-schema.d.ts +1 -1
  252. package/dist/evals.js +2 -2
  253. package/dist/explicit-capture.d.ts +8 -8
  254. package/dist/explicit-capture.js +6 -6
  255. package/dist/external-wiki-access.d.ts +10 -10
  256. package/dist/external-wiki-access.js +49 -49
  257. package/dist/external-wiki-collection-registration.d.ts +1 -1
  258. package/dist/external-wiki-collection.d.ts +1 -1
  259. package/dist/external-wiki-mcp-tools.d.ts +10 -10
  260. package/dist/extraction-error-classification.d.ts +1 -1
  261. package/dist/extraction-faithfulness.d.ts +1 -1
  262. package/dist/extraction-judge-telemetry.d.ts +1 -1
  263. package/dist/extraction-judge-training.d.ts +1 -1
  264. package/dist/extraction-judge.d.ts +1 -1
  265. package/dist/extraction-liveness.d.ts +1 -1
  266. package/dist/extraction-normalization.d.ts +14 -0
  267. package/dist/extraction-normalization.js +22 -0
  268. package/dist/extraction-normalization.js.map +1 -0
  269. package/dist/extraction-prompt.d.ts +4 -3
  270. package/dist/extraction-prompt.js +3 -1
  271. package/dist/extraction-source-grounding-rules.d.ts +1 -1
  272. package/dist/extraction-source-grounding.d.ts +1 -1
  273. package/dist/extraction.d.ts +18 -1
  274. package/dist/extraction.js +21 -19
  275. package/dist/fallback-llm.d.ts +1 -1
  276. package/dist/{first-start-migration-ZSHEFEI3.js → first-start-migration-626C5554.js} +5 -5
  277. package/dist/{forget-DNAJ66ZD.js → forget-GJ42LCBW.js} +2 -2
  278. package/dist/graph-dashboard-diff.d.ts +1 -1
  279. package/dist/graph-dashboard-key.d.ts +1 -1
  280. package/dist/graph-dashboard-parser.d.ts +1 -1
  281. package/dist/graph-edge-reinforcement.d.ts +1 -1
  282. package/dist/graph-snapshot.d.ts +1 -1
  283. package/dist/graph.d.ts +1 -1
  284. package/dist/harmonic-construction.d.ts +43 -0
  285. package/dist/harmonic-construction.js +26 -0
  286. package/dist/harmonic-construction.js.map +1 -0
  287. package/dist/harmonic-retrieval.d.ts +1 -0
  288. package/dist/harmonic-retrieval.js +10 -4
  289. package/dist/importance.d.ts +1 -1
  290. package/dist/importers/index.d.ts +1 -1
  291. package/dist/in-flight-reads.d.ts +1 -1
  292. package/dist/index.d.ts +698 -696
  293. package/dist/index.js +207 -161
  294. package/dist/intent.d.ts +1 -1
  295. package/dist/json-store.d.ts +15 -1
  296. package/dist/json-store.js +11 -3
  297. package/dist/lcm/engine.d.ts +1 -1
  298. package/dist/lcm/engine.js +2 -2
  299. package/dist/lcm/index.d.ts +1 -1
  300. package/dist/lcm/index.js +4 -4
  301. package/dist/lcm/tools.d.ts +1 -1
  302. package/dist/lifecycle.d.ts +1 -1
  303. package/dist/live-connectors-runner.d.ts +1 -1
  304. package/dist/local-llm.d.ts +1 -1
  305. package/dist/local-model-endpoint.d.ts +1 -1
  306. package/dist/maintenance/archive-observations.js +2 -2
  307. package/dist/maintenance/atomic-file.d.ts +5 -0
  308. package/dist/maintenance/atomic-file.js +12 -0
  309. package/dist/maintenance/atomic-file.js.map +1 -0
  310. package/dist/maintenance/memory-governance.d.ts +1 -1
  311. package/dist/maintenance/memory-governance.js +12 -12
  312. package/dist/maintenance/migrate-observations.js +3 -3
  313. package/dist/maintenance/observation-ledger-utils.d.ts +1 -1
  314. package/dist/maintenance/observation-ledger-utils.js +2 -2
  315. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
  316. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +13 -13
  317. package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
  318. package/dist/maintenance/rebuild-memory-projection.js +14 -14
  319. package/dist/maintenance/rebuild-observations.js +3 -3
  320. package/dist/{maintenance-j7sfNQdK.d.ts → maintenance-DKbKZi3u.d.ts} +3 -3
  321. package/dist/mcp-memory-inspector-app.d.ts +10 -10
  322. package/dist/memory-action-policy.d.ts +1 -1
  323. package/dist/memory-cache.d.ts +1 -1
  324. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  325. package/dist/memory-projection-store.d.ts +1 -1
  326. package/dist/memory-provenance.d.ts +1 -1
  327. package/dist/memory-snapshot.d.ts +1 -1
  328. package/dist/memory-worth-outcomes.d.ts +2 -2
  329. package/dist/models-json.d.ts +1 -1
  330. package/dist/namespaces/migrate.d.ts +3 -3
  331. package/dist/namespaces/migrate.js +22 -22
  332. package/dist/namespaces/principal.d.ts +1 -1
  333. package/dist/namespaces/search.d.ts +1 -1
  334. package/dist/namespaces/search.js +9 -9
  335. package/dist/namespaces/storage.d.ts +3 -3
  336. package/dist/namespaces/storage.js +12 -12
  337. package/dist/native-knowledge.d.ts +1 -1
  338. package/dist/objective-state-writers.js +3 -3
  339. package/dist/objective-state.js +2 -2
  340. package/dist/offline-sync-impression-drain.d.ts +1 -1
  341. package/dist/offline-sync-impression-drain.js +2 -2
  342. package/dist/operator-doctor-corpus.d.ts +1 -1
  343. package/dist/operator-doctor-corpus.js +24 -24
  344. package/dist/operator-doctor-replica.d.ts +1 -1
  345. package/dist/operator-toolkit.d.ts +3 -3
  346. package/dist/operator-toolkit.js +33 -32
  347. package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
  348. package/dist/orchestration/maintenance.d.ts +4 -4
  349. package/dist/orchestration/maintenance.js +18 -18
  350. package/dist/{orchestrator-Haa9xVPV.d.ts → orchestrator-BRwD7ceU.d.ts} +7 -7
  351. package/dist/orchestrator.d.ts +8 -8
  352. package/dist/orchestrator.js +132 -127
  353. package/dist/page-versioning.js +3 -3
  354. package/dist/patterns-cli.d.ts +1 -1
  355. package/dist/{pipeline-1h2GpiHP.d.ts → pipeline-DC-1C9T8.d.ts} +1 -1
  356. package/dist/policy-runtime.d.ts +1 -1
  357. package/dist/proactive-contention.d.ts +1 -1
  358. package/dist/provenance.d.ts +1 -1
  359. package/dist/{qmd-UdwoF71D.d.ts → qmd-DdeCEZdb.d.ts} +1 -1
  360. package/dist/qmd-preflight.d.ts +2 -2
  361. package/dist/qmd-recall-cache.d.ts +1 -1
  362. package/dist/qmd.d.ts +2 -2
  363. package/dist/qmd.js +4 -4
  364. package/dist/recall-concurrency-config.d.ts +1 -1
  365. package/dist/recall-disclosure-escalation.d.ts +1 -1
  366. package/dist/recall-explain-renderer.d.ts +1 -1
  367. package/dist/recall-explain-renderer.js +3 -3
  368. package/dist/recall-memory-map.d.ts +1 -1
  369. package/dist/recall-planner-llm.d.ts +1 -1
  370. package/dist/recall-state.d.ts +1 -1
  371. package/dist/recall-state.js +2 -2
  372. package/dist/recall-tag-filter.d.ts +1 -1
  373. package/dist/recall-timings.d.ts +1 -1
  374. package/dist/recall-xray-cli.d.ts +1 -1
  375. package/dist/recall-xray-cli.js +4 -4
  376. package/dist/recall-xray-renderer.d.ts +1 -1
  377. package/dist/recall-xray-renderer.js +3 -3
  378. package/dist/recall-xray.d.ts +1 -1
  379. package/dist/recall-xray.js +2 -2
  380. package/dist/reconcile/cursor.d.ts +1 -1
  381. package/dist/reconcile/manifest.d.ts +1 -1
  382. package/dist/reconcile/plan.d.ts +1 -1
  383. package/dist/relevance.js +2 -2
  384. package/dist/replay/normalizers/chatgpt.d.ts +1 -1
  385. package/dist/replay/normalizers/claude.d.ts +1 -1
  386. package/dist/replay/normalizers/openclaw.d.ts +1 -1
  387. package/dist/replay/normalizers/shared.d.ts +1 -1
  388. package/dist/replay/runner.d.ts +1 -1
  389. package/dist/replay/types.d.ts +1 -1
  390. package/dist/replica-divergence.d.ts +1 -1
  391. package/dist/replica-peers-config.d.ts +1 -1
  392. package/dist/{resolution-3K27T4VO.js → resolution-MDPNOEG6.js} +4 -4
  393. package/dist/resolution-MDPNOEG6.js.map +1 -0
  394. package/dist/resolve-auth-token.d.ts +1 -1
  395. package/dist/resume-bundles.js +8 -7
  396. package/dist/retrieval-agents.d.ts +2 -2
  397. package/dist/retrieval-tiers.d.ts +1 -1
  398. package/dist/routing/engine.d.ts +1 -1
  399. package/dist/routing/store.d.ts +1 -1
  400. package/dist/salvage-envelope.d.ts +1 -1
  401. package/dist/salvage-envelope.js +3 -3
  402. package/dist/schemas.d.ts +213 -116
  403. package/dist/schemas.js +1 -1
  404. package/dist/{scope-profiles-APjhSe-w.d.ts → scope-profiles-BXVq4Jv0.d.ts} +1 -1
  405. package/dist/search/embed-helper.d.ts +1 -1
  406. package/dist/search/factory.d.ts +1 -1
  407. package/dist/search/factory.js +8 -8
  408. package/dist/search/index.d.ts +1 -1
  409. package/dist/search/index.js +13 -13
  410. package/dist/search/lancedb-backend.d.ts +1 -1
  411. package/dist/search/lancedb-backend.js +2 -2
  412. package/dist/search/meilisearch-backend.d.ts +1 -1
  413. package/dist/search/meilisearch-backend.js +2 -2
  414. package/dist/search/noop-backend.d.ts +1 -1
  415. package/dist/search/orama-backend.d.ts +1 -1
  416. package/dist/search/orama-backend.js +2 -2
  417. package/dist/search/port.d.ts +1 -1
  418. package/dist/search/remote-backend.d.ts +1 -1
  419. package/dist/{semantic-consolidation-CrySDbk3.d.ts → semantic-consolidation-CGYxfa8F.d.ts} +1 -1
  420. package/dist/semantic-consolidation.d.ts +2 -2
  421. package/dist/semantic-consolidation.js +13 -13
  422. package/dist/semantic-rule-promotion.js +12 -12
  423. package/dist/semantic-rule-verifier.d.ts +1 -1
  424. package/dist/semantic-rule-verifier.js +12 -12
  425. package/dist/{service-Da_BI4S8.d.ts → service-CBDBQFCN.d.ts} +2 -2
  426. package/dist/session-observer-bands.d.ts +1 -1
  427. package/dist/session-observer-state.d.ts +1 -1
  428. package/dist/shared-context/manager.d.ts +11 -11
  429. package/dist/signal.d.ts +1 -1
  430. package/dist/source-agent-qualifier.d.ts +1 -1
  431. package/dist/source-agent-qualifier.js +16 -16
  432. package/dist/{storage-D1apCiCS.d.ts → storage-V--MQi7w.d.ts} +1 -1
  433. package/dist/storage.d.ts +2 -2
  434. package/dist/storage.js +11 -11
  435. package/dist/summarizer.d.ts +1 -1
  436. package/dist/summary-snapshot.d.ts +1 -1
  437. package/dist/temporal-supersession.d.ts +13 -2
  438. package/dist/temporal-supersession.js +1 -1
  439. package/dist/temporal-timeline-recall.d.ts +1 -1
  440. package/dist/temporal-validity.d.ts +1 -1
  441. package/dist/threading.d.ts +1 -1
  442. package/dist/tier-migration.d.ts +2 -2
  443. package/dist/tier-routing.d.ts +1 -1
  444. package/dist/{tier-stats-OPTSBNRH.js → tier-stats-2JCZYEF7.js} +5 -5
  445. package/dist/topics.d.ts +1 -1
  446. package/dist/transcript.d.ts +1 -1
  447. package/dist/transfer/autodetect.js +1 -1
  448. package/dist/transfer/backup.js +2 -2
  449. package/dist/transfer/capsule-export.js +3 -3
  450. package/dist/transfer/capsule-import.js +5 -5
  451. package/dist/transfer/types.d.ts +66 -66
  452. package/dist/trust-score-stage.d.ts +1 -1
  453. package/dist/trust-score.d.ts +1 -1
  454. package/dist/trust-zones.js +2 -2
  455. package/dist/{types-D_Au9qJO.d.ts → types-D_a6Sqjz.d.ts} +25 -8
  456. package/dist/types.d.ts +1 -1
  457. package/dist/types.js +1 -1
  458. package/dist/utility-learner.js +3 -3
  459. package/dist/utility-runtime.d.ts +1 -1
  460. package/dist/utility-runtime.js +4 -4
  461. package/dist/utility-telemetry.js +2 -2
  462. package/dist/verified-recall.js +12 -12
  463. package/dist/work-product-ledger.js +2 -2
  464. package/dist/write-envelope.d.ts +1 -1
  465. package/dist/write-envelope.js +2 -2
  466. package/package.json +32 -2
  467. package/src/abstraction-nodes.ts +182 -4
  468. package/src/causal-trajectory.ts +258 -3
  469. package/src/cli/harmonic-search.ts +23 -0
  470. package/src/cli/research-status-commands.ts +2 -1
  471. package/src/cli.ts +1 -24
  472. package/src/coding/pre-action-gate.test.ts +516 -0
  473. package/src/coding/pre-action-gate.ts +320 -0
  474. package/src/config.test.ts +85 -0
  475. package/src/config.ts +2 -0
  476. package/src/cue-anchors.test.ts +90 -0
  477. package/src/cue-anchors.ts +264 -11
  478. package/src/dependency-frontmatter.test.ts +83 -0
  479. package/src/dependency-propagation-config.ts +94 -0
  480. package/src/deterministic-order.ts +14 -0
  481. package/src/extraction-normalization.ts +71 -0
  482. package/src/extraction-prompt.ts +45 -11
  483. package/src/extraction.ts +48 -32
  484. package/src/faithfulness-graph-guard.test.ts +27 -0
  485. package/src/harmonic-construction.test.ts +1799 -0
  486. package/src/harmonic-construction.ts +367 -0
  487. package/src/harmonic-retrieval.ts +166 -25
  488. package/src/index.ts +4 -5
  489. package/src/json-store.ts +354 -12
  490. package/src/orchestration/consolidation-run.ts +192 -0
  491. package/src/orchestration/contradiction-linking-coordinator.ts +35 -1
  492. package/src/orchestration/dependency-propagation-triggers.test.ts +286 -0
  493. package/src/orchestration/dependency-propagation.test.ts +487 -0
  494. package/src/orchestration/dependency-propagation.ts +263 -0
  495. package/src/orchestration/dependency-revalidation.ts +173 -0
  496. package/src/orchestration/extraction-persist-deps.ts +93 -0
  497. package/src/orchestration/extraction-persist.ts +101 -94
  498. package/src/orchestration/harmonic-construction-persist.ts +86 -0
  499. package/src/orchestration/recall-internal.ts +1 -0
  500. package/src/orchestrator.ts +2 -1
  501. package/src/schemas.ts +15 -0
  502. package/src/storage.ts +14 -0
  503. package/src/temporal-supersession.ts +29 -1
  504. package/src/testing/orchestrator-lite.ts +27 -8
  505. package/src/testing/subjects/extraction-lifecycle.test.ts +91 -50
  506. package/src/types.ts +22 -7
  507. package/dist/chunk-3S63QIFQ.js.map +0 -1
  508. package/dist/chunk-CMQZNEIF.js.map +0 -1
  509. package/dist/chunk-DNHVPZOD.js.map +0 -1
  510. package/dist/chunk-EY64JLOM.js.map +0 -1
  511. package/dist/chunk-FZZ2QTJI.js +0 -111
  512. package/dist/chunk-FZZ2QTJI.js.map +0 -1
  513. package/dist/chunk-IZANPXMV.js.map +0 -1
  514. package/dist/chunk-J7T4MX7P.js.map +0 -1
  515. package/dist/chunk-KVJRXN2E.js.map +0 -1
  516. package/dist/chunk-LPSF4OQH.js +0 -47
  517. package/dist/chunk-LPSF4OQH.js.map +0 -1
  518. package/dist/chunk-LZGCJSQR.js.map +0 -1
  519. package/dist/chunk-OADWQ5CR.js +0 -115
  520. package/dist/chunk-OADWQ5CR.js.map +0 -1
  521. package/dist/chunk-RN53QBM4.js.map +0 -1
  522. package/dist/chunk-W4FBGYGK.js.map +0 -1
  523. package/dist/chunk-YQIVWS7Y.js.map +0 -1
  524. /package/dist/{auto-sync-7O6RP2RT.js.map → auto-sync-QFQGOEO2.js.map} +0 -0
  525. /package/dist/{capsule-crypto-YO5QJ6L3.js.map → capsule-crypto-7FJQINUR.js.map} +0 -0
  526. /package/dist/{capsule-merge-6GFHWECG.js.map → capsule-merge-KXTRZ23Z.js.map} +0 -0
  527. /package/dist/{chunk-ICP53SKG.js.map → chunk-2HIJHXB3.js.map} +0 -0
  528. /package/dist/{chunk-BXLOS5AJ.js.map → chunk-2NLLXCJG.js.map} +0 -0
  529. /package/dist/{chunk-5JRC6BYS.js.map → chunk-47J4EDGR.js.map} +0 -0
  530. /package/dist/{chunk-2VHLLPTX.js.map → chunk-4EABKPZS.js.map} +0 -0
  531. /package/dist/{chunk-RJV6Q2FT.js.map → chunk-4JWJMRPJ.js.map} +0 -0
  532. /package/dist/{chunk-MXPB6PJQ.js.map → chunk-4S3ECH3U.js.map} +0 -0
  533. /package/dist/{chunk-CGASUJVP.js.map → chunk-5V6IXHPI.js.map} +0 -0
  534. /package/dist/{chunk-R5IGA2NH.js.map → chunk-5XCN4XBU.js.map} +0 -0
  535. /package/dist/{chunk-2RPJ4NEE.js.map → chunk-64BHFFKZ.js.map} +0 -0
  536. /package/dist/{chunk-FQC3DHH2.js.map → chunk-66SE3BNH.js.map} +0 -0
  537. /package/dist/{chunk-TERNBNJB.js.map → chunk-6FC3IZ26.js.map} +0 -0
  538. /package/dist/{chunk-K7VKAHFE.js.map → chunk-6XGEBQ3R.js.map} +0 -0
  539. /package/dist/{chunk-JFLOOTXU.js.map → chunk-7BLWBSRL.js.map} +0 -0
  540. /package/dist/{chunk-ABR2HEJO.js.map → chunk-7NDM2PNK.js.map} +0 -0
  541. /package/dist/{chunk-JXZ7NLYH.js.map → chunk-7VWZ4LRW.js.map} +0 -0
  542. /package/dist/{chunk-R6YJI3HE.js.map → chunk-AW4QUFQF.js.map} +0 -0
  543. /package/dist/{chunk-P65YJEEL.js.map → chunk-AXFWMRKI.js.map} +0 -0
  544. /package/dist/{chunk-WG5HSQ4P.js.map → chunk-BAKXNQ3C.js.map} +0 -0
  545. /package/dist/{chunk-NM2WP3B7.js.map → chunk-BJYET5TX.js.map} +0 -0
  546. /package/dist/{chunk-HLKPRWF4.js.map → chunk-DATDLJAO.js.map} +0 -0
  547. /package/dist/{chunk-DX3XRGLH.js.map → chunk-DQTCGVFK.js.map} +0 -0
  548. /package/dist/{chunk-IPBNC77A.js.map → chunk-E633OXMH.js.map} +0 -0
  549. /package/dist/{chunk-Z5UC3OKB.js.map → chunk-ELQCS47S.js.map} +0 -0
  550. /package/dist/{chunk-FMXJ555A.js.map → chunk-EURCX6PS.js.map} +0 -0
  551. /package/dist/{chunk-MZZR3J6M.js.map → chunk-FV7YQTN3.js.map} +0 -0
  552. /package/dist/{chunk-3R6D33UF.js.map → chunk-GGBSF2X7.js.map} +0 -0
  553. /package/dist/{chunk-SYUBB3WM.js.map → chunk-GKEYXXKX.js.map} +0 -0
  554. /package/dist/{chunk-5AGR7SAI.js.map → chunk-GSEPRIZC.js.map} +0 -0
  555. /package/dist/{chunk-UTVZKHJK.js.map → chunk-GUKBW4HL.js.map} +0 -0
  556. /package/dist/{chunk-2F6NP3NT.js.map → chunk-HDQUQBPW.js.map} +0 -0
  557. /package/dist/{chunk-6HMYUWXR.js.map → chunk-HTP6XRUI.js.map} +0 -0
  558. /package/dist/{chunk-UYUYZ4WY.js.map → chunk-IARXXZU4.js.map} +0 -0
  559. /package/dist/{chunk-MNB5RMAY.js.map → chunk-IIFFC3RL.js.map} +0 -0
  560. /package/dist/{chunk-VDX2J7OX.js.map → chunk-IPLYGWQF.js.map} +0 -0
  561. /package/dist/{chunk-NZBZ7IS2.js.map → chunk-JDCQK3C5.js.map} +0 -0
  562. /package/dist/{chunk-C3KVFJH5.js.map → chunk-JI62YGPI.js.map} +0 -0
  563. /package/dist/{chunk-LULR4IUW.js.map → chunk-KATEWTQJ.js.map} +0 -0
  564. /package/dist/{chunk-BMCHFWGX.js.map → chunk-KMWYZTIE.js.map} +0 -0
  565. /package/dist/{chunk-JGSKJHF7.js.map → chunk-KQS72GCR.js.map} +0 -0
  566. /package/dist/{chunk-2RIWJUSQ.js.map → chunk-LQKXVQZR.js.map} +0 -0
  567. /package/dist/{chunk-LQL7ARIC.js.map → chunk-LTOAJXZB.js.map} +0 -0
  568. /package/dist/{chunk-QKD65RGL.js.map → chunk-LYMNZZIM.js.map} +0 -0
  569. /package/dist/{chunk-3PY7VHV7.js.map → chunk-MCA2X4WH.js.map} +0 -0
  570. /package/dist/{chunk-S5NZBKKQ.js.map → chunk-N3CXAYPJ.js.map} +0 -0
  571. /package/dist/{chunk-WQIHRA5F.js.map → chunk-N3LL5NEU.js.map} +0 -0
  572. /package/dist/{chunk-Z4U6U3M3.js.map → chunk-NKL25FCF.js.map} +0 -0
  573. /package/dist/{chunk-LMDRGRJ2.js.map → chunk-NOB2T2FC.js.map} +0 -0
  574. /package/dist/{chunk-P2OTGMTR.js.map → chunk-NSGU76YO.js.map} +0 -0
  575. /package/dist/{chunk-L6DCVUCA.js.map → chunk-O76MWTVS.js.map} +0 -0
  576. /package/dist/{chunk-WZFAPHIK.js.map → chunk-OIOZ6MOP.js.map} +0 -0
  577. /package/dist/{chunk-UMOO7IY7.js.map → chunk-P2KBDJJ6.js.map} +0 -0
  578. /package/dist/{chunk-SXWHN7GC.js.map → chunk-PDEKQWDV.js.map} +0 -0
  579. /package/dist/{chunk-ENEA47UC.js.map → chunk-PLCHU56K.js.map} +0 -0
  580. /package/dist/{chunk-IXPKESVP.js.map → chunk-PWIMF7LP.js.map} +0 -0
  581. /package/dist/{chunk-RHTO4HTL.js.map → chunk-PWLB4TRK.js.map} +0 -0
  582. /package/dist/{chunk-RVYVMQK4.js.map → chunk-QSYL5CXK.js.map} +0 -0
  583. /package/dist/{chunk-B6KGGRUL.js.map → chunk-QWLW3VQH.js.map} +0 -0
  584. /package/dist/{chunk-JBPKEARU.js.map → chunk-RKNJBZ55.js.map} +0 -0
  585. /package/dist/{chunk-QCECHYZL.js.map → chunk-RVO6TCTU.js.map} +0 -0
  586. /package/dist/{chunk-SHDZNSK4.js.map → chunk-S2SJEOTM.js.map} +0 -0
  587. /package/dist/{chunk-ULWHRQEQ.js.map → chunk-S75UQ3T3.js.map} +0 -0
  588. /package/dist/{chunk-LXOM6IQU.js.map → chunk-SEF4IOFE.js.map} +0 -0
  589. /package/dist/{chunk-I3YHVVT4.js.map → chunk-SHYIMIX5.js.map} +0 -0
  590. /package/dist/{chunk-G5OB4XZX.js.map → chunk-VANZKHTN.js.map} +0 -0
  591. /package/dist/{chunk-I4TQST3L.js.map → chunk-VFS3MK5F.js.map} +0 -0
  592. /package/dist/{chunk-SMPVHGHG.js.map → chunk-WPZX7MEA.js.map} +0 -0
  593. /package/dist/{chunk-ZRWB5D4H.js.map → chunk-WT6UL3UA.js.map} +0 -0
  594. /package/dist/{chunk-DQEMWVMT.js.map → chunk-X7Y7WX73.js.map} +0 -0
  595. /package/dist/{chunk-JHMAYABJ.js.map → chunk-XL3TATMJ.js.map} +0 -0
  596. /package/dist/{chunk-MC6XO7T4.js.map → chunk-YLBE6PLR.js.map} +0 -0
  597. /package/dist/{chunk-OLX2HJFW.js.map → chunk-YLHM5BQQ.js.map} +0 -0
  598. /package/dist/{chunk-EZ25VE3G.js.map → chunk-YNDLCWXS.js.map} +0 -0
  599. /package/dist/{chunk-GF22HWS2.js.map → chunk-Z54EM5YZ.js.map} +0 -0
  600. /package/dist/{chunk-GVX3NAUU.js.map → chunk-ZDAYWJV6.js.map} +0 -0
  601. /package/dist/{chunk-EYAIZBLM.js.map → chunk-ZJIFYUJI.js.map} +0 -0
  602. /package/dist/{chunk-CNQQMB67.js.map → chunk-ZN4EYMKJ.js.map} +0 -0
  603. /package/dist/{resolution-3K27T4VO.js.map → coding/pre-action-gate.js.map} +0 -0
  604. /package/dist/{first-start-migration-ZSHEFEI3.js.map → first-start-migration-626C5554.js.map} +0 -0
  605. /package/dist/{forget-DNAJ66ZD.js.map → forget-GJ42LCBW.js.map} +0 -0
  606. /package/dist/{tier-stats-OPTSBNRH.js.map → tier-stats-2JCZYEF7.js.map} +0 -0
package/src/json-store.ts CHANGED
@@ -1,19 +1,53 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import type { Dirent } from "node:fs";
3
+ import {
4
+ lstat,
5
+ mkdir,
6
+ open,
7
+ readFile,
8
+ readdir,
9
+ rename,
10
+ unlink,
11
+ utimes,
12
+ writeFile,
13
+ type FileHandle,
14
+ } from "node:fs/promises";
1
15
  import path from "node:path";
2
- import { readFile, readdir } from "node:fs/promises";
3
16
 
4
- export async function listJsonFiles(dir: string): Promise<string[]> {
17
+ function hasErrorCode(error: unknown, code: string): boolean {
18
+ return typeof error === "object" && error !== null && "code" in error && (error as { code?: unknown }).code === code;
19
+ }
20
+
21
+ async function listJsonFilesStrictInner(dir: string, allowMissingDirectory: boolean): Promise<string[]> {
22
+ let entries: Dirent[];
5
23
  try {
6
- const entries = await readdir(dir, { withFileTypes: true });
7
- const out: string[] = [];
8
- for (const entry of entries) {
9
- const fullPath = path.join(dir, entry.name);
10
- if (entry.isDirectory()) {
11
- out.push(...(await listJsonFiles(fullPath)));
12
- } else if (entry.isFile() && entry.name.endsWith(".json")) {
13
- out.push(fullPath);
14
- }
24
+ entries = await readdir(dir, { withFileTypes: true });
25
+ } catch (error) {
26
+ if (allowMissingDirectory && hasErrorCode(error, "ENOENT")) return [];
27
+ throw error;
28
+ }
29
+ const out: string[] = [];
30
+ for (const entry of entries) {
31
+ const fullPath = path.join(dir, entry.name);
32
+ if (entry.isDirectory()) {
33
+ out.push(...(await listJsonFilesStrictInner(fullPath, false)));
34
+ } else if (entry.isFile() && entry.name.endsWith(".json")) {
35
+ out.push(fullPath);
15
36
  }
16
- return out.sort();
37
+ }
38
+ return out.sort();
39
+ }
40
+
41
+ export async function listJsonFilesStrict(
42
+ dir: string,
43
+ options: { allowMissingDirectory?: boolean } = {}
44
+ ): Promise<string[]> {
45
+ return listJsonFilesStrictInner(dir, options.allowMissingDirectory === true);
46
+ }
47
+
48
+ export async function listJsonFiles(dir: string): Promise<string[]> {
49
+ try {
50
+ return await listJsonFilesStrict(dir);
17
51
  } catch {
18
52
  return [];
19
53
  }
@@ -37,6 +71,314 @@ export async function listNamedFiles(dir: string, fileName: string): Promise<str
37
71
  }
38
72
  }
39
73
 
74
+ const jsonStoreMutationTails = new Map<string, Promise<void>>();
75
+
76
+ const JSON_STORE_LOCK_RETRY_MS = 25;
77
+ const JSON_STORE_LOCK_STALE_MS = 60_000;
78
+ const JSON_STORE_LOCK_TIMEOUT_MS = 10_000;
79
+
80
+ type JsonStoreMutationLockTestHooks = {
81
+ beforeLockOwnerWrite?: (lockPath: string, ownerToken: string) => Promise<void> | void;
82
+ beforeLockOwnershipConfirm?: (lockPath: string, ownerToken: string) => Promise<void> | void;
83
+ afterReclaimGuardWrite?: (reclaimPath: string, ownerToken: string) => Promise<void> | void;
84
+ retryMs?: number;
85
+ staleLockMs?: number;
86
+ timeoutMs?: number;
87
+ };
88
+
89
+ let jsonStoreMutationLockTestHooks: JsonStoreMutationLockTestHooks | null = null;
90
+
91
+ export function setJsonStoreMutationLockTestHooks(hooks: JsonStoreMutationLockTestHooks | null): void {
92
+ jsonStoreMutationLockTestHooks = hooks;
93
+ }
94
+
95
+ function jsonStoreLockRetryMs(): number {
96
+ return jsonStoreMutationLockTestHooks?.retryMs ?? JSON_STORE_LOCK_RETRY_MS;
97
+ }
98
+
99
+ function jsonStoreLockStaleMs(): number {
100
+ return jsonStoreMutationLockTestHooks?.staleLockMs ?? JSON_STORE_LOCK_STALE_MS;
101
+ }
102
+
103
+ function jsonStoreLockTimeoutMs(): number {
104
+ return jsonStoreMutationLockTestHooks?.timeoutMs ?? JSON_STORE_LOCK_TIMEOUT_MS;
105
+ }
106
+
107
+ async function closeAndRemoveJsonStoreReclaimGuard(reclaimPath: string, reclaimHandle: FileHandle): Promise<void> {
108
+ await reclaimHandle.close().catch(() => undefined);
109
+ await unlink(reclaimPath).catch((error) => {
110
+ if (!hasErrorCode(error, "ENOENT")) throw error;
111
+ });
112
+ }
113
+
114
+ async function removeStaleJsonStoreReclaimGuard(reclaimPath: string): Promise<void> {
115
+ let initial: JsonStoreLockState;
116
+ try {
117
+ initial = await readJsonStoreLockState(reclaimPath);
118
+ } catch (error) {
119
+ if (hasErrorCode(error, "ENOENT")) return;
120
+ throw error;
121
+ }
122
+ if (Date.now() - initial.mtimeMs <= jsonStoreLockStaleMs()) return;
123
+
124
+ let ownerPid: number | undefined;
125
+ try {
126
+ const metadata = JSON.parse(initial.content) as { pid?: unknown };
127
+ ownerPid = typeof metadata.pid === "number" && Number.isInteger(metadata.pid) ? metadata.pid : undefined;
128
+ } catch {
129
+ ownerPid = undefined;
130
+ }
131
+ if (ownerPid !== undefined && processIsRunning(ownerPid)) return;
132
+
133
+ let confirmed: JsonStoreLockState;
134
+ try {
135
+ confirmed = await readJsonStoreLockState(reclaimPath);
136
+ } catch (error) {
137
+ if (hasErrorCode(error, "ENOENT")) return;
138
+ throw error;
139
+ }
140
+ if (!sameJsonStoreLockState(initial, confirmed)) return;
141
+ await unlink(reclaimPath).catch((error) => {
142
+ if (!hasErrorCode(error, "ENOENT")) throw error;
143
+ });
144
+ }
145
+
146
+ async function acquireJsonStoreReclaimGuard(reclaimPath: string): Promise<FileHandle | undefined> {
147
+ try {
148
+ return await open(reclaimPath, "wx", 0o600);
149
+ } catch (error) {
150
+ if (!hasErrorCode(error, "EEXIST")) throw error;
151
+ await removeStaleJsonStoreReclaimGuard(reclaimPath);
152
+ try {
153
+ return await open(reclaimPath, "wx", 0o600);
154
+ } catch (retryError) {
155
+ if (hasErrorCode(retryError, "EEXIST")) return undefined;
156
+ throw retryError;
157
+ }
158
+ }
159
+ }
160
+
161
+ function waitForJsonStoreLock(): Promise<void> {
162
+ const { promise, resolve } = Promise.withResolvers<void>();
163
+ setTimeout(resolve, jsonStoreLockRetryMs());
164
+ return promise;
165
+ }
166
+
167
+ function processIsRunning(pid: number): boolean {
168
+ try {
169
+ process.kill(pid, 0);
170
+ return true;
171
+ } catch (error) {
172
+ return !hasErrorCode(error, "ESRCH");
173
+ }
174
+ }
175
+
176
+ type JsonStoreLockState = {
177
+ mtimeMs: number;
178
+ size: number;
179
+ ino: number | undefined;
180
+ content: string;
181
+ };
182
+
183
+ async function readJsonStoreLockState(lockPath: string): Promise<JsonStoreLockState> {
184
+ const lockStat = await lstat(lockPath);
185
+ if (!lockStat.isFile()) {
186
+ throw new Error(`JSON store mutation lock is not a regular file: ${lockPath}`);
187
+ }
188
+ return {
189
+ mtimeMs: lockStat.mtimeMs,
190
+ size: lockStat.size,
191
+ ino: typeof lockStat.ino === "number" ? lockStat.ino : undefined,
192
+ content: await readFile(lockPath, "utf8"),
193
+ };
194
+ }
195
+
196
+ function sameJsonStoreLockState(left: JsonStoreLockState, right: JsonStoreLockState): boolean {
197
+ return (
198
+ left.mtimeMs === right.mtimeMs &&
199
+ left.size === right.size &&
200
+ left.ino === right.ino &&
201
+ left.content === right.content
202
+ );
203
+ }
204
+
205
+ async function removeJsonStoreMutationLockIfOwned(lockPath: string, token: string): Promise<void> {
206
+ try {
207
+ const state = await readJsonStoreLockState(lockPath);
208
+ const metadata = JSON.parse(state.content) as { token?: unknown };
209
+ if (metadata.token === token) await unlink(lockPath);
210
+ } catch (error) {
211
+ if (!hasErrorCode(error, "ENOENT") && !(error instanceof SyntaxError)) throw error;
212
+ }
213
+ }
214
+
215
+ async function removeStaleJsonStoreLock(lockPath: string): Promise<void> {
216
+ const reclaimPath = `${lockPath}.reclaim`;
217
+ const reclaimHandle = await acquireJsonStoreReclaimGuard(reclaimPath);
218
+ if (!reclaimHandle) return;
219
+ try {
220
+ await reclaimHandle.writeFile(JSON.stringify({ pid: process.pid }), "utf8");
221
+ await jsonStoreMutationLockTestHooks?.afterReclaimGuardWrite?.(reclaimPath, String(process.pid));
222
+
223
+ let initial: JsonStoreLockState;
224
+ try {
225
+ initial = await readJsonStoreLockState(lockPath);
226
+ } catch (error) {
227
+ if (hasErrorCode(error, "ENOENT")) return;
228
+ throw error;
229
+ }
230
+ if (Date.now() - initial.mtimeMs <= jsonStoreLockStaleMs()) return;
231
+ let ownerPid: number | undefined;
232
+ try {
233
+ const metadata = JSON.parse(initial.content) as { pid?: unknown };
234
+ ownerPid = typeof metadata.pid === "number" && Number.isInteger(metadata.pid) ? metadata.pid : undefined;
235
+ } catch {
236
+ ownerPid = undefined;
237
+ }
238
+ if (ownerPid !== undefined && processIsRunning(ownerPid)) return;
239
+
240
+ let confirmed: JsonStoreLockState;
241
+ try {
242
+ confirmed = await readJsonStoreLockState(lockPath);
243
+ } catch (error) {
244
+ if (hasErrorCode(error, "ENOENT")) return;
245
+ throw error;
246
+ }
247
+ if (!sameJsonStoreLockState(initial, confirmed)) return;
248
+ await unlink(lockPath).catch((error) => {
249
+ if (!hasErrorCode(error, "ENOENT")) throw error;
250
+ });
251
+ } finally {
252
+ await closeAndRemoveJsonStoreReclaimGuard(reclaimPath, reclaimHandle);
253
+ }
254
+ }
255
+
256
+ async function confirmJsonStoreMutationLockOwnership(
257
+ lockPath: string,
258
+ token: string,
259
+ deadline: number
260
+ ): Promise<boolean> {
261
+ const reclaimPath = `${lockPath}.reclaim`;
262
+ while (true) {
263
+ const reclaimHandle = await acquireJsonStoreReclaimGuard(reclaimPath);
264
+ if (!reclaimHandle) {
265
+ if (Date.now() >= deadline) return false;
266
+ await waitForJsonStoreLock();
267
+ continue;
268
+ }
269
+ try {
270
+ try {
271
+ const state = await readJsonStoreLockState(lockPath);
272
+ const metadata = JSON.parse(state.content) as { token?: unknown };
273
+ return metadata.token === token;
274
+ } catch (error) {
275
+ if (hasErrorCode(error, "ENOENT") || error instanceof SyntaxError) return false;
276
+ throw error;
277
+ }
278
+ } finally {
279
+ await closeAndRemoveJsonStoreReclaimGuard(reclaimPath, reclaimHandle);
280
+ }
281
+ }
282
+ }
283
+
284
+ async function acquireJsonStoreMutationFileLock(key: string): Promise<() => Promise<void>> {
285
+ const lockPath = `${path.resolve(key)}.mutation.lock`;
286
+ await mkdir(path.dirname(lockPath), { recursive: true });
287
+ const token = randomUUID();
288
+ const deadline = Date.now() + jsonStoreLockTimeoutMs();
289
+ while (true) {
290
+ let handle: FileHandle;
291
+ try {
292
+ handle = await open(lockPath, "wx", 0o600);
293
+ } catch (error) {
294
+ if (!hasErrorCode(error, "EEXIST")) throw error;
295
+ await removeStaleJsonStoreLock(lockPath).catch((staleError) => {
296
+ if (!hasErrorCode(staleError, "ENOENT")) throw staleError;
297
+ });
298
+ if (Date.now() >= deadline) {
299
+ throw new Error(`Timed out acquiring JSON store mutation lock: ${lockPath}`);
300
+ }
301
+ await waitForJsonStoreLock();
302
+ continue;
303
+ }
304
+ try {
305
+ await jsonStoreMutationLockTestHooks?.beforeLockOwnerWrite?.(lockPath, token);
306
+ await handle.writeFile(JSON.stringify({ pid: process.pid, token }), "utf8");
307
+ } finally {
308
+ await handle.close().catch(() => undefined);
309
+ }
310
+ await jsonStoreMutationLockTestHooks?.beforeLockOwnershipConfirm?.(lockPath, token);
311
+
312
+ if (!(await confirmJsonStoreMutationLockOwnership(lockPath, token, deadline))) {
313
+ await removeJsonStoreMutationLockIfOwned(lockPath, token);
314
+ if (Date.now() >= deadline) {
315
+ throw new Error(`Timed out acquiring JSON store mutation lock: ${lockPath}`);
316
+ }
317
+ await waitForJsonStoreLock();
318
+ continue;
319
+ }
320
+
321
+ const heartbeat = setInterval(
322
+ () => {
323
+ void readFile(lockPath, "utf8")
324
+ .then((content) => {
325
+ const metadata = JSON.parse(content) as { token?: unknown };
326
+ if (metadata.token !== token) return;
327
+ const now = new Date();
328
+ return utimes(lockPath, now, now);
329
+ })
330
+ .catch(() => undefined);
331
+ },
332
+ Math.max(1, Math.floor(jsonStoreLockStaleMs() / 3))
333
+ );
334
+ heartbeat.unref();
335
+ return async () => {
336
+ clearInterval(heartbeat);
337
+ try {
338
+ const metadata = JSON.parse(await readFile(lockPath, "utf8")) as { token?: unknown };
339
+ if (metadata.token === token) await unlink(lockPath);
340
+ } catch (error) {
341
+ if (!hasErrorCode(error, "ENOENT")) throw error;
342
+ }
343
+ };
344
+ }
345
+ }
346
+
347
+ export async function withJsonStoreMutationLock<T>(key: string, operation: () => Promise<T>): Promise<T> {
348
+ const normalizedKey = path.resolve(key);
349
+ const previous = jsonStoreMutationTails.get(normalizedKey) ?? Promise.resolve();
350
+ const { promise: current, resolve: release } = Promise.withResolvers<void>();
351
+ const tail = previous.catch(() => undefined).then(() => current);
352
+ jsonStoreMutationTails.set(normalizedKey, tail);
353
+ await previous.catch(() => undefined);
354
+ let releaseFileLock: (() => Promise<void>) | undefined;
355
+ try {
356
+ releaseFileLock = await acquireJsonStoreMutationFileLock(normalizedKey);
357
+ return await operation();
358
+ } finally {
359
+ try {
360
+ await releaseFileLock?.();
361
+ } finally {
362
+ release();
363
+ if (jsonStoreMutationTails.get(normalizedKey) === tail) {
364
+ jsonStoreMutationTails.delete(normalizedKey);
365
+ }
366
+ }
367
+ }
368
+ }
369
+
40
370
  export async function readJsonFile(filePath: string): Promise<unknown> {
41
371
  return JSON.parse(await readFile(filePath, "utf8")) as unknown;
42
372
  }
373
+
374
+ export async function writeJsonFileAtomic(filePath: string, value: unknown): Promise<void> {
375
+ await mkdir(path.dirname(filePath), { recursive: true });
376
+ const tempPath = `${filePath}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`;
377
+ try {
378
+ await writeFile(tempPath, JSON.stringify(value, null, 2), "utf8");
379
+ await rename(tempPath, filePath);
380
+ } catch (error) {
381
+ await unlink(tempPath).catch(() => undefined);
382
+ throw error;
383
+ }
384
+ }
@@ -32,7 +32,9 @@ import { applyCommitmentLedgerLifecycle } from "../commitment-ledger.js";
32
32
  import { recordDreamsPhaseRun } from "../maintenance/dreams-ledger.js";
33
33
  import { deindexMemoriesBatchAsync } from "../temporal-index-batch.js";
34
34
  import { isActiveMemoryStatus } from "../memory-lifecycle-ledger-utils.js";
35
+ import { propagateInvalidation } from "./dependency-propagation.js";
35
36
  import {
37
+ resolveCapabilities,
36
38
  resolveConsolidationCapabilities,
37
39
  resolveCreationMemoryCapabilities,
38
40
  resolveIndexingCapabilities,
@@ -42,6 +44,7 @@ import {
42
44
  resolveRecallEnhancementCapabilities,
43
45
  type MemoryLifecycleCapabilitySet,
44
46
  } from "../capabilities.js";
47
+ import { pruneOrphanCueAnchors } from "../cue-anchors.js";
45
48
  import type { LifecyclePolicyCoordinator } from "./lifecycle-policy-coordinator.js";
46
49
  import type { CompressionGuidelineCoordinator } from "./compression-guideline-coordinator.js";
47
50
  import type { SemanticConsolidationCoordinator } from "./semantic-consolidation-coordinator.js";
@@ -49,6 +52,7 @@ import type { EntitySynthesisCoordinator } from "./entity-synthesis-coordinator.
49
52
  import type { RecallSectionCoordinator } from "./recall-section-coordinator.js";
50
53
  import type { TierMigrationCoordinator } from "./tier-migration-coordinator.js";
51
54
  import type { StorageManager } from "../index.js";
55
+ import type { NamespaceCatalog } from "../namespaces/catalog.js";
52
56
  import type { NamespaceStorageRouter } from "../namespaces/storage.js";
53
57
  import type { ExtractionEngine } from "../extraction.js";
54
58
  import type { EmbeddingFallback } from "../embedding-fallback.js";
@@ -67,6 +71,7 @@ export interface ConsolidationRunCoordinatorDeps {
67
71
  config: PluginConfig;
68
72
  getStorage: () => StorageManager;
69
73
  getStorageRouter: () => NamespaceStorageRouter;
74
+ getNamespaceCatalog?: () => NamespaceCatalog;
70
75
  getExtraction: () => ExtractionEngine;
71
76
  embeddingFallback: EmbeddingFallback;
72
77
  tmtBuilder: TmtBuilder;
@@ -100,9 +105,142 @@ export interface ConsolidationRunCoordinatorDeps {
100
105
  ) => Promise<{ content: string } | null>;
101
106
  }
102
107
 
108
+ const MAX_HARMONIC_NAMESPACE_STORES = 50;
109
+ const HARMONIC_CATALOG_CURSOR_FILE = "harmonic-catalog-cursor.json";
110
+
111
+ type HarmonicStore = {
112
+ memoryDir: string;
113
+ abstractionNodeStoreDir?: string;
114
+ };
115
+
116
+ type HarmonicCatalogCursor = {
117
+ nextStorageDir?: string;
118
+ };
119
+
103
120
  export class ConsolidationRunCoordinator {
104
121
  constructor(private readonly deps: ConsolidationRunCoordinatorDeps) {}
105
122
 
123
+ private async readHarmonicCatalogCursor(defaultDir: string): Promise<string | undefined> {
124
+ const cursorPath = path.join(defaultDir, "state", HARMONIC_CATALOG_CURSOR_FILE);
125
+ try {
126
+ const raw = await readFile(cursorPath, "utf-8");
127
+ const parsed = JSON.parse(raw) as HarmonicCatalogCursor;
128
+ return typeof parsed.nextStorageDir === "string" && parsed.nextStorageDir.length > 0
129
+ ? path.resolve(parsed.nextStorageDir)
130
+ : undefined;
131
+ } catch (error) {
132
+ if ((error as NodeJS.ErrnoException).code !== "ENOENT") {
133
+ log.warn(
134
+ `harmonic namespace catalog cursor read failed open: ${
135
+ error instanceof Error ? error.message : String(error)
136
+ }`,
137
+ );
138
+ }
139
+ return undefined;
140
+ }
141
+ }
142
+
143
+ private async writeHarmonicCatalogCursor(
144
+ defaultDir: string,
145
+ nextStorageDir: string,
146
+ ): Promise<void> {
147
+ const stateDir = path.join(defaultDir, "state");
148
+ await mkdir(stateDir, { recursive: true });
149
+ await writeFile(
150
+ path.join(stateDir, HARMONIC_CATALOG_CURSOR_FILE),
151
+ JSON.stringify({ nextStorageDir }, null, 2),
152
+ "utf-8",
153
+ );
154
+ }
155
+
156
+ private async pruneHarmonicStores(storage: StorageManager): Promise<void> {
157
+ const config = this.deps.config;
158
+ if (
159
+ !resolveCapabilities(config).harmonicRetrieval ||
160
+ !resolveConsolidationCapabilities(config).abstractionAnchors
161
+ ) {
162
+ return;
163
+ }
164
+
165
+ const stores = new Map<string, HarmonicStore>();
166
+ const defaultDir = path.resolve(storage.dir);
167
+ stores.set(defaultDir, {
168
+ memoryDir: storage.dir,
169
+ abstractionNodeStoreDir: config.abstractionNodeStoreDir,
170
+ });
171
+
172
+ try {
173
+ const catalog = this.deps.getNamespaceCatalog?.();
174
+ if (catalog?.enabled) {
175
+ const records = await catalog.listNamespaces({ discoveredBy: "write" });
176
+ const catalogStores = new Map<string, HarmonicStore>();
177
+ for (const record of records) {
178
+ const storageDir = path.resolve(record.storageDir);
179
+ if (!stores.has(storageDir) && !catalogStores.has(storageDir)) {
180
+ catalogStores.set(storageDir, { memoryDir: record.storageDir });
181
+ }
182
+ }
183
+
184
+ const candidates = [...catalogStores.entries()];
185
+ if (candidates.length > 0) {
186
+ const cursor = await this.readHarmonicCatalogCursor(defaultDir);
187
+ const cursorIndex = cursor
188
+ ? candidates.findIndex(([storageDir]) => storageDir === cursor)
189
+ : -1;
190
+ const startIndex = cursorIndex >= 0 ? cursorIndex : 0;
191
+ const selectedCount = Math.min(
192
+ candidates.length,
193
+ MAX_HARMONIC_NAMESPACE_STORES - 1,
194
+ );
195
+
196
+ for (let offset = 0; offset < selectedCount; offset += 1) {
197
+ const index = (startIndex + offset) % candidates.length;
198
+ const [storageDir, store] = candidates[index];
199
+ stores.set(storageDir, store);
200
+ }
201
+
202
+ const nextIndex = (startIndex + selectedCount) % candidates.length;
203
+ const nextStorageDir = candidates[nextIndex][0];
204
+ try {
205
+ await this.writeHarmonicCatalogCursor(defaultDir, nextStorageDir);
206
+ } catch (error) {
207
+ log.warn(
208
+ `harmonic namespace catalog cursor write failed open: ${
209
+ error instanceof Error ? error.message : String(error)
210
+ }`,
211
+ );
212
+ }
213
+
214
+ if (selectedCount < candidates.length) {
215
+ log.warn(
216
+ `harmonic namespace catalog truncated at ${MAX_HARMONIC_NAMESPACE_STORES} stores; ` +
217
+ `skipped ${candidates.length - selectedCount} store(s)`,
218
+ );
219
+ }
220
+ }
221
+ }
222
+ } catch (error) {
223
+ log.warn(
224
+ `harmonic namespace catalog read failed open: ${error instanceof Error ? error.message : String(error)}`,
225
+ );
226
+ }
227
+
228
+ for (const store of stores.values()) {
229
+ try {
230
+ const removed = await pruneOrphanCueAnchors(store);
231
+ if (removed > 0) {
232
+ log.info(`harmonic anchor prune removed ${removed} orphan(s) from ${store.memoryDir}`);
233
+ }
234
+ } catch (error) {
235
+ log.warn(
236
+ `harmonic anchor prune failed open for ${store.memoryDir}: ${
237
+ error instanceof Error ? error.message : String(error)
238
+ }`,
239
+ );
240
+ }
241
+ }
242
+ }
243
+
106
244
  async run(): Promise<{
107
245
  memoriesProcessed: number;
108
246
  merged: number;
@@ -124,6 +262,7 @@ export class ConsolidationRunCoordinator {
124
262
  if (this.deps.getAccessTrackingBuffer().size > 0) {
125
263
  await this.deps.flushAccessTracking();
126
264
  }
265
+ await this.pruneHarmonicStores(storage);
127
266
 
128
267
  let allMemories = await storage.readAllMemories();
129
268
  if (allMemories.length < 5) {
@@ -170,10 +309,36 @@ export class ConsolidationRunCoordinator {
170
309
  const toInvalidate = resolveIndexingCapabilities(config).queryAwareIndexing
171
310
  ? (memoryLookup?.get(item.existingId) ?? null)
172
311
  : null;
312
+ // Always capture the full pre-delete snapshot for propagation.
313
+ const propagationOld = allMemories.find(
314
+ (memory) => memory.frontmatter.id === item.existingId,
315
+ );
173
316
  if (await storage.invalidateMemory(item.existingId)) {
174
317
  invalidated += 1;
175
318
  memoryItemMutated = true;
176
319
  await this.deps.embeddingFallback.removeFromIndex(item.existingId);
320
+ if (propagationOld) {
321
+ try {
322
+ await propagateInvalidation(
323
+ {
324
+ storage,
325
+ extraction: this.deps.getExtraction(),
326
+ config,
327
+ },
328
+ {
329
+ oldMemory: propagationOld,
330
+ replacementId: null,
331
+ replacementContent: null,
332
+ cause: "consolidation_invalidate",
333
+ namespaceScope: config.defaultNamespace,
334
+ },
335
+ );
336
+ } catch (propagationErr) {
337
+ log.warn(
338
+ `consolidation dependency propagation failed for ${item.existingId}: ${propagationErr}`,
339
+ );
340
+ }
341
+ }
177
342
  if (toInvalidate?.path && toInvalidate.frontmatter?.created) {
178
343
  itemsDeindexBatch.push({
179
344
  path: toInvalidate.path,
@@ -217,10 +382,37 @@ export class ConsolidationRunCoordinator {
217
382
  const toMergeInvalidate = resolveIndexingCapabilities(config).queryAwareIndexing
218
383
  ? (memoryLookup?.get(item.mergeWith) ?? null)
219
384
  : null;
385
+ // Capture the doomed memory before invalidation, independent of
386
+ // queryAwareIndexing and its optional lookup map.
387
+ const propagationOld = allMemories.find(
388
+ (memory) => memory.frontmatter.id === item.mergeWith,
389
+ );
220
390
  if (await storage.invalidateMemory(item.mergeWith)) {
221
391
  invalidated += 1;
222
392
  merged += 1;
223
393
  await this.deps.embeddingFallback.removeFromIndex(item.mergeWith);
394
+ if (propagationOld) {
395
+ try {
396
+ await propagateInvalidation(
397
+ {
398
+ storage,
399
+ extraction: this.deps.getExtraction(),
400
+ config,
401
+ },
402
+ {
403
+ oldMemory: propagationOld,
404
+ replacementId: item.existingId,
405
+ replacementContent: item.updatedContent,
406
+ cause: "consolidation_merge",
407
+ namespaceScope: config.defaultNamespace,
408
+ },
409
+ );
410
+ } catch (propagationErr) {
411
+ log.warn(
412
+ `consolidation dependency propagation failed for ${item.mergeWith}: ${propagationErr}`,
413
+ );
414
+ }
415
+ }
224
416
  if (
225
417
  toMergeInvalidate?.path &&
226
418
  toMergeInvalidate.frontmatter?.created
@@ -17,6 +17,7 @@
17
17
  */
18
18
 
19
19
  import type {
20
+ MemoryFile,
20
21
  MemoryLink,
21
22
  PluginConfig,
22
23
  QmdSearchResult,
@@ -28,6 +29,7 @@ import type { ExtractionEngine } from "../extraction.js";
28
29
  import { log } from "../logger.js";
29
30
  import { resolveIndexingCapabilities } from "../capabilities.js";
30
31
  import { deindexMemoryAsync } from "../temporal-index.js";
32
+ import { propagateInvalidation } from "./dependency-propagation.js";
31
33
 
32
34
  /** Result type of {@link ContradictionLinkingCoordinator.checkForContradiction}. */
33
35
  export interface ContradictionResult {
@@ -243,12 +245,44 @@ export class ContradictionLinkingCoordinator {
243
245
  ) {
244
246
  return;
245
247
  }
248
+
249
+ // Capture links before the primary supersession. The propagation hook is
250
+ // orchestration-owned, so its own supersessions cannot recurse.
251
+ let oldMemory: MemoryFile | null = null;
252
+ try {
253
+ oldMemory = await storage.getMemoryById(contradiction.supersededId);
254
+ } catch (err) {
255
+ log.warn(`contradiction propagation snapshot failed for ${contradiction.supersededId}: ${err}`);
256
+ }
257
+
246
258
  try {
247
- await storage.supersedeMemory(
259
+ const superseded = await storage.supersedeMemory(
248
260
  contradiction.supersededId,
249
261
  newMemoryId,
250
262
  contradiction.reason,
251
263
  );
264
+ if (!superseded) return;
265
+ if (oldMemory) {
266
+ try {
267
+ await propagateInvalidation(
268
+ {
269
+ storage,
270
+ extraction: this.getExtraction(),
271
+ config,
272
+ },
273
+ {
274
+ oldMemory,
275
+ replacementId: newMemoryId,
276
+ replacementContent: (await storage.getMemoryById(newMemoryId))?.content ?? null,
277
+ cause: "contradiction",
278
+ namespaceScope: this.namespaceFromPath(storage.dir),
279
+ },
280
+ );
281
+ } catch (err) {
282
+ log.warn(`contradiction dependency propagation failed for ${contradiction.supersededId}: ${err}`);
283
+ }
284
+ }
285
+
252
286
  if (
253
287
  resolveIndexingCapabilities(config).queryAwareIndexing &&
254
288
  contradiction.supersededPath