@remnic/core 9.50.3 → 9.51.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 (486) hide show
  1. package/dist/access-admin-ops-surface.d.ts +13 -11
  2. package/dist/access-admin-ops-surface.js +41 -39
  3. package/dist/access-authorization-probe.d.ts +13 -11
  4. package/dist/access-authorization-probe.js +42 -40
  5. package/dist/access-boundary.d.ts +13 -11
  6. package/dist/access-boundary.js +41 -39
  7. package/dist/access-cli.js +109 -104
  8. package/dist/access-cli.js.map +1 -1
  9. package/dist/access-coding-context-resolution.d.ts +3 -1
  10. package/dist/access-extraction-force-flush.d.ts +13 -11
  11. package/dist/access-extraction-force-flush.js +41 -39
  12. package/dist/access-health-types.d.ts +3 -1
  13. package/dist/access-http-lcm-compaction.d.ts +13 -11
  14. package/dist/access-http-lifecycle-flush.d.ts +13 -11
  15. package/dist/access-http-offline-stream.d.ts +13 -11
  16. package/dist/access-http-query.js +41 -39
  17. package/dist/access-http.d.ts +13 -11
  18. package/dist/access-http.js +52 -50
  19. package/dist/access-identity-continuity-surface.d.ts +11 -9
  20. package/dist/access-identity-continuity-surface.js +41 -39
  21. package/dist/access-lcm-surface.d.ts +13 -11
  22. package/dist/access-lcm-surface.js +41 -39
  23. package/dist/access-mcp.d.ts +13 -11
  24. package/dist/access-mcp.js +47 -45
  25. package/dist/access-memory-search-fanout.d.ts +4 -2
  26. package/dist/{access-namespace-preflight-Dj2QolFE.d.ts → access-namespace-preflight-Ds6CGlCP.d.ts} +1 -1
  27. package/dist/access-namespace-preflight.d.ts +5 -3
  28. package/dist/access-namespace-preflight.js +41 -39
  29. package/dist/access-observe-write-surface.d.ts +13 -11
  30. package/dist/access-observe-write-surface.js +41 -39
  31. package/dist/access-offline-manifest.d.ts +11 -9
  32. package/dist/access-operations-batch.js +43 -41
  33. package/dist/access-operations.d.ts +16 -14
  34. package/dist/access-operations.js +46 -44
  35. package/dist/access-recall-concurrency.d.ts +13 -11
  36. package/dist/access-recall-concurrency.js +41 -39
  37. package/dist/access-recall-response.d.ts +13 -11
  38. package/dist/access-recall-response.js +41 -39
  39. package/dist/access-recall-surface.d.ts +13 -11
  40. package/dist/access-recall-surface.js +41 -39
  41. package/dist/access-schema.d.ts +88 -88
  42. package/dist/access-schema.js +3 -3
  43. package/dist/{access-service-DesbnTSa.d.ts → access-service-BY0KJ44c.d.ts} +7 -7
  44. package/dist/access-service-helpers.d.ts +13 -11
  45. package/dist/access-service.d.ts +13 -11
  46. package/dist/access-service.js +41 -39
  47. package/dist/access-surface-catalog.d.ts +13 -11
  48. package/dist/access-wearables-meetings-surface.d.ts +5 -3
  49. package/dist/action-confidence.d.ts +3 -1
  50. package/dist/active-memory-bridge.d.ts +3 -1
  51. package/dist/active-recall.d.ts +3 -1
  52. package/dist/active-recall.js +5 -3
  53. package/dist/active-recall.js.map +1 -1
  54. package/dist/adapters/index.js +4 -4
  55. package/dist/adapters/registry.js +2 -2
  56. package/dist/ambient-provenance.d.ts +3 -1
  57. package/dist/archive-mutation-version.d.ts +9 -0
  58. package/dist/archive-mutation-version.js +20 -0
  59. package/dist/artifact-search.d.ts +3 -1
  60. package/dist/behavior-learner.d.ts +3 -1
  61. package/dist/behavior-signals.d.ts +3 -1
  62. package/dist/bootstrap.d.ts +11 -9
  63. package/dist/briefing.d.ts +4 -2
  64. package/dist/briefing.js +10 -9
  65. package/dist/buffer-surprise-report.d.ts +3 -1
  66. package/dist/buffer-turn-helpers.d.ts +3 -1
  67. package/dist/buffer.d.ts +4 -2
  68. package/dist/buffer.js +5 -5
  69. package/dist/bulk-import/index.d.ts +5 -3
  70. package/dist/calibration.d.ts +3 -1
  71. package/dist/capabilities.d.ts +3 -1
  72. package/dist/{catalog-D-G7RgXR.d.ts → catalog-D3B4RDy1.d.ts} +1 -1
  73. package/dist/causal-behavior.d.ts +3 -1
  74. package/dist/causal-behavior.js +2 -2
  75. package/dist/causal-chain.js +2 -2
  76. package/dist/causal-consolidation.d.ts +3 -1
  77. package/dist/causal-consolidation.js +13 -12
  78. package/dist/causal-consolidation.js.map +1 -1
  79. package/dist/causal-retrieval.js +2 -2
  80. package/dist/causal-trajectory-graph.d.ts +4 -2
  81. package/dist/causal-trajectory-graph.js +2 -1
  82. package/dist/causal-trajectory-graph.js.map +1 -1
  83. package/dist/causal-trajectory.js +1 -1
  84. package/dist/{chunk-KDG2KTWW.js → chunk-33SV3E43.js} +4 -4
  85. package/dist/{chunk-2HGUDBRJ.js → chunk-37ZO6LLJ.js} +2 -2
  86. package/dist/{chunk-QW3WFHKU.js → chunk-45BRYON6.js} +2 -2
  87. package/dist/{chunk-GZICBRWK.js → chunk-4F6X3RXW.js} +2 -2
  88. package/dist/{chunk-7BAYBYY5.js → chunk-4PC4PRJE.js} +2 -2
  89. package/dist/{chunk-VJXY5ZCT.js → chunk-52UKFTUK.js} +2 -2
  90. package/dist/{chunk-ESG7Z255.js → chunk-5UDMFE3Q.js} +2 -2
  91. package/dist/{chunk-JPHEOE6Z.js → chunk-6MTSFX7A.js} +15 -15
  92. package/dist/chunk-6ZN34ISG.js +44 -0
  93. package/dist/chunk-6ZN34ISG.js.map +1 -0
  94. package/dist/{chunk-M4MP34AQ.js → chunk-AHZOMHWN.js} +1 -1
  95. package/dist/{chunk-Z3RHPGSY.js → chunk-AIUBBHSF.js} +3 -3
  96. package/dist/{chunk-S3AYIQCU.js → chunk-AXIDQG5A.js} +12 -12
  97. package/dist/{chunk-QN7NTKRC.js → chunk-AZ2QBGYB.js} +1 -1
  98. package/dist/{chunk-47J4EDGR.js → chunk-AZM4CCAC.js} +8 -8
  99. package/dist/{chunk-IXXABW5A.js → chunk-BHXYAVUM.js} +11 -5
  100. package/dist/chunk-BHXYAVUM.js.map +1 -0
  101. package/dist/{chunk-L2DPF4DF.js → chunk-BIJAWZYW.js} +54 -12
  102. package/dist/chunk-BIJAWZYW.js.map +1 -0
  103. package/dist/{chunk-LEJPSMKM.js → chunk-C5QLI33R.js} +3 -3
  104. package/dist/{chunk-SV3PSA7Y.js → chunk-CV6BBVYV.js} +5 -5
  105. package/dist/{chunk-V7X767RT.js → chunk-DCZBSE4F.js} +52 -52
  106. package/dist/chunk-FC67T4E6.js +70 -0
  107. package/dist/chunk-FC67T4E6.js.map +1 -0
  108. package/dist/{chunk-7PKFPLLZ.js → chunk-FXTYIA46.js} +2 -2
  109. package/dist/{chunk-64BHFFKZ.js → chunk-HLYR2TQL.js} +5 -5
  110. package/dist/{chunk-5C2HNJMO.js → chunk-J5LLX6IL.js} +32 -32
  111. package/dist/{chunk-RKNJBZ55.js → chunk-JBPKEARU.js} +4 -4
  112. package/dist/{chunk-PLKFO2HJ.js → chunk-JL43BVDE.js} +2 -2
  113. package/dist/{chunk-2S72LWKX.js → chunk-JYL3BVVZ.js} +2 -2
  114. package/dist/{chunk-IPLYGWQF.js → chunk-KQAFEZQX.js} +5 -5
  115. package/dist/chunk-LXY5VVGM.js +61 -0
  116. package/dist/chunk-LXY5VVGM.js.map +1 -0
  117. package/dist/{chunk-PYKKWQZ2.js → chunk-M7BXDKPR.js} +6 -6
  118. package/dist/{chunk-Z54EM5YZ.js → chunk-MAXVH44E.js} +7 -7
  119. package/dist/{chunk-LYMNZZIM.js → chunk-NIS256NW.js} +2 -2
  120. package/dist/{chunk-67QG75MJ.js → chunk-NLK2VZYZ.js} +2 -2
  121. package/dist/{chunk-A4QMKFFO.js → chunk-O5FFBO2M.js} +14 -28
  122. package/dist/chunk-O5FFBO2M.js.map +1 -0
  123. package/dist/{chunk-JYIFGGEM.js → chunk-OUKBMQ2O.js} +2 -2
  124. package/dist/{chunk-75XOWNRS.js → chunk-OYESWJ43.js} +4 -4
  125. package/dist/{chunk-TS4AJ2GI.js → chunk-PA45XCUD.js} +3 -3
  126. package/dist/{chunk-BJYET5TX.js → chunk-PRDJMOST.js} +7 -1
  127. package/dist/chunk-PRDJMOST.js.map +1 -0
  128. package/dist/{chunk-4MBPIL4V.js → chunk-PUSLMZBQ.js} +2 -2
  129. package/dist/{chunk-RVO6TCTU.js → chunk-QCECHYZL.js} +6 -6
  130. package/dist/{chunk-GFIKG4FR.js → chunk-QGR6OVGT.js} +2 -2
  131. package/dist/{chunk-NSGU76YO.js → chunk-QHFV6VNU.js} +6 -2
  132. package/dist/chunk-QHFV6VNU.js.map +1 -0
  133. package/dist/{chunk-PDEKQWDV.js → chunk-QT2FRYI4.js} +18 -2
  134. package/dist/chunk-QT2FRYI4.js.map +1 -0
  135. package/dist/{chunk-HNZKVLAN.js → chunk-S354QO4R.js} +2 -2
  136. package/dist/{chunk-NO37MR45.js → chunk-SOEN6KCF.js} +2 -2
  137. package/dist/{chunk-FXX6RQYC.js → chunk-TPTECFWR.js} +2 -2
  138. package/dist/{chunk-GDDGZVFI.js → chunk-UEVLYVNW.js} +2 -2
  139. package/dist/{chunk-YQ4IQ2GA.js → chunk-UT5BV5OG.js} +2 -2
  140. package/dist/{chunk-LAQ33B5D.js → chunk-UU3G6GUP.js} +1 -1
  141. package/dist/chunk-UU3G6GUP.js.map +1 -0
  142. package/dist/{chunk-LNTUXKBT.js → chunk-UYYW2KPU.js} +2 -2
  143. package/dist/{chunk-BOFVT6P3.js → chunk-VBHPOWBJ.js} +175 -98
  144. package/dist/chunk-VBHPOWBJ.js.map +1 -0
  145. package/dist/{chunk-QSYL5CXK.js → chunk-VKXWK44Q.js} +3 -3
  146. package/dist/{chunk-KMWYZTIE.js → chunk-VMMQDEN5.js} +2 -2
  147. package/dist/{chunk-JB6D7EFB.js → chunk-VVG2BOKA.js} +2 -2
  148. package/dist/chunk-W5BIQOAJ.js +69 -0
  149. package/dist/chunk-W5BIQOAJ.js.map +1 -0
  150. package/dist/{chunk-V5H6OJCR.js → chunk-W5XVQFLM.js} +2 -2
  151. package/dist/{chunk-OIOZ6MOP.js → chunk-W6FNX2LP.js} +2 -2
  152. package/dist/{chunk-6QPHF6RR.js → chunk-WQM326GS.js} +2 -2
  153. package/dist/{chunk-TQFHQPWD.js → chunk-XADV5IZ3.js} +8 -8
  154. package/dist/{chunk-DATDLJAO.js → chunk-XAPMEU3K.js} +2 -2
  155. package/dist/chunk-XXSOVESA.js +42 -0
  156. package/dist/chunk-XXSOVESA.js.map +1 -0
  157. package/dist/{chunk-IK6X5QPO.js → chunk-ZHY5TMJG.js} +1193 -443
  158. package/dist/chunk-ZHY5TMJG.js.map +1 -0
  159. package/dist/{chunk-N3LL5NEU.js → chunk-ZMYDYNI4.js} +2 -2
  160. package/dist/{cli-D4vvtxjY.d.ts → cli-CnOkH9hA.d.ts} +6 -6
  161. package/dist/cli.d.ts +15 -13
  162. package/dist/cli.js +74 -70
  163. package/dist/coding/pre-action-gate.d.ts +3 -1
  164. package/dist/coding/pre-action-gate.js +2 -2
  165. package/dist/compounding/engine.d.ts +4 -2
  166. package/dist/compounding/engine.js +10 -9
  167. package/dist/compounding/preference-consolidator.d.ts +3 -1
  168. package/dist/compression-optimizer.d.ts +3 -1
  169. package/dist/config.d.ts +3 -1
  170. package/dist/config.js +5 -3
  171. package/dist/connectors/codex-materialize-runner.d.ts +3 -1
  172. package/dist/connectors/codex-materialize-runner.js +10 -9
  173. package/dist/connectors/codex-materialize.d.ts +3 -1
  174. package/dist/connectors/index.d.ts +3 -1
  175. package/dist/connectors/index.js +10 -9
  176. package/dist/consolidation-provenance-check.d.ts +4 -2
  177. package/dist/consolidation-undo.d.ts +4 -2
  178. package/dist/contradiction/index.d.ts +4 -2
  179. package/dist/contradiction-config.d.ts +29 -0
  180. package/dist/contradiction-config.js +12 -0
  181. package/dist/contradiction-config.js.map +1 -0
  182. package/dist/converge-config.d.ts +3 -1
  183. package/dist/convergence-refresh.d.ts +4 -2
  184. package/dist/convergence-refresh.js +12 -11
  185. package/dist/conversation-index/backend.d.ts +3 -1
  186. package/dist/conversation-index/chunker.d.ts +3 -1
  187. package/dist/conversation-index/faiss-adapter.d.ts +3 -1
  188. package/dist/conversation-index/indexer.d.ts +3 -1
  189. package/dist/conversation-index/search.d.ts +3 -1
  190. package/dist/corpus-watermark.d.ts +3 -1
  191. package/dist/corpus-watermark.js +21 -20
  192. package/dist/day-summary.d.ts +3 -1
  193. package/dist/delinearize.d.ts +3 -1
  194. package/dist/dependency-propagation-config.d.ts +3 -1
  195. package/dist/direct-answer-wiring.d.ts +3 -1
  196. package/dist/direct-answer.d.ts +3 -1
  197. package/dist/embedding-fallback.d.ts +3 -1
  198. package/dist/enrichment/index.d.ts +3 -1
  199. package/dist/entity-retrieval.d.ts +4 -2
  200. package/dist/entity-retrieval.js +10 -9
  201. package/dist/entity-schema.d.ts +3 -1
  202. package/dist/explicit-capture.d.ts +11 -9
  203. package/dist/explicit-capture.js +3 -2
  204. package/dist/external-wiki-access.d.ts +13 -11
  205. package/dist/external-wiki-access.js +42 -40
  206. package/dist/external-wiki-collection-registration.d.ts +3 -1
  207. package/dist/external-wiki-collection.d.ts +3 -1
  208. package/dist/external-wiki-mcp-tools.d.ts +13 -11
  209. package/dist/extraction-error-classification.d.ts +3 -1
  210. package/dist/extraction-faithfulness.d.ts +3 -1
  211. package/dist/extraction-judge-telemetry.d.ts +3 -1
  212. package/dist/extraction-judge-training.d.ts +3 -1
  213. package/dist/extraction-judge.d.ts +3 -1
  214. package/dist/extraction-liveness.d.ts +3 -1
  215. package/dist/extraction-normalization.d.ts +3 -1
  216. package/dist/extraction-prompt.d.ts +3 -1
  217. package/dist/extraction-source-grounding-rules.d.ts +3 -1
  218. package/dist/extraction-source-grounding.d.ts +3 -1
  219. package/dist/extraction.d.ts +3 -1
  220. package/dist/extraction.js +22 -21
  221. package/dist/fallback-llm.d.ts +3 -1
  222. package/dist/graph-444E-DrF.d.ts +349 -0
  223. package/dist/graph-dashboard-diff.d.ts +4 -2
  224. package/dist/graph-dashboard-key.d.ts +4 -2
  225. package/dist/graph-dashboard-parser.d.ts +4 -2
  226. package/dist/{graph-edge-decay-Z6ENALU2.js → graph-edge-decay-65KMOJWY.js} +4 -3
  227. package/dist/graph-edge-decay-65KMOJWY.js.map +1 -0
  228. package/dist/graph-edge-reinforcement.d.ts +4 -2
  229. package/dist/graph-path-reconstruction.d.ts +10 -0
  230. package/dist/graph-path-reconstruction.js +12 -0
  231. package/dist/graph-path-reconstruction.js.map +1 -0
  232. package/dist/graph-path-scoring-config.d.ts +8 -0
  233. package/dist/graph-path-scoring-config.js +10 -0
  234. package/dist/graph-path-scoring-config.js.map +1 -0
  235. package/dist/graph-path-scoring.d.ts +36 -0
  236. package/dist/graph-path-scoring.js +11 -0
  237. package/dist/graph-path-scoring.js.map +1 -0
  238. package/dist/graph-snapshot.d.ts +4 -2
  239. package/dist/graph-snapshot.js +3 -2
  240. package/dist/graph.d.ts +5 -318
  241. package/dist/graph.js +5 -1
  242. package/dist/harmonic-retrieval.js +1 -1
  243. package/dist/importance.d.ts +3 -1
  244. package/dist/importers/index.d.ts +3 -1
  245. package/dist/in-flight-reads.d.ts +3 -1
  246. package/dist/index.d.ts +696 -694
  247. package/dist/index.js +149 -144
  248. package/dist/intent.d.ts +3 -1
  249. package/dist/lcm/engine.d.ts +3 -1
  250. package/dist/lcm/engine.js +3 -3
  251. package/dist/lcm/index.d.ts +3 -1
  252. package/dist/lcm/index.js +6 -6
  253. package/dist/lcm/tools.d.ts +3 -1
  254. package/dist/lifecycle.d.ts +3 -1
  255. package/dist/live-connectors-runner.d.ts +3 -1
  256. package/dist/local-llm.d.ts +3 -1
  257. package/dist/local-model-endpoint.d.ts +3 -1
  258. package/dist/maintenance/memory-governance.d.ts +3 -1
  259. package/dist/maintenance/memory-governance.js +10 -9
  260. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +4 -2
  261. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +10 -9
  262. package/dist/maintenance/rebuild-memory-projection.d.ts +4 -2
  263. package/dist/maintenance/rebuild-memory-projection.js +11 -10
  264. package/dist/{maintenance-ClmUVpGI.d.ts → maintenance-CKwxpdRx.d.ts} +3 -3
  265. package/dist/mcp-memory-inspector-app.d.ts +13 -11
  266. package/dist/memory-action-policy.d.ts +3 -1
  267. package/dist/memory-cache.d.ts +3 -1
  268. package/dist/memory-lifecycle-ledger-utils.d.ts +3 -1
  269. package/dist/memory-projection-store.d.ts +3 -1
  270. package/dist/memory-provenance.d.ts +3 -1
  271. package/dist/memory-snapshot.d.ts +3 -1
  272. package/dist/memory-worth-outcomes.d.ts +4 -2
  273. package/dist/models-json.d.ts +3 -1
  274. package/dist/namespaces/migrate.d.ts +5 -3
  275. package/dist/namespaces/migrate.js +20 -19
  276. package/dist/namespaces/principal.d.ts +3 -1
  277. package/dist/namespaces/search.d.ts +3 -1
  278. package/dist/namespaces/search.js +7 -7
  279. package/dist/namespaces/storage.d.ts +5 -3
  280. package/dist/namespaces/storage.js +10 -9
  281. package/dist/native-knowledge.d.ts +3 -1
  282. package/dist/offline-sync-impression-drain.d.ts +3 -1
  283. package/dist/operator-doctor-corpus.d.ts +3 -1
  284. package/dist/operator-doctor-corpus.js +22 -21
  285. package/dist/operator-doctor-replica.d.ts +3 -1
  286. package/dist/operator-toolkit.d.ts +6 -4
  287. package/dist/operator-toolkit.js +33 -29
  288. package/dist/orchestration/compression-guideline-coordinator.d.ts +4 -2
  289. package/dist/orchestration/maintenance.d.ts +6 -4
  290. package/dist/orchestration/maintenance.js +15 -14
  291. package/dist/{orchestrator-qJ07zI8H.d.ts → orchestrator-BshGam-o.d.ts} +45 -19
  292. package/dist/orchestrator.d.ts +11 -9
  293. package/dist/orchestrator.js +109 -104
  294. package/dist/patterns-cli.d.ts +3 -1
  295. package/dist/{pipeline-WFCxhHOn.d.ts → pipeline-D21Rs6gW.d.ts} +1 -1
  296. package/dist/policy-runtime.d.ts +3 -1
  297. package/dist/proactive-contention.d.ts +3 -1
  298. package/dist/provenance.d.ts +3 -1
  299. package/dist/{qmd-5tzkQ44y.d.ts → qmd-Dhle1P4X.d.ts} +1 -1
  300. package/dist/qmd-preflight.d.ts +4 -2
  301. package/dist/qmd-recall-cache.d.ts +3 -1
  302. package/dist/qmd.d.ts +4 -2
  303. package/dist/qmd.js +4 -4
  304. package/dist/recall-concurrency-config.d.ts +3 -1
  305. package/dist/recall-disclosure-escalation.d.ts +3 -1
  306. package/dist/recall-explain-renderer.d.ts +3 -1
  307. package/dist/recall-explain-renderer.js +3 -3
  308. package/dist/recall-memory-map.d.ts +3 -1
  309. package/dist/recall-planner-llm.d.ts +3 -1
  310. package/dist/recall-planner-llm.js +3 -3
  311. package/dist/recall-state.d.ts +7 -1
  312. package/dist/recall-state.js +1 -1
  313. package/dist/recall-tag-filter.d.ts +3 -1
  314. package/dist/recall-timings.d.ts +3 -1
  315. package/dist/recall-xray-cli.d.ts +3 -1
  316. package/dist/recall-xray-cli.js +4 -4
  317. package/dist/recall-xray-renderer.d.ts +3 -1
  318. package/dist/recall-xray-renderer.js +3 -3
  319. package/dist/recall-xray.d.ts +7 -1
  320. package/dist/recall-xray.js +2 -2
  321. package/dist/reconcile/cursor.d.ts +3 -1
  322. package/dist/reconcile/manifest.d.ts +3 -1
  323. package/dist/reconcile/plan.d.ts +3 -1
  324. package/dist/replay/normalizers/chatgpt.d.ts +3 -1
  325. package/dist/replay/normalizers/claude.d.ts +3 -1
  326. package/dist/replay/normalizers/openclaw.d.ts +3 -1
  327. package/dist/replay/normalizers/shared.d.ts +3 -1
  328. package/dist/replay/runner.d.ts +3 -1
  329. package/dist/replay/types.d.ts +3 -1
  330. package/dist/replica-divergence.d.ts +3 -1
  331. package/dist/replica-peers-config.d.ts +3 -1
  332. package/dist/resolve-auth-token.d.ts +3 -1
  333. package/dist/resume-bundles.js +6 -4
  334. package/dist/retrieval-agents.d.ts +4 -2
  335. package/dist/retrieval-tiers.d.ts +3 -1
  336. package/dist/routing/engine.d.ts +3 -1
  337. package/dist/routing/store.d.ts +3 -1
  338. package/dist/salvage-envelope.d.ts +3 -1
  339. package/dist/schemas.d.ts +116 -116
  340. package/dist/{scope-profiles--vfXPl3X.d.ts → scope-profiles-NzGPDXLn.d.ts} +1 -1
  341. package/dist/search/embed-helper.d.ts +3 -1
  342. package/dist/search/factory.d.ts +3 -1
  343. package/dist/search/factory.js +6 -6
  344. package/dist/search/index.d.ts +3 -1
  345. package/dist/search/index.js +12 -12
  346. package/dist/search/lancedb-backend.d.ts +3 -1
  347. package/dist/search/meilisearch-backend.d.ts +3 -1
  348. package/dist/search/noop-backend.d.ts +3 -1
  349. package/dist/search/orama-backend.d.ts +3 -1
  350. package/dist/search/port.d.ts +3 -1
  351. package/dist/search/remote-backend.d.ts +3 -1
  352. package/dist/{semantic-consolidation-BBDuP9nJ.d.ts → semantic-consolidation-DLDKvyy5.d.ts} +1 -1
  353. package/dist/semantic-consolidation.d.ts +4 -2
  354. package/dist/semantic-consolidation.js +11 -10
  355. package/dist/semantic-rule-promotion.js +10 -9
  356. package/dist/semantic-rule-verifier.d.ts +3 -1
  357. package/dist/semantic-rule-verifier.js +10 -9
  358. package/dist/{service-B8DtbpCM.d.ts → service-BIgVM7fL.d.ts} +2 -2
  359. package/dist/session-observer-bands.d.ts +3 -1
  360. package/dist/session-observer-state.d.ts +3 -1
  361. package/dist/shared-context/manager.d.ts +11 -9
  362. package/dist/signal.d.ts +3 -1
  363. package/dist/source-agent-qualifier.d.ts +3 -1
  364. package/dist/source-agent-qualifier.js +18 -17
  365. package/dist/{storage-BkYN1RIy.d.ts → storage-CVfGWqCI.d.ts} +7 -6
  366. package/dist/storage.d.ts +4 -2
  367. package/dist/storage.js +9 -8
  368. package/dist/summarizer.d.ts +3 -1
  369. package/dist/summary-snapshot.d.ts +3 -1
  370. package/dist/temporal-supersession.d.ts +4 -2
  371. package/dist/temporal-timeline-recall.d.ts +3 -1
  372. package/dist/temporal-validity.d.ts +3 -1
  373. package/dist/threading.d.ts +3 -1
  374. package/dist/tier-migration.d.ts +4 -2
  375. package/dist/tier-routing.d.ts +3 -1
  376. package/dist/topics.d.ts +3 -1
  377. package/dist/transcript.d.ts +3 -1
  378. package/dist/transfer/autodetect.js +1 -1
  379. package/dist/transfer/backup.js +1 -1
  380. package/dist/transfer/capsule-export.js +2 -2
  381. package/dist/transfer/types.d.ts +66 -66
  382. package/dist/trust-score-stage.d.ts +3 -1
  383. package/dist/trust-score.d.ts +3 -1
  384. package/dist/{types-u2s9j1uD.d.ts → types-CkiDUorT.d.ts} +10 -16
  385. package/dist/types.d.ts +3 -1
  386. package/dist/types.js +1 -1
  387. package/dist/utility-runtime.d.ts +3 -1
  388. package/dist/verified-recall.js +10 -9
  389. package/dist/write-envelope.d.ts +3 -1
  390. package/package.json +2 -2
  391. package/src/archive-mutation-version.ts +59 -0
  392. package/src/config.test.ts +45 -0
  393. package/src/config.ts +10 -30
  394. package/src/contradiction/contradiction.test.ts +86 -1
  395. package/src/contradiction-config.ts +92 -0
  396. package/src/graph-path-reconstruction.ts +91 -0
  397. package/src/graph-path-scoring-config.ts +55 -0
  398. package/src/graph-path-scoring.test.ts +238 -0
  399. package/src/graph-path-scoring.ts +77 -0
  400. package/src/graph.test.ts +225 -5
  401. package/src/graph.ts +72 -5
  402. package/src/orchestration/contradiction-linking-coordinator.ts +246 -76
  403. package/src/orchestration/contradiction-localization.integration.test.ts +1953 -0
  404. package/src/orchestration/extraction-anchor-snapshot.ts +83 -0
  405. package/src/orchestration/extraction-persist-deps.ts +8 -2
  406. package/src/orchestration/extraction-persist.ts +43 -34
  407. package/src/orchestration/graph-path-state-loader.test.ts +801 -0
  408. package/src/orchestration/graph-path-state-loader.ts +318 -0
  409. package/src/orchestration/graph-recall-coordinator.integration.test.ts +1163 -0
  410. package/src/orchestration/graph-recall-coordinator.ts +206 -29
  411. package/src/orchestration/graph-recall-seam.ts +19 -0
  412. package/src/orchestration/recall-internal-deps.ts +7 -13
  413. package/src/orchestration/recall-internal.ts +5 -0
  414. package/src/orchestration/recall-introspection.ts +9 -1
  415. package/src/orchestration/recall-search-pipeline.ts +8 -13
  416. package/src/orchestration/update-localization.test.ts +784 -0
  417. package/src/orchestration/update-localization.ts +173 -0
  418. package/src/orchestrator.ts +19 -18
  419. package/src/recall-state.test.ts +29 -1
  420. package/src/recall-state.ts +13 -0
  421. package/src/recall-xray-renderer.test.ts +45 -0
  422. package/src/recall-xray-renderer.ts +16 -0
  423. package/src/recall-xray.ts +13 -0
  424. package/src/storage/supersession-side-effects.ts +97 -0
  425. package/src/storage/tombstone-blocked-capture-sync.ts +13 -5
  426. package/src/storage-contract/cache-coherence.test.ts +299 -0
  427. package/src/storage.ts +86 -88
  428. package/src/types.ts +12 -15
  429. package/dist/chunk-A4QMKFFO.js.map +0 -1
  430. package/dist/chunk-BJYET5TX.js.map +0 -1
  431. package/dist/chunk-BOFVT6P3.js.map +0 -1
  432. package/dist/chunk-IK6X5QPO.js.map +0 -1
  433. package/dist/chunk-IXXABW5A.js.map +0 -1
  434. package/dist/chunk-L2DPF4DF.js.map +0 -1
  435. package/dist/chunk-LAQ33B5D.js.map +0 -1
  436. package/dist/chunk-NSGU76YO.js.map +0 -1
  437. package/dist/chunk-PDEKQWDV.js.map +0 -1
  438. /package/dist/{graph-edge-decay-Z6ENALU2.js.map → archive-mutation-version.js.map} +0 -0
  439. /package/dist/{chunk-KDG2KTWW.js.map → chunk-33SV3E43.js.map} +0 -0
  440. /package/dist/{chunk-2HGUDBRJ.js.map → chunk-37ZO6LLJ.js.map} +0 -0
  441. /package/dist/{chunk-QW3WFHKU.js.map → chunk-45BRYON6.js.map} +0 -0
  442. /package/dist/{chunk-GZICBRWK.js.map → chunk-4F6X3RXW.js.map} +0 -0
  443. /package/dist/{chunk-7BAYBYY5.js.map → chunk-4PC4PRJE.js.map} +0 -0
  444. /package/dist/{chunk-VJXY5ZCT.js.map → chunk-52UKFTUK.js.map} +0 -0
  445. /package/dist/{chunk-ESG7Z255.js.map → chunk-5UDMFE3Q.js.map} +0 -0
  446. /package/dist/{chunk-JPHEOE6Z.js.map → chunk-6MTSFX7A.js.map} +0 -0
  447. /package/dist/{chunk-M4MP34AQ.js.map → chunk-AHZOMHWN.js.map} +0 -0
  448. /package/dist/{chunk-Z3RHPGSY.js.map → chunk-AIUBBHSF.js.map} +0 -0
  449. /package/dist/{chunk-S3AYIQCU.js.map → chunk-AXIDQG5A.js.map} +0 -0
  450. /package/dist/{chunk-QN7NTKRC.js.map → chunk-AZ2QBGYB.js.map} +0 -0
  451. /package/dist/{chunk-47J4EDGR.js.map → chunk-AZM4CCAC.js.map} +0 -0
  452. /package/dist/{chunk-LEJPSMKM.js.map → chunk-C5QLI33R.js.map} +0 -0
  453. /package/dist/{chunk-SV3PSA7Y.js.map → chunk-CV6BBVYV.js.map} +0 -0
  454. /package/dist/{chunk-V7X767RT.js.map → chunk-DCZBSE4F.js.map} +0 -0
  455. /package/dist/{chunk-7PKFPLLZ.js.map → chunk-FXTYIA46.js.map} +0 -0
  456. /package/dist/{chunk-64BHFFKZ.js.map → chunk-HLYR2TQL.js.map} +0 -0
  457. /package/dist/{chunk-5C2HNJMO.js.map → chunk-J5LLX6IL.js.map} +0 -0
  458. /package/dist/{chunk-RKNJBZ55.js.map → chunk-JBPKEARU.js.map} +0 -0
  459. /package/dist/{chunk-PLKFO2HJ.js.map → chunk-JL43BVDE.js.map} +0 -0
  460. /package/dist/{chunk-2S72LWKX.js.map → chunk-JYL3BVVZ.js.map} +0 -0
  461. /package/dist/{chunk-IPLYGWQF.js.map → chunk-KQAFEZQX.js.map} +0 -0
  462. /package/dist/{chunk-PYKKWQZ2.js.map → chunk-M7BXDKPR.js.map} +0 -0
  463. /package/dist/{chunk-Z54EM5YZ.js.map → chunk-MAXVH44E.js.map} +0 -0
  464. /package/dist/{chunk-LYMNZZIM.js.map → chunk-NIS256NW.js.map} +0 -0
  465. /package/dist/{chunk-67QG75MJ.js.map → chunk-NLK2VZYZ.js.map} +0 -0
  466. /package/dist/{chunk-JYIFGGEM.js.map → chunk-OUKBMQ2O.js.map} +0 -0
  467. /package/dist/{chunk-75XOWNRS.js.map → chunk-OYESWJ43.js.map} +0 -0
  468. /package/dist/{chunk-TS4AJ2GI.js.map → chunk-PA45XCUD.js.map} +0 -0
  469. /package/dist/{chunk-4MBPIL4V.js.map → chunk-PUSLMZBQ.js.map} +0 -0
  470. /package/dist/{chunk-RVO6TCTU.js.map → chunk-QCECHYZL.js.map} +0 -0
  471. /package/dist/{chunk-GFIKG4FR.js.map → chunk-QGR6OVGT.js.map} +0 -0
  472. /package/dist/{chunk-HNZKVLAN.js.map → chunk-S354QO4R.js.map} +0 -0
  473. /package/dist/{chunk-NO37MR45.js.map → chunk-SOEN6KCF.js.map} +0 -0
  474. /package/dist/{chunk-FXX6RQYC.js.map → chunk-TPTECFWR.js.map} +0 -0
  475. /package/dist/{chunk-GDDGZVFI.js.map → chunk-UEVLYVNW.js.map} +0 -0
  476. /package/dist/{chunk-YQ4IQ2GA.js.map → chunk-UT5BV5OG.js.map} +0 -0
  477. /package/dist/{chunk-LNTUXKBT.js.map → chunk-UYYW2KPU.js.map} +0 -0
  478. /package/dist/{chunk-QSYL5CXK.js.map → chunk-VKXWK44Q.js.map} +0 -0
  479. /package/dist/{chunk-KMWYZTIE.js.map → chunk-VMMQDEN5.js.map} +0 -0
  480. /package/dist/{chunk-JB6D7EFB.js.map → chunk-VVG2BOKA.js.map} +0 -0
  481. /package/dist/{chunk-V5H6OJCR.js.map → chunk-W5XVQFLM.js.map} +0 -0
  482. /package/dist/{chunk-OIOZ6MOP.js.map → chunk-W6FNX2LP.js.map} +0 -0
  483. /package/dist/{chunk-6QPHF6RR.js.map → chunk-WQM326GS.js.map} +0 -0
  484. /package/dist/{chunk-TQFHQPWD.js.map → chunk-XADV5IZ3.js.map} +0 -0
  485. /package/dist/{chunk-DATDLJAO.js.map → chunk-XAPMEU3K.js.map} +0 -0
  486. /package/dist/{chunk-N3LL5NEU.js.map → chunk-ZMYDYNI4.js.map} +0 -0
