@remnic/core 9.45.0 → 9.45.2

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 (387) hide show
  1. package/dist/access-admin-ops-surface.d.ts +10 -10
  2. package/dist/access-admin-ops-surface.js +25 -25
  3. package/dist/access-audit.js +2 -2
  4. package/dist/access-authorization-probe.d.ts +10 -10
  5. package/dist/access-authorization-probe.js +26 -26
  6. package/dist/access-boundary.d.ts +10 -10
  7. package/dist/access-boundary.js +25 -25
  8. package/dist/access-cli.js +69 -68
  9. package/dist/access-cli.js.map +1 -1
  10. package/dist/access-extraction-force-flush.d.ts +10 -10
  11. package/dist/access-extraction-force-flush.js +25 -25
  12. package/dist/access-health-types.d.ts +1 -1
  13. package/dist/access-http-lcm-compaction.d.ts +10 -10
  14. package/dist/access-http-lifecycle-flush.d.ts +10 -10
  15. package/dist/access-http-query.js +25 -25
  16. package/dist/access-http.d.ts +10 -10
  17. package/dist/access-http.js +34 -34
  18. package/dist/access-identity-continuity-surface.d.ts +8 -8
  19. package/dist/access-identity-continuity-surface.js +25 -25
  20. package/dist/access-lcm-surface.d.ts +10 -10
  21. package/dist/access-lcm-surface.js +25 -25
  22. package/dist/access-mcp.d.ts +10 -10
  23. package/dist/access-mcp.js +30 -30
  24. package/dist/access-memory-search-fanout.d.ts +2 -2
  25. package/dist/{access-namespace-preflight-47dOyty9.d.ts → access-namespace-preflight-5yZ4g6F8.d.ts} +1 -1
  26. package/dist/access-namespace-preflight.d.ts +3 -3
  27. package/dist/access-namespace-preflight.js +25 -25
  28. package/dist/access-observe-write-surface.d.ts +10 -10
  29. package/dist/access-observe-write-surface.js +25 -25
  30. package/dist/access-operations-batch.js +27 -27
  31. package/dist/access-operations.d.ts +10 -10
  32. package/dist/access-operations.js +29 -29
  33. package/dist/access-recall-concurrency.d.ts +10 -10
  34. package/dist/access-recall-concurrency.js +25 -25
  35. package/dist/access-recall-response.d.ts +10 -10
  36. package/dist/access-recall-response.js +25 -25
  37. package/dist/access-recall-surface.d.ts +10 -10
  38. package/dist/access-recall-surface.js +25 -25
  39. package/dist/access-schema.js +3 -3
  40. package/dist/{access-service-DBo88Dmm.d.ts → access-service-CiJRsgAB.d.ts} +7 -7
  41. package/dist/access-service-helpers.d.ts +10 -10
  42. package/dist/access-service.d.ts +10 -10
  43. package/dist/access-service.js +25 -25
  44. package/dist/access-surface-catalog.d.ts +10 -10
  45. package/dist/access-wearables-meetings-surface.d.ts +3 -3
  46. package/dist/action-confidence.d.ts +1 -1
  47. package/dist/active-memory-bridge.d.ts +1 -1
  48. package/dist/active-recall.d.ts +1 -1
  49. package/dist/active-recall.js +3 -2
  50. package/dist/active-recall.js.map +1 -1
  51. package/dist/adapters/index.js +4 -4
  52. package/dist/adapters/registry.js +2 -2
  53. package/dist/behavior-learner.d.ts +1 -1
  54. package/dist/behavior-signals.d.ts +1 -1
  55. package/dist/bootstrap.d.ts +8 -8
  56. package/dist/briefing.d.ts +2 -2
  57. package/dist/briefing.js +8 -8
  58. package/dist/buffer-surprise-report.d.ts +1 -1
  59. package/dist/buffer-turn-helpers.d.ts +1 -1
  60. package/dist/buffer.d.ts +2 -2
  61. package/dist/bulk-import/index.d.ts +3 -3
  62. package/dist/calibration.d.ts +1 -1
  63. package/dist/capabilities.d.ts +1 -1
  64. package/dist/{catalog-DPQynQZG.d.ts → catalog-scBmy0sO.d.ts} +1 -1
  65. package/dist/causal-behavior.d.ts +1 -1
  66. package/dist/causal-behavior.js +2 -2
  67. package/dist/causal-chain.js +2 -2
  68. package/dist/causal-consolidation.d.ts +1 -1
  69. package/dist/causal-consolidation.js +11 -11
  70. package/dist/causal-retrieval.js +2 -2
  71. package/dist/causal-trajectory-graph.d.ts +1 -1
  72. package/dist/causal-trajectory-graph.js +2 -2
  73. package/dist/causal-trajectory.js +1 -1
  74. package/dist/{chunk-GBJJUPNV.js → chunk-33PLLLL7.js} +2 -2
  75. package/dist/{chunk-ZAB5PG65.js → chunk-3F2LKUMU.js} +2 -2
  76. package/dist/{chunk-TXBU7YDV.js → chunk-3TBLDMJA.js} +2 -2
  77. package/dist/{chunk-6UWB5PTR.js → chunk-4L6HUREQ.js} +54 -24
  78. package/dist/chunk-4L6HUREQ.js.map +1 -0
  79. package/dist/{chunk-FLBPATMZ.js → chunk-4UH4BTGK.js} +33 -33
  80. package/dist/{chunk-TVVEYCNW.js → chunk-7K5Q6COX.js} +4 -4
  81. package/dist/{chunk-K6OTW3TP.js → chunk-A5OJCXZL.js} +2 -2
  82. package/dist/{chunk-QQ3NDJOM.js → chunk-AAIUERNB.js} +2 -2
  83. package/dist/{chunk-C7EI7CA6.js → chunk-BJKPPZ6Z.js} +2 -2
  84. package/dist/{chunk-65V4K4MT.js → chunk-CJ2ZR7UA.js} +17 -17
  85. package/dist/{chunk-TM72UOX2.js → chunk-CUM2BBPN.js} +5 -1
  86. package/dist/chunk-CUM2BBPN.js.map +1 -0
  87. package/dist/{chunk-GQBZ7EVF.js → chunk-D3J5SLQK.js} +2 -2
  88. package/dist/{chunk-3HLCRYBV.js → chunk-DL7ZD3JH.js} +3 -3
  89. package/dist/{chunk-ZPJJE7MF.js → chunk-DNWXFTLD.js} +2 -2
  90. package/dist/{chunk-YQQK7W7T.js → chunk-E53DSZEN.js} +2 -2
  91. package/dist/{chunk-6OLQJJYE.js → chunk-E5UK4VPE.js} +2 -2
  92. package/dist/{chunk-3HKQOFOV.js → chunk-E6PNLPGJ.js} +19 -19
  93. package/dist/{chunk-Z54EM5YZ.js → chunk-GF22HWS2.js} +4 -4
  94. package/dist/chunk-HBVPYRDW.js +39 -0
  95. package/dist/chunk-HBVPYRDW.js.map +1 -0
  96. package/dist/{chunk-W6ROK2KU.js → chunk-HNZKVLAN.js} +2 -2
  97. package/dist/{chunk-GDC4INBF.js → chunk-HO3QBJEY.js} +2 -2
  98. package/dist/{chunk-U5G66ORD.js → chunk-HREE4JHI.js} +48 -48
  99. package/dist/{chunk-GSL47NPM.js → chunk-J7VGGECD.js} +1 -1
  100. package/dist/chunk-J7VGGECD.js.map +1 -0
  101. package/dist/{chunk-RKNJBZ55.js → chunk-JBPKEARU.js} +4 -4
  102. package/dist/{chunk-7PVFOFPJ.js → chunk-JE7EK33X.js} +2 -2
  103. package/dist/{chunk-WG2PI44B.js → chunk-JVLCVFQ4.js} +2 -2
  104. package/dist/{chunk-UZGJFIIG.js → chunk-JYIFGGEM.js} +2 -2
  105. package/dist/{chunk-IPLYGWQF.js → chunk-KQAFEZQX.js} +5 -5
  106. package/dist/{chunk-3SHB4YAW.js → chunk-L2DPF4DF.js} +4 -4
  107. package/dist/{chunk-VRYJSKOM.js → chunk-LZ4LDKHZ.js} +2 -2
  108. package/dist/{chunk-PO5LSKQO.js → chunk-MU7ZHSZE.js} +2 -2
  109. package/dist/{chunk-CAGPP5NB.js → chunk-NRV4Y3PM.js} +1 -1
  110. package/dist/{chunk-SS7YWVPF.js → chunk-OAEQLRCY.js} +2 -2
  111. package/dist/{chunk-FVGQ5LIS.js → chunk-OQ5PRDDS.js} +2 -2
  112. package/dist/{chunk-5YGO5VEH.js → chunk-P4DRWEYC.js} +2 -2
  113. package/dist/{chunk-XMZV27S5.js → chunk-PDLBLTOK.js} +2 -2
  114. package/dist/{chunk-VCGPO2VD.js → chunk-PKNLM44P.js} +4 -4
  115. package/dist/{chunk-XFQRFWVS.js → chunk-QN25OCUF.js} +2 -2
  116. package/dist/{chunk-J4OKD6QX.js → chunk-RN7DY3FC.js} +5 -5
  117. package/dist/{chunk-7JO6RVBI.js → chunk-S2NCTZGJ.js} +4 -4
  118. package/dist/{chunk-R4Q7CQGZ.js → chunk-TDHTVMPG.js} +2 -2
  119. package/dist/{chunk-FXGLFGIG.js → chunk-TIHMZFIV.js} +3 -3
  120. package/dist/{chunk-ZS5UZU5M.js → chunk-U7GW7NE7.js} +7 -7
  121. package/dist/{chunk-WC4SPYHX.js → chunk-UVIKWC7M.js} +10 -10
  122. package/dist/{chunk-2QR2RRH6.js → chunk-UYLMNVY6.js} +4 -4
  123. package/dist/{chunk-G24XIK6H.js → chunk-VUPTKTDV.js} +2 -2
  124. package/dist/{chunk-GOPWZYZH.js → chunk-VWAXN2BN.js} +8 -8
  125. package/dist/{chunk-JZ7SSAQ5.js → chunk-XYTOI63Z.js} +3 -3
  126. package/dist/{cli-DQ4VhjqX.d.ts → cli-BUGN3d6_.d.ts} +5 -5
  127. package/dist/cli.d.ts +12 -12
  128. package/dist/cli.js +52 -51
  129. package/dist/compounding/engine.d.ts +2 -2
  130. package/dist/compounding/engine.js +8 -8
  131. package/dist/compounding/preference-consolidator.d.ts +1 -1
  132. package/dist/compression-optimizer.d.ts +1 -1
  133. package/dist/config.d.ts +1 -1
  134. package/dist/config.js +3 -2
  135. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  136. package/dist/connectors/codex-materialize-runner.js +8 -8
  137. package/dist/connectors/codex-materialize.d.ts +1 -1
  138. package/dist/connectors/index.d.ts +1 -1
  139. package/dist/connectors/index.js +8 -8
  140. package/dist/consolidation-provenance-check.d.ts +2 -2
  141. package/dist/consolidation-undo.d.ts +2 -2
  142. package/dist/contradiction/index.d.ts +2 -2
  143. package/dist/converge-config.d.ts +11 -0
  144. package/dist/converge-config.js +12 -0
  145. package/dist/convergence-refresh.d.ts +2 -2
  146. package/dist/convergence-refresh.js +10 -10
  147. package/dist/conversation-index/backend.d.ts +1 -1
  148. package/dist/conversation-index/chunker.d.ts +1 -1
  149. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  150. package/dist/conversation-index/indexer.d.ts +1 -1
  151. package/dist/conversation-index/search.d.ts +1 -1
  152. package/dist/corpus-watermark.d.ts +1 -1
  153. package/dist/corpus-watermark.js +10 -10
  154. package/dist/day-summary.d.ts +1 -1
  155. package/dist/delinearize.d.ts +1 -1
  156. package/dist/direct-answer-wiring.d.ts +1 -1
  157. package/dist/direct-answer.d.ts +1 -1
  158. package/dist/embedding-fallback.d.ts +1 -1
  159. package/dist/enrichment/index.d.ts +1 -1
  160. package/dist/entity-retrieval.d.ts +2 -2
  161. package/dist/entity-retrieval.js +8 -8
  162. package/dist/entity-schema.d.ts +1 -1
  163. package/dist/explicit-capture.d.ts +8 -8
  164. package/dist/extraction-error-classification.d.ts +1 -1
  165. package/dist/extraction-faithfulness.d.ts +1 -1
  166. package/dist/extraction-judge-telemetry.d.ts +1 -1
  167. package/dist/extraction-judge-training.d.ts +1 -1
  168. package/dist/extraction-judge.d.ts +1 -1
  169. package/dist/extraction-liveness.d.ts +1 -1
  170. package/dist/extraction-source-grounding-rules.d.ts +1 -1
  171. package/dist/extraction-source-grounding.d.ts +1 -1
  172. package/dist/extraction.d.ts +1 -1
  173. package/dist/extraction.js +10 -10
  174. package/dist/fallback-llm.d.ts +1 -1
  175. package/dist/graph-dashboard-diff.d.ts +1 -1
  176. package/dist/graph-dashboard-key.d.ts +1 -1
  177. package/dist/graph-dashboard-parser.d.ts +1 -1
  178. package/dist/{graph-edge-decay-GF3ZSGSP.js → graph-edge-decay-Z6ENALU2.js} +4 -4
  179. package/dist/graph-edge-decay-Z6ENALU2.js.map +1 -0
  180. package/dist/graph-edge-reinforcement.d.ts +1 -1
  181. package/dist/graph-snapshot.d.ts +1 -1
  182. package/dist/graph-snapshot.js +3 -3
  183. package/dist/graph.d.ts +1 -1
  184. package/dist/graph.js +2 -2
  185. package/dist/importance.d.ts +1 -1
  186. package/dist/importers/index.d.ts +1 -1
  187. package/dist/in-flight-reads.d.ts +1 -1
  188. package/dist/index.d.ts +20 -19
  189. package/dist/index.js +77 -71
  190. package/dist/intent.d.ts +1 -1
  191. package/dist/lcm/engine.d.ts +1 -1
  192. package/dist/lcm/engine.js +2 -2
  193. package/dist/lcm/index.d.ts +1 -1
  194. package/dist/lcm/index.js +4 -4
  195. package/dist/lcm/tools.d.ts +1 -1
  196. package/dist/lifecycle.d.ts +1 -1
  197. package/dist/live-connectors-runner.d.ts +1 -1
  198. package/dist/local-llm.d.ts +1 -1
  199. package/dist/local-model-endpoint.d.ts +1 -1
  200. package/dist/maintenance/memory-governance.d.ts +1 -1
  201. package/dist/maintenance/memory-governance.js +8 -8
  202. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
  203. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +8 -8
  204. package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
  205. package/dist/maintenance/rebuild-memory-projection.js +9 -9
  206. package/dist/{maintenance-_RV38GlE.d.ts → maintenance-LbuS2rUA.d.ts} +3 -3
  207. package/dist/mcp-memory-inspector-app.d.ts +10 -10
  208. package/dist/memory-action-policy.d.ts +1 -1
  209. package/dist/memory-cache.d.ts +1 -1
  210. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  211. package/dist/memory-projection-store.d.ts +1 -1
  212. package/dist/memory-provenance.d.ts +1 -1
  213. package/dist/memory-worth-outcomes.d.ts +2 -2
  214. package/dist/models-json.d.ts +1 -1
  215. package/dist/namespaces/migrate.d.ts +3 -3
  216. package/dist/namespaces/migrate.js +9 -9
  217. package/dist/namespaces/principal.d.ts +1 -1
  218. package/dist/namespaces/search.d.ts +1 -1
  219. package/dist/namespaces/storage.d.ts +3 -3
  220. package/dist/namespaces/storage.js +8 -8
  221. package/dist/native-knowledge.d.ts +1 -1
  222. package/dist/offline-sync-impression-drain.d.ts +1 -1
  223. package/dist/operator-doctor-corpus.d.ts +1 -1
  224. package/dist/operator-doctor-corpus.js +11 -11
  225. package/dist/operator-doctor-replica.d.ts +1 -1
  226. package/dist/operator-toolkit.d.ts +3 -3
  227. package/dist/operator-toolkit.js +19 -18
  228. package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
  229. package/dist/orchestration/maintenance.d.ts +4 -4
  230. package/dist/orchestration/maintenance.js +13 -13
  231. package/dist/{orchestrator-B2ecFpRO.d.ts → orchestrator-rHiWt32X.d.ts} +7 -7
  232. package/dist/orchestrator.d.ts +8 -8
  233. package/dist/orchestrator.js +69 -68
  234. package/dist/patterns-cli.d.ts +1 -1
  235. package/dist/{pipeline-Cs76XC-p.d.ts → pipeline-W_97O8BV.d.ts} +1 -1
  236. package/dist/policy-runtime.d.ts +1 -1
  237. package/dist/proactive-contention.d.ts +1 -1
  238. package/dist/provenance.d.ts +1 -1
  239. package/dist/{qmd-WJwvBgiF.d.ts → qmd-LWtMofAf.d.ts} +1 -1
  240. package/dist/qmd-preflight.d.ts +2 -2
  241. package/dist/qmd-recall-cache.d.ts +1 -1
  242. package/dist/qmd.d.ts +2 -2
  243. package/dist/recall-concurrency-config.d.ts +1 -1
  244. package/dist/recall-disclosure-escalation.d.ts +1 -1
  245. package/dist/recall-explain-renderer.d.ts +1 -1
  246. package/dist/recall-explain-renderer.js +3 -3
  247. package/dist/recall-memory-map.d.ts +1 -1
  248. package/dist/recall-planner-llm.d.ts +1 -1
  249. package/dist/recall-state.d.ts +1 -1
  250. package/dist/recall-tag-filter.d.ts +1 -1
  251. package/dist/recall-timings.d.ts +1 -1
  252. package/dist/recall-xray-cli.d.ts +1 -1
  253. package/dist/recall-xray-cli.js +4 -4
  254. package/dist/recall-xray-renderer.d.ts +1 -1
  255. package/dist/recall-xray-renderer.js +3 -3
  256. package/dist/recall-xray.d.ts +1 -1
  257. package/dist/recall-xray.js +2 -2
  258. package/dist/reconcile/cursor.d.ts +11 -1
  259. package/dist/reconcile/cursor.js +54 -0
  260. package/dist/reconcile/cursor.js.map +1 -1
  261. package/dist/reconcile/manifest.d.ts +3 -3
  262. package/dist/reconcile/manifest.js +42 -4
  263. package/dist/reconcile/manifest.js.map +1 -1
  264. package/dist/reconcile/plan.d.ts +32 -21
  265. package/dist/reconcile/plan.js +2 -1
  266. package/dist/replay/normalizers/chatgpt.d.ts +1 -1
  267. package/dist/replay/normalizers/claude.d.ts +1 -1
  268. package/dist/replay/normalizers/openclaw.d.ts +1 -1
  269. package/dist/replay/normalizers/shared.d.ts +1 -1
  270. package/dist/replay/runner.d.ts +1 -1
  271. package/dist/replay/types.d.ts +1 -1
  272. package/dist/replica-divergence.d.ts +1 -1
  273. package/dist/replica-peers-config.d.ts +1 -1
  274. package/dist/resolve-auth-token.d.ts +1 -1
  275. package/dist/resume-bundles.js +4 -3
  276. package/dist/retrieval-agents.d.ts +2 -2
  277. package/dist/retrieval-tiers.d.ts +1 -1
  278. package/dist/routing/engine.d.ts +1 -1
  279. package/dist/routing/store.d.ts +1 -1
  280. package/dist/salvage-envelope.d.ts +1 -1
  281. package/dist/{scope-profiles-CQ0NAleS.d.ts → scope-profiles-BiQKOE-p.d.ts} +1 -1
  282. package/dist/search/embed-helper.d.ts +1 -1
  283. package/dist/search/factory.d.ts +1 -1
  284. package/dist/search/index.d.ts +1 -1
  285. package/dist/search/lancedb-backend.d.ts +1 -1
  286. package/dist/search/meilisearch-backend.d.ts +1 -1
  287. package/dist/search/noop-backend.d.ts +1 -1
  288. package/dist/search/orama-backend.d.ts +1 -1
  289. package/dist/search/port.d.ts +1 -1
  290. package/dist/search/remote-backend.d.ts +1 -1
  291. package/dist/{semantic-consolidation-BWxOBMtz.d.ts → semantic-consolidation-dHYCyqgh.d.ts} +1 -1
  292. package/dist/semantic-consolidation.d.ts +2 -2
  293. package/dist/semantic-consolidation.js +9 -9
  294. package/dist/semantic-rule-promotion.js +8 -8
  295. package/dist/semantic-rule-verifier.d.ts +1 -1
  296. package/dist/semantic-rule-verifier.js +8 -8
  297. package/dist/{service-DW06sY3P.d.ts → service-DJG3KCQ4.d.ts} +2 -2
  298. package/dist/session-observer-bands.d.ts +1 -1
  299. package/dist/session-observer-state.d.ts +1 -1
  300. package/dist/shared-context/manager.d.ts +1 -1
  301. package/dist/signal.d.ts +1 -1
  302. package/dist/source-agent-qualifier.d.ts +1 -1
  303. package/dist/source-agent-qualifier.js +8 -8
  304. package/dist/{storage-qRIQPA6F.d.ts → storage-F9FVh-w9.d.ts} +1 -1
  305. package/dist/storage.d.ts +2 -2
  306. package/dist/storage.js +7 -7
  307. package/dist/summarizer.d.ts +1 -1
  308. package/dist/summary-snapshot.d.ts +1 -1
  309. package/dist/temporal-supersession.d.ts +2 -2
  310. package/dist/temporal-timeline-recall.d.ts +1 -1
  311. package/dist/temporal-validity.d.ts +1 -1
  312. package/dist/threading.d.ts +1 -1
  313. package/dist/tier-migration.d.ts +2 -2
  314. package/dist/tier-routing.d.ts +1 -1
  315. package/dist/topics.d.ts +1 -1
  316. package/dist/transcript.d.ts +1 -1
  317. package/dist/transfer/autodetect.js +1 -1
  318. package/dist/transfer/backup.js +1 -1
  319. package/dist/transfer/capsule-export.js +2 -2
  320. package/dist/trust-score-stage.d.ts +1 -1
  321. package/dist/trust-score.d.ts +1 -1
  322. package/dist/{types-CqWwMPr_.d.ts → types-rEwubvim.d.ts} +6 -1
  323. package/dist/types.d.ts +1 -1
  324. package/dist/types.js +1 -1
  325. package/dist/utility-runtime.d.ts +1 -1
  326. package/dist/verified-recall.js +8 -8
  327. package/dist/write-envelope.d.ts +1 -1
  328. package/package.json +2 -2
  329. package/src/config.test.ts +24 -0
  330. package/src/config.ts +3 -0
  331. package/src/converge-config.ts +39 -0
  332. package/src/index.ts +1 -2
  333. package/src/reconcile/cursor.test.ts +30 -0
  334. package/src/reconcile/cursor.ts +63 -0
  335. package/src/reconcile/manifest.test.ts +93 -2
  336. package/src/reconcile/manifest.ts +56 -3
  337. package/src/reconcile/plan.test.ts +40 -52
  338. package/src/reconcile/plan.ts +95 -61
  339. package/src/types.ts +5 -0
  340. package/dist/chunk-6UWB5PTR.js.map +0 -1
  341. package/dist/chunk-GSL47NPM.js.map +0 -1
  342. package/dist/chunk-TM72UOX2.js.map +0 -1
  343. /package/dist/{chunk-GBJJUPNV.js.map → chunk-33PLLLL7.js.map} +0 -0
  344. /package/dist/{chunk-ZAB5PG65.js.map → chunk-3F2LKUMU.js.map} +0 -0
  345. /package/dist/{chunk-TXBU7YDV.js.map → chunk-3TBLDMJA.js.map} +0 -0
  346. /package/dist/{chunk-FLBPATMZ.js.map → chunk-4UH4BTGK.js.map} +0 -0
  347. /package/dist/{chunk-TVVEYCNW.js.map → chunk-7K5Q6COX.js.map} +0 -0
  348. /package/dist/{chunk-K6OTW3TP.js.map → chunk-A5OJCXZL.js.map} +0 -0
  349. /package/dist/{chunk-QQ3NDJOM.js.map → chunk-AAIUERNB.js.map} +0 -0
  350. /package/dist/{chunk-C7EI7CA6.js.map → chunk-BJKPPZ6Z.js.map} +0 -0
  351. /package/dist/{chunk-65V4K4MT.js.map → chunk-CJ2ZR7UA.js.map} +0 -0
  352. /package/dist/{chunk-GQBZ7EVF.js.map → chunk-D3J5SLQK.js.map} +0 -0
  353. /package/dist/{chunk-3HLCRYBV.js.map → chunk-DL7ZD3JH.js.map} +0 -0
  354. /package/dist/{chunk-ZPJJE7MF.js.map → chunk-DNWXFTLD.js.map} +0 -0
  355. /package/dist/{chunk-YQQK7W7T.js.map → chunk-E53DSZEN.js.map} +0 -0
  356. /package/dist/{chunk-6OLQJJYE.js.map → chunk-E5UK4VPE.js.map} +0 -0
  357. /package/dist/{chunk-3HKQOFOV.js.map → chunk-E6PNLPGJ.js.map} +0 -0
  358. /package/dist/{chunk-Z54EM5YZ.js.map → chunk-GF22HWS2.js.map} +0 -0
  359. /package/dist/{chunk-W6ROK2KU.js.map → chunk-HNZKVLAN.js.map} +0 -0
  360. /package/dist/{chunk-GDC4INBF.js.map → chunk-HO3QBJEY.js.map} +0 -0
  361. /package/dist/{chunk-U5G66ORD.js.map → chunk-HREE4JHI.js.map} +0 -0
  362. /package/dist/{chunk-RKNJBZ55.js.map → chunk-JBPKEARU.js.map} +0 -0
  363. /package/dist/{chunk-7PVFOFPJ.js.map → chunk-JE7EK33X.js.map} +0 -0
  364. /package/dist/{chunk-WG2PI44B.js.map → chunk-JVLCVFQ4.js.map} +0 -0
  365. /package/dist/{chunk-UZGJFIIG.js.map → chunk-JYIFGGEM.js.map} +0 -0
  366. /package/dist/{chunk-IPLYGWQF.js.map → chunk-KQAFEZQX.js.map} +0 -0
  367. /package/dist/{chunk-3SHB4YAW.js.map → chunk-L2DPF4DF.js.map} +0 -0
  368. /package/dist/{chunk-VRYJSKOM.js.map → chunk-LZ4LDKHZ.js.map} +0 -0
  369. /package/dist/{chunk-PO5LSKQO.js.map → chunk-MU7ZHSZE.js.map} +0 -0
  370. /package/dist/{chunk-CAGPP5NB.js.map → chunk-NRV4Y3PM.js.map} +0 -0
  371. /package/dist/{chunk-SS7YWVPF.js.map → chunk-OAEQLRCY.js.map} +0 -0
  372. /package/dist/{chunk-FVGQ5LIS.js.map → chunk-OQ5PRDDS.js.map} +0 -0
  373. /package/dist/{chunk-5YGO5VEH.js.map → chunk-P4DRWEYC.js.map} +0 -0
  374. /package/dist/{chunk-XMZV27S5.js.map → chunk-PDLBLTOK.js.map} +0 -0
  375. /package/dist/{chunk-VCGPO2VD.js.map → chunk-PKNLM44P.js.map} +0 -0
  376. /package/dist/{chunk-XFQRFWVS.js.map → chunk-QN25OCUF.js.map} +0 -0
  377. /package/dist/{chunk-J4OKD6QX.js.map → chunk-RN7DY3FC.js.map} +0 -0
  378. /package/dist/{chunk-7JO6RVBI.js.map → chunk-S2NCTZGJ.js.map} +0 -0
  379. /package/dist/{chunk-R4Q7CQGZ.js.map → chunk-TDHTVMPG.js.map} +0 -0
  380. /package/dist/{chunk-FXGLFGIG.js.map → chunk-TIHMZFIV.js.map} +0 -0
  381. /package/dist/{chunk-ZS5UZU5M.js.map → chunk-U7GW7NE7.js.map} +0 -0
  382. /package/dist/{chunk-WC4SPYHX.js.map → chunk-UVIKWC7M.js.map} +0 -0
  383. /package/dist/{chunk-2QR2RRH6.js.map → chunk-UYLMNVY6.js.map} +0 -0
  384. /package/dist/{chunk-G24XIK6H.js.map → chunk-VUPTKTDV.js.map} +0 -0
  385. /package/dist/{chunk-GOPWZYZH.js.map → chunk-VWAXN2BN.js.map} +0 -0
  386. /package/dist/{chunk-JZ7SSAQ5.js.map → chunk-XYTOI63Z.js.map} +0 -0
  387. /package/dist/{graph-edge-decay-GF3ZSGSP.js.map → converge-config.js.map} +0 -0
