@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,320 @@
1
+ import { createHash } from "node:crypto";
2
+ import path from "node:path";
3
+ import {
4
+ readCausalTrajectoryRecordsStrict,
5
+ readCausalTrajectoryRevisionToken,
6
+ resolveCausalTrajectoryStoreDir,
7
+ type ActionIntent,
8
+ type ActionStrategyId,
9
+ type CausalTrajectoryRecord,
10
+ type CausalTrajectoryStrictReadResult,
11
+ type EditKind,
12
+ } from "../causal-trajectory.js";
13
+ import type { CodingContext } from "../types.js";
14
+
15
+ export const PRE_ACTION_FINGERPRINT_VERSION = 1;
16
+ export const PRE_ACTION_WARNING_VERSION = 1;
17
+ export const PRE_ACTION_GATE_DEFAULT_TIMEOUT_MS = 50;
18
+
19
+ export type PreActionGateStatus = "NO_MATCH" | "MATCH_WARN" | "ERROR_FAIL_OPEN";
20
+
21
+ export interface PreActionGateRequest {
22
+ sessionKey: string;
23
+ strategyId: ActionStrategyId;
24
+ intent: ActionIntent;
25
+ codingContext: CodingContext;
26
+ memoryDir?: string;
27
+ causalTrajectoryStoreDir?: string;
28
+ signal?: AbortSignal;
29
+ }
30
+
31
+ export interface PreActionGateResult {
32
+ status: PreActionGateStatus;
33
+ reason?: string;
34
+ advisoryText?: string;
35
+ fingerprint?: string;
36
+ matchedTrajectoryId?: string;
37
+ revision?: string;
38
+ }
39
+
40
+ export interface NormalizedActionIntent {
41
+ kind: "command" | "edit";
42
+ strategyId: ActionStrategyId;
43
+ fingerprint: string;
44
+ }
45
+
46
+ export interface PreActionGateDependencies {
47
+ readStrict?: (options: {
48
+ memoryDir: string;
49
+ causalTrajectoryStoreDir?: string;
50
+ signal?: AbortSignal;
51
+ }) => Promise<CausalTrajectoryStrictReadResult>;
52
+ getRevision?: (options: {
53
+ memoryDir: string;
54
+ causalTrajectoryStoreDir?: string;
55
+ }) => Promise<string>;
56
+ clock?: () => number;
57
+ maxCacheSize?: number;
58
+ timeoutMs?: number;
59
+ }
60
+
61
+ const ACTION_STRATEGIES: ReadonlySet<ActionStrategyId> = new Set([
62
+ "RUN_CHECK",
63
+ "CHANGE_IMPLEMENTATION",
64
+ "CHANGE_TEST",
65
+ "CHANGE_CONFIGURATION",
66
+ "CHANGE_DEPENDENCY",
67
+ "INVALIDATE_CACHE",
68
+ "RETRY_ACTION",
69
+ "INSPECT_STATE",
70
+ ]);
71
+ const EDIT_KINDS: ReadonlySet<EditKind> = new Set(["create", "update", "delete", "rename"]);
72
+ const MAX_COMMAND_CHARS = 128;
73
+ const MAX_ARGUMENTS = 32;
74
+ const MAX_ARGUMENT_CHARS = 128;
75
+ const MAX_PATH_CHARS = 512;
76
+ const MAX_SLOT_CHARS = 128;
77
+ const MAX_CITATION_CHARS = 180;
78
+
79
+ function bound(value: string, max: number, field: string): string {
80
+ const normalized = value.trim();
81
+ if (normalized.length > max) throw new Error(`${field} exceeds ${max} characters`);
82
+ return normalized;
83
+ }
84
+
85
+ export function sanitizePayloadString(input: string): string {
86
+ return input
87
+ .replace(/(?:\/home\/[^\s/]+|\/Users\/[^\s/]+|[A-Za-z]:\\Users\\[^\s\\]+)/g, "$HOME")
88
+ .replace(/sk-[a-zA-Z0-9_-]{10,}/g, "<secret>")
89
+ .replace(/bearer\s+[a-zA-Z0-9._-]+/gi, "bearer <secret>")
90
+ .trim();
91
+ }
92
+
93
+ function normalizeRepositoryPath(filePath: string, codingContext: CodingContext): string {
94
+ const root = path.resolve(codingContext.rootPath);
95
+ const absolute = path.isAbsolute(filePath) ? path.resolve(filePath) : path.resolve(root, filePath);
96
+ const relative = path.relative(root, absolute);
97
+ if (relative === ".." || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) {
98
+ throw new Error("edit path must be contained by codingContext.rootPath");
99
+ }
100
+ return bound(relative.split(path.sep).join("/"), MAX_PATH_CHARS, "repo-relative path");
101
+ }
102
+
103
+ function normalizeCommandArgument(
104
+ argument: string,
105
+ codingContext: CodingContext,
106
+ secretValue: boolean,
107
+ ): string {
108
+ const value = bound(sanitizePayloadString(argument), MAX_ARGUMENT_CHARS, "command argument");
109
+ if (secretValue || value.includes("<secret>")) return "<secret>";
110
+ if (/^--(?:token|key|secret|password|authorization)=/i.test(value)) {
111
+ return `${value.slice(0, value.indexOf("=") + 1)}<secret>`;
112
+ }
113
+ if (/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value)) return "<uuid>";
114
+ if (/^[0-9a-f]{7,64}$/i.test(value)) return "<sha>";
115
+ if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z$/.test(value)) return "<timestamp>";
116
+ if (/^\d+(?:\.\d+)?(?:ms|s|m|h|d)$/.test(value)) return "<duration>";
117
+ if (/^-?\d+(?:\.\d+)?$/.test(value)) return "<number>";
118
+ const pathLike = path.isAbsolute(value)
119
+ || (!/^[a-z][a-z0-9+.-]*:\/\//i.test(value) && /[\\/]/.test(value) && !value.startsWith("--"));
120
+ if (pathLike) {
121
+ let relative: string;
122
+ try {
123
+ relative = normalizeRepositoryPath(value, codingContext);
124
+ } catch {
125
+ return "<external-path>";
126
+ }
127
+ return /(?:^|\/)(?:tmp|temp)(?:\/|$)|\.tmp$/i.test(relative)
128
+ ? `<repo-temp-path:${relative}>`
129
+ : `<repo-path:${relative}>`;
130
+ }
131
+ return value;
132
+ }
133
+
134
+ export function normalizeActionIntent(
135
+ intent: ActionIntent,
136
+ strategyId: ActionStrategyId,
137
+ codingContext: CodingContext,
138
+ ): NormalizedActionIntent {
139
+ if (!ACTION_STRATEGIES.has(strategyId)) throw new Error(`unsupported action strategy: ${strategyId}`);
140
+
141
+ let payload: string;
142
+ if (intent.kind === "command") {
143
+ const command = bound(sanitizePayloadString(intent.command), MAX_COMMAND_CHARS, "command");
144
+ const args = intent.args ?? [];
145
+ if (args.length > MAX_ARGUMENTS) throw new Error(`command args exceed ${MAX_ARGUMENTS} entries`);
146
+ const normalizedArgs = args.map((argument, index) => {
147
+ const prior = index > 0 ? args[index - 1] : undefined;
148
+ const secretValue = prior !== undefined
149
+ && /^--(?:token|key|secret|password|authorization)$/i.test(prior);
150
+ return normalizeCommandArgument(argument, codingContext, secretValue);
151
+ });
152
+ payload = JSON.stringify({ kind: "command", strategyId, command, args: normalizedArgs });
153
+ } else if (intent.kind === "edit") {
154
+ if (!EDIT_KINDS.has(intent.editKind)) throw new Error(`unsupported edit kind: ${intent.editKind}`);
155
+ const relativePath = normalizeRepositoryPath(intent.filePath, codingContext);
156
+ payload = JSON.stringify({
157
+ kind: "edit",
158
+ strategyId,
159
+ filePath: relativePath,
160
+ editKind: intent.editKind,
161
+ symbol: intent.symbol ? bound(intent.symbol, MAX_SLOT_CHARS, "symbol") : undefined,
162
+ range: intent.range ? bound(intent.range, MAX_SLOT_CHARS, "range") : undefined,
163
+ diffShape: intent.diffShape ? bound(intent.diffShape, MAX_SLOT_CHARS, "diffShape") : undefined,
164
+ });
165
+ } else {
166
+ throw new Error("action intent kind must be command or edit");
167
+ }
168
+
169
+ return {
170
+ kind: intent.kind,
171
+ strategyId,
172
+ fingerprint: `v1:sha256:${createHash("sha256").update(payload).digest("hex")}`,
173
+ };
174
+ }
175
+
176
+ function matchTrajectory(
177
+ record: CausalTrajectoryRecord,
178
+ projectId: string,
179
+ normalized: NormalizedActionIntent,
180
+ ): boolean {
181
+ const identity = record.actionIdentity;
182
+ return record.outcomeKind === "failure"
183
+ && record.codingContext?.projectId === projectId
184
+ && identity?.fingerprintVersion === PRE_ACTION_FINGERPRINT_VERSION
185
+ && identity.strategyId === normalized.strategyId
186
+ && identity.fingerprint === normalized.fingerprint;
187
+ }
188
+
189
+ function boundedCitation(value: string | undefined, fallback: string): string {
190
+ const sanitized = sanitizePayloadString(value ?? fallback).replace(/\s+/g, " ");
191
+ return sanitized.slice(0, MAX_CITATION_CHARS);
192
+ }
193
+
194
+ export class PreActionFailureGate {
195
+ private readonly cache = new Map<string, PreActionGateResult>();
196
+ private readonly maxCacheSize: number;
197
+ private readonly readStrict: NonNullable<PreActionGateDependencies["readStrict"]>;
198
+ private readonly getRevision: NonNullable<PreActionGateDependencies["getRevision"]>;
199
+ private readonly clock: () => number;
200
+ private readonly timeoutMs: number;
201
+
202
+ constructor(deps: PreActionGateDependencies = {}) {
203
+ this.readStrict = deps.readStrict ?? readCausalTrajectoryRecordsStrict;
204
+ this.getRevision = deps.getRevision ?? readCausalTrajectoryRevisionToken;
205
+ this.clock = deps.clock ?? Date.now;
206
+ this.maxCacheSize = deps.maxCacheSize ?? 500;
207
+ this.timeoutMs = Math.max(1, deps.timeoutMs ?? PRE_ACTION_GATE_DEFAULT_TIMEOUT_MS);
208
+ }
209
+
210
+ public clearCache(): void {
211
+ this.cache.clear();
212
+ }
213
+
214
+ async evaluate(request: PreActionGateRequest): Promise<PreActionGateResult> {
215
+ const deadline = this.clock() + this.timeoutMs;
216
+ const controller = new AbortController();
217
+ const abortFromExternal = () => controller.abort();
218
+ request.signal?.addEventListener("abort", abortFromExternal, { once: true });
219
+ if (request.signal?.aborted) controller.abort();
220
+
221
+ let resolveTimeout!: (result: PreActionGateResult) => void;
222
+ const timeoutPromise = new Promise<PreActionGateResult>((resolve) => {
223
+ resolveTimeout = resolve;
224
+ });
225
+ const timer = setTimeout(() => {
226
+ controller.abort();
227
+ resolveTimeout({ status: "ERROR_FAIL_OPEN", reason: `PreActionFailureGate timed out after ${this.timeoutMs}ms` });
228
+ }, this.timeoutMs);
229
+
230
+ try {
231
+ return await Promise.race([
232
+ this.evaluateInternal(request, controller.signal, deadline),
233
+ timeoutPromise,
234
+ ]);
235
+ } catch (error) {
236
+ return { status: "ERROR_FAIL_OPEN", reason: error instanceof Error ? error.message : String(error) };
237
+ } finally {
238
+ clearTimeout(timer);
239
+ request.signal?.removeEventListener("abort", abortFromExternal);
240
+ }
241
+ }
242
+
243
+ private async evaluateInternal(
244
+ request: PreActionGateRequest,
245
+ signal: AbortSignal,
246
+ deadline: number,
247
+ ): Promise<PreActionGateResult> {
248
+ if (!request.memoryDir?.trim()) return { status: "ERROR_FAIL_OPEN", reason: "memoryDir is required" };
249
+ if (!request.sessionKey?.trim()) return { status: "ERROR_FAIL_OPEN", reason: "sessionKey is required" };
250
+ if (!request.codingContext?.projectId?.trim() || !request.codingContext.rootPath?.trim()) {
251
+ return { status: "ERROR_FAIL_OPEN", reason: "codingContext with projectId and rootPath is required" };
252
+ }
253
+
254
+ let normalized: NormalizedActionIntent;
255
+ try {
256
+ normalized = normalizeActionIntent(request.intent, request.strategyId, request.codingContext);
257
+ } catch (error) {
258
+ return { status: "ERROR_FAIL_OPEN", reason: error instanceof Error ? error.message : String(error) };
259
+ }
260
+
261
+ const revisionOptions = {
262
+ memoryDir: request.memoryDir,
263
+ causalTrajectoryStoreDir: request.causalTrajectoryStoreDir,
264
+ };
265
+ const preRevision = await this.getRevision(revisionOptions);
266
+ const branch = request.codingContext.branch ?? "";
267
+ const storeId = createHash("sha256")
268
+ .update(resolveCausalTrajectoryStoreDir(request.memoryDir, request.causalTrajectoryStoreDir))
269
+ .digest("hex");
270
+ const cacheKey = createHash("sha256").update(JSON.stringify([
271
+ request.codingContext.projectId,
272
+ branch,
273
+ request.sessionKey,
274
+ PRE_ACTION_FINGERPRINT_VERSION,
275
+ preRevision,
276
+ normalized.fingerprint,
277
+ storeId,
278
+ ])).digest("hex");
279
+ const cached = this.cache.get(cacheKey);
280
+ if (cached) return cached;
281
+
282
+ if (signal.aborted || this.clock() >= deadline) return { status: "ERROR_FAIL_OPEN", reason: "deadline exceeded" };
283
+ const scan = await this.readStrict({ ...revisionOptions, signal });
284
+ if (signal.aborted || this.clock() >= deadline) return { status: "ERROR_FAIL_OPEN", reason: "deadline exceeded" };
285
+ if (scan.invalidTrajectories.length > 0) {
286
+ return { status: "ERROR_FAIL_OPEN", reason: `store contains ${scan.invalidTrajectories.length} invalid record(s)` };
287
+ }
288
+
289
+ const postRevision = await this.getRevision(revisionOptions);
290
+ const stableRevision = preRevision === postRevision;
291
+ const match = scan.trajectories
292
+ .filter((record) => matchTrajectory(record, request.codingContext.projectId, normalized))
293
+ .sort((left, right) => {
294
+ const recordedAtOrder = right.recordedAt.localeCompare(left.recordedAt);
295
+ return recordedAtOrder !== 0
296
+ ? recordedAtOrder
297
+ : left.trajectoryId.localeCompare(right.trajectoryId);
298
+ })[0];
299
+ const result: PreActionGateResult = match
300
+ ? {
301
+ status: "MATCH_WARN",
302
+ advisoryText: `[PreActionFailureGate ${PRE_ACTION_WARNING_VERSION}] A similar action failed before. Prior act: "${boundedCitation(match.actionSummary, "recorded action")}". Failure: "${boundedCitation(match.outcomeSummary, "recorded failure")}". Next safe check: "${boundedCitation(match.followUpSummary, "verify prerequisites before retrying")}".`,
303
+ fingerprint: normalized.fingerprint,
304
+ matchedTrajectoryId: match.trajectoryId,
305
+ revision: postRevision,
306
+ }
307
+ : { status: "NO_MATCH", fingerprint: normalized.fingerprint, revision: postRevision };
308
+
309
+ if (stableRevision && !signal.aborted && this.clock() < deadline) this.setCache(cacheKey, result);
310
+ return result;
311
+ }
312
+
313
+ private setCache(key: string, result: PreActionGateResult): void {
314
+ if (this.cache.size >= this.maxCacheSize) {
315
+ const oldest = this.cache.keys().next().value;
316
+ if (oldest !== undefined) this.cache.delete(oldest);
317
+ }
318
+ this.cache.set(key, result);
319
+ }
320
+ }
@@ -1474,6 +1474,7 @@ test("parseConfig codingKnowledge: accepts CLI-style boolean strings (CLAUDE.md
1474
1474
  assert.equal(result.codingKnowledge.architectureCardLlmSummary, true);
1475
1475
  });