@@ -534,3 +534,302 @@ test("tier move: cold-to-hot move invalidates cold cache and cannot remain in re
534
534
  await rm(dir, { recursive: true, force: true });
535
535
  }
536
536
  });
537
+
538
+ test("archive mutation version ignores hot and cold writes", async () => {
539
+ const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-archive-version-"));
540
+ try {
541
+ resetStaticCaches();
542
+ const storage = new StorageManager(dir);
543
+ await storage.ensureDirectories();
544
+ const initial = storage.getArchiveMutationVersion();
545
+
546
+ const { id } = await storage.writeMemory("fact", "archive version probe");
547
+ assert.equal(storage.getArchiveMutationVersion(), initial);
548
+
549
+ const coldInvalidator = storage as unknown as {
550
+ invalidateColdMemoriesCache: () => void;
551
+ };
552
+ coldInvalidator.invalidateColdMemoriesCache();
553
+ assert.equal(storage.getArchiveMutationVersion(), initial);
554
+
555
+ const memory = await storage.getMemoryById(id);
556
+ assert.ok(memory);
557
+ assert.ok(await storage.archiveMemory(memory));
558
+ assert.ok(storage.getArchiveMutationVersion() > initial);
559
+ } finally {
560
+ resetStaticCaches();
561
+ await rm(dir, { recursive: true, force: true });
562
+ }
563
+ });
564
+ test("archive version advances when a tier move commits archive write before source delete fails", async () => {
565
+ const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-archive-partial-move-"));
566
+ try {
567
+ resetStaticCaches();
568
+ const storage = new StorageManager(dir);
569
+ await storage.ensureDirectories();
570
+ const { id } = await storage.writeMemory("fact", "archive move partial");
571
+ const memory = await storage.getMemoryById(id);
572
+ assert.ok(memory);
573
+ const targetPath = path.join(dir, "archive", "partial", path.basename(memory.path));
574
+ const initial = storage.getArchiveMutationVersion();
575
+ const internals = storage as unknown as {
576
+ deleteManagedStorageFile: (filePath: string) => Promise<boolean>;
577
+ };
578
+ const originalDelete = internals.deleteManagedStorageFile.bind(storage);
579
+ internals.deleteManagedStorageFile = async (filePath) => {
580
+ if (path.resolve(filePath) === path.resolve(memory.path)) {
581
+ throw new Error("forced archive source delete failure");
582
+ }
583
+ return originalDelete(filePath);
584
+ };
585
+ await assert.rejects(storage.moveMemoryToPath(memory, targetPath), /forced archive source delete failure/);
586
+ assert.ok(storage.getArchiveMutationVersion() > initial);
587
+ assert.ok((await readFile(targetPath, "utf8")).includes("archive move partial"));
588
+ } finally {
589
+ resetStaticCaches();
590
+ await rm(dir, { recursive: true, force: true });
591
+ }
592
+ });
593
+
594
+ test("archive version advances when archive write commits before source delete fails", async () => {
595
+ const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-archive-partial-archive-"));
596
+ try {
597
+ resetStaticCaches();
598
+ const storage = new StorageManager(dir);
599
+ await storage.ensureDirectories();
600
+ const { id } = await storage.writeMemory("fact", "archive write partial");
601
+ const memory = await storage.getMemoryById(id);
602
+ assert.ok(memory);
603
+ const initial = storage.getArchiveMutationVersion();
604
+ const internals = storage as unknown as {
605
+ deleteManagedStorageFile: (filePath: string) => Promise<boolean>;
606
+ };
607
+ const originalDelete = internals.deleteManagedStorageFile.bind(storage);
608
+ internals.deleteManagedStorageFile = async (filePath) => {
609
+ if (path.resolve(filePath) === path.resolve(memory.path)) {
610
+ throw new Error("forced archive source delete failure");
611
+ }
612
+ return originalDelete(filePath);
613
+ };
614
+ const result = await storage.archiveMemory(memory, { at: new Date("2026-01-02T00:00:00.000Z") });
615
+ assert.equal(result, null);
616
+ assert.ok(storage.getArchiveMutationVersion() > initial);
617
+ assert.ok((await readFile(path.join(dir, "archive", "2026-01-02", path.basename(memory.path)), "utf8")).includes("archive write partial"));
618
+ } finally {
619
+ resetStaticCaches();
620
+ await rm(dir, { recursive: true, force: true });
621
+ }
622
+ });
623
+
624
+ test("archive version advances when invalidateMemory deletes an archive path", async () => {
625
+
626
+ const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-archive-invalidate-"));
627
+ try {
628
+ resetStaticCaches();
629
+ const storage = new StorageManager(dir);
630
+ await storage.ensureDirectories();
631
+ const { id } = await storage.writeMemory("fact", "archive invalidation");
632
+ const memory = await storage.getMemoryById(id);
633
+ assert.ok(memory);
634
+ const archivedPath = await storage.archiveMemory(memory, { at: new Date("2026-01-03T00:00:00.000Z") });
635
+ assert.ok(archivedPath);
636
+ const archived = (await storage.readArchivedMemories()).find((candidate) => candidate.frontmatter.id === id);
637
+ assert.ok(archived);
638
+ const internals = storage as unknown as {
639
+ readAllMemories: () => Promise<unknown[]>;
640
+ };
641
+ internals.readAllMemories = async () => [archived];
642
+ const initial = storage.getArchiveMutationVersion();
643
+ assert.equal(await storage.invalidateMemory(id), true);
644
+ assert.ok(storage.getArchiveMutationVersion() > initial);
645
+ } finally {
646
+ resetStaticCaches();
647
+ await rm(dir, { recursive: true, force: true });
648
+ }
649
+ });
650
+ test("invalidateMemory returns false without side effects when the target is already absent", async () => {
651
+ const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-invalidate-absent-"));
652
+ try {
653
+ resetStaticCaches();
654
+ const storage = new StorageManager(dir);
655
+ await storage.ensureDirectories();
656
+ const { id } = await storage.writeMemory("fact", "already absent");
657
+ const memory = await storage.getMemoryById(id);
658
+ assert.ok(memory);
659
+ const initialStatus = storage.getMemoryStatusVersion();
660
+ await rm(memory.path);
661
+ assert.equal(await storage.invalidateMemory(id), false);
662
+ assert.equal(storage.getMemoryStatusVersion(), initialStatus);
663
+ } finally {
664
+ resetStaticCaches();
665
+ await rm(dir, { recursive: true, force: true });
666
+ }
667
+ });
668
+
669
+ test("archive generation advances once per archive file mutation", async () => {
670
+ const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-archive-version-delta-"));
671
+ try {
672
+ resetStaticCaches();
673
+ const storage = new StorageManager(dir);
674
+ await storage.ensureDirectories();
675
+ const { id } = await storage.writeMemory("fact", "archive generation deltas");
676
+ const memory = await storage.getMemoryById(id);
677
+ assert.ok(memory);
678
+ const initial = storage.getArchiveMutationVersion();
679
+
680
+ const firstArchivePath = path.join(dir, "archive", "2026-01-06", path.basename(memory.path));
681
+ assert.equal(await storage.moveMemoryToPath(memory, firstArchivePath), true);
682
+ const afterHotToArchive = storage.getArchiveMutationVersion();
683
+ assert.equal(afterHotToArchive - initial, 1);
684
+
685
+ const archived = (await storage.readArchivedMemories()).find((candidate) => candidate.frontmatter.id === id);
686
+ assert.ok(archived);
687
+ const secondArchivePath = path.join(dir, "archive", "2026-01-07", path.basename(archived.path));
688
+ assert.equal(await storage.moveMemoryToPath(archived, secondArchivePath), true);
689
+ const afterArchiveToArchive = storage.getArchiveMutationVersion();
690
+ assert.equal(afterArchiveToArchive - afterHotToArchive, 2);
691
+
692
+ const movedArchive = (await storage.readArchivedMemories()).find((candidate) => candidate.frontmatter.id === id);
693
+ assert.ok(movedArchive);
694
+ assert.equal(await storage.moveMemoryToPath(movedArchive, storage.buildTierMemoryPath(movedArchive, "hot")), true);
695
+ assert.equal(storage.getArchiveMutationVersion() - afterArchiveToArchive, 1);
696
+ } finally {
697
+ resetStaticCaches();
698
+ await rm(dir, { recursive: true, force: true });
699
+ }
700
+ });
701
+
702
+ test("maintenance deletion keeps a non-matching archive memory", async () => {
703
+ const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-archive-maintenance-guard-"));
704
+ try {
705
+ resetStaticCaches();
706
+ const storage = new StorageManager(dir);
707
+ await storage.ensureDirectories();
708
+ const { id } = await storage.writeMemory("fact", "archive maintenance guard");
709
+ const memory = await storage.getMemoryById(id);
710
+ assert.ok(memory);
711
+ assert.ok(await storage.archiveMemory(memory, { at: new Date("2026-01-05T00:00:00.000Z") }));
712
+ const archived = (await storage.readArchivedMemories()).find((candidate) => candidate.frontmatter.id === id);
713
+ assert.ok(archived);
714
+ const initial = storage.getArchiveMutationVersion();
715
+ assert.equal(await storage.deleteMemoryForMaintenance(archived, () => false), null);
716
+ assert.equal(storage.getArchiveMutationVersion(), initial);
717
+ assert.ok((await readFile(archived.path, "utf8")).includes("archive maintenance guard"));
718
+ } finally {
719
+ resetStaticCaches();
720
+ await rm(dir, { recursive: true, force: true });
721
+ }
722
+ });
723
+
724
+ test("archive version advances when maintenance deletes an archive path", async () => {
725
+ const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-archive-maintenance-delete-"));
726
+ try {
727
+ resetStaticCaches();
728
+ const storage = new StorageManager(dir);
729
+ await storage.ensureDirectories();
730
+ const { id } = await storage.writeMemory("fact", "archive maintenance delete");
731
+ const memory = await storage.getMemoryById(id);
732
+ assert.ok(memory);
733
+ assert.ok(await storage.archiveMemory(memory, { at: new Date("2026-01-04T00:00:00.000Z") }));
734
+ const archived = (await storage.readArchivedMemories()).find((candidate) => candidate.frontmatter.id === id);
735
+ assert.ok(archived);
736
+ const initial = storage.getArchiveMutationVersion();
737
+ const removed = await storage.deleteMemoryForMaintenance(archived);
738
+ assert.ok(removed);
739
+ assert.equal(removed.frontmatter.id, id);
740
+ assert.ok(storage.getArchiveMutationVersion() > initial);
741
+ } finally {
742
+ resetStaticCaches();
743
+ await rm(dir, { recursive: true, force: true });
744
+ }
745
+ });
746
+
747
+ test("archive mutation version advances once for an offline archive write", async () => {
748
+ const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-offline-archive-write-"));
749
+ try {
750
+ resetStaticCaches();
751
+ const storage = new StorageManager(dir);
752
+ await storage.ensureDirectories();
753
+ const archivePath = path.join(dir, "archive", "2026-01-08", "offline-write.md");
754
+ const content = [
755
+ "---",
756
+ "id: offline-archive-write",
757
+ "category: fact",
758
+ "---",
759
+ "offline archive write",
760
+ ].join("\n");
761
+ const initial = storage.getArchiveMutationVersion();
762
+
763
+ await storage.writeOfflineSyncFile(archivePath, Buffer.from(content));
764
+
765
+ assert.equal(storage.getArchiveMutationVersion() - initial, 1);
766
+
767
+ const hotPath = path.join(dir, "facts", "offline-hot-write.md");
768
+ const beforeHot = storage.getArchiveMutationVersion();
769
+ await storage.writeOfflineSyncFile(
770
+ hotPath,
771
+ Buffer.from(["---", "id: offline-hot-write", "category: fact", "---", "offline hot write"].join("\n")),
772
+ );
773
+ assert.equal(storage.getArchiveMutationVersion() - beforeHot, 0);
774
+ } finally {
775
+ resetStaticCaches();
776
+ await rm(dir, { recursive: true, force: true });
777
+ }
778
+ });
779
+
780
+ test("archive mutation version advances once for an offline chunked archive write", async () => {
781
+ const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-offline-archive-chunks-"));
782
+ try {
783
+ resetStaticCaches();
784
+ const storage = new StorageManager(dir);
785
+ await storage.ensureDirectories();
786
+ const archivePath = path.join(dir, "archive", "2026-01-09", "offline-chunks.md");
787
+ const content = Buffer.from(
788
+ ["---", "id: offline-archive-chunks", "category: fact", "---", "offline chunked archive write"].join("\n"),
789
+ );
790
+ const initial = storage.getArchiveMutationVersion();
791
+
792
+ await storage.writeOfflineSyncFileChunks(
793
+ archivePath,
794
+ (async function* () {
795
+ yield content.subarray(0, 17);
796
+ yield content.subarray(17);
797
+ })(),
798
+ );
799
+
800
+ assert.equal(storage.getArchiveMutationVersion() - initial, 1);
801
+ } finally {
802
+ resetStaticCaches();
803
+ await rm(dir, { recursive: true, force: true });
804
+ }
805
+ });
806
+
807
+ test("archive mutation version advances once for an offline archive delete", async () => {
808
+ const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-offline-archive-delete-"));
809
+ try {
810
+ resetStaticCaches();
811
+ const storage = new StorageManager(dir);
812
+ await storage.ensureDirectories();
813
+ const archivePath = path.join(dir, "archive", "2026-01-10", "offline-delete.md");
814
+ const content = [
815
+ "---",
816
+ "id: offline-archive-delete",
817
+ "category: fact",
818
+ "---",
819
+ "offline archive delete",
820
+ ].join("\n");
821
+ await storage.writeOfflineSyncFile(archivePath, Buffer.from(content));
822
+ const initial = storage.getArchiveMutationVersion();
823
+
824
+ await storage.deleteOfflineSyncFile(archivePath);
825
+
826
+ assert.equal(storage.getArchiveMutationVersion() - initial, 1);
827
+ const statusBeforeRetry = storage.getMemoryStatusVersion();
828
+ await storage.deleteOfflineSyncFile(archivePath);
829
+ assert.equal(storage.getArchiveMutationVersion() - initial, 1);
830
+ assert.ok(storage.getMemoryStatusVersion() > statusBeforeRetry);
831
+ } finally {
832
+ resetStaticCaches();
833
+ await rm(dir, { recursive: true, force: true });
834
+ }
835
+ });
package/src/storage.ts CHANGED
@@ -79,6 +79,7 @@ import {
79
79
  deleteInFlightReadsForDir,
80
80
  clearInFlightReads,
81
81
  } from "./in-flight-reads.js";