package/dist/types.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { aS as AccessTrackingEntry, a1 as ActiveRecallChatType, a5 as ActiveRecallModelFallbackPolicy, a3 as ActiveRecallPromptStyle, a2 as ActiveRecallQueryMode, a4 as ActiveRecallThinking, t as AgentAccessAuthToken, co as AgentAccessHttpConfig, cp as AgentDefaultsConfig, cq as AgentPersona, A as AgentPersonaModelConfig, cr as BehaviorLoopAdjustment, r as BehaviorLoopPolicyState, cs as BehaviorSignalDirection, a6 as BehaviorSignalEvent, ct as BehaviorSignalType, bb as BootstrapOptions, bc as BootstrapResult, g as BriefingActiveThread, cu as BriefingCalendarSourceError, bw as BriefingConfig, e as BriefingFocus, d as BriefingFollowup, bx as BriefingOpenCommitment, i as BriefingRecentEntity, h as BriefingResult, B as BriefingSections, by as BriefingWindow, cv as BufferEntryState, aO as BufferState, a7 as BufferSurpriseEvent, j as BufferTurn, f as CalendarEvent, C as CalendarSource, w as CaptureMode, cw as ChatConfig, m as Checkpoint, cx as CodexCliReasoningEffort, cy as CodexCompactionFlushMode, bB as CodexCompatConfig, cz as CodexConnectorConfig, b8 as CodingContext, cA as CodingGraphLspConfig, bk as CodingKnowledgeConfig, be as CodingModeConfig, cB as CompressionGuidelineActivationState, ad as CompressionGuidelineOptimizerActionSummary, ac as CompressionGuidelineOptimizerEventCounts, ae as CompressionGuidelineOptimizerRuleUpdate, cC as CompressionGuidelineOptimizerSourceWindow, ah as CompressionGuidelineOptimizerState, cD as ConfidenceTier, cE as ConsolidationAction, cF as ConsolidationItem, bd as ConsolidationObservation, K as ConsolidationResult, cG as ContradictionScanConfig, V as ConversationThread, cH as CronConversationRecallMode, cI as CronRecallMode, bC as DEFAULT_RECALL_DISCLOSURE, N as DaySummaryResult, cJ as DreamingConfig, cK as DreamingNarrativePromptStyle, cL as DreamsDeepSleepConfig, cM as DreamsLightSleepConfig, D as DreamsPhase, cN as DreamsPhaseStatus, cO as DreamsPhasesConfig, cP as DreamsRemConfig, a as DreamsRunResult, b9 as DreamsStatusResult, cQ as EngramTraceEvent, aR as EntityActivityEntry, E as EntityFile, ai as EntityMention, aQ as EntityRelationship, aj as EntitySchemaDefinition, ak as EntitySchemaSectionDefinition, al as EntityStructuredSection, aM as EntityTimelineEntry, bE as ExtractedFact, cR as ExtractedProcedureStep, cS as ExtractedQuestion, cT as ExtractedReasoningTrace, cU as ExtractedReasoningTraceStep, cV as ExtractedRelationship, $ as ExtractionFailureClass, cW as ExtractionPassSource, J as ExtractionResult, F as FaithfulnessFrontmatter, aP as FileHygieneConfig, G as GatewayConfig, cX as GitHubLiveConnectorConfig, cY as GmailLiveConnectorConfig, cZ as GoogleDriveLiveConnectorConfig, c_ as HeartbeatConfig, c$ as HeartbeatDetectionMode, H as HourlySummary, I as IdentityInjectionMode, a0 as ImportanceLevel, an as ImportanceScore, W as LifecycleState, L as LiveConnectorsConfig, d0 as LlmTraceCallback, d1 as LlmTraceEvent, ap as MemoryActionEligibilityContext, bN as MemoryActionEligibilitySource, ag as MemoryActionEvent, d2 as MemoryActionOutcome, d3 as MemoryActionPolicyDecision, aq as MemoryActionPolicyResult, d4 as MemoryActionStatus, af as MemoryActionType, v as MemoryCategory, M as MemoryFile, l as MemoryFrontmatter, ao as MemoryIntent, z as MemoryLifecycleEvent, ar as MemoryLifecycleEventType, as as MemoryLifecycleStateSummary, aN as MemoryLink, d5 as MemoryLinkType, bO as MemoryObservation, d6 as MemoryOsPresetName, y as MemoryProjectionCurrentState, bP as MemoryScope, x as MemoryStatus, aT as MemorySummary, aw as MetaState, d7 as ModelApi, d8 as ModelDefinitionConfig, d9 as ModelProviderAuthMode, at as ModelProviderConfig, da as NamespacePolicy, au as NativeKnowledgeConfig, db as NativeKnowledgeFolderRuleConfig, dc as NativeKnowledgeObsidianVaultConfig, dd as NativeKnowledgeOpenClawWorkspaceConfig, de as NotionLiveConnectorConfig, P as PluginConfig, Y as PolicyClass, df as PrincipalFromSessionKeyMode, dg as PrincipalRule, dh as ProceduralConfig, am as ProvenanceConfig, O as ProvenanceSource, aB as QmdSearchExplain, Q as QmdSearchResult, di as QuestionEntry, bQ as RECALL_DISCLOSURE_LEVELS, dj as ReasoningEffort, b as RecallDisclosure, dk as RecallPipelineConfig, R as RecallPlanMode, ba as RecallSectionConfig, c as RecallTierExplain, dl as RecallTraceEvent, dm as RelevanceFeedback, ay as RetrievalTier, dn as SPECULATIVE_TTL_DAYS, dp as ScopeProfileAutoPromoteConfig, o as ScopeProfileConfig, p as ScopeProfileLayerId, q as ScopeProfilePromotionTarget, dq as ScopeProfileTeamProjectConfig, dr as ScopeTeamConfig, ds as ScoredEntity, s as SecretRef, dt as SemanticChunkingConfigShape, S as SessionObserverBandConfig, du as SignalLevel, az as SignalScanResult, dv as SlotBehaviorConfig, dw as SlotMismatchMode, n as SourceConnectorProvenance, aA as TopicScore, T as TranscriptEntry, dx as TriggerMode, U as TrustWeights, X as VerificationState, dy as confidenceTier, bY as isRecallDisclosure } from './types-CqWwMPr_.js';
1
+ export { aU as AccessTrackingEntry, a1 as ActiveRecallChatType, a5 as ActiveRecallModelFallbackPolicy, a3 as ActiveRecallPromptStyle, a2 as ActiveRecallQueryMode, a4 as ActiveRecallThinking, t as AgentAccessAuthToken, cq as AgentAccessHttpConfig, cr as AgentDefaultsConfig, cs as AgentPersona, A as AgentPersonaModelConfig, ct as BehaviorLoopAdjustment, r as BehaviorLoopPolicyState, cu as BehaviorSignalDirection, a6 as BehaviorSignalEvent, cv as BehaviorSignalType, bd as BootstrapOptions, be as BootstrapResult, g as BriefingActiveThread, cw as BriefingCalendarSourceError, by as BriefingConfig, e as BriefingFocus, d as BriefingFollowup, bz as BriefingOpenCommitment, i as BriefingRecentEntity, h as BriefingResult, B as BriefingSections, bA as BriefingWindow, cx as BufferEntryState, aQ as BufferState, a7 as BufferSurpriseEvent, j as BufferTurn, f as CalendarEvent, C as CalendarSource, w as CaptureMode, cy as ChatConfig, m as Checkpoint, cz as CodexCliReasoningEffort, cA as CodexCompactionFlushMode, bD as CodexCompatConfig, cB as CodexConnectorConfig, ba as CodingContext, cC as CodingGraphLspConfig, bm as CodingKnowledgeConfig, bg as CodingModeConfig, cD as CompressionGuidelineActivationState, ad as CompressionGuidelineOptimizerActionSummary, ac as CompressionGuidelineOptimizerEventCounts, ae as CompressionGuidelineOptimizerRuleUpdate, cE as CompressionGuidelineOptimizerSourceWindow, ah as CompressionGuidelineOptimizerState, cF as ConfidenceTier, cG as ConsolidationAction, cH as ConsolidationItem, bf as ConsolidationObservation, K as ConsolidationResult, cI as ContradictionScanConfig, aj as ConvergeConfig, ai as ConvergeConflictPolicy, V as ConversationThread, cJ as CronConversationRecallMode, cK as CronRecallMode, bE as DEFAULT_RECALL_DISCLOSURE, N as DaySummaryResult, cL as DreamingConfig, cM as DreamingNarrativePromptStyle, cN as DreamsDeepSleepConfig, cO as DreamsLightSleepConfig, D as DreamsPhase, cP as DreamsPhaseStatus, cQ as DreamsPhasesConfig, cR as DreamsRemConfig, a as DreamsRunResult, bb as DreamsStatusResult, cS as EngramTraceEvent, aT as EntityActivityEntry, E as EntityFile, ak as EntityMention, aS as EntityRelationship, al as EntitySchemaDefinition, am as EntitySchemaSectionDefinition, an as EntityStructuredSection, aO as EntityTimelineEntry, bG as ExtractedFact, cT as ExtractedProcedureStep, cU as ExtractedQuestion, cV as ExtractedReasoningTrace, cW as ExtractedReasoningTraceStep, cX as ExtractedRelationship, $ as ExtractionFailureClass, cY as ExtractionPassSource, J as ExtractionResult, F as FaithfulnessFrontmatter, aR as FileHygieneConfig, G as GatewayConfig, cZ as GitHubLiveConnectorConfig, c_ as GmailLiveConnectorConfig, c$ as GoogleDriveLiveConnectorConfig, d0 as HeartbeatConfig, d1 as HeartbeatDetectionMode, H as HourlySummary, I as IdentityInjectionMode, a0 as ImportanceLevel, ap as ImportanceScore, W as LifecycleState, L as LiveConnectorsConfig, d2 as LlmTraceCallback, d3 as LlmTraceEvent, ar as MemoryActionEligibilityContext, bP as MemoryActionEligibilitySource, ag as MemoryActionEvent, d4 as MemoryActionOutcome, d5 as MemoryActionPolicyDecision, as as MemoryActionPolicyResult, d6 as MemoryActionStatus, af as MemoryActionType, v as MemoryCategory, M as MemoryFile, l as MemoryFrontmatter, aq as MemoryIntent, z as MemoryLifecycleEvent, at as MemoryLifecycleEventType, au as MemoryLifecycleStateSummary, aP as MemoryLink, d7 as MemoryLinkType, bQ as MemoryObservation, d8 as MemoryOsPresetName, y as MemoryProjectionCurrentState, bR as MemoryScope, x as MemoryStatus, aV as MemorySummary, ay as MetaState, d9 as ModelApi, da as ModelDefinitionConfig, db as ModelProviderAuthMode, av as ModelProviderConfig, dc as NamespacePolicy, aw as NativeKnowledgeConfig, dd as NativeKnowledgeFolderRuleConfig, de as NativeKnowledgeObsidianVaultConfig, df as NativeKnowledgeOpenClawWorkspaceConfig, dg as NotionLiveConnectorConfig, P as PluginConfig, Y as PolicyClass, dh as PrincipalFromSessionKeyMode, di as PrincipalRule, dj as ProceduralConfig, ao as ProvenanceConfig, O as ProvenanceSource, aD as QmdSearchExplain, Q as QmdSearchResult, dk as QuestionEntry, bS as RECALL_DISCLOSURE_LEVELS, dl as ReasoningEffort, b as RecallDisclosure, dm as RecallPipelineConfig, R as RecallPlanMode, bc as RecallSectionConfig, c as RecallTierExplain, dn as RecallTraceEvent, dp as RelevanceFeedback, aA as RetrievalTier, dq as SPECULATIVE_TTL_DAYS, dr as ScopeProfileAutoPromoteConfig, o as ScopeProfileConfig, p as ScopeProfileLayerId, q as ScopeProfilePromotionTarget, ds as ScopeProfileTeamProjectConfig, dt as ScopeTeamConfig, du as ScoredEntity, s as SecretRef, dv as SemanticChunkingConfigShape, S as SessionObserverBandConfig, dw as SignalLevel, aB as SignalScanResult, dx as SlotBehaviorConfig, dy as SlotMismatchMode, n as SourceConnectorProvenance, aC as TopicScore, T as TranscriptEntry, dz as TriggerMode, U as TrustWeights, X as VerificationState, dA as confidenceTier, b_ as isRecallDisclosure } from './types-rEwubvim.js';
2
2
  import './message-parts/index.js';