1476
1476
 
1477
+
1477
1478
  test("parseConfig codingKnowledge: rejects unknown structuralProvider value (rule 51)", () => {
1478
1479
  assert.throws(
1479
1480
  () =>
@@ -1609,6 +1610,90 @@ test("parseConfig: non-array patternReinforcementCategories falls back to defaul
1609
1610
  ]);
1610
1611
  });
1611
1612
 
1613
+ test("parseConfig: dependency propagation defaults stay disabled and bounded", () => {
1614
+ const result = parseConfig({ openaiApiKey: "sk-test" });
1615
+ assert.deepEqual(result.dependencyPropagation, {
1616
+ enabled: false,
1617
+ linkTypes: ["supports", "follows"],
1618
+ maxDependents: 10,
1619
+ timeoutMs: 20_000,
1620
+ dryRun: false,
1621
+ });
1622
+ });
1623
+
1624
+ test("parseConfig: dependency propagation accepts documented overrides", () => {
1625
+ const result = parseConfig({
1626
+ openaiApiKey: "sk-test",
1627
+ dependencyPropagation: {
1628
+ enabled: "true",
1629
+ linkTypes: ["references", "supports", "references"],
1630
+ maxDependents: "0",
1631
+ timeoutMs: "2500",
1632
+ dryRun: "yes",
1633
+ },
1634
+ });
1635
+
1636
+ assert.deepEqual(result.dependencyPropagation, {
1637
+ enabled: true,
1638
+ linkTypes: ["references", "supports"],
1639
+ maxDependents: 0,
1640
+ timeoutMs: 2_500,
1641
+ dryRun: true,
1642
+ });
1643
+ });
1644
+
1645
+ test("parseConfig: dependency propagation honors every documented falsy string", () => {
1646
+ for (const value of ["false", "0", "no", "off"]) {
1647
+ const result = parseConfig({
1648
+ openaiApiKey: "sk-test",
1649
+ dependencyPropagation: { enabled: value, dryRun: value },
1650
+ });
1651
+ assert.equal(result.dependencyPropagation.enabled, false, `${value} must disable propagation`);
1652
+ assert.equal(result.dependencyPropagation.dryRun, false, `${value} must disable dry run`);
1653
+ }
1654
+ });
1655
+
1656
+ test("parseConfig: dependency propagation rejects invalid integers", () => {
1657
+ for (const maxDependents of ["abc", 3.7, -1]) {
1658
+ assert.throws(
1659
+ () =>
1660
+ parseConfig({
1661
+ openaiApiKey: "sk-test",
1662
+ dependencyPropagation: { maxDependents },
1663
+ }),
1664
+ /dependencyPropagation\.maxDependents must be a non-negative integer/,
1665
+ );
1666
+ }
1667
+
1668
+ assert.throws(
1669
+ () =>
1670
+ parseConfig({
1671
+ openaiApiKey: "sk-test",
1672
+ dependencyPropagation: { timeoutMs: 0 },
1673
+ }),
1674
+ /dependencyPropagation\.timeoutMs must be a positive integer/,
1675
+ );
1676
+ });
1677
+
1678
+ test("parseConfig: dependency propagation rejects invalid link types and shapes", () => {
1679
+ assert.throws(
1680
+ () =>
1681
+ parseConfig({
1682
+ openaiApiKey: "sk-test",
1683
+ dependencyPropagation: { linkTypes: ["supports", "related"] },
1684
+ }),
1685
+ /dependencyPropagation\.linkTypes must contain only supports, follows, references/,
1686
+ );
1687
+ assert.throws(
1688
+ () =>
1689
+ parseConfig({
1690
+ openaiApiKey: "sk-test",
1691
+ dependencyPropagation: { linkTypes: "supports" },
1692
+ }),
1693
+ /dependencyPropagation\.linkTypes must be an array/,
1694
+ );
1695
+ });
1696
+
1612
1697
  // ── #683 PR 2/N: connectors.googleDrive parsing.