82
+ import * as archive from "./archive-mutation-version.js";
82
83
  import { rotateMarkdownFileToArchive } from "./hygiene.js";
83
84
  import { sanitizeMemoryContent } from "./sanitize.js";
84
85
  import { withholdToolScopedFromSharedNamespace } from "./tool-scoped-memory.js";
@@ -125,7 +126,6 @@ import {
125
126
  import {
126
127
  TombstoneStore,
127
128
  collectRetiredMemoriesForRebuild,
128
- buildRetiredFactTombstoneInputs,
129
129
  type TombstoneStoreOptions,
130
130
  type TombstoneFileIo,
131
131
  type TombstoneReason,
@@ -133,6 +133,7 @@ import {
133
133
  type TombstoneStats,
134
134
  } from "./lifecycle/tombstones.js";
135
135
  import { supersessionKeysForFact } from "./temporal-supersession.js";
136
+ import { runSupersessionSideEffects } from "./storage/supersession-side-effects.js";
136
137
  import type {
137
138
  AccessTrackingEntry,
138
139
  BufferState,
@@ -2401,15 +2402,18 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
2401
2402
  return this.readSharedVersion("memory-corpus", StorageManager.memoryCorpusVersionByDir);
2402
2403
  }
2403
2404
 
2405
+ /**
2406
+ * Bump only — NOT invalidateAllForDir (that would drop the very hot
2407
+ * entry the write path just patched).
2408
+ */
2404
2409
  protected bumpMemoryCorpusVersion(): void {
2405
- // Bump only — NOT invalidateAllForDir (that would drop the very hot
2406
- // entry the write path just patched).
2407
2410
  this.bumpSharedVersion("memory-corpus", StorageManager.memoryCorpusVersionByDir);
2408
2411
  // Drop the in-flight readAllMemories slot (#1902): a concurrent read
2409
2412
  // must not attach to a scan that began BEFORE this mutation. (The patch
2410
2413
  // path uses bumpMemoryCorpusVersionExclusive and clears the slot itself.)
2411
2414
  deleteInFlightReadsForDir(this.baseDir);
2412
2415
  }
2416
+ getArchiveMutationVersion(): number { return archive.getArchiveMutationVersionForDir(this.baseDir); }
2413
2417
 
2414
2418
  /**
2415
2419
  * Corpus bump reporting whether THIS process's append was the only one
@@ -4569,16 +4573,19 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
4569
4573
  invalidateMemoryCachesForTiers(tiers: Iterable<"hot" | "cold" | "archive">): void {
4570
4574
  let hotChanged = false;
4571
4575
  let coldChanged = false;
4576
+ let archiveChanged = false;
4572
4577
  for (const tier of tiers) {
4573
4578
  if (tier === "cold") {
4574
4579
  coldChanged = true;
4575
- } else if (tier === "hot" || tier === "archive") {
4580
+ } else if (tier === "archive") {
4581
+ hotChanged = true;
4582
+ archiveChanged = true;
4583
+ } else if (tier === "hot") {
4576
4584
  hotChanged = true;
4577
4585
  }
4578
4586
  }
4579
- if (hotChanged) {
4580
- this.invalidateAllMemoriesCache();
4581
- }
4587
+ if (hotChanged) this.invalidateAllMemoriesCache();
4588
+ archive.bumpArchiveMutationIfChanged(this.baseDir, archiveChanged);
4582
4589
  if (coldChanged) {
4583
4590
  this.invalidateColdMemoriesCache();
4584
4591
  }
@@ -5140,6 +5147,7 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
5140
5147
  this.notifyCatalogWrite();
5141
5148
  }
5142
5149
  async moveMemoryToPath(memory: MemoryFile, targetPath: string): Promise<boolean> {
5150
+ const { recordArchiveDelete, recordArchiveWrite } = archive;
5143
5151
  const changed = await this.withTombstoneBlockedMemoryPathLock(
5144
5152
  memory.path,
5145
5153
  async (current) => {
@@ -5168,12 +5176,12 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
5168
5176
  let durable = false;
5169
5177
  try {
5170
5178
  if (destination?.frontmatter.id === current.frontmatter.id) {
5171
- await this.deleteManagedStorageFile(current.path);
5179
+ await recordArchiveDelete(this.baseDir, current.path, () => this.deleteManagedStorageFile(current.path));
5172
5180
  durable = true;
5173
5181
  this.invalidateAllMemoriesCache();
5174
5182
  updateProjectedMemoryPath(this.baseDir, current.frontmatter.id, projectedPath);
5175
5183
  } else {
5176
- await this.writeMemoryFileAtomic(targetPath, current);
5184
+ await recordArchiveWrite(this.baseDir, targetPath, () => this.writeMemoryFileAtomic(targetPath, current));
5177
5185
  if (memory.frontmatter.entityRef !== current.frontmatter.entityRef) {
5178
5186
  memory.frontmatter.entityRef = current.frontmatter.entityRef;
5179
5187
  }
@@ -5181,7 +5189,7 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
5181
5189
  const sourcePath = path.resolve(current.path);
5182
5190
  const destPath = path.resolve(targetPath);
5183
5191
  if (sourcePath !== destPath) {
5184
- await this.deleteManagedStorageFile(current.path);
5192
+ await recordArchiveDelete(this.baseDir, current.path, () => this.deleteManagedStorageFile(current.path));
5185
5193
  this.invalidateAllMemoriesCache();
5186
5194
  updateProjectedMemoryPath(this.baseDir, current.frontmatter.id, projectedPath);
5187
5195
  }
@@ -5228,6 +5236,7 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
5228
5236
  * Returns the new file path on success, null on failure.
5229
5237
  */
5230
5238
  async archiveMemory(memory: MemoryFile, lifecycle?: MemoryLifecycleEventWriteOptions): Promise<string | null> {
5239
+ const { recordArchiveDelete, recordArchiveWrite } = archive;
5231
5240
  const archiveCurrent = async (current: MemoryFile, markDurable: () => void): Promise<string | null> => {
5232
5241
  try {
5233
5242
  const now = lifecycle?.at ?? new Date();
@@ -5250,7 +5259,7 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
5250
5259
  // Snapshot a pre-existing destination (retried archive) so a repair
5251
5260
  // failure restores it instead of deleting the only archived copy (§14).
5252
5261
  const priorDest = await this.readStorageSecureFile(destPath).catch(() => null);
5253
- await this.writeStorageSecureFile(destPath, fileContent);
5262
+ await recordArchiveWrite(this.baseDir, destPath, () => this.writeStorageSecureFile(destPath, fileContent));
5254
5263
  if (typeof current.frontmatter.entityRef === "string") {
5255
5264
  try {
5256
5265
  await this.entityRefRepair.repair(
@@ -5261,17 +5270,27 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
5261
5270
  current.content
5262
5271
  );
5263
5272
  } catch (err) {
5264
- // Restore/remove the destination before reporting failure (§14):
5265
- // a retained fresh copy would surface the memory in BOTH scans.
5266
5273
  if (priorDest === null) {
5267
- await unlink(destPath).catch(() => undefined);
5274
+ await recordArchiveDelete(this.baseDir, destPath, () =>
5275
+ unlink(destPath).then(
5276
+ () => true,
5277
+ () => false
5278
+ )
5279
+ );
5268
5280
  } else {
5269
- await this.writeStorageSecureFile(destPath, priorDest).catch(() => undefined);
5281
+ await recordArchiveDelete(this.baseDir, destPath, () =>
5282
+ this.writeStorageSecureFile(destPath, priorDest).then(
5283
+ () => true,
5284
+ () => false
5285
+ )
5286
+ );
5270
5287
  }
5271
5288
  throw err;
5272
5289
  }
5273
5290
  }
5274
- if (!(await this.deleteManagedStorageFile(current.path))) return null;
5291
+ const deleted = await recordArchiveDelete(this.baseDir, current.path, () =>
5292
+ this.deleteManagedStorageFile(current.path));
5293
+ if (!deleted) return null;
5275
5294
  markDurable();
5276
5295
  markProjectedMemoryPathInvalid(this.baseDir, current.frontmatter.id);
5277
5296
  this.invalidateAllMemoriesCache();
@@ -5370,7 +5389,9 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
5370
5389
  if (!memory) return false;
5371
5390
 
5372
5391
  return await this.runTombstoneBlockedInvalidation(memory, async (current, rebuildMarker, markDurable) => {
5373
- if (!(await this.deleteManagedStorageFile(current.path))) return false;
5392
+ const deleted = await archive.recordArchiveDelete(this.baseDir, current.path, () =>
5393
+ this.deleteManagedStorageFile(current.path));
5394
+ if (!deleted) return false;
5374
5395
  markDurable();
5375
5396
  markProjectedMemoryPathInvalid(this.baseDir, id);
5376
5397
  this.invalidateAllMemoriesCache();
@@ -6987,26 +7008,34 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
6987
7008
  .sort((a, b) => (a.frontmatter.chunkIndex ?? 0) - (b.frontmatter.chunkIndex ?? 0));
6988
7009
  }
6989
7010
 
6990
- // ---------------------------------------------------------------------------
6991
- // Contradiction Detection (Phase 2B)
6992
- // ---------------------------------------------------------------------------
6993
-
6994
- /**
6995
- * Mark a memory as superseded by another.
6996
- * Updates the old memory's status and adds the supersededBy link.
6997
- */
6998
7011
  async supersedeMemory(oldMemoryId: string, newMemoryId: string, reason: string): Promise<boolean> {
6999
7012
  const memories = await this.readAllMemories();
7000
- const oldMemory = memories.find((m) => m.frontmatter.id === oldMemoryId);
7013
+ let oldMemory = memories.find(
7014
+ (memory) =>
7015
+ memory.frontmatter.id === oldMemoryId &&
7016
+ inferMemoryStatus(memory.frontmatter, toMemoryPathRel(this.baseDir, memory.path)) === "active",
7017
+ );
7018
+ if (!oldMemory) {
7019
+ oldMemory = (await this.readAllColdMemories()).find(
7020
+ (memory) =>
7021
+ memory.frontmatter.id === oldMemoryId &&
7022
+ inferMemoryStatus(memory.frontmatter, toMemoryPathRel(this.baseDir, memory.path)) === "active",
7023
+ );
7024
+ }
7001
7025
  if (!oldMemory) return false;
7002
7026
 
7003
7027
  const now = new Date().toISOString();
7004
7028
  let currentBefore = oldMemory;
7005
7029
  let updatedFm = oldMemory.frontmatter;
7006
7030
 
7007
- try {
7008
- const written = await this.withTombstoneBlockedMemoryPathLock(oldMemory.path, async (current) => {
7031
+ const written = await this.withTombstoneBlockedMemoryPathLock(oldMemory.path, async (current) => {
7009
7032
  if (current?.frontmatter.id !== oldMemoryId) return false;
7033
+ if (
7034
+ current.frontmatter.supersededBy !== undefined ||
7035
+ inferMemoryStatus(current.frontmatter, toMemoryPathRel(this.baseDir, current.path)) !== "active"
7036
+ ) {
7037
+ return false;
7038
+ }
7010
7039
  currentBefore = current;
7011
7040
  const refIdsAtWrite = this.currentHistoricalIds();
7012
7041
  updatedFm = entityRefs.canonicalizeEntityRefOption(
@@ -7026,67 +7055,36 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
7026
7055
  );
7027
7056
  }
7028
7057
  return true;
7029
- });
7030
- if (!written) return false;
7031
- // Advance the corpus sentinel immediately after the on-disk write, BEFORE
7032
- // the awaited lifecycle append (Cursor Medium, #1902). Otherwise a warm
7033
- // hot-memories cache keeps serving the pre-supersede snapshot during the
7034
- // await window; bumpMemoryStatusVersion() below additionally invalidates
7035
- // the entity cache for the status change.
7036
- this.bumpMemoryCorpusVersion();
7037
- await this.appendGeneratedMemoryLifecycleEventFailOpen("storage.supersedeMemory", {
7038
- memoryId: oldMemoryId,
7039
- eventType: "superseded",
7040
- timestamp: now,
7041
- actor: "storage.supersedeMemory",
7042
- reasonCode: reason,
7043
- before: this.summarizeLifecycleState(currentBefore.frontmatter, currentBefore.path),
7044
- after: this.summarizeLifecycleState(updatedFm, currentBefore.path),
7045
- relatedMemoryIds: [newMemoryId],
7046
- });
7047
- this.bumpMemoryStatusVersion();
7048
- log.debug(`superseded memory ${oldMemoryId} by ${newMemoryId}: ${reason}`);
7049
-
7050
- // #1579 — every contradiction verb (keep-a/keep-b/merge) funnels here,
7051
- // so emitting covers each exactly once (rule 22); facts only. One
7052
- // tombstone PER derived supersession key (thread Oci-Y) so a
7053
- // paraphrased re-write is caught on the keyed tier.
7054
- if (currentBefore.frontmatter.category === "fact") {
7055
- for (const input of buildRetiredFactTombstoneInputs(
7056
- {
7057
- id: oldMemoryId,
7058
- content: stripCitationForTemplate(currentBefore.content, this.citationTemplate),
7059
- contentHash: currentBefore.frontmatter.contentHash,
7060
- entityRef: updatedFm.entityRef,
7061
- structuredAttributes: currentBefore.frontmatter.structuredAttributes,
7062
- },
7063
- {
7064
- reason: "contradiction_resolution",
7065
- createdBy: "contradiction_resolution",
7066
- createdAt: now,
7067
- supersessionKeysForFact,
7068
- }
7069
- )) {
7070
- await this.appendTombstone(input);
7071
- }
7072
- }
7073
-
7074
- // Audit-trail correction — sealed even INSIDE the engine (#2022 review).
7075
- const auditBody = `Superseded: ${currentBefore.content}\n\nReason: ${reason}`;
7076
- const auditInput = {
7077
- content: auditBody,
7078
- category: "correction" as const,
7079
- confidence: 1.0,
7080
- tags: ["supersession", "auto-resolved"],
7081
- };
7082
- const auditEnvelope = composeMemoryEnvelope(auditInput, { source: "contradiction-detection" });
7083
- await this.writeSealedMemory(auditEnvelope, { lineage: [oldMemoryId, newMemoryId] });
7058
+ }).catch((err) => { log.error(`failed to supersede memory ${oldMemoryId}:`, err); return false; });
7059
+ if (!written) return false;
7060
+ await runSupersessionSideEffects({
7061
+ oldMemoryId,
7062
+ newMemoryId,
7063
+ reason,
7064
+ now,
7065
+ currentBefore,
7066
+ updatedFm,
7067
+ citationTemplate: this.citationTemplate,
7068
+ isColdOrArchiveTierPath: (memoryPath) => this.isColdOrArchiveTierPath(memoryPath),
7069
+ invalidateColdMemoriesCache: () => this.invalidateColdMemoriesCache(),
7070
+ bumpMemoryCorpusVersion: () => this.bumpMemoryCorpusVersion(),
7071
+ appendLifecycleEvent: () =>
7072
+ this.appendGeneratedMemoryLifecycleEventFailOpen("storage.supersedeMemory", {
7073
+ memoryId: oldMemoryId,
7074
+ eventType: "superseded",
7075
+ timestamp: now,
7076
+ actor: "storage.supersedeMemory",
7077
+ reasonCode: reason,
7078
+ before: this.summarizeLifecycleState(currentBefore.frontmatter, currentBefore.path),
7079
+ after: this.summarizeLifecycleState(updatedFm, currentBefore.path),
7080
+ relatedMemoryIds: [newMemoryId],
7081
+ }),
7082
+ bumpMemoryStatusVersion: () => this.bumpMemoryStatusVersion(),
7083
+ appendTombstone: (input) => this.appendTombstone(input),
7084
+ writeSealedMemory: (envelope, extras) => this.writeSealedMemory(envelope, extras),
7085
+ });
7084
7086
 
7085
- return true;
7086
- } catch (err) {
7087
- log.error(`failed to supersede memory ${oldMemoryId}:`, err);
7088
- return false;
7089
- }
7087
+ return true;
7090
7088
  }
7091
7089
 
7092
7090
  // ---------------------------------------------------------------------------
package/src/types.ts CHANGED
@@ -5,6 +5,10 @@ import type { WearablesConfig } from "./wearables/types.js";
5
5
  import type { ExtractionLivenessConfig } from "./extraction-liveness.js";
6
6
  import type { ReplicaPeersConfig } from "./replica-peers-config.js";
7
7
  import type { ExternalWikiRoot } from "./external-wiki-config.js";
8
+ import type { ContradictionLocalizationConfig, ContradictionScanConfig } from "./contradiction-config.js";
9
+ import type { GraphPathScoringConfig } from "./graph-path-scoring-config.js";
10
+ export type { ContradictionLocalizationConfig, ContradictionScanConfig } from "./contradiction-config.js";
11
+ export type { GraphPathScoringConfig } from "./graph-path-scoring-config.js";
8
12
 
9
13
  import type { AmbientCaptureProvenance, BufferTurnOwner } from "./buffer-turn-helpers.js";
10
14
  export type ReasoningEffort = "none" | "low" | "medium" | "high";
@@ -609,21 +613,6 @@ export interface ScopeTeamConfig {
609
613
  promote: string[];
610
614
  }
611
615
 
612
- /** Configuration for the nightly contradiction-scan cron (issue #520). */
613
- export interface ContradictionScanConfig {
614
- /** Master switch for the contradiction scan cron. Default true. */
615
- enabled: boolean;
616
- /** Embedding cosine similarity floor for candidate pair generation. Default 0.82. */
617
- similarityFloor: number;
618
- /** Minimum topic-token Jaccard overlap for unstructured pairs. Default 0.4. */
619
- topicOverlapFloor: number;
620
- /** Cap on candidate pairs evaluated per cron run. Default 500. */
621
- maxPairsPerRun: number;
622
- /** Cooldown in days before re-evaluating a pair judged independent/both-valid. Default 14. */
623
- cooldownDays: number;
624
- /** When true, pairs judged "duplicates" are auto-flagged for dedup (still need user approval). Default false. */
625
- autoMergeDuplicates: boolean;
626
- }
627
616
  export interface DependencyPropagationConfig {
628
617
  /** Master switch. Default false. */
629
618
  enabled: boolean;
@@ -684,6 +673,7 @@ export interface SemanticChunkingConfigShape {
684
673
  fallbackToRecursive: boolean;
685
674
  }
686
675
 
676
+
687
677
  export interface PluginConfig extends BoundedJsonlStateConfig {
688
678
  openaiApiKey: string | undefined;
689
679
  openaiBaseUrl: string | undefined;
@@ -860,6 +850,8 @@ export interface PluginConfig extends BoundedJsonlStateConfig {
860
850
  contradictionAutoResolve: boolean;
861
851
  /** Nightly contradiction-scan cron config (issue #520). */
862
852
  contradictionScan: ContradictionScanConfig;
853
+ /** Anchor-first contradiction candidate localization settings (issue #2327). */
854
+ contradictionLocalization: ContradictionLocalizationConfig;
863
855
  /** One-hop dependency invalidation propagation settings (issue #2326). */
864
856
  dependencyPropagation: DependencyPropagationConfig;
865
857
  // Temporal Supersession (issue #375)
@@ -2101,6 +2093,7 @@ export interface PluginConfig extends BoundedJsonlStateConfig {
2101
2093
  causalGraphEnabled: boolean;
2102
2094
  maxGraphTraversalSteps: number;
2103
2095
  graphActivationDecay: number;
2096
+ graphPathScoring: GraphPathScoringConfig;
2104
2097
  /** Weight of graph activation score when blending with seed QMD score (0-1). */
2105
2098
  graphExpansionActivationWeight: number;
2106
2099
  /** Lower bound for blended graph-expanded recall scores (0-1). */
@@ -3476,6 +3469,10 @@ export interface QmdSearchResult {
3476
3469
  transport?: "daemon" | "subprocess" | "hybrid" | "scoped_prefilter";
3477
3470
  /** Namespace that owned this result when returned by a namespace fanout search. */
3478
3471
  namespace?: string;
3472
+ /** Graph activation path evidence from opt-in path scoring. */
3473
+ pathNodeIds?: string[];
3474
+ /** True when a graph path penalty was applied. */
3475
+ pathPenaltyApplied?: boolean;
3479
3476
  sourceConnector?: string;
3480
3477
  }
3481
3478