3
3
  import './bounded-jsonl-state.js';
4
4
  export { ContinuityImprovementLoop, ContinuityIncidentCloseInput, ContinuityIncidentOpenInput, ContinuityIncidentRecord, ContinuityIncidentState, ContinuityLoopCadence, ContinuityLoopReviewInput, ContinuityLoopStatus, ContinuityLoopUpsertInput } from './types-continuity.js';
package/dist/types.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  SPECULATIVE_TTL_DAYS,
5
5
  confidenceTier,
6
6
  isRecallDisclosure
7
- } from "./chunk-GSL47NPM.js";
7
+ } from "./chunk-J7VGGECD.js";
8
8
  import "./chunk-PZ5AY32C.js";
9
9
  export {
10
10
  DEFAULT_RECALL_DISCLOSURE,
@@ -1,5 +1,5 @@
1
1
  import { TierRoutingPolicy } from './tier-routing.js';
2
- import './types-CqWwMPr_.js';
2
+ import './types-rEwubvim.js';
3
3
  import './message-parts/index.js';
4
4
  import './bounded-jsonl-state.js';
5
5
  import './operator-doctor-types.js';
@@ -1,24 +1,26 @@
1
1
  import {
2
2
  compareVerifiedEpisodeResults,
3
3
  searchVerifiedEpisodes
4
- } from "./chunk-FVGQ5LIS.js";
4
+ } from "./chunk-OQ5PRDDS.js";
5
5
  import "./chunk-B7RWBZXW.js";