1613
1698
 
1614
1699
  test("parseConfig connectors defaults: googleDrive disabled with empty creds", () => {
package/src/config.ts CHANGED
@@ -41,6 +41,7 @@ import { coerceBool, coerceBooleanLike, coerceInstallExtension, coerceNumber } f
41
41
  import { parseRecallConcurrencyConfig } from "./recall-concurrency-config.js";
42
42
  import { parseExtractionLivenessConfig } from "./extraction-liveness.js";
43
43
  import { parseReplicaPeersConfig } from "./replica-peers-config.js";
44
+ import { parseDependencyPropagationConfig } from "./dependency-propagation-config.js";
44
45
  import { hasLegacyConnectorEntries } from "./connectors/paths.js";
45
46
  import {
46
47
  parseQmdChunkStrategy,
@@ -1808,6 +1809,7 @@ export function parseConfig(
1808
1809
  contradictionAutoResolve: cfg.contradictionAutoResolve !== false,
1809
1810
  // Contradiction Scan cron (issue #520)
1810
1811
  contradictionScan: parseContradictionScanConfig(cfg.contradictionScan),
1812
+ dependencyPropagation: parseDependencyPropagationConfig(cfg),
1811
1813
  // Temporal Supersession (issue #375)
1812
1814
  temporalSupersessionEnabled: cfg.temporalSupersessionEnabled !== false, // On by default
1813
1815
  temporalSupersessionIncludeInRecall:
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Cancellation contract for the shared full-corpus read primitives (issue #2307).
3
+ *
4
+ * `readAllArtifactsCached`, `readAllEntityFiles`, `readAllMemories`, and the
5
+ * artifact source-status snapshot each walk and parse an entire memory tree. Issue
6
+ * #2291 bounded the recall providers that call them, so a timed-out recall returns
7
+ * on time — but the scan underneath kept running, and for the primitives without
8
+ * in-flight coalescing every abandoned request started another one. On a large or
9
+ * network-mounted store those pile up into sustained I/O no live request needs.
10
+ *
11
+ * The mechanism is a plain optional parameter, not ambient async context: these
12
+ * primitives have dozens of callers across extraction, maintenance, wearables, and
13
+ * coding surfaces, and an ambient signal would silently attach a request's
14
+ * cancellation to background work that merely shares its async context. An
15
+ * explicit parameter is greppable, and a caller that does not opt in behaves
16
+ * exactly as before.
17
+ *
18
+ * Two invariants bind every implementation:
19
+ *
20
+ * 1. **Checked before the cache lookup.** A caller that has already given up gets
21
+ * an `AbortError`, warm cache or not — the same contract the recall providers
22
+ * follow, so cancellation never depends on cache state.
23
+ * 2. **A cancelled read never publishes.** Every checkpoint throws, so control
24
+ * leaves before the cache write. A partial corpus must never be cached, or
25
+ * served, as if it were complete.
26
+ */
27
+
28
+ import { throwIfAborted } from "./abort-error.js";
29
+
30
+ export interface CorpusReadOptions {
31
+ /**
32
+ * Stops the read at its next directory, batch, or attempt boundary. A single
33
+ * in-flight file read is not interrupted; the boundaries are what bound the
34
+ * work, and on a tree large enough to matter there are thousands of them.
35
+ */
36
+ abortSignal?: AbortSignal;
37
+ }
38
+
39
+ /** Stop a corpus read at a scan boundary when its caller has given up. */
40
+ export function checkCorpusReadAbort(options?: CorpusReadOptions): void {
41
+ throwIfAborted(options?.abortSignal, "corpus read aborted");
42
+ }
@@ -0,0 +1,90 @@
1
+ import assert from "node:assert/strict";
2
+ import { mkdtemp, readFile, rm } from "node:fs/promises";
3
+ import os from "node:os";
4
+ import path from "node:path";
5
+ import test from "node:test";
6
+ import { upsertAbstractionNode } from "./abstraction-nodes.js";
7
+ import { pruneOrphanCueAnchors, upsertCueAnchor, validateCueAnchor } from "./cue-anchors.js";
8
+
9
+ const RECORDED_AT = "2026-08-08T20:00:00.000Z";
10
+
11
+ function anchor(sourceMemoryIds: string[]) {
12
+ return {
13
+ schemaVersion: 1 as const,
14
+ anchorId: "cue-provenance",
15
+ anchorType: "tool" as const,
16
+ anchorValue: "storage tool",
17
+ normalizedCue: "storage tool",
18
+ recordedAt: RECORDED_AT,
19
+ sessionKey: "session:test",
20
+ nodeRefs: ["node-storage"],
21
+ sourceMemoryIdsByNodeRef: { "node-storage": sourceMemoryIds },
22
+ };
23
+ }
24
+
25
+ test("repeated same-node upserts retain only live node source IDs", async () => {
26
+ const memoryDir = await mkdtemp(path.join(os.tmpdir(), "remnic-cue-anchor-provenance-upsert-"));
27
+ try {
28
+ await upsertAbstractionNode({
29
+ memoryDir,
30
+ node: {
31
+ schemaVersion: 1,
32
+ nodeId: "node-storage",
33
+ recordedAt: RECORDED_AT,
34
+ sessionKey: "session:test",
35
+ kind: "episode",
36
+ abstractionLevel: "micro",
37
+ title: "Storage episode",
38
+ summary: "The storage episode remains live.",
39
+ sourceMemoryIds: ["mem-0", "mem-1"],
40
+ },
41
+ });
42
+
43
+ let filePath = "";
44
+ for (let index = 0; index < 100; index++) {
45
+ filePath = await upsertCueAnchor({
46
+ memoryDir,
47
+ anchor: anchor([`mem-${index}`, "mem-1", `stale-${index}`]),
48
+ });
49
+ }
50
+
51
+ const persisted = validateCueAnchor(JSON.parse(await readFile(filePath, "utf8")));
52
+ assert.deepEqual(persisted.sourceMemoryIdsByNodeRef, {
53
+ "node-storage": ["mem-0", "mem-1"],
54
+ });
55
+ } finally {
56
+ await rm(memoryDir, { recursive: true, force: true });
57
+ }
58
+ });
59
+
60
+ test("pruneOrphanCueAnchors trims stale provenance from a live node", async () => {
61
+ const memoryDir = await mkdtemp(path.join(os.tmpdir(), "remnic-cue-anchor-provenance-prune-"));
62
+ try {
63
+ const anchorPath = await upsertCueAnchor({
64
+ memoryDir,
65
+ anchor: anchor(["mem-keep", "mem-stale"]),
66
+ });
67
+ await upsertAbstractionNode({
68
+ memoryDir,
69
+ node: {
70
+ schemaVersion: 1,
71
+ nodeId: "node-storage",
72
+ recordedAt: RECORDED_AT,
73
+ sessionKey: "session:test",
74
+ kind: "episode",
75
+ abstractionLevel: "micro",
76
+ title: "Storage episode",
77
+ summary: "The storage episode remains live.",
78
+ sourceMemoryIds: ["mem-keep"],
79
+ },
80
+ });
81
+
82
+ assert.equal(await pruneOrphanCueAnchors({ memoryDir }), 0);
83
+ const persisted = validateCueAnchor(JSON.parse(await readFile(anchorPath, "utf8")));
84
+ assert.deepEqual(persisted.sourceMemoryIdsByNodeRef, {
85
+ "node-storage": ["mem-keep"],
86
+ });
87
+ } finally {
88
+ await rm(memoryDir, { recursive: true, force: true });
89
+ }
90
+ });