6
6
  import "./chunk-ZBJMUXZH.js";
7
- import "./chunk-3HKQOFOV.js";
8
- import "./chunk-ENTCVTQR.js";
7
+ import "./chunk-E6PNLPGJ.js";
9
8
  import "./chunk-UHVXE24Y.js";
9
+ import "./chunk-ENTCVTQR.js";
10
10
  import "./chunk-WIPEXG6R.js";
11
11
  import "./chunk-J6A3CX5N.js";
12
- import "./chunk-GSL47NPM.js";
12
+ import "./chunk-J7VGGECD.js";
13
13
  import "./chunk-WUNIWKY4.js";
14
14
  import "./chunk-EGGE52UU.js";
15
15
  import "./chunk-ZA53AZND.js";
16
+ import "./chunk-SCU65EZI.js";
16
17
  import "./chunk-WRJVB3C2.js";
17
18
  import "./chunk-GCASGYIO.js";
18
19
  import "./chunk-7RJUVTVF.js";
19
- import "./chunk-SCU65EZI.js";
20
20
  import "./chunk-DM2T26WE.js";
21
21
  import "./chunk-LDXUBPMO.js";
22
+ import "./chunk-JYIJNNN3.js";
23
+ import "./chunk-AAD2ZS6P.js";
22
24
  import "./chunk-RVLJEII5.js";
23
25
  import "./chunk-S5SLVSVY.js";
24
26
  import "./chunk-CGASUJVP.js";
@@ -26,8 +28,6 @@ import "./chunk-R3DJVOSM.js";
26
28
  import "./chunk-BT7NVCML.js";
27
29
  import "./chunk-3CSX3ETE.js";
28
30
  import "./chunk-RL6NEVXT.js";
29
- import "./chunk-JYIJNNN3.js";
30
- import "./chunk-AAD2ZS6P.js";
31
31
  import "./chunk-YXZG5TVN.js";
32
32
  import "./chunk-W5H6ZRPT.js";
33
33
  import "./chunk-G7D6GZ5J.js";
@@ -47,8 +47,8 @@ import "./chunk-45GF7Y3V.js";
47
47
  import "./chunk-RGMVMVMF.js";
48
48
  import "./chunk-N7RWREIQ.js";
49
49
  import "./chunk-5I4M26Q7.js";
50
- import "./chunk-5GKPFL3S.js";
51
50
  import "./chunk-ZIKENA2C.js";
51
+ import "./chunk-5GKPFL3S.js";
52
52
  import "./chunk-PQVCH2AE.js";
53
53
  import "./chunk-EYIEWJNI.js";
54
54
  import "./chunk-JUC24CTX.js";
@@ -1,4 +1,4 @@
1
- import { v as MemoryCategory } from './types-CqWwMPr_.js';
1
+ import { v as MemoryCategory } from './types-rEwubvim.js';
2
2
  import './message-parts/index.js';
3
3
  import './bounded-jsonl-state.js';
4
4
  import './operator-doctor-types.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remnic/core",
3
- "version": "9.45.0",
3
+ "version": "9.45.2",
4
4
  "description": "Framework-agnostic Remnic memory engine — orchestrator, storage, extraction, search, trust zones",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -3106,7 +3106,7 @@
3106
3106
  "core"
3107
3107
  ],
3108
3108
  "peerDependencies": {
3109
- "@remnic/coding-graph": "^9.45.0"
3109
+ "@remnic/coding-graph": "^9.45.2"
3110
3110
  },
3111
3111
  "peerDependenciesMeta": {
3112
3112
  "@remnic/coding-graph": {
@@ -2416,3 +2416,27 @@ test("parseConfig forwards bridgeMode as a raw passthrough (validation is in res
2416
2416
  test("parseConfig leaves the OpenClaw delegate timeout to the plugin parser", () => {
2417
2417
  assert.equal("bridgeHealthTimeoutMs" in parseConfig({ bridgeHealthTimeoutMs: 7_500 }), false);
2418
2418
  });
2419
+
2420
+ test("parseConfig validates converge conflict policy and defaults to newest-wins", () => {
2421
+ assert.deepEqual(parseConfig({}).converge, { conflictPolicy: "newest-wins" });
2422
+
2423
+ for (const conflictPolicy of ["newest-wins", "manual"] as const) {
2424
+ assert.equal(parseConfig({ converge: { conflictPolicy } }).converge.conflictPolicy, conflictPolicy);
2425
+ }
2426
+
2427
+ for (const conflictPolicy of ["keep-both", "", "unknown", 0, false, null]) {
2428
+ assert.throws(
2429
+ () => parseConfig({ converge: { conflictPolicy } }),
2430
+ /converge\.conflictPolicy.*newest-wins.*manual/,
2431
+ );
2432
+ }
2433
+
2434
+ for (const converge of [0, null, [], new Date(), new Map()]) {
2435
+ assert.throws(() => parseConfig({ converge }), /converge must be a plain object/);
2436
+ }
2437
+
2438
+ assert.throws(
2439
+ () => parseConfig({ converge: { conflictPolciy: "manual" } }),
2440
+ /converge contains unknown key "conflictPolciy"/,
2441
+ );
2442
+ });
package/src/config.ts CHANGED
@@ -26,6 +26,7 @@ import type {
26
26
  TriggerMode,
27
27
  TrustWeights,
28
28
  } from "./types.js";
29
+ import { parseConvergeConfig } from "./converge-config.js";
29
30
  import { log } from "./logger.js";
30
31
  import { cloneDefaultSessionObserverBands } from "./session-observer-bands.js";
31
32
  import { readEnvVar, resolveHomeDir } from "./runtime/env.js";
@@ -80,6 +81,7 @@ const DEFAULT_WORKSPACE_DIR = path.join(
80
81
  );
81
82
 
82
83
  const DEFAULT_INIT_GATE_TIMEOUT_MS = 30_000;
84
+
83
85
  const CLIENT_SECRET_FIELD = ["client", "Secret"].join("") as "clientSecret";
84
86
  const REFRESH_TOKEN_FIELD = ["refresh", "Token"].join("") as "refreshToken";
85
87
  const LEGACY_ACTIVE_RECALL_CUSTOM_FIELD = [
@@ -2332,6 +2334,7 @@ export function parseConfig(
2332
2334
  procedural,
2333
2335
  extractionLiveness: parseExtractionLivenessConfig(cfg),
2334
2336
  replicaPeers: parseReplicaPeersConfig(cfg),
2337
+ converge: parseConvergeConfig(cfg.converge),
2335
2338
  wearables,
2336
2339
  meetings,
2337
2340
  activity,
@@ -0,0 +1,39 @@
1
+ import type { ConvergeConfig, ConvergeConflictPolicy } from "./types.js";
2
+
3
+ export const CONVERGE_CONFLICT_POLICIES = [
4
+ "newest-wins",
5
+ "manual",
6
+ ] as const satisfies readonly ConvergeConflictPolicy[];
7
+
8
+ export const DEFAULT_CONVERGE_CONFLICT_POLICY: ConvergeConflictPolicy = "newest-wins";
9
+
10
+ export function parseConvergeConfig(block: unknown): ConvergeConfig {
11
+ if (block === undefined) {
12
+ return { conflictPolicy: DEFAULT_CONVERGE_CONFLICT_POLICY };
13
+ }
14
+ if (block === null || typeof block !== "object" || Array.isArray(block)) {
15
+ throw new Error("converge must be a plain object");
16
+ }
17
+ const prototype = Object.getPrototypeOf(block);
18
+ if (prototype !== Object.prototype && prototype !== null) {
19
+ throw new Error("converge must be a plain object");
20
+ }
21
+ const { conflictPolicy, ...unknown } = block as Record<string, unknown>;
22
+ const unknownKey = Object.keys(unknown)[0];
23
+ if (unknownKey !== undefined) {
24
+ throw new Error(`converge contains unknown key ${JSON.stringify(unknownKey)}`);
25
+ }
26
+ if (conflictPolicy === undefined) {
27
+ return { conflictPolicy: DEFAULT_CONVERGE_CONFLICT_POLICY };
28
+ }
29
+ if (
30
+ typeof conflictPolicy === "string" &&
31
+ CONVERGE_CONFLICT_POLICIES.includes(conflictPolicy as ConvergeConflictPolicy)
32
+ ) {
33
+ return { conflictPolicy: conflictPolicy as ConvergeConflictPolicy };
34
+ }
35
+
36
+ throw new Error(
37
+ `converge.conflictPolicy must be one of ${CONVERGE_CONFLICT_POLICIES.join(", ")}; got ${JSON.stringify(conflictPolicy)}`
38
+ );
39
+ }
package/src/index.ts CHANGED
@@ -1394,8 +1394,7 @@ export type {
1394
1394
  CalendarSource,
1395
1395
  RecallDisclosure,
1396
1396
  } from "./types.js";
1397
-
1398
- // Recall disclosure depth (issue #677).
1397
+ export { CONVERGE_CONFLICT_POLICIES, DEFAULT_CONVERGE_CONFLICT_POLICY } from "./converge-config.js";
1399
1398
  export {
1400
1399
  DEFAULT_RECALL_DISCLOSURE,
1401
1400
  RECALL_DISCLOSURE_LEVELS,
@@ -5,6 +5,7 @@ import * as path from "node:path";
5
5
  import { test } from "node:test";
6
6
  import {
7
7
  defaultConvergeCursorPath,
8
+ deriveConvergeCursorBase,
8
9
  hashPeerNamespace,
9
10
  normalizeConvergeCursor,
10
11
  readConvergeCursor,
@@ -13,6 +14,7 @@ import {
13
14
  } from "./cursor.js";
14
15
 
15
16
  const shaA = "a".repeat(64);
17
+ const shaB = "b".repeat(64);
16
18
 
17
19
  test("hashPeerNamespace: deterministic key normalization", () => {
18
20
  const k1 = hashPeerNamespace("http://peer.example.com/", "default");
@@ -46,6 +48,18 @@ test("defaultConvergeCursorPath: constructs path under memoryDir state", () => {
46
48
  assert.ok(p.endsWith(".json"));
47
49
  });
48
50
 
51
+ test("deriveConvergeCursorBase retains a deferred semantic agreement", () => {
52
+ const semanticAgreement = {
53
+ local: { path: "facts/local.md", sha256: shaA },
54
+ peer: { path: "facts/peer.md", sha256: shaB },
55
+ };
56
+
57
+ assert.deepEqual(
58
+ deriveConvergeCursorBase([], "default", [semanticAgreement]).semanticAgreements,
59
+ [semanticAgreement]
60
+ );
61
+ });
62
+
49
63
  test("normalizeConvergeCursor: validates envelope shape", () => {
50
64
  assert.throws(() => normalizeConvergeCursor(null), /must be an object/);
51
65
  assert.throws(() => normalizeConvergeCursor({ version: 2 }), /version must be 1/);
@@ -63,11 +77,19 @@ test("normalizeConvergeCursor: validates envelope shape", () => {
63
77
  peerUrl: "http://peer",
64
78
  namespace: "default",
65
79
  baseFiles: [{ path: "a.md", sha256: shaA }],
80
+ semanticAgreements: [{
81
+ local: { path: "facts/local.md", sha256: shaA },
82
+ peer: { path: "facts/peer.md", sha256: shaB },
83
+ }],
66
84
  });
67
85
  assert.equal(valid.peerUrl, "http://peer");
68
86
  assert.equal(valid.namespace, "default");
69
87
  assert.equal(valid.baseFiles.length, 1);
70
88
  assert.equal(valid.baseFiles[0]?.path, "a.md");
89
+ assert.deepEqual(valid.semanticAgreements, [{
90
+ local: { path: "facts/local.md", sha256: shaA },
91
+ peer: { path: "facts/peer.md", sha256: shaB },
92
+ }]);
71
93
  });
72
94
 
73
95
  test("readConvergeCursor: returns null when file is missing or invalid", async () => {
@@ -96,6 +118,10 @@ test("writeConvergeCursor & readConvergeCursor: atomic write roundtrip", async (
96
118
  lastConvergedAt: new Date().toISOString(),
97
119
  baseFiles: [{ path: "facts/a.md", sha256: shaA, bytes: 120, mtimeMs: 1000 }],
98
120
  completedPaths: ["facts/a.md"],
121
+ semanticAgreements: [{
122
+ local: { path: "facts/local.md", sha256: shaA },
123
+ peer: { path: "facts/peer.md", sha256: shaB },
124
+ }],
99
125
  };
100
126
 
101
127
  await writeConvergeCursor(cursorPath, cursor);
@@ -106,6 +132,10 @@ test("writeConvergeCursor & readConvergeCursor: atomic write roundtrip", async (
106
132
  assert.equal(read.baseFiles.length, 1);
107
133
  assert.equal(read.baseFiles[0]?.sha256, shaA);
108
134
  assert.deepEqual(read.completedPaths, ["facts/a.md"]);
135
+ assert.deepEqual(read.semanticAgreements, [{
136
+ local: { path: "facts/local.md", sha256: shaA },
137
+ peer: { path: "facts/peer.md", sha256: shaB },
138
+ }]);
109
139
 
110
140
  // Update existing cursor atomically
111
141
  const updated: ConvergeCursorState = {
@@ -1,6 +1,7 @@
1
1
  import { createHash, randomUUID } from "node:crypto";
2
2
  import * as fs from "node:fs/promises";
3
3
  import * as path from "node:path";
4
+ import type { ReconcilePlanEntry, ReconcileSemanticAgreement } from "./plan.js";
4
5
 
5
6
  export interface ConvergeCursorFileState {
6
7
  path: string;
@@ -15,6 +16,7 @@ export interface ConvergeCursorState {
15
16
  namespace: string;
16
17
  lastConvergedAt?: string;
17
18
  baseFiles: ConvergeCursorFileState[];
19
+ semanticAgreements?: ReconcileSemanticAgreement[];
18
20
  completedPaths?: string[];
19
21
  }
20
22
 
@@ -48,6 +50,56 @@ export function defaultConvergeCursorPath(
48
50
  return path.join(path.resolve(memoryDir), ".remnic", "state", "converge-cursors", `${key}.json`);
49
51
  }
50
52
 
53
+ function normalizeSemanticFileState(input: unknown): { path: string; sha256: string } | undefined {
54
+ if (!input || typeof input !== "object" || Array.isArray(input)) return undefined;
55
+ const file = input as Record<string, unknown>;
56
+ if (typeof file.path !== "string" || typeof file.sha256 !== "string") return undefined;
57
+ return { path: file.path, sha256: file.sha256 };
58
+ }
59
+
60
+ function digestAfterReconcile(entry: ReconcilePlanEntry): string | undefined {
61
+ if (entry.action === "push") return entry.localSha256;
62
+ if (entry.action === "pull") return entry.peerSha256;
63
+ if (entry.action === "conflict") {
64
+ if (entry.resolution === "local-wins") return entry.localSha256;
65
+ if (entry.resolution === "peer-wins") return entry.peerSha256;
66
+ return undefined;
67
+ }
68
+ if (entry.action !== "identical") return undefined;
69
+ if (entry.localSha256 && entry.peerSha256 && entry.localSha256 !== entry.peerSha256) return undefined;
70
+ return entry.localSha256 ?? entry.peerSha256;
71
+ }
72
+
73
+ function semanticAgreementKey(agreement: ReconcileSemanticAgreement): string {
74
+ return `${agreement.local.path}\0${agreement.peer.path}`;
75
+ }
76
+
77
+ export function deriveConvergeCursorBase(
78
+ entries: readonly ReconcilePlanEntry[],
79
+ namespace: string,
80
+ priorSemanticAgreements: readonly ReconcileSemanticAgreement[] = [],
81
+ ): Pick<ConvergeCursorState, "baseFiles" | "semanticAgreements"> {
82
+ const baseFiles: ConvergeCursorFileState[] = [];
83
+ const semanticAgreementsByPathPair = new Map(
84
+ priorSemanticAgreements.map((agreement) => [semanticAgreementKey(agreement), agreement])
85
+ );
86
+ for (const entry of entries) {
87
+ if (entry.namespace !== namespace) continue;
88
+ if (entry.semanticAgreement) {
89
+ semanticAgreementsByPathPair.set(semanticAgreementKey(entry.semanticAgreement), entry.semanticAgreement);
90
+ continue;
91
+ }
92
+ const sha256 = digestAfterReconcile(entry);
93
+ if (sha256) baseFiles.push({ path: entry.path, sha256 });
94
+ }
95
+ baseFiles.sort((left, right) => left.path.localeCompare(right.path));
96
+ const semanticAgreements = [...semanticAgreementsByPathPair.values()];
97
+ semanticAgreements.sort((left, right) =>
98
+ left.local.path.localeCompare(right.local.path) || left.peer.path.localeCompare(right.peer.path)
99
+ );
100
+ return { baseFiles, semanticAgreements };
101
+ }
102
+
51
103
  export function normalizeConvergeCursor(input: unknown): ConvergeCursorState {
52
104
  if (!input || typeof input !== "object" || Array.isArray(input)) {
53
105
  throw new Error("converge cursor must be an object");
@@ -78,6 +130,16 @@ export function normalizeConvergeCursor(input: unknown): ConvergeCursorState {
78
130
  }
79
131
  }
80
132
  }
133
+ const semanticAgreements: ReconcileSemanticAgreement[] = [];
134
+ if (Array.isArray(obj.semanticAgreements)) {
135
+ for (const item of obj.semanticAgreements) {
136
+ if (!item || typeof item !== "object" || Array.isArray(item)) continue;
137
+ const agreement = item as Record<string, unknown>;
138
+ const local = normalizeSemanticFileState(agreement.local);
139
+ const peer = normalizeSemanticFileState(agreement.peer);
140
+ if (local && peer) semanticAgreements.push({ local, peer });
141
+ }
142
+ }
81
143
  const completedPaths: string[] = [];
82
144
  if (Array.isArray(obj.completedPaths)) {
83
145
  for (const item of obj.completedPaths) {
@@ -92,6 +154,7 @@ export function normalizeConvergeCursor(input: unknown): ConvergeCursorState {
92
154
  namespace: obj.namespace.trim(),
93
155
  lastConvergedAt: typeof obj.lastConvergedAt === "string" ? obj.lastConvergedAt : undefined,
94
156
  baseFiles,
157
+ semanticAgreements,
95
158
  completedPaths,
96
159
  };
97
160
  }
@@ -132,8 +132,11 @@ test("semantic collapse prevents different active fact paths from transferring b
132
132
  namespace: "default",
133
133
  action: "identical",
134
134
  reason: "semantic_duplicate",
135
- localSha256: localFile.sha256,
136
- peerSha256: peerFile.sha256,
135
+ semanticAgreement: {
136
+ local: localFile,
137
+ peer: peerFile,
138
+ },
139
+ semanticChange: "unchanged",
137
140
  },
138
141
  ]);
139
142
  assert.equal(collapsed.byNamespace[0]?.identical, 1);
@@ -141,6 +144,51 @@ test("semantic collapse prevents different active fact paths from transferring b
141
144
  assert.equal(collapsed.byNamespace[0]?.push, 0);
142
145
  });
143
146
 
147
+ test("semantic collapse classifies a later one-sided metadata edit from its per-side base", () => {
148
+ const semanticHash = ContentHashIndex.computeHash("same active fact");
149
+ const priorLocal = { path: "facts/local-id.md", sha256: "a".repeat(64) };
150
+ const currentLocal = { ...priorLocal, sha256: "c".repeat(64) };
151
+ const peerFile = { path: "facts/peer-id.md", sha256: "b".repeat(64) };
152
+ const manifest = (file: typeof currentLocal): ReconcileManifest => ({
153
+ format: "remnic-reconcile-manifest",
154
+ schemaVersion: 1,
155
+ files: [{
156
+ ...file,
157
+ memory: {
158
+ id: file.path,
159
+ category: "fact",
160
+ contentHash: semanticHash,
161
+ status: "active",
162
+ },
163
+ }],
164
+ });
165
+ const plan = planReconciliation([{
166
+ namespace: "default",
167
+ local: [currentLocal],
168
+ peer: [peerFile],
169
+ }]);
170
+
171
+ const collapsed = collapseActiveFactDuplicates(
172
+ plan,
173
+ new Map([["default", manifest(currentLocal)]]),
174
+ new Map([["default", manifest(peerFile)]]),
175
+ new Map([["default", [{ local: priorLocal, peer: peerFile }]]])
176
+ );
177
+
178
+ assert.deepEqual(collapsed.entries, [{
179
+ path: currentLocal.path,
180
+ namespace: "default",
181
+ action: "identical",
182
+ reason: "semantic_duplicate",
183
+ semanticAgreement: {
184
+ local: currentLocal,
185
+ peer: peerFile,
186
+ },
187
+ semanticChange: "local_changed",
188
+ }]);
189
+ assert.equal(collapsed.converged, true);
190
+ });
191
+
144
192
  test("semantic collapse does not fold non-active facts or unrelated path conflicts", () => {
145
193
  const semanticHash = ContentHashIndex.computeHash("same inactive fact");
146
194
  const localFile = { path: "facts/local.md", sha256: "a".repeat(64) };
@@ -215,6 +263,49 @@ test("semantic collapse preserves same-path metadata updates", () => {
215
263
  assert.equal(collapsed.entries[0]?.action, "push");
216
264
  });
217
265
 
266
+ test("semantic collapse preserves a shared-path metadata update when peer canonical path differs", () => {
267
+ const semanticHash = ContentHashIndex.computeHash("same raw fact");
268
+ const sharedLocal = { path: "facts/b.md", sha256: "a".repeat(64) };
269
+ const sharedPeer = { path: "facts/b.md", sha256: "b".repeat(64) };
270
+ const peerDuplicate = { path: "facts/a.md", sha256: "c".repeat(64) };
271
+ const plan = planReconciliation([{
272
+ namespace: "default",
273
+ local: [sharedLocal],
274
+ peer: [peerDuplicate, sharedPeer],
275
+ base: [{ path: sharedPeer.path, sha256: sharedPeer.sha256 }],
276
+ }]);
277
+ const manifest = (files: Array<{ path: string; sha256: string }>): ReconcileManifest => ({
278
+ format: "remnic-reconcile-manifest",
279
+ schemaVersion: 1,
280
+ files: files.map((file) => ({
281
+ ...file,
282
+ memory: {
283
+ id: file.path,
284
+ category: "fact",
285
+ contentHash: semanticHash,
286
+ status: "active",
287
+ },
288
+ })),
289
+ });
290
+
291
+ const collapsed = collapseActiveFactDuplicates(
292
+ plan,
293
+ new Map([["default", manifest([sharedLocal])]]),
294
+ new Map([["default", manifest([peerDuplicate, sharedPeer])]])
295
+ );
296
+
297
+ assert.deepEqual(collapsed.entries, [{
298
+ path: sharedLocal.path,
299
+ namespace: "default",
300
+ action: "push",
301
+ reason: "local_changed",
302
+ localSha256: sharedLocal.sha256,
303
+ peerSha256: sharedPeer.sha256,
304
+ baseSha256: sharedPeer.sha256,
305
+ }]);
306
+ assert.equal(collapsed.converged, false);
307
+ });
308
+
218
309
  test("semantic collapse remains converged after transferring the canonical one-sided duplicate", () => {
219
310
  const semanticHash = ContentHashIndex.computeHash("same one-sided fact");
220
311
  const canonical = { path: "facts/a.md", sha256: "a".repeat(64) };
@@ -7,6 +7,8 @@ import {
7
7
  type ReconcileFileState,
8
8
  type ReconcilePlan,
9
9
  type ReconcilePlanEntry,
10
+ type ReconcileSemanticAgreement,
11
+ type ReconcileSemanticChange,
10
12
  summarizeReconcilePlan,
11
13
  } from "./plan.js";
12
14
 
@@ -153,10 +155,28 @@ function comparePlanEntries(left: ReconcilePlanEntry, right: ReconcilePlanEntry)
153
155
  return left.path < right.path ? -1 : left.path > right.path ? 1 : 0;
154
156
  }
155
157
 
158
+ function semanticAgreementKey(agreement: ReconcileSemanticAgreement): string {
159
+ return `${agreement.local.path}\0${agreement.peer.path}`;
160
+ }
161
+
162
+ function classifySemanticChange(
163
+ current: ReconcileSemanticAgreement,
164
+ prior: ReconcileSemanticAgreement | undefined
165
+ ): ReconcileSemanticChange {
166
+ if (!prior) return "unchanged";
167
+ const localChanged = current.local.sha256 !== prior.local.sha256;
168
+ const peerChanged = current.peer.sha256 !== prior.peer.sha256;
169
+ if (localChanged && peerChanged) return "both_modified";
170
+ if (localChanged) return "local_changed";
171
+ if (peerChanged) return "peer_changed";
172
+ return "unchanged";
173
+ }
174
+
156
175
  export function collapseActiveFactDuplicates(
157
176
  plan: ReconcilePlan,
158
177
  localManifests: ReadonlyMap<string, ReconcileManifest>,
159
- peerManifests: ReadonlyMap<string, ReconcileManifest>
178
+ peerManifests: ReadonlyMap<string, ReconcileManifest>,
179
+ priorSemanticAgreements?: ReadonlyMap<string, readonly ReconcileSemanticAgreement[]>,
160
180
  ): ReconcilePlan {
161
181
  const entriesByNamespace = new Map<string, ReconcilePlanEntry[]>();
162
182
  for (const entry of plan.entries) {
@@ -174,6 +194,12 @@ export function collapseActiveFactDuplicates(
174
194
  const peerByPath = activeFactByPath(peerManifest);
175
195
  const localFilesByPath = new Map((localManifest?.files ?? []).map((file) => [file.path, file]));
176
196
  const peerFilesByPath = new Map((peerManifest?.files ?? []).map((file) => [file.path, file]));
197
+ const priorSemanticByPathPair = new Map(
198
+ (priorSemanticAgreements?.get(namespace) ?? []).map((agreement) => [
199
+ semanticAgreementKey(agreement),
200
+ agreement,
201
+ ])
202
+ );
177
203
  const localByHash = new Map<string, ActiveFactManifestFile[]>();
178
204
  const peerByHash = new Map<string, ActiveFactManifestFile[]>();
179
205
 
@@ -214,6 +240,26 @@ export function collapseActiveFactDuplicates(
214
240
  ...localCandidates.map((file) => file.path),
215
241
  ...peerCandidates.map((file) => file.path),
216
242
  ]);
243
+ const authoritativeSamePathEntries = new Set(entries.filter(
244
+ (entry) =>
245
+ duplicatePaths.has(entry.path)
246
+ && localFilesByPath.has(entry.path)
247
+ && peerFilesByPath.has(entry.path)
248
+ && entry.action !== "identical"
249
+ ));
250
+ if (authoritativeSamePathEntries.size > 0) {
251
+ for (const entry of entries) {
252
+ if (
253
+ duplicatePaths.has(entry.path)
254
+ && !authoritativeSamePathEntries.has(entry)
255
+ && (entry.action === "pull" || entry.action === "push" || entry.action === "identical")
256
+ ) {
257
+ removed.add(entry);
258
+ changed = true;
259
+ }
260
+ }
261
+ continue;
262
+ }
217
263
  const unsafeEntry = entries.some(
218
264
  (entry) => duplicatePaths.has(entry.path) && (entry.action === "suppress" || entry.action === "conflict")
219
265
  );
@@ -226,13 +272,20 @@ export function collapseActiveFactDuplicates(
226
272
  removed.add(entry);
227
273
  }
228
274
  }
275
+ const semanticAgreement: ReconcileSemanticAgreement = {
276
+ local: { path: localPath, sha256: localFile.sha256 },
277
+ peer: { path: peerPath, sha256: peerFile.sha256 },
278
+ };
229
279
  replacements.push({
230
280
  path: localPath < peerPath ? localPath : peerPath,
231
281
  namespace,
232
282
  action: "identical",
233
283
  reason: "semantic_duplicate",
234
- localSha256: localFile.sha256,
235
- peerSha256: peerFile.sha256,
284
+ semanticAgreement,
285
+ semanticChange: classifySemanticChange(
286
+ semanticAgreement,
287
+ priorSemanticByPathPair.get(semanticAgreementKey(semanticAgreement))
288
+ ),
236
289
  });
237
290
  changed = true;
238
291
  continue;