@nicia-ai/typegraph 0.44.0 → 0.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (392) hide show
  1. package/dist/backend/drizzle/indexes.cjs +11 -11
  2. package/dist/backend/drizzle/indexes.d.cts +1 -1
  3. package/dist/backend/drizzle/indexes.d.ts +1 -1
  4. package/dist/backend/drizzle/indexes.js +7 -7
  5. package/dist/backend/index.cjs +53 -54
  6. package/dist/backend/index.d.cts +3 -3
  7. package/dist/backend/index.d.ts +3 -3
  8. package/dist/backend/index.js +13 -14
  9. package/dist/backend/postgres/index.cjs +29 -30
  10. package/dist/backend/postgres/index.d.cts +7 -7
  11. package/dist/backend/postgres/index.d.ts +7 -7
  12. package/dist/backend/postgres/index.js +16 -17
  13. package/dist/backend/postgres/pglite-store.cjs +48 -43
  14. package/dist/backend/postgres/pglite-store.cjs.map +1 -1
  15. package/dist/backend/postgres/pglite-store.d.cts +15 -9
  16. package/dist/backend/postgres/pglite-store.d.ts +15 -9
  17. package/dist/backend/postgres/pglite-store.js +44 -39
  18. package/dist/backend/postgres/pglite-store.js.map +1 -1
  19. package/dist/backend/postgres/pglite.cjs +18 -19
  20. package/dist/backend/postgres/pglite.d.cts +4 -4
  21. package/dist/backend/postgres/pglite.d.ts +4 -4
  22. package/dist/backend/postgres/pglite.js +17 -18
  23. package/dist/backend/sqlite/index.cjs +26 -27
  24. package/dist/backend/sqlite/index.d.cts +6 -6
  25. package/dist/backend/sqlite/index.d.ts +6 -6
  26. package/dist/backend/sqlite/index.js +14 -15
  27. package/dist/backend/sqlite/libsql.cjs +21 -22
  28. package/dist/backend/sqlite/libsql.cjs.map +1 -1
  29. package/dist/backend/sqlite/libsql.d.cts +15 -8
  30. package/dist/backend/sqlite/libsql.d.ts +15 -8
  31. package/dist/backend/sqlite/libsql.js +17 -18
  32. package/dist/backend/sqlite/libsql.js.map +1 -1
  33. package/dist/backend/sqlite/local-store.cjs +49 -44
  34. package/dist/backend/sqlite/local-store.cjs.map +1 -1
  35. package/dist/backend/sqlite/local-store.d.cts +15 -10
  36. package/dist/backend/sqlite/local-store.d.ts +15 -10
  37. package/dist/backend/sqlite/local-store.js +45 -40
  38. package/dist/backend/sqlite/local-store.js.map +1 -1
  39. package/dist/backend/sqlite/local.cjs +19 -20
  40. package/dist/backend/sqlite/local.d.cts +3 -3
  41. package/dist/backend/sqlite/local.d.ts +3 -3
  42. package/dist/backend/sqlite/local.js +17 -18
  43. package/dist/{chunk-XMYJY7NI.js → chunk-2LG2XB2M.js} +3 -3
  44. package/dist/{chunk-XMYJY7NI.js.map → chunk-2LG2XB2M.js.map} +1 -1
  45. package/dist/{chunk-QGKILWGZ.cjs → chunk-2NA5DYLO.cjs} +4 -4
  46. package/dist/{chunk-QGKILWGZ.cjs.map → chunk-2NA5DYLO.cjs.map} +1 -1
  47. package/dist/{chunk-5MUSU4ZP.cjs → chunk-3DHZCOT7.cjs} +20 -20
  48. package/dist/chunk-3DHZCOT7.cjs.map +1 -0
  49. package/dist/{chunk-OVUUTCPJ.cjs → chunk-4UGOKMI5.cjs} +268 -150
  50. package/dist/chunk-4UGOKMI5.cjs.map +1 -0
  51. package/dist/{chunk-FRHHDHKH.js → chunk-5262ZMTR.js} +26 -5
  52. package/dist/chunk-5262ZMTR.js.map +1 -0
  53. package/dist/{chunk-HOIFFY4M.js → chunk-5763DULU.js} +248 -76
  54. package/dist/chunk-5763DULU.js.map +1 -0
  55. package/dist/{chunk-7G32LIQM.js → chunk-5UVRGXD3.js} +277 -7
  56. package/dist/chunk-5UVRGXD3.js.map +1 -0
  57. package/dist/{chunk-IIT5K7SK.cjs → chunk-62ZP23AW.cjs} +15 -15
  58. package/dist/{chunk-IIT5K7SK.cjs.map → chunk-62ZP23AW.cjs.map} +1 -1
  59. package/dist/{chunk-S4KQ5LV4.js → chunk-775A4ZMN.js} +40 -6
  60. package/dist/chunk-775A4ZMN.js.map +1 -0
  61. package/dist/{chunk-QYWINYEA.cjs → chunk-7BQXPCGN.cjs} +830 -170
  62. package/dist/chunk-7BQXPCGN.cjs.map +1 -0
  63. package/dist/{chunk-FJMPR3OH.cjs → chunk-7EO3TCQB.cjs} +33 -7
  64. package/dist/chunk-7EO3TCQB.cjs.map +1 -0
  65. package/dist/chunk-7GT72YHH.cjs +1979 -0
  66. package/dist/chunk-7GT72YHH.cjs.map +1 -0
  67. package/dist/{chunk-SQRD2CYF.js → chunk-7VQXLT5O.js} +717 -76
  68. package/dist/chunk-7VQXLT5O.js.map +1 -0
  69. package/dist/{chunk-BCP7LLOY.js → chunk-7Z5OR7KO.js} +2706 -625
  70. package/dist/chunk-7Z5OR7KO.js.map +1 -0
  71. package/dist/chunk-A4OC4DVN.cjs +12 -0
  72. package/dist/{chunk-4SZ6XPTG.cjs.map → chunk-A4OC4DVN.cjs.map} +1 -1
  73. package/dist/{chunk-TDXIBCGY.cjs → chunk-A7J2YDDI.cjs} +5 -3
  74. package/dist/chunk-A7J2YDDI.cjs.map +1 -0
  75. package/dist/{chunk-FMMIX6N4.js → chunk-AKLS3BYZ.js} +56 -5
  76. package/dist/chunk-AKLS3BYZ.js.map +1 -0
  77. package/dist/{chunk-D7PG5D5K.js → chunk-AMKPPFUO.js} +32 -6
  78. package/dist/chunk-AMKPPFUO.js.map +1 -0
  79. package/dist/{chunk-PAW2XUZN.js → chunk-ASTI57H3.js} +3 -3
  80. package/dist/{chunk-PAW2XUZN.js.map → chunk-ASTI57H3.js.map} +1 -1
  81. package/dist/{chunk-FMGEZBAQ.js → chunk-BKCUOV7A.js} +27 -5
  82. package/dist/chunk-BKCUOV7A.js.map +1 -0
  83. package/dist/chunk-BSFJMMV3.cjs +268 -0
  84. package/dist/chunk-BSFJMMV3.cjs.map +1 -0
  85. package/dist/{chunk-63KCKSSH.js → chunk-C23WSN5E.js} +209 -24
  86. package/dist/chunk-C23WSN5E.js.map +1 -0
  87. package/dist/{chunk-JRP3VGHS.js → chunk-CBTIUB76.js} +3 -3
  88. package/dist/{chunk-JRP3VGHS.js.map → chunk-CBTIUB76.js.map} +1 -1
  89. package/dist/chunk-CNV4TXJG.js +58 -0
  90. package/dist/chunk-CNV4TXJG.js.map +1 -0
  91. package/dist/{chunk-QB6VMOJ2.cjs → chunk-CXBHOOIQ.cjs} +45 -10
  92. package/dist/chunk-CXBHOOIQ.cjs.map +1 -0
  93. package/dist/{chunk-46GDII45.js → chunk-DCQVHAYQ.js} +5 -5
  94. package/dist/{chunk-46GDII45.js.map → chunk-DCQVHAYQ.js.map} +1 -1
  95. package/dist/chunk-DLNROMQ7.js +306 -0
  96. package/dist/chunk-DLNROMQ7.js.map +1 -0
  97. package/dist/chunk-DYATYRY4.js +47 -0
  98. package/dist/chunk-DYATYRY4.js.map +1 -0
  99. package/dist/chunk-E4WNQBEF.cjs +217 -0
  100. package/dist/chunk-E4WNQBEF.cjs.map +1 -0
  101. package/dist/{chunk-G6Q5UM7U.js → chunk-FWJKWH6U.js} +5 -3
  102. package/dist/chunk-FWJKWH6U.js.map +1 -0
  103. package/dist/{chunk-BNUFUFAU.js → chunk-HFHTMECK.js} +7 -7
  104. package/dist/chunk-HFHTMECK.js.map +1 -0
  105. package/dist/{chunk-TFMVL4QH.js → chunk-I5MOXA4H.js} +20 -14
  106. package/dist/chunk-I5MOXA4H.js.map +1 -0
  107. package/dist/{chunk-4MB3AQAQ.js → chunk-J3WZ3FA2.js} +77 -3
  108. package/dist/chunk-J3WZ3FA2.js.map +1 -0
  109. package/dist/{chunk-UR7W5YQK.js → chunk-JBQQ7THH.js} +5 -3
  110. package/dist/chunk-JBQQ7THH.js.map +1 -0
  111. package/dist/chunk-JIVMTW7W.js +3393 -0
  112. package/dist/chunk-JIVMTW7W.js.map +1 -0
  113. package/dist/{chunk-2Y4IFKW7.js → chunk-JXA2ZP2Q.js} +6 -17
  114. package/dist/chunk-JXA2ZP2Q.js.map +1 -0
  115. package/dist/{chunk-GYA4JRP5.js → chunk-JXXDZTMN.js} +2 -2
  116. package/dist/chunk-JXXDZTMN.js.map +1 -0
  117. package/dist/chunk-JZUR7ZWE.js +254 -0
  118. package/dist/chunk-JZUR7ZWE.js.map +1 -0
  119. package/dist/chunk-K5ELX2GT.js +248 -0
  120. package/dist/chunk-K5ELX2GT.js.map +1 -0
  121. package/dist/chunk-LBJKZXDE.cjs +257 -0
  122. package/dist/chunk-LBJKZXDE.cjs.map +1 -0
  123. package/dist/{chunk-FGO5JFVJ.cjs → chunk-M4BDU5RX.cjs} +12 -12
  124. package/dist/{chunk-FGO5JFVJ.cjs.map → chunk-M4BDU5RX.cjs.map} +1 -1
  125. package/dist/{chunk-MIJKEVV7.js → chunk-MSY7FSX4.js} +37 -4
  126. package/dist/chunk-MSY7FSX4.js.map +1 -0
  127. package/dist/{chunk-ST3LPB2V.cjs → chunk-MUK4BU7K.cjs} +788 -146
  128. package/dist/chunk-MUK4BU7K.cjs.map +1 -0
  129. package/dist/{chunk-MCHP7RHZ.cjs → chunk-MXJDTH5B.cjs} +64 -41
  130. package/dist/chunk-MXJDTH5B.cjs.map +1 -0
  131. package/dist/{chunk-2VLBGQBY.cjs → chunk-N3257XE6.cjs} +724 -577
  132. package/dist/chunk-N3257XE6.cjs.map +1 -0
  133. package/dist/chunk-N66HCGCY.cjs +57 -0
  134. package/dist/chunk-N66HCGCY.cjs.map +1 -0
  135. package/dist/{chunk-CPEL3YIR.cjs → chunk-NFCVHQ5P.cjs} +55 -22
  136. package/dist/chunk-NFCVHQ5P.cjs.map +1 -0
  137. package/dist/{chunk-C4F7VJ5D.cjs → chunk-NI72YOJB.cjs} +84 -2
  138. package/dist/chunk-NI72YOJB.cjs.map +1 -0
  139. package/dist/{chunk-EE7N5XXQ.cjs → chunk-NK5Q7UNE.cjs} +10 -21
  140. package/dist/chunk-NK5Q7UNE.cjs.map +1 -0
  141. package/dist/{chunk-PHXITZE4.js → chunk-NMWDXFPH.js} +4 -4
  142. package/dist/{chunk-PHXITZE4.js.map → chunk-NMWDXFPH.js.map} +1 -1
  143. package/dist/{chunk-FSXTPBRN.js → chunk-NQ6BRJBE.js} +416 -850
  144. package/dist/chunk-NQ6BRJBE.js.map +1 -0
  145. package/dist/chunk-OH5E5KIO.js +2057 -0
  146. package/dist/chunk-OH5E5KIO.js.map +1 -0
  147. package/dist/chunk-ONU3HIED.cjs +2082 -0
  148. package/dist/chunk-ONU3HIED.cjs.map +1 -0
  149. package/dist/{chunk-STQ3BSED.cjs → chunk-PNN7RHVR.cjs} +66 -44
  150. package/dist/chunk-PNN7RHVR.cjs.map +1 -0
  151. package/dist/{chunk-6DCB664D.js → chunk-PQBQG7IM.js} +3 -3
  152. package/dist/{chunk-6DCB664D.js.map → chunk-PQBQG7IM.js.map} +1 -1
  153. package/dist/{chunk-ACSVZPK7.cjs → chunk-PWLJ77UV.cjs} +5 -3
  154. package/dist/chunk-PWLJ77UV.cjs.map +1 -0
  155. package/dist/chunk-Q7Q4WSLJ.cjs +328 -0
  156. package/dist/chunk-Q7Q4WSLJ.cjs.map +1 -0
  157. package/dist/{chunk-BEFM74L2.js → chunk-QLRESYPU.js} +637 -493
  158. package/dist/chunk-QLRESYPU.js.map +1 -0
  159. package/dist/{chunk-SBPC5IP3.js → chunk-QWX5YA3K.js} +784 -202
  160. package/dist/chunk-QWX5YA3K.js.map +1 -0
  161. package/dist/{chunk-TCRIQMBU.js → chunk-RJS7DECT.js} +8 -9
  162. package/dist/chunk-RJS7DECT.js.map +1 -0
  163. package/dist/{chunk-6JZUSDY2.cjs → chunk-RMQLSPA2.cjs} +297 -27
  164. package/dist/chunk-RMQLSPA2.cjs.map +1 -0
  165. package/dist/{chunk-SJDMVITW.cjs → chunk-RT5ZY4XA.cjs} +6 -5
  166. package/dist/chunk-RT5ZY4XA.cjs.map +1 -0
  167. package/dist/{chunk-IJTLXNGJ.js → chunk-T4XNKYXB.js} +780 -127
  168. package/dist/chunk-T4XNKYXB.js.map +1 -0
  169. package/dist/{chunk-PDGEXGS6.cjs → chunk-TQR4KBY2.cjs} +354 -182
  170. package/dist/chunk-TQR4KBY2.cjs.map +1 -0
  171. package/dist/chunk-TTAITEPJ.cjs +755 -0
  172. package/dist/chunk-TTAITEPJ.cjs.map +1 -0
  173. package/dist/{chunk-NN3QSOVS.cjs → chunk-U5SON7R2.cjs} +27 -27
  174. package/dist/{chunk-NN3QSOVS.cjs.map → chunk-U5SON7R2.cjs.map} +1 -1
  175. package/dist/{chunk-A2I2XO52.cjs → chunk-U63GDNRC.cjs} +32 -26
  176. package/dist/chunk-U63GDNRC.cjs.map +1 -0
  177. package/dist/{chunk-YNULOIR5.cjs → chunk-UDISNXDL.cjs} +64 -43
  178. package/dist/chunk-UDISNXDL.cjs.map +1 -0
  179. package/dist/{chunk-GWEDD3DH.js → chunk-UV3SN74I.js} +5 -5
  180. package/dist/{chunk-GWEDD3DH.js.map → chunk-UV3SN74I.js.map} +1 -1
  181. package/dist/{chunk-U5W4LKZV.cjs → chunk-VCRRKBLN.cjs} +9 -9
  182. package/dist/{chunk-U5W4LKZV.cjs.map → chunk-VCRRKBLN.cjs.map} +1 -1
  183. package/dist/{chunk-EFELJVLA.js → chunk-VGTJPTIC.js} +28 -5
  184. package/dist/chunk-VGTJPTIC.js.map +1 -0
  185. package/dist/chunk-VQH4VAWD.cjs +12 -0
  186. package/dist/{chunk-EPTSMFH7.cjs.map → chunk-VQH4VAWD.cjs.map} +1 -1
  187. package/dist/{chunk-SNXVDZAJ.js → chunk-W6OG3HDG.js} +5 -4
  188. package/dist/chunk-W6OG3HDG.js.map +1 -0
  189. package/dist/chunk-WDGA7IYB.js +207 -0
  190. package/dist/chunk-WDGA7IYB.js.map +1 -0
  191. package/dist/chunk-WEVQJ5LH.js +736 -0
  192. package/dist/chunk-WEVQJ5LH.js.map +1 -0
  193. package/dist/{chunk-3PRKZW6D.cjs → chunk-XBYVV3MP.cjs} +60 -5
  194. package/dist/chunk-XBYVV3MP.cjs.map +1 -0
  195. package/dist/{chunk-GFRGG2US.cjs → chunk-XCAGZAKP.cjs} +7 -7
  196. package/dist/{chunk-GFRGG2US.cjs.map → chunk-XCAGZAKP.cjs.map} +1 -1
  197. package/dist/{chunk-XR4YZFKW.cjs → chunk-XDF2UPEQ.cjs} +3864 -1783
  198. package/dist/chunk-XDF2UPEQ.cjs.map +1 -0
  199. package/dist/{chunk-7V2FGGI2.cjs → chunk-XMQSEJCF.cjs} +632 -1080
  200. package/dist/chunk-XMQSEJCF.cjs.map +1 -0
  201. package/dist/chunk-XNLIZYRZ.cjs +3432 -0
  202. package/dist/chunk-XNLIZYRZ.cjs.map +1 -0
  203. package/dist/{chunk-66UVLHQA.cjs → chunk-XNSI2FJO.cjs} +99 -100
  204. package/dist/chunk-XNSI2FJO.cjs.map +1 -0
  205. package/dist/chunk-XQSCL77R.cjs +60 -0
  206. package/dist/chunk-XQSCL77R.cjs.map +1 -0
  207. package/dist/{chunk-SVJ5GEXW.cjs → chunk-XUO3KQFO.cjs} +2 -2
  208. package/dist/chunk-XUO3KQFO.cjs.map +1 -0
  209. package/dist/{chunk-HJH3RMXG.cjs → chunk-YAAM3M2S.cjs} +10 -10
  210. package/dist/{chunk-HJH3RMXG.cjs.map → chunk-YAAM3M2S.cjs.map} +1 -1
  211. package/dist/{chunk-ATLN63JA.js → chunk-YBFHZUXX.js} +6 -6
  212. package/dist/{chunk-ATLN63JA.js.map → chunk-YBFHZUXX.js.map} +1 -1
  213. package/dist/{chunk-K3BUWSFR.js → chunk-YDFDBE6D.js} +119 -6
  214. package/dist/chunk-YDFDBE6D.js.map +1 -0
  215. package/dist/{chunk-OSZPLZIV.cjs → chunk-YVWGEQJE.cjs} +318 -132
  216. package/dist/chunk-YVWGEQJE.cjs.map +1 -0
  217. package/dist/{chunk-QT6V3YRH.js → chunk-YWGVVALJ.js} +3 -3
  218. package/dist/{chunk-QT6V3YRH.js.map → chunk-YWGVVALJ.js.map} +1 -1
  219. package/dist/core/index.cjs +40 -41
  220. package/dist/core/index.d.cts +4 -5
  221. package/dist/core/index.d.ts +4 -5
  222. package/dist/core/index.js +8 -9
  223. package/dist/{ddl-eWg7hx6R.d.cts → ddl-BJcOp4WZ.d.cts} +3 -3
  224. package/dist/{ddl-D5369kOY.d.ts → ddl-BXfGHbPN.d.ts} +3 -3
  225. package/dist/graph-extension/index.cjs +26 -23
  226. package/dist/graph-extension/index.d.cts +16 -6
  227. package/dist/graph-extension/index.d.ts +16 -6
  228. package/dist/graph-extension/index.js +7 -8
  229. package/dist/graph-merge/index.cjs +2459 -655
  230. package/dist/graph-merge/index.cjs.map +1 -1
  231. package/dist/graph-merge/index.d.cts +170 -33
  232. package/dist/graph-merge/index.d.ts +170 -33
  233. package/dist/graph-merge/index.js +2269 -468
  234. package/dist/graph-merge/index.js.map +1 -1
  235. package/dist/{index-By89Sezh.d.ts → index-BSHvKfok.d.ts} +221 -10
  236. package/dist/{index-DcQ3Sxs-.d.cts → index-DxaYCv8Y.d.cts} +221 -10
  237. package/dist/index.cjs +330 -269
  238. package/dist/index.cjs.map +1 -1
  239. package/dist/index.d.cts +590 -576
  240. package/dist/index.d.ts +590 -576
  241. package/dist/index.js +73 -50
  242. package/dist/index.js.map +1 -1
  243. package/dist/indexes/index.cjs +17 -17
  244. package/dist/indexes/index.d.cts +4 -4
  245. package/dist/indexes/index.d.ts +4 -4
  246. package/dist/indexes/index.js +10 -10
  247. package/dist/interchange/index.cjs +165 -50
  248. package/dist/interchange/index.cjs.map +1 -1
  249. package/dist/interchange/index.d.cts +261 -16
  250. package/dist/interchange/index.d.ts +261 -16
  251. package/dist/interchange/index.js +128 -24
  252. package/dist/interchange/index.js.map +1 -1
  253. package/dist/{manager-B0KjKE93.d.ts → manager-CfZAimti.d.ts} +36 -5
  254. package/dist/{manager-Cn0NFIhN.d.cts → manager-HGk6E_HW.d.cts} +36 -5
  255. package/dist/{materialize-indexes-BD4V3svD.d.ts → materialize-indexes-6A7dWGtb.d.cts} +10 -2
  256. package/dist/{materialize-indexes-DVRhd5h4.d.cts → materialize-indexes-BMJP6Tms.d.ts} +10 -2
  257. package/dist/{postgres-DaEWvN4x.d.cts → postgres-DFYWENdR.d.cts} +1961 -439
  258. package/dist/{postgres-u0a0HN2D.d.ts → postgres-e7a9TdvR.d.ts} +1961 -439
  259. package/dist/profiler/index.cjs +15 -15
  260. package/dist/profiler/index.d.cts +9 -10
  261. package/dist/profiler/index.d.ts +9 -10
  262. package/dist/profiler/index.js +4 -4
  263. package/dist/provenance/index.cjs +46 -48
  264. package/dist/provenance/index.cjs.map +1 -1
  265. package/dist/provenance/index.d.cts +7 -7
  266. package/dist/provenance/index.d.ts +7 -7
  267. package/dist/provenance/index.js +12 -14
  268. package/dist/provenance/index.js.map +1 -1
  269. package/dist/schema/index.cjs +50 -49
  270. package/dist/schema/index.d.cts +9 -16
  271. package/dist/schema/index.d.ts +9 -16
  272. package/dist/schema/index.js +23 -22
  273. package/dist/{searchable-CnYEancP.d.ts → searchable-9OQoPuRs.d.ts} +1 -2
  274. package/dist/{searchable-BT7j9_IK.d.cts → searchable-CIje5XYD.d.cts} +1 -2
  275. package/dist/{sqlite-BrMoSsI7.d.cts → sqlite-DerU5tc7.d.ts} +2029 -347
  276. package/dist/{sqlite-CHhZUyO5.d.ts → sqlite-DitnISa9.d.cts} +2029 -347
  277. package/dist/{store-view-Bvdku0Ht.d.ts → store-DawaWWjJ.d.ts} +3145 -2556
  278. package/dist/{store-view-w-md0nQ4.d.cts → store-RwTJx8LX.d.cts} +3145 -2556
  279. package/dist/{temporal-BCORwUau.d.cts → temporal-Bn-Fi8FJ.d.cts} +1 -1
  280. package/dist/{temporal--x9T8K4S.d.ts → temporal-BtM4UALv.d.ts} +1 -1
  281. package/dist/{types-6-WJmSD4.d.cts → types-CoIx8HX5.d.cts} +1 -1
  282. package/dist/{types-Cjvkj0jA.d.ts → types-HkveCCx0.d.cts} +866 -21
  283. package/dist/{types-Cjvkj0jA.d.cts → types-HkveCCx0.d.ts} +866 -21
  284. package/dist/{types-COODtTJU.d.ts → types-KFfk-8Ah.d.ts} +1 -1
  285. package/dist/{where-CUQmCR6d.d.cts → where--fk7_0kv.d.cts} +1 -1
  286. package/dist/{where-5xVawAwL.d.ts → where-ws5hf-Ov.d.ts} +1 -1
  287. package/package.json +1 -1
  288. package/dist/chunk-2BIG7U6E.cjs +0 -83
  289. package/dist/chunk-2BIG7U6E.cjs.map +0 -1
  290. package/dist/chunk-2L54C2C2.js +0 -144
  291. package/dist/chunk-2L54C2C2.js.map +0 -1
  292. package/dist/chunk-2VLBGQBY.cjs.map +0 -1
  293. package/dist/chunk-2WDD2NO3.js +0 -59
  294. package/dist/chunk-2WDD2NO3.js.map +0 -1
  295. package/dist/chunk-2Y4IFKW7.js.map +0 -1
  296. package/dist/chunk-35S6P5ZU.js +0 -27
  297. package/dist/chunk-35S6P5ZU.js.map +0 -1
  298. package/dist/chunk-3PRKZW6D.cjs.map +0 -1
  299. package/dist/chunk-4MB3AQAQ.js.map +0 -1
  300. package/dist/chunk-4SZ6XPTG.cjs +0 -12
  301. package/dist/chunk-5MUSU4ZP.cjs.map +0 -1
  302. package/dist/chunk-63KCKSSH.js.map +0 -1
  303. package/dist/chunk-66UVLHQA.cjs.map +0 -1
  304. package/dist/chunk-6JZUSDY2.cjs.map +0 -1
  305. package/dist/chunk-764JHTLT.cjs +0 -15
  306. package/dist/chunk-764JHTLT.cjs.map +0 -1
  307. package/dist/chunk-7G32LIQM.js.map +0 -1
  308. package/dist/chunk-7V2FGGI2.cjs.map +0 -1
  309. package/dist/chunk-A2I2XO52.cjs.map +0 -1
  310. package/dist/chunk-A4PBRX4C.cjs +0 -100
  311. package/dist/chunk-A4PBRX4C.cjs.map +0 -1
  312. package/dist/chunk-ACSVZPK7.cjs.map +0 -1
  313. package/dist/chunk-ALFUGRYB.cjs +0 -1282
  314. package/dist/chunk-ALFUGRYB.cjs.map +0 -1
  315. package/dist/chunk-B75XRV3O.js +0 -125
  316. package/dist/chunk-B75XRV3O.js.map +0 -1
  317. package/dist/chunk-BCP7LLOY.js.map +0 -1
  318. package/dist/chunk-BEFM74L2.js.map +0 -1
  319. package/dist/chunk-BNUFUFAU.js.map +0 -1
  320. package/dist/chunk-C4F7VJ5D.cjs.map +0 -1
  321. package/dist/chunk-CPEL3YIR.cjs.map +0 -1
  322. package/dist/chunk-D7PG5D5K.js.map +0 -1
  323. package/dist/chunk-DI74SMXS.cjs +0 -29
  324. package/dist/chunk-DI74SMXS.cjs.map +0 -1
  325. package/dist/chunk-DK2S42XB.js +0 -77
  326. package/dist/chunk-DK2S42XB.js.map +0 -1
  327. package/dist/chunk-DRACN6XG.js +0 -27
  328. package/dist/chunk-DRACN6XG.js.map +0 -1
  329. package/dist/chunk-EE7N5XXQ.cjs.map +0 -1
  330. package/dist/chunk-EFELJVLA.js.map +0 -1
  331. package/dist/chunk-EPTSMFH7.cjs +0 -12
  332. package/dist/chunk-EQ7JKLZO.cjs +0 -157
  333. package/dist/chunk-EQ7JKLZO.cjs.map +0 -1
  334. package/dist/chunk-FJMPR3OH.cjs.map +0 -1
  335. package/dist/chunk-FMGEZBAQ.js.map +0 -1
  336. package/dist/chunk-FMMIX6N4.js.map +0 -1
  337. package/dist/chunk-FRHHDHKH.js.map +0 -1
  338. package/dist/chunk-FSXTPBRN.js.map +0 -1
  339. package/dist/chunk-G6Q5UM7U.js.map +0 -1
  340. package/dist/chunk-GYA4JRP5.js.map +0 -1
  341. package/dist/chunk-HOHAJ2NR.cjs +0 -61
  342. package/dist/chunk-HOHAJ2NR.cjs.map +0 -1
  343. package/dist/chunk-HOIFFY4M.js.map +0 -1
  344. package/dist/chunk-IIMQJYAM.js +0 -81
  345. package/dist/chunk-IIMQJYAM.js.map +0 -1
  346. package/dist/chunk-IJTLXNGJ.js.map +0 -1
  347. package/dist/chunk-ITE4IXAK.js +0 -25
  348. package/dist/chunk-ITE4IXAK.js.map +0 -1
  349. package/dist/chunk-K3BUWSFR.js.map +0 -1
  350. package/dist/chunk-KCO5EFJU.js +0 -79
  351. package/dist/chunk-KCO5EFJU.js.map +0 -1
  352. package/dist/chunk-KKYELPZ2.cjs +0 -83
  353. package/dist/chunk-KKYELPZ2.cjs.map +0 -1
  354. package/dist/chunk-MCHP7RHZ.cjs.map +0 -1
  355. package/dist/chunk-MIJKEVV7.js.map +0 -1
  356. package/dist/chunk-NCX65HBY.cjs +0 -1396
  357. package/dist/chunk-NCX65HBY.cjs.map +0 -1
  358. package/dist/chunk-OSZPLZIV.cjs.map +0 -1
  359. package/dist/chunk-OVUUTCPJ.cjs.map +0 -1
  360. package/dist/chunk-PDGEXGS6.cjs.map +0 -1
  361. package/dist/chunk-QB6VMOJ2.cjs.map +0 -1
  362. package/dist/chunk-QMQLUA66.js +0 -12
  363. package/dist/chunk-QMQLUA66.js.map +0 -1
  364. package/dist/chunk-QYWINYEA.cjs.map +0 -1
  365. package/dist/chunk-S4KQ5LV4.js.map +0 -1
  366. package/dist/chunk-SBPC5IP3.js.map +0 -1
  367. package/dist/chunk-SJDMVITW.cjs.map +0 -1
  368. package/dist/chunk-SNXVDZAJ.js.map +0 -1
  369. package/dist/chunk-SQRD2CYF.js.map +0 -1
  370. package/dist/chunk-ST3LPB2V.cjs.map +0 -1
  371. package/dist/chunk-STQ3BSED.cjs.map +0 -1
  372. package/dist/chunk-SVJ5GEXW.cjs.map +0 -1
  373. package/dist/chunk-TCRIQMBU.js.map +0 -1
  374. package/dist/chunk-TDXIBCGY.cjs.map +0 -1
  375. package/dist/chunk-TFMVL4QH.js.map +0 -1
  376. package/dist/chunk-TRF4EBJT.cjs +0 -30
  377. package/dist/chunk-TRF4EBJT.cjs.map +0 -1
  378. package/dist/chunk-TVLKA4AY.js +0 -94
  379. package/dist/chunk-TVLKA4AY.js.map +0 -1
  380. package/dist/chunk-UR7W5YQK.js.map +0 -1
  381. package/dist/chunk-VITTKBWF.js +0 -1263
  382. package/dist/chunk-VITTKBWF.js.map +0 -1
  383. package/dist/chunk-WBUFJ7BS.cjs +0 -131
  384. package/dist/chunk-WBUFJ7BS.cjs.map +0 -1
  385. package/dist/chunk-XR4YZFKW.cjs.map +0 -1
  386. package/dist/chunk-YNULOIR5.cjs.map +0 -1
  387. package/dist/chunk-ZDH3DX3C.cjs +0 -30
  388. package/dist/chunk-ZDH3DX3C.cjs.map +0 -1
  389. package/dist/chunk-ZTAJL4DT.cjs +0 -85
  390. package/dist/chunk-ZTAJL4DT.cjs.map +0 -1
  391. package/dist/define-graph-DVF-oN1i.d.cts +0 -173
  392. package/dist/define-graph-SvYXOl78.d.ts +0 -173
@@ -1,48 +1,45 @@
1
1
  'use strict';
2
2
 
3
- var chunkXR4YZFKW_cjs = require('../chunk-XR4YZFKW.cjs');
4
- require('../chunk-HJH3RMXG.cjs');
5
- var chunkALFUGRYB_cjs = require('../chunk-ALFUGRYB.cjs');
6
- require('../chunk-NCX65HBY.cjs');
7
- var chunk7V2FGGI2_cjs = require('../chunk-7V2FGGI2.cjs');
8
- require('../chunk-ZDH3DX3C.cjs');
9
- require('../chunk-CPEL3YIR.cjs');
10
- require('../chunk-3PRKZW6D.cjs');
11
- require('../chunk-EQ7JKLZO.cjs');
12
- var chunk2VLBGQBY_cjs = require('../chunk-2VLBGQBY.cjs');
13
- var chunkTRF4EBJT_cjs = require('../chunk-TRF4EBJT.cjs');
14
- var chunkEE7N5XXQ_cjs = require('../chunk-EE7N5XXQ.cjs');
15
- require('../chunk-KKYELPZ2.cjs');
16
- var chunkACSVZPK7_cjs = require('../chunk-ACSVZPK7.cjs');
17
- require('../chunk-WBUFJ7BS.cjs');
18
- var chunkQB6VMOJ2_cjs = require('../chunk-QB6VMOJ2.cjs');
19
- require('../chunk-ZTAJL4DT.cjs');
20
- require('../chunk-IIT5K7SK.cjs');
21
- require('../chunk-GFRGG2US.cjs');
22
- require('../chunk-A2I2XO52.cjs');
3
+ var chunkXDF2UPEQ_cjs = require('../chunk-XDF2UPEQ.cjs');
4
+ require('../chunk-YAAM3M2S.cjs');
5
+ var chunkONU3HIED_cjs = require('../chunk-ONU3HIED.cjs');
6
+ require('../chunk-7GT72YHH.cjs');
7
+ var chunkTTAITEPJ_cjs = require('../chunk-TTAITEPJ.cjs');
8
+ var chunkN3257XE6_cjs = require('../chunk-N3257XE6.cjs');
9
+ var chunkNK5Q7UNE_cjs = require('../chunk-NK5Q7UNE.cjs');
10
+ var chunkXNLIZYRZ_cjs = require('../chunk-XNLIZYRZ.cjs');
11
+ var chunkXMQSEJCF_cjs = require('../chunk-XMQSEJCF.cjs');
12
+ var chunkPWLJ77UV_cjs = require('../chunk-PWLJ77UV.cjs');
13
+ require('../chunk-BSFJMMV3.cjs');
14
+ var chunkNFCVHQ5P_cjs = require('../chunk-NFCVHQ5P.cjs');
15
+ var chunkXBYVV3MP_cjs = require('../chunk-XBYVV3MP.cjs');
16
+ var chunkCXBHOOIQ_cjs = require('../chunk-CXBHOOIQ.cjs');
17
+ var chunkE4WNQBEF_cjs = require('../chunk-E4WNQBEF.cjs');
18
+ var chunkQ7Q4WSLJ_cjs = require('../chunk-Q7Q4WSLJ.cjs');
19
+ require('../chunk-62ZP23AW.cjs');
20
+ require('../chunk-XCAGZAKP.cjs');
21
+ require('../chunk-U63GDNRC.cjs');
23
22
  var chunkZY4GXIVN_cjs = require('../chunk-ZY4GXIVN.cjs');
24
23
  require('../chunk-NAUA4PW5.cjs');
25
- require('../chunk-OVUUTCPJ.cjs');
26
- require('../chunk-U5W4LKZV.cjs');
27
- require('../chunk-FJMPR3OH.cjs');
28
- require('../chunk-SJDMVITW.cjs');
29
- var chunk764JHTLT_cjs = require('../chunk-764JHTLT.cjs');
24
+ require('../chunk-4UGOKMI5.cjs');
25
+ var chunkVCRRKBLN_cjs = require('../chunk-VCRRKBLN.cjs');
26
+ require('../chunk-7EO3TCQB.cjs');
27
+ require('../chunk-RT5ZY4XA.cjs');
30
28
  require('../chunk-HAHNRASW.cjs');
31
- var chunkQYWINYEA_cjs = require('../chunk-QYWINYEA.cjs');
32
- require('../chunk-SVJ5GEXW.cjs');
33
- require('../chunk-HOHAJ2NR.cjs');
34
- require('../chunk-DI74SMXS.cjs');
35
- require('../chunk-A4PBRX4C.cjs');
36
- var chunkC4F7VJ5D_cjs = require('../chunk-C4F7VJ5D.cjs');
37
- require('../chunk-TDXIBCGY.cjs');
29
+ var chunk7BQXPCGN_cjs = require('../chunk-7BQXPCGN.cjs');
30
+ var chunkXUO3KQFO_cjs = require('../chunk-XUO3KQFO.cjs');
31
+ require('../chunk-LBJKZXDE.cjs');
32
+ var chunkNI72YOJB_cjs = require('../chunk-NI72YOJB.cjs');
33
+ require('../chunk-A7J2YDDI.cjs');
34
+ var chunkN66HCGCY_cjs = require('../chunk-N66HCGCY.cjs');
38
35
  var zod = require('zod');
39
36
 
40
37
  // src/graph-merge/canonical-props.ts
41
38
  function canonicalizeProps(props) {
42
- return JSON.stringify(props, chunkACSVZPK7_cjs.sortedReplacer);
39
+ return JSON.stringify(props, chunkPWLJ77UV_cjs.sortedReplacer);
43
40
  }
44
41
  function canonicalValueKey(value) {
45
- return JSON.stringify(value, chunkACSVZPK7_cjs.sortedReplacer);
42
+ return JSON.stringify(value, chunkPWLJ77UV_cjs.sortedReplacer);
46
43
  }
47
44
  function edgeStateSignature(edge) {
48
45
  return JSON.stringify([
@@ -103,8 +100,834 @@ function compareMergeKeys(left, right) {
103
100
  return leftKind < rightKind ? -1 : leftKind > rightKind ? 1 : 0;
104
101
  }
105
102
 
103
+ // src/graph-merge/errors.ts
104
+ var MERGE_ERROR_CODES = {
105
+ merge: "GRAPH_MERGE_ERROR",
106
+ invalidOptions: "GRAPH_MERGE_INVALID_OPTIONS",
107
+ branch: "GRAPH_MERGE_BRANCH_ERROR",
108
+ similarityUnavailable: "GRAPH_MERGE_SIMILARITY_UNAVAILABLE",
109
+ conflict: "GRAPH_MERGE_CONFLICT",
110
+ identityConflict: "GRAPH_MERGE_IDENTITY_CONFLICT",
111
+ baseVersionMismatch: "GRAPH_MERGE_BASE_VERSION_MISMATCH"
112
+ };
113
+ function toTypeGraphErrorOptions(category, options) {
114
+ return {
115
+ category,
116
+ ...options.details === void 0 ? {} : { details: options.details },
117
+ ...options.suggestion === void 0 ? {} : { suggestion: options.suggestion },
118
+ ...options.cause === void 0 ? {} : { cause: options.cause }
119
+ };
120
+ }
121
+ var MergeError = class extends chunkNI72YOJB_cjs.TypeGraphError {
122
+ static errorCategory = "system";
123
+ constructor(message, options = {}) {
124
+ const errorClass = new.target;
125
+ super(
126
+ message,
127
+ MERGE_ERROR_CODES.merge,
128
+ toTypeGraphErrorOptions(errorClass.errorCategory, options)
129
+ );
130
+ this.name = "MergeError";
131
+ }
132
+ };
133
+ var InvalidMergeOptionsError = class extends MergeError {
134
+ static errorCategory = "user";
135
+ code = MERGE_ERROR_CODES.invalidOptions;
136
+ constructor(message, options = {}) {
137
+ super(message, options);
138
+ this.name = "InvalidMergeOptionsError";
139
+ }
140
+ };
141
+ var BranchError = class extends chunkNI72YOJB_cjs.TypeGraphError {
142
+ constructor(message, options = {}) {
143
+ super(
144
+ message,
145
+ MERGE_ERROR_CODES.branch,
146
+ toTypeGraphErrorOptions("system", options)
147
+ );
148
+ this.name = "BranchError";
149
+ }
150
+ };
151
+ var SimilarityUnavailableError = class extends MergeError {
152
+ code = MERGE_ERROR_CODES.similarityUnavailable;
153
+ constructor(message, options = {}) {
154
+ super(message, {
155
+ ...options,
156
+ suggestion: options.suggestion ?? "Pass MergeOptions.embedder (a local model), or use a fulltext/custom similarity strategy."
157
+ });
158
+ this.name = "SimilarityUnavailableError";
159
+ }
160
+ };
161
+ var MergeConflictError = class extends MergeError {
162
+ code = MERGE_ERROR_CODES.conflict;
163
+ constructor(message, options = {}) {
164
+ super(message, options);
165
+ this.name = "MergeConflictError";
166
+ }
167
+ };
168
+ var IdentityMergeConflictError = class extends MergeError {
169
+ code = MERGE_ERROR_CODES.identityConflict;
170
+ constructor(message, options = {}) {
171
+ super(message, options);
172
+ this.name = "IdentityMergeConflictError";
173
+ }
174
+ };
175
+ var BaseVersionMismatchError = class extends MergeError {
176
+ code = MERGE_ERROR_CODES.baseVersionMismatch;
177
+ constructor(message, options = {}) {
178
+ super(message, {
179
+ ...options,
180
+ suggestion: options.suggestion ?? "Re-branch from the current target so the branch base matches before merging."
181
+ });
182
+ this.name = "BaseVersionMismatchError";
183
+ }
184
+ };
185
+ function describeCause(cause) {
186
+ return cause instanceof Error ? cause.message : String(cause);
187
+ }
188
+
189
+ // src/graph-merge/union-find.ts
190
+ var UnionFind = class {
191
+ constructor(compare) {
192
+ this.compare = compare;
193
+ }
194
+ compare;
195
+ parent = /* @__PURE__ */ new Map();
196
+ /** Adds `value` as its own singleton set if it is not already present. */
197
+ add(value) {
198
+ if (!this.parent.has(value)) {
199
+ this.parent.set(value, value);
200
+ }
201
+ }
202
+ /** Returns the representative of `value`'s set, compressing the path to it. */
203
+ find(value) {
204
+ this.add(value);
205
+ let root = value;
206
+ while (this.parent.get(root) !== root) {
207
+ root = chunkN66HCGCY_cjs.requireDefined(this.parent.get(root));
208
+ }
209
+ let cursor = value;
210
+ while (cursor !== root) {
211
+ const next = chunkN66HCGCY_cjs.requireDefined(this.parent.get(cursor));
212
+ this.parent.set(cursor, root);
213
+ cursor = next;
214
+ }
215
+ return root;
216
+ }
217
+ /** Merges the sets of `left` and `right`; the `compare`-minimal root wins. */
218
+ union(left, right) {
219
+ const leftRoot = this.find(left);
220
+ const rightRoot = this.find(right);
221
+ if (leftRoot === rightRoot) {
222
+ return;
223
+ }
224
+ if (this.compare(leftRoot, rightRoot) <= 0) {
225
+ this.parent.set(rightRoot, leftRoot);
226
+ } else {
227
+ this.parent.set(leftRoot, rightRoot);
228
+ }
229
+ }
230
+ /** Every value seen by {@link add}/{@link find}/{@link union}, insertion order. */
231
+ members() {
232
+ return [...this.parent.keys()];
233
+ }
234
+ };
235
+
236
+ // src/graph-merge/merge-identity.ts
237
+ function endpointTuple(assertion) {
238
+ return [assertion.a.kind, assertion.a.id, assertion.b.kind, assertion.b.id];
239
+ }
240
+ function identityEndpointKey(assertion) {
241
+ return chunkXNLIZYRZ_cjs.encodeTupleKey(endpointTuple(assertion));
242
+ }
243
+ function identitySemanticKey(assertion) {
244
+ return chunkXNLIZYRZ_cjs.identityAssertionSemanticKey(
245
+ assertion.relation,
246
+ assertion.a,
247
+ assertion.b
248
+ );
249
+ }
250
+ function compareIdentitySurvivors(left, right) {
251
+ const byValidity = chunkXMQSEJCF_cjs.compareCodePoints(left.validFrom, right.validFrom);
252
+ return byValidity === 0 ? chunkXMQSEJCF_cjs.compareCodePoints(left.id, right.id) : byValidity;
253
+ }
254
+ var DUPLICATE_IDENTITY_ASSERTION_DROP_REASON = "identity:duplicate-assertion";
255
+ var REDUNDANT_IDENTITY_ASSERTION_DROP_REASON = "identity:endpoints-collapsed";
256
+ function droppedIdentityAssertion(assertion, reason) {
257
+ return { kind: "identity", id: assertion.id, reason };
258
+ }
259
+ function dedupeIdentityAssertions(assertions, committedIds) {
260
+ const survivorBySemantic = /* @__PURE__ */ new Map();
261
+ const dropped = [];
262
+ for (const assertion of assertions) {
263
+ const key = identitySemanticKey(assertion);
264
+ const previous = survivorBySemantic.get(key);
265
+ if (previous === void 0) {
266
+ survivorBySemantic.set(key, assertion);
267
+ continue;
268
+ }
269
+ const assertionCommitted = committedIds.has(assertion.id);
270
+ const previousCommitted = committedIds.has(previous.id);
271
+ const [survivor, loser] = assertionCommitted === previousCommitted ? compareIdentitySurvivors(assertion, previous) < 0 ? [assertion, previous] : [previous, assertion] : assertionCommitted ? [assertion, previous] : [previous, assertion];
272
+ survivorBySemantic.set(key, survivor);
273
+ if (loser.id === survivor.id && loser.validFrom === survivor.validFrom && (loser.validTo ?? void 0) === (survivor.validTo ?? void 0)) {
274
+ continue;
275
+ }
276
+ dropped.push(
277
+ droppedIdentityAssertion(loser, DUPLICATE_IDENTITY_ASSERTION_DROP_REASON)
278
+ );
279
+ }
280
+ return {
281
+ survivors: [...survivorBySemantic.values()].toSorted(
282
+ (left, right) => chunkXMQSEJCF_cjs.compareCodePoints(identitySemanticKey(left), identitySemanticKey(right))
283
+ ),
284
+ dropped
285
+ };
286
+ }
287
+ function assertNoOpposingIdentityRelations(assertions) {
288
+ const byEndpoint = /* @__PURE__ */ new Map();
289
+ for (const assertion of assertions) {
290
+ const key = identityEndpointKey(assertion);
291
+ const group = byEndpoint.get(key) ?? [];
292
+ group.push(assertion);
293
+ byEndpoint.set(key, group);
294
+ }
295
+ for (const [endpoint, group] of byEndpoint) {
296
+ if (new Set(group.map((assertion) => assertion.relation)).size < 2) {
297
+ continue;
298
+ }
299
+ throw new IdentityMergeConflictError(
300
+ "Branches asserted opposing identity relations for one endpoint pair.",
301
+ { details: { endpoint, assertions: group } }
302
+ );
303
+ }
304
+ }
305
+ function assertNoRetractReassertRace(staging) {
306
+ const retractedBySemantic = /* @__PURE__ */ new Map();
307
+ for (const staged of staging.retractedIdentityAssertions) {
308
+ const key = identitySemanticKey(staged.assertion);
309
+ const retractions = retractedBySemantic.get(key) ?? [];
310
+ retractions.push(staged);
311
+ retractedBySemantic.set(key, retractions);
312
+ }
313
+ for (const staged of staging.newIdentityAssertions) {
314
+ const retractions = retractedBySemantic.get(identitySemanticKey(staged.assertion)) ?? [];
315
+ const selfRetracted = retractions.some(
316
+ (retraction) => retraction.branchId === staged.branchId
317
+ );
318
+ if (selfRetracted) {
319
+ continue;
320
+ }
321
+ const crossBranchRetraction = retractions.find(
322
+ (retraction) => retraction.assertion.id !== staged.assertion.id
323
+ );
324
+ if (crossBranchRetraction !== void 0) {
325
+ throw new IdentityMergeConflictError(
326
+ "Branches contain a retract/reassert race for one identity pair.",
327
+ {
328
+ details: {
329
+ retractedAssertion: crossBranchRetraction.assertion,
330
+ retractedBy: crossBranchRetraction.branchId,
331
+ reassertedAssertion: staged.assertion,
332
+ reassertedBy: staged.branchId
333
+ }
334
+ }
335
+ );
336
+ }
337
+ }
338
+ }
339
+ var RETRACTION_TARGET_MISMATCH_DROP_REASON = "identity:retraction-target-mismatch";
340
+ var RETRACTION_DELETION_OVERRULED_DROP_REASON = "identity:deletion-overruled";
341
+ var NO_STORED_ASSERTIONS = /* @__PURE__ */ new Map();
342
+ function planIdentityChanges(staging, storedIdentityRowsById) {
343
+ assertNoOpposingIdentityRelations(
344
+ staging.newIdentityAssertions.map((staged) => staged.assertion)
345
+ );
346
+ assertNoRetractReassertRace(staging);
347
+ assertOneIdOneTruth(
348
+ staging.newIdentityAssertions.map((staged) => staged.assertion),
349
+ NO_STORED_ASSERTIONS
350
+ );
351
+ const committedIds = new Set(
352
+ staging.newIdentityAssertions.map((staged) => staged.assertion).filter((assertion) => {
353
+ const stored = storedIdentityRowsById.get(assertion.id);
354
+ return stored !== void 0 && assertionTruthKey(stored) === assertionTruthKey(assertion);
355
+ }).map((assertion) => assertion.id)
356
+ );
357
+ const deduped = dedupeIdentityAssertions(
358
+ staging.newIdentityAssertions.map((staged) => staged.assertion),
359
+ committedIds
360
+ );
361
+ const retractionById = /* @__PURE__ */ new Map();
362
+ for (const staged of staging.retractedIdentityAssertions) {
363
+ const previous = retractionById.get(staged.assertion.id);
364
+ if (previous !== void 0 && assertionIdentityKey(previous) !== assertionIdentityKey(staged.assertion)) {
365
+ throw new IdentityMergeConflictError(
366
+ "One assertion id was staged for retraction with two different identity truths.",
367
+ {
368
+ details: {
369
+ assertionId: staged.assertion.id,
370
+ first: previous,
371
+ second: staged.assertion
372
+ }
373
+ }
374
+ );
375
+ }
376
+ retractionById.set(staged.assertion.id, staged.assertion);
377
+ }
378
+ const retractions = [];
379
+ const retractionDropped = [];
380
+ for (const [assertionId, retraction] of retractionById) {
381
+ const stored = storedIdentityRowsById.get(assertionId);
382
+ if (stored !== void 0 && stored.validTo === void 0 && assertionIdentityKey(stored) !== assertionIdentityKey(retraction)) {
383
+ retractionDropped.push({
384
+ kind: "identity",
385
+ id: assertionId,
386
+ reason: RETRACTION_TARGET_MISMATCH_DROP_REASON
387
+ });
388
+ continue;
389
+ }
390
+ retractions.push(retraction);
391
+ }
392
+ const survivingIds = new Set(
393
+ deduped.survivors.map((survivor) => survivor.id)
394
+ );
395
+ for (const retraction of retractions) {
396
+ if (survivingIds.has(retraction.id)) {
397
+ throw new IdentityMergeConflictError(
398
+ "One assertion id was staged as both a new assertion and a retraction.",
399
+ { details: { assertionId: retraction.id } }
400
+ );
401
+ }
402
+ }
403
+ return {
404
+ assertions: deduped.survivors,
405
+ retractions: retractions.toSorted(
406
+ (left, right) => chunkXMQSEJCF_cjs.compareCodePoints(left.id, right.id)
407
+ ),
408
+ dropped: [...deduped.dropped, ...retractionDropped]
409
+ };
410
+ }
411
+ function resolveIdentityEndpoint(endpoint, canonicalOf, retypeMap) {
412
+ const key = mergeKeyOf(endpoint);
413
+ const canonical = canonicalOf.get(key) ?? key;
414
+ return {
415
+ kind: retypeMap.get(canonical) ?? kindOf(canonical),
416
+ id: idOf(canonical)
417
+ };
418
+ }
419
+ function remapIdentityAssertionEndpoints(assertions, canonicalOf, retypeMap, storedRowsById) {
420
+ const remapped = [];
421
+ const dropped = [];
422
+ for (const assertion of assertions) {
423
+ const remappedA = resolveIdentityEndpoint(
424
+ assertion.a,
425
+ canonicalOf,
426
+ retypeMap
427
+ );
428
+ const remappedB = resolveIdentityEndpoint(
429
+ assertion.b,
430
+ canonicalOf,
431
+ retypeMap
432
+ );
433
+ if (mergeKeyOf(remappedA) === mergeKeyOf(remappedB)) {
434
+ if (assertion.relation === "different") {
435
+ throw new IdentityMergeConflictError(
436
+ "Node reconciliation collapsed a different-identity assertion onto one survivor.",
437
+ { details: { assertion, survivor: remappedA } }
438
+ );
439
+ }
440
+ dropped.push(
441
+ droppedIdentityAssertion(
442
+ assertion,
443
+ REDUNDANT_IDENTITY_ASSERTION_DROP_REASON
444
+ )
445
+ );
446
+ continue;
447
+ }
448
+ const [a, b] = chunkXNLIZYRZ_cjs.normalizeIdentityPair(remappedA, remappedB);
449
+ const result = { ...assertion, a, b };
450
+ const stored = storedRowsById.get(assertion.id);
451
+ if (stored !== void 0 && assertionTruthKey(stored) === assertionTruthKey(assertion) && assertionTruthKey(result) !== assertionTruthKey(assertion)) {
452
+ throw new IdentityMergeConflictError(
453
+ "Node reconciliation moved the endpoints of an assertion already committed on the target; committed identity rows cannot be rewritten by a merge.",
454
+ {
455
+ details: { assertionId: assertion.id, stored, remapped: result },
456
+ suggestion: "Exclude the colliding nodes from entity resolution, or manually retract the committed assertion and re-assert the canonical pair under a new id before merging."
457
+ }
458
+ );
459
+ }
460
+ remapped.push(result);
461
+ }
462
+ const committedIds = new Set(
463
+ remapped.filter((assertion) => {
464
+ const stored = storedRowsById.get(assertion.id);
465
+ return stored !== void 0 && assertionTruthKey(stored) === assertionTruthKey(assertion);
466
+ }).map((assertion) => assertion.id)
467
+ );
468
+ const deduped = dedupeIdentityAssertions(remapped, committedIds);
469
+ assertNoOpposingIdentityRelations(deduped.survivors);
470
+ return {
471
+ assertions: deduped.survivors,
472
+ dropped: [...dropped, ...deduped.dropped]
473
+ };
474
+ }
475
+ function assertIdentityEndpointsNotDeleted(assertions, nodeDeletions, retypeMap) {
476
+ const deletedIdentities = /* @__PURE__ */ new Set();
477
+ for (const key of nodeDeletions.keys()) {
478
+ deletedIdentities.add(key);
479
+ const retyped = retypeMap.get(key);
480
+ if (retyped !== void 0) {
481
+ deletedIdentities.add(mergeKey(retyped, idOf(key)));
482
+ }
483
+ }
484
+ for (const assertion of assertions) {
485
+ for (const endpoint of [assertion.a, assertion.b]) {
486
+ if (!deletedIdentities.has(mergeKeyOf(endpoint))) {
487
+ continue;
488
+ }
489
+ throw new IdentityMergeConflictError(
490
+ "A branch asserted an identity relation over a node another branch deleted.",
491
+ { details: { assertion, deletedEndpoint: endpoint } }
492
+ );
493
+ }
494
+ }
495
+ }
496
+ function assertNoContradictoryIdentityClosure(plannedAssertions, retractions, baseAssertions, deletedNodes, canonicalOf, retypeMap, identityContext, nodeUniverse) {
497
+ const retracted = new Set(retractions);
498
+ const survivesDeletion = (assertion) => !deletedNodes.has(mergeKey(assertion.a.kind, assertion.a.id)) && !deletedNodes.has(mergeKey(assertion.b.kind, assertion.b.id));
499
+ const mergedLedger = [
500
+ ...plannedAssertions,
501
+ ...baseAssertions.filter(
502
+ (assertion) => !retracted.has(assertion.id) && survivesDeletion(assertion)
503
+ ).map((assertion) => ({
504
+ ...assertion,
505
+ a: resolveIdentityEndpoint(assertion.a, canonicalOf, retypeMap),
506
+ b: resolveIdentityEndpoint(assertion.b, canonicalOf, retypeMap)
507
+ }))
508
+ ];
509
+ const sameClasses = new UnionFind(
510
+ (left, right) => compareMergeKeys(left, right)
511
+ );
512
+ for (const node of nodeUniverse) {
513
+ sameClasses.add(mergeKey(node.kind, node.id));
514
+ }
515
+ for (const assertion of mergedLedger) {
516
+ if (assertion.relation === "same") {
517
+ sameClasses.union(mergeKeyOf(assertion.a), mergeKeyOf(assertion.b));
518
+ }
519
+ }
520
+ const membersOfClass = (root) => sameClasses.members().filter((member) => sameClasses.find(member) === root).map((member) => ({ kind: kindOf(member), id: idOf(member) })).toSorted(
521
+ (left, right) => compareMergeKeys(mergeKeyOf(left), mergeKeyOf(right))
522
+ );
523
+ const firstDisjointPair = (kinds) => {
524
+ for (const [index, left] of kinds.entries()) {
525
+ for (const right of kinds.slice(index + 1)) {
526
+ if (identityContext.areDisjoint(left, right)) return [left, right];
527
+ }
528
+ }
529
+ return void 0;
530
+ };
531
+ const refsById = /* @__PURE__ */ new Map();
532
+ const addRef = (kind, id) => {
533
+ const keys = refsById.get(id) ?? [];
534
+ keys.push(mergeKey(kind, id));
535
+ refsById.set(id, keys);
536
+ };
537
+ for (const node of nodeUniverse) addRef(node.kind, node.id);
538
+ for (const assertion of mergedLedger) {
539
+ addRef(assertion.a.kind, assertion.a.id);
540
+ addRef(assertion.b.kind, assertion.b.id);
541
+ }
542
+ for (const keys of refsById.values()) {
543
+ const disjointKinds = firstDisjointPair([
544
+ ...new Set(keys.map((key) => kindOf(key)))
545
+ ]);
546
+ if (disjointKinds === void 0) continue;
547
+ throw new IdentityMergeConflictError(
548
+ "The merged graph would give one id to two ontology-disjoint kinds.",
549
+ {
550
+ details: {
551
+ disjointKinds,
552
+ sharedId: idOf(chunkN66HCGCY_cjs.requireDefined(keys[0]))
553
+ }
554
+ }
555
+ );
556
+ }
557
+ if (identityContext.sameIdAcrossKinds === "fold") {
558
+ for (const keys of refsById.values()) {
559
+ const [first, ...rest] = keys;
560
+ if (first === void 0) continue;
561
+ for (const other of rest) sameClasses.union(first, other);
562
+ }
563
+ }
564
+ for (const assertion of mergedLedger) {
565
+ if (assertion.relation !== "different") {
566
+ continue;
567
+ }
568
+ const root = sameClasses.find(mergeKeyOf(assertion.a));
569
+ if (root !== sameClasses.find(mergeKeyOf(assertion.b))) {
570
+ continue;
571
+ }
572
+ throw new IdentityMergeConflictError(
573
+ "The merged identity ledger would assert one pair of nodes is both the same and different.",
574
+ { details: { assertion, sameClass: membersOfClass(root) } }
575
+ );
576
+ }
577
+ const kindsByRoot = /* @__PURE__ */ new Map();
578
+ for (const member of sameClasses.members()) {
579
+ const root = sameClasses.find(member);
580
+ const kinds = kindsByRoot.get(root) ?? /* @__PURE__ */ new Set();
581
+ kinds.add(kindOf(member));
582
+ kindsByRoot.set(root, kinds);
583
+ }
584
+ for (const [root, kinds] of kindsByRoot) {
585
+ const disjointKinds = firstDisjointPair([...kinds]);
586
+ if (disjointKinds === void 0) continue;
587
+ throw new IdentityMergeConflictError(
588
+ "The merged identity ledger would join two ontology-disjoint kinds into one class.",
589
+ { details: { disjointKinds, sameClass: membersOfClass(root) } }
590
+ );
591
+ }
592
+ }
593
+ async function buildIdentityPeerProbe(target, probedIds, targetPeers, plan, profile) {
594
+ const finalIds = /* @__PURE__ */ new Set([
595
+ ...plan.canonicalEntities.filter(
596
+ (entity) => !plan.nodeDeletions.has(mergeKey(entity.kind, entity.canonicalId))
597
+ ).map((entity) => entity.canonicalId),
598
+ ...plan.identityAssertions.flatMap((assertion) => [
599
+ assertion.a.id,
600
+ assertion.b.id
601
+ ])
602
+ ]);
603
+ const plannedDeletions = new Set(plan.nodeDeletions.keys());
604
+ const relevantPeers = targetPeers.filter(
605
+ (peer) => finalIds.has(peer.id) && !plannedDeletions.has(mergeKey(peer.kind, peer.id))
606
+ );
607
+ const seedsByKey = /* @__PURE__ */ new Map();
608
+ const addSeed = (kind, id) => {
609
+ seedsByKey.set(mergeKey(kind, id), { kind, id });
610
+ };
611
+ for (const entity of plan.canonicalEntities) {
612
+ const sourceKey = mergeKey(entity.kind, entity.canonicalId);
613
+ if (plan.nodeDeletions.has(sourceKey)) continue;
614
+ addSeed(plan.retypeMap.get(sourceKey) ?? entity.kind, entity.canonicalId);
615
+ }
616
+ for (const assertion of plan.identityAssertions) {
617
+ addSeed(assertion.a.kind, assertion.a.id);
618
+ addSeed(assertion.b.kind, assertion.b.id);
619
+ }
620
+ for (const peer of relevantPeers) addSeed(peer.kind, peer.id);
621
+ const seeds = [...seedsByKey.values()];
622
+ const liveKeys = new Set(
623
+ targetPeers.map((peer) => mergeKey(peer.kind, peer.id)).filter((key) => !plannedDeletions.has(key))
624
+ );
625
+ const snapshot = await snapshotIdentityClasses(
626
+ target,
627
+ seeds,
628
+ liveKeys,
629
+ plannedDeletions
630
+ );
631
+ const memberKeys = /* @__PURE__ */ new Set([
632
+ ...seeds.map((seed) => mergeKey(seed.kind, seed.id)),
633
+ ...snapshot.groups.flatMap(
634
+ (group) => group.map((member) => mergeKey(member.kind, member.id))
635
+ )
636
+ ]);
637
+ const ledger = (await relevantLedgerAssertions(target, memberKeys, chunkTTAITEPJ_cjs.storeBackend(target))).filter(
638
+ (assertion) => !plannedDeletions.has(mergeKey(assertion.a.kind, assertion.a.id)) && !plannedDeletions.has(mergeKey(assertion.b.kind, assertion.b.id))
639
+ );
640
+ return {
641
+ probe: {
642
+ profile,
643
+ plannedDeletions,
644
+ ids: probedIds.filter((id) => finalIds.has(id)),
645
+ observed: new Set(
646
+ relevantPeers.map((peer) => mergeKey(peer.kind, peer.id))
647
+ ),
648
+ memberKeys,
649
+ differentFingerprint: differentLedgerFingerprint(ledger),
650
+ classFingerprints: snapshot.fingerprints,
651
+ seeds
652
+ },
653
+ snapshot,
654
+ ledger
655
+ };
656
+ }
657
+ async function snapshotIdentityClasses(target, seeds, liveKeys, plannedDeletions, txBackend) {
658
+ const classes = await chunkTTAITEPJ_cjs.storeRuntime(target).structuralIdentityClasses(
659
+ seeds,
660
+ txBackend
661
+ );
662
+ const fingerprints = /* @__PURE__ */ new Map();
663
+ const groups = [];
664
+ for (const seed of seeds) {
665
+ const key = mergeKey(seed.kind, seed.id);
666
+ const members = (classes.get(chunkXNLIZYRZ_cjs.identityReferenceKey(seed)) ?? [seed]).filter(
667
+ (member) => !plannedDeletions.has(mergeKey(member.kind, member.id))
668
+ );
669
+ groups.push(members);
670
+ fingerprints.set(key, encodeClassFingerprint(liveKeys.has(key), members));
671
+ }
672
+ return { fingerprints, groups };
673
+ }
674
+ async function relevantLedgerAssertions(target, memberKeys, backend) {
675
+ const current = await chunkTTAITEPJ_cjs.storeRuntime(target).identityAssertionsAtTarget(
676
+ backend,
677
+ "state"
678
+ );
679
+ return current.filter(
680
+ (assertion) => memberKeys.has(mergeKey(assertion.a.kind, assertion.a.id)) || memberKeys.has(mergeKey(assertion.b.kind, assertion.b.id))
681
+ );
682
+ }
683
+ function differentLedgerFingerprint(assertions) {
684
+ return JSON.stringify(
685
+ assertions.filter((assertion) => assertion.relation === "different").map((assertion) => [assertion.id, ...endpointTuple(assertion)]).toSorted(
686
+ (left, right) => chunkXMQSEJCF_cjs.compareStrings(chunkXNLIZYRZ_cjs.encodeTupleKey(left), chunkXNLIZYRZ_cjs.encodeTupleKey(right))
687
+ )
688
+ );
689
+ }
690
+ function encodeClassFingerprint(live, members) {
691
+ return JSON.stringify([
692
+ live,
693
+ members.map((member) => [member.kind, member.id]).toSorted(
694
+ ([leftKind, leftId], [rightKind, rightId]) => compareMergeKeys(
695
+ mergeKey(leftKind, leftId),
696
+ mergeKey(rightKind, rightId)
697
+ )
698
+ )
699
+ ]);
700
+ }
701
+ function assertionTruthKey(assertion) {
702
+ return JSON.stringify([
703
+ assertion.relation,
704
+ ...endpointTuple(assertion),
705
+ assertion.validFrom,
706
+ assertion.validTo ?? null
707
+ ]);
708
+ }
709
+ function assertionIdentityKey(assertion) {
710
+ return JSON.stringify([
711
+ assertion.relation,
712
+ ...endpointTuple(assertion),
713
+ assertion.validFrom
714
+ ]);
715
+ }
716
+ function assertOneIdOneTruth(planned, storedById) {
717
+ const plannedById = /* @__PURE__ */ new Map();
718
+ for (const assertion of planned) {
719
+ const previous = plannedById.get(assertion.id);
720
+ if (previous !== void 0 && assertionTruthKey(previous) !== assertionTruthKey(assertion)) {
721
+ throw new IdentityMergeConflictError(
722
+ "One assertion id was staged for two different identity truths.",
723
+ {
724
+ details: {
725
+ assertionId: assertion.id,
726
+ first: previous,
727
+ second: assertion
728
+ }
729
+ }
730
+ );
731
+ }
732
+ plannedById.set(assertion.id, assertion);
733
+ const stored = storedById.get(assertion.id);
734
+ if (stored !== void 0 && assertionTruthKey(stored) !== assertionTruthKey(assertion)) {
735
+ throw new IdentityMergeConflictError(
736
+ "A staged assertion id already identifies different truth in the target ledger.",
737
+ { details: { assertionId: assertion.id, staged: assertion, stored } }
738
+ );
739
+ }
740
+ }
741
+ }
742
+ async function assertPlannedIdentityIdsFresh(target, txBackend, plan) {
743
+ const plannedIds = [
744
+ ...plan.identityAssertions.map((assertion) => assertion.id),
745
+ ...plan.identityRetractions.map((retraction) => retraction.id)
746
+ ];
747
+ if (plannedIds.length === 0) return;
748
+ const storedById = await chunkTTAITEPJ_cjs.storeRuntime(target).identityAssertionRowsByIds(
749
+ plannedIds,
750
+ txBackend
751
+ );
752
+ for (const assertion of plan.identityAssertions) {
753
+ const stored = storedById.get(assertion.id);
754
+ if (stored !== void 0 && assertionTruthKey(stored) !== assertionTruthKey(assertion)) {
755
+ throw new BaseVersionMismatchError(
756
+ "The merge validated its assertion ids as of planning, but a row identifying different truth under a planned id was committed before the commit transaction.",
757
+ {
758
+ details: { assertionId: assertion.id },
759
+ suggestion: "Retry the merge \u2014 the plan is recomputed from current state. A persistent refusal means the branch's assertion id conflicts with target truth and needs manual resolution."
760
+ }
761
+ );
762
+ }
763
+ }
764
+ for (const retraction of plan.identityRetractions) {
765
+ const stored = storedById.get(retraction.id);
766
+ if (stored !== void 0 && stored.validTo === void 0 && assertionIdentityKey(stored) !== assertionIdentityKey(retraction)) {
767
+ throw new BaseVersionMismatchError(
768
+ "The merge validated each planned retraction against the target row its id identified at planning, but that row's truth changed before the commit transaction.",
769
+ {
770
+ details: { assertionId: retraction.id },
771
+ suggestion: "Retry the merge \u2014 the plan is recomputed from current state."
772
+ }
773
+ );
774
+ }
775
+ }
776
+ }
777
+ function affectedIdentityClassSeeds(plan, profile) {
778
+ const seedsByKey = /* @__PURE__ */ new Map();
779
+ const addSeed = (kind, id) => {
780
+ const key = mergeKey(kind, id);
781
+ if (plan.nodeDeletions.has(key)) return;
782
+ seedsByKey.set(key, { kind, id });
783
+ };
784
+ for (const assertion of [
785
+ ...plan.identityAssertions,
786
+ ...plan.identityRetractions
787
+ ]) {
788
+ addSeed(assertion.a.kind, assertion.a.id);
789
+ addSeed(assertion.b.kind, assertion.b.id);
790
+ }
791
+ if (profile === "fold") {
792
+ for (const entity of plan.canonicalEntities) {
793
+ const sourceKey = mergeKey(entity.kind, entity.canonicalId);
794
+ if (plan.nodeDeletions.has(sourceKey)) continue;
795
+ addSeed(plan.retypeMap.get(sourceKey) ?? entity.kind, entity.canonicalId);
796
+ }
797
+ }
798
+ return [...seedsByKey.values()];
799
+ }
800
+ async function assertMergedIdentityClassesConsistent(target, txBackend, plan) {
801
+ await chunkTTAITEPJ_cjs.storeRuntime(target).assertIdentityClassesConsistentAtTarget(
802
+ txBackend,
803
+ affectedIdentityClassSeeds(plan, target.graph.identity?.sameIdAcrossKinds)
804
+ );
805
+ }
806
+ var IDENTITY_ENVIRONMENT_CODES = /* @__PURE__ */ new Set([
807
+ "IDENTITY_MERGE_REQUIRES_PROFILE",
808
+ "IDENTITY_REQUIRES_ATOMIC_BACKEND",
809
+ "IDENTITY_REQUIRES_STATEMENT_EXECUTION",
810
+ "IDENTITY_BIND_BUDGET_TOO_SMALL",
811
+ // Environment/corruption statements — translating one into "re-plan against
812
+ // the current target" would be advice that can never succeed. The applier
813
+ // reaches the last two through the current different-ness probe (see
814
+ // `identity/separation`), which refuses rather than guessing when the derived
815
+ // separation relation is missing or disagrees with the ledger.
816
+ "IDENTITY_NOT_ENABLED",
817
+ "IDENTITY_STORAGE_MISSING",
818
+ "IDENTITY_SCHEMA_CONTRADICTION",
819
+ "IDENTITY_IMPORT_REQUIRES_PROFILE"
820
+ ]);
821
+ function identityRefusalCode(error) {
822
+ const detailCode = error.details["code"];
823
+ if (typeof detailCode === "string" && detailCode.startsWith("IDENTITY_")) {
824
+ return detailCode;
825
+ }
826
+ if (error.code.startsWith("IDENTITY_")) return error.code;
827
+ const issues = error.details["issues"];
828
+ if (Array.isArray(issues)) {
829
+ for (const issue of issues) {
830
+ const code = issue["code"];
831
+ if (typeof code === "string" && code.startsWith("IDENTITY_")) {
832
+ return code;
833
+ }
834
+ }
835
+ }
836
+ return void 0;
837
+ }
838
+ function translateIdentityCommitError(error) {
839
+ if (error instanceof MergeError) return error;
840
+ if (!(error instanceof chunkNI72YOJB_cjs.TypeGraphError)) return error;
841
+ const identityCode = identityRefusalCode(error);
842
+ const identityRefusal = error instanceof chunkNI72YOJB_cjs.IdentityContradictionError || error instanceof chunkNI72YOJB_cjs.NodeNotFoundError || identityCode !== void 0 && !IDENTITY_ENVIRONMENT_CODES.has(identityCode);
843
+ if (!identityRefusal) return error;
844
+ return new IdentityMergeConflictError(
845
+ `The identity applier refused the resolved plan inside the commit transaction \u2014 identity truth on the target is incompatible with the plan. Cause: ${describeCause(error)}`,
846
+ {
847
+ cause: error,
848
+ details: { ...identityCode === void 0 ? {} : { identityCode } },
849
+ suggestion: "Retry once \u2014 the plan is recomputed from current state. If the refusal persists, the branches' identity truth conflicts with the target and needs manual resolution (change the branch's assertion, or resolve the target's truth first)."
850
+ }
851
+ );
852
+ }
853
+ async function assertIdentityPeersStable(target, txBackend, probe, plan) {
854
+ if (probe === void 0) return;
855
+ const live = (await chunkTTAITEPJ_cjs.storeRuntime(target).liveNodesSharingIds(probe.ids, txBackend)).filter((peer) => !probe.plannedDeletions.has(mergeKey(peer.kind, peer.id)));
856
+ const seedKindsById = /* @__PURE__ */ new Map();
857
+ for (const seed of probe.seeds) {
858
+ const kinds = seedKindsById.get(seed.id) ?? /* @__PURE__ */ new Set();
859
+ kinds.add(seed.kind);
860
+ seedKindsById.set(seed.id, kinds);
861
+ }
862
+ const appeared = live.filter(
863
+ (peer) => probe.profile === "fold" || [...seedKindsById.get(peer.id) ?? []].some(
864
+ (kind) => target.registry.areDisjoint(peer.kind, kind)
865
+ )
866
+ ).map((peer) => mergeKey(peer.kind, peer.id)).filter((key) => !probe.observed.has(key)).sort((left, right) => compareMergeKeys(left, right));
867
+ if (appeared.length > 0) {
868
+ throw new BaseVersionMismatchError(
869
+ `mergeIncremental() simulated identity folding against the target's live same-id peers as of planning, but ${appeared.length} committed row(s) sharing a planned node's id appeared before the commit transaction. Committing the plan could fold nodes into classes the plan never validated.`,
870
+ { details: { appeared } }
871
+ );
872
+ }
873
+ const { fingerprints: liveFingerprints, groups: liveGroups } = await snapshotIdentityClasses(
874
+ target,
875
+ probe.seeds,
876
+ new Set(live.map((peer) => mergeKey(peer.kind, peer.id))),
877
+ probe.plannedDeletions,
878
+ txBackend
879
+ );
880
+ const drifted = [...probe.classFingerprints].filter(([key, fingerprint]) => liveFingerprints.get(key) !== fingerprint).map(([key]) => key).sort((left, right) => chunkXMQSEJCF_cjs.compareStrings(left, right));
881
+ if (drifted.length > 0) {
882
+ throw new BaseVersionMismatchError(
883
+ `mergeIncremental() validated identity against the classes visible at planning, but the identity class of ${drifted.length} node(s) the plan folds on changed before the commit transaction. Committing the plan could contradict identity truth it never validated.`,
884
+ { details: { drifted } }
885
+ );
886
+ }
887
+ const ledger = (await relevantLedgerAssertions(target, probe.memberKeys, txBackend)).filter(
888
+ (assertion) => !probe.plannedDeletions.has(mergeKey(assertion.a.kind, assertion.a.id)) && !probe.plannedDeletions.has(mergeKey(assertion.b.kind, assertion.b.id))
889
+ );
890
+ if (differentLedgerFingerprint(ledger) !== probe.differentFingerprint) {
891
+ throw new BaseVersionMismatchError(
892
+ "mergeIncremental() validated identity against the `different` assertions visible at planning, but that ledger changed before the commit transaction. Committing the plan could contradict identity truth it never validated.",
893
+ { details: {} }
894
+ );
895
+ }
896
+ try {
897
+ assertNoContradictoryIdentityClosure(
898
+ plan.identityAssertions,
899
+ plan.identityRetractions.map((retraction) => retraction.id),
900
+ ledger,
901
+ probe.plannedDeletions,
902
+ plan.canonicalOf,
903
+ plan.retypeMap,
904
+ {
905
+ sameIdAcrossKinds: probe.profile,
906
+ areDisjoint: (left, right) => target.registry.areDisjoint(left, right)
907
+ },
908
+ [...probe.seeds, ...liveGroups.flat()]
909
+ );
910
+ } catch (error) {
911
+ if (!(error instanceof IdentityMergeConflictError)) throw error;
912
+ throw new BaseVersionMismatchError(
913
+ "mergeIncremental() validated identity as of planning, but identity truth committed before the commit transaction invalidates the plan. Re-plan against the current target.",
914
+ { details: { conflict: error.message } }
915
+ );
916
+ }
917
+ }
918
+
106
919
  // src/graph-merge/state-diff.ts
107
920
  var ENUMERATION_PAGE_SIZE = 1e3;
921
+ var EXPLICIT_RETRACTION = { kind: "explicit" };
922
+ function validWindowOf(row) {
923
+ return {
924
+ validFrom: chunkQ7Q4WSLJ_cjs.canonicalizeDatabaseTimestamp(row.valid_from),
925
+ validTo: chunkQ7Q4WSLJ_cjs.canonicalizeDatabaseTimestamp(row.valid_to)
926
+ };
927
+ }
928
+ function windowsDiffer(left, right) {
929
+ return left.validFrom !== right.validFrom || left.validTo !== right.validTo;
930
+ }
108
931
  async function enumerateAllNodes(backend, graphId, kind) {
109
932
  const collected = [];
110
933
  let after;
@@ -123,7 +946,7 @@ async function enumerateAllNodes(backend, graphId, kind) {
123
946
  if (page.length < ENUMERATION_PAGE_SIZE) {
124
947
  break;
125
948
  }
126
- after = chunk764JHTLT_cjs.requireDefined(page.at(-1)).id;
949
+ after = chunkN66HCGCY_cjs.requireDefined(page.at(-1)).id;
127
950
  }
128
951
  return collected;
129
952
  }
@@ -145,7 +968,7 @@ async function enumerateAllEdges(backend, graphId, kind) {
145
968
  if (page.length < ENUMERATION_PAGE_SIZE) {
146
969
  break;
147
970
  }
148
- after = chunk764JHTLT_cjs.requireDefined(page.at(-1)).id;
971
+ after = chunkN66HCGCY_cjs.requireDefined(page.at(-1)).id;
149
972
  }
150
973
  return collected;
151
974
  }
@@ -165,6 +988,7 @@ function diffNodeKind(kind, baseRows, forkRows) {
165
988
  const created = [];
166
989
  const modified = [];
167
990
  const deleted = [];
991
+ const windowed = [];
168
992
  for (const forkRow of forkRows) {
169
993
  if (!isLive(forkRow)) {
170
994
  continue;
@@ -190,6 +1014,16 @@ function diffNodeKind(kind, baseRows, forkRows) {
190
1014
  row: forkRow
191
1015
  });
192
1016
  }
1017
+ const baseWindow = validWindowOf(baseRow);
1018
+ const forkWindow = validWindowOf(forkRow);
1019
+ if (windowsDiffer(baseWindow, forkWindow)) {
1020
+ windowed.push({
1021
+ id: forkRow.id,
1022
+ kind,
1023
+ base: baseWindow,
1024
+ fork: forkWindow
1025
+ });
1026
+ }
193
1027
  }
194
1028
  for (const baseRow of baseRows) {
195
1029
  if (!isLive(baseRow)) {
@@ -197,10 +1031,14 @@ function diffNodeKind(kind, baseRows, forkRows) {
197
1031
  }
198
1032
  const forkRow = forkIndex.get(baseRow.id);
199
1033
  if (forkRow === void 0 || !isLive(forkRow)) {
200
- deleted.push({ id: baseRow.id, kind });
1034
+ deleted.push({
1035
+ id: baseRow.id,
1036
+ kind,
1037
+ deletedAt: forkRow === void 0 ? void 0 : chunkQ7Q4WSLJ_cjs.canonicalizeDatabaseTimestamp(forkRow.deleted_at)
1038
+ });
201
1039
  }
202
1040
  }
203
- return { new: created, modified, deleted };
1041
+ return { new: created, modified, deleted, windowed };
204
1042
  }
205
1043
  function diffEdgeKind(kind, baseRows, forkRows) {
206
1044
  const baseIndex = indexById(baseRows);
@@ -208,6 +1046,7 @@ function diffEdgeKind(kind, baseRows, forkRows) {
208
1046
  const created = [];
209
1047
  const modified = [];
210
1048
  const deleted = [];
1049
+ const windowed = [];
211
1050
  for (const forkRow of forkRows) {
212
1051
  if (!isLive(forkRow)) {
213
1052
  continue;
@@ -241,6 +1080,22 @@ function diffEdgeKind(kind, baseRows, forkRows) {
241
1080
  row: forkRow
242
1081
  });
243
1082
  }
1083
+ const baseWindow = validWindowOf(baseRow);
1084
+ const forkWindow = validWindowOf(forkRow);
1085
+ if (windowsDiffer(baseWindow, forkWindow)) {
1086
+ windowed.push({
1087
+ id: forkRow.id,
1088
+ kind,
1089
+ fromId: forkRow.from_id,
1090
+ toId: forkRow.to_id,
1091
+ fromKind: forkRow.from_kind,
1092
+ toKind: forkRow.to_kind,
1093
+ props: forkProps,
1094
+ baseProps,
1095
+ base: baseWindow,
1096
+ fork: forkWindow
1097
+ });
1098
+ }
244
1099
  }
245
1100
  for (const baseRow of baseRows) {
246
1101
  if (!isLive(baseRow)) {
@@ -251,27 +1106,82 @@ function diffEdgeKind(kind, baseRows, forkRows) {
251
1106
  deleted.push({ id: baseRow.id, kind });
252
1107
  }
253
1108
  }
254
- return { new: created, modified, deleted };
1109
+ return { new: created, modified, deleted, windowed };
1110
+ }
1111
+ function classifyRetraction(assertion, deletedByKey, forkAssertion) {
1112
+ if (forkAssertion !== void 0) {
1113
+ const stamp = forkAssertion.endedBy;
1114
+ if (stamp !== void 0 && deletedByKey.has(mergeKey(stamp.kind, stamp.id))) {
1115
+ return { kind: "cascade", deletedNode: { ...stamp } };
1116
+ }
1117
+ return EXPLICIT_RETRACTION;
1118
+ }
1119
+ for (const endpoint of [assertion.a, assertion.b]) {
1120
+ const deletion = deletedByKey.get(mergeKey(endpoint.kind, endpoint.id));
1121
+ if (deletion !== void 0 && deletion.deletedAt === void 0) {
1122
+ return {
1123
+ kind: "cascade",
1124
+ deletedNode: { kind: deletion.kind, id: deletion.id }
1125
+ };
1126
+ }
1127
+ }
1128
+ return EXPLICIT_RETRACTION;
1129
+ }
1130
+ async function classifyRetractions(forkStore, retracted, deletedNodes) {
1131
+ if (retracted.length === 0 || deletedNodes.length === 0) {
1132
+ return retracted.map((assertion) => ({
1133
+ assertion,
1134
+ cause: EXPLICIT_RETRACTION
1135
+ }));
1136
+ }
1137
+ const deletedByKey = new Map(
1138
+ deletedNodes.map((deletion) => [
1139
+ mergeKey(deletion.kind, deletion.id),
1140
+ deletion
1141
+ ])
1142
+ );
1143
+ const forkRowsById = await chunkTTAITEPJ_cjs.storeRuntime(forkStore).identityAssertionRowsByIds(
1144
+ retracted.map((assertion) => assertion.id)
1145
+ );
1146
+ return retracted.map((assertion) => ({
1147
+ assertion,
1148
+ cause: classifyRetraction(
1149
+ assertion,
1150
+ deletedByKey,
1151
+ forkRowsById.get(assertion.id)
1152
+ )
1153
+ }));
255
1154
  }
256
1155
  function byId(left, right) {
257
- return chunkTRF4EBJT_cjs.compareStrings(left.id, right.id);
1156
+ return chunkXMQSEJCF_cjs.compareStrings(left.id, right.id);
258
1157
  }
259
1158
  async function diffAgainstBase(baseStore, forkStore, captureForkState = true) {
260
1159
  const graph = baseStore.graph;
261
- const nodeKinds = chunkQB6VMOJ2_cjs.getNodeKinds(graph);
262
- const edgeKinds = chunkQB6VMOJ2_cjs.getEdgeKinds(graph);
1160
+ const nodeKinds = chunkCXBHOOIQ_cjs.getNodeKinds(graph);
1161
+ const edgeKinds = chunkCXBHOOIQ_cjs.getEdgeKinds(graph);
1162
+ const [baseIdentity, forkIdentity] = await Promise.all([
1163
+ chunkTTAITEPJ_cjs.storeRuntime(baseStore).readCurrentIdentityAssertions("state"),
1164
+ chunkTTAITEPJ_cjs.storeRuntime(forkStore).readCurrentIdentityAssertions("state")
1165
+ ]);
1166
+ const baseIdentityById = new Map(
1167
+ baseIdentity.map((assertion) => [assertion.id, assertion])
1168
+ );
1169
+ const forkIdentityById = new Map(
1170
+ forkIdentity.map((assertion) => [assertion.id, assertion])
1171
+ );
263
1172
  const newNodes = [];
264
1173
  const modifiedNodes = [];
265
1174
  const deletedNodes = [];
1175
+ const windowedNodes = [];
266
1176
  const forkNodeVersions = /* @__PURE__ */ new Map();
267
1177
  for (const kind of nodeKinds) {
268
1178
  const baseRows = await enumerateAllNodes(
269
- chunk7V2FGGI2_cjs.storeBackend(baseStore),
1179
+ chunkTTAITEPJ_cjs.storeBackend(baseStore),
270
1180
  baseStore.graphId,
271
1181
  kind
272
1182
  );
273
1183
  const forkRows = await enumerateAllNodes(
274
- chunk7V2FGGI2_cjs.storeBackend(forkStore),
1184
+ chunkTTAITEPJ_cjs.storeBackend(forkStore),
275
1185
  forkStore.graphId,
276
1186
  kind
277
1187
  );
@@ -290,19 +1200,23 @@ async function diffAgainstBase(baseStore, forkStore, captureForkState = true) {
290
1200
  for (const entry of delta.deleted) {
291
1201
  deletedNodes.push(entry);
292
1202
  }
1203
+ for (const entry of delta.windowed) {
1204
+ windowedNodes.push(entry);
1205
+ }
293
1206
  }
294
1207
  const newEdges = [];
295
1208
  const modifiedEdges = [];
296
1209
  const deletedEdges = [];
1210
+ const windowedEdges = [];
297
1211
  const forkEdgeSignatures = /* @__PURE__ */ new Map();
298
1212
  for (const kind of edgeKinds) {
299
1213
  const baseRows = await enumerateAllEdges(
300
- chunk7V2FGGI2_cjs.storeBackend(baseStore),
1214
+ chunkTTAITEPJ_cjs.storeBackend(baseStore),
301
1215
  baseStore.graphId,
302
1216
  kind
303
1217
  );
304
1218
  const forkRows = await enumerateAllEdges(
305
- chunk7V2FGGI2_cjs.storeBackend(forkStore),
1219
+ chunkTTAITEPJ_cjs.storeBackend(forkStore),
306
1220
  forkStore.graphId,
307
1221
  kind
308
1222
  );
@@ -331,17 +1245,46 @@ async function diffAgainstBase(baseStore, forkStore, captureForkState = true) {
331
1245
  for (const entry of delta.deleted) {
332
1246
  deletedEdges.push(entry);
333
1247
  }
1248
+ for (const entry of delta.windowed) {
1249
+ windowedEdges.push(entry);
1250
+ }
334
1251
  }
1252
+ const retractedAssertions = baseIdentity.filter((assertion) => {
1253
+ const fork = forkIdentityById.get(assertion.id);
1254
+ return fork === void 0 || assertionTruthKey(fork) !== assertionTruthKey(assertion);
1255
+ }).toSorted((left, right) => chunkXMQSEJCF_cjs.compareStrings(left.id, right.id));
1256
+ const classifiedRetractions = await classifyRetractions(
1257
+ forkStore,
1258
+ retractedAssertions,
1259
+ deletedNodes
1260
+ );
335
1261
  return {
336
1262
  nodes: {
337
1263
  new: newNodes.sort((left, right) => byId(left, right)),
338
1264
  modified: modifiedNodes.sort((left, right) => byId(left, right)),
339
- deleted: deletedNodes.sort((left, right) => byId(left, right))
1265
+ deleted: deletedNodes.sort((left, right) => byId(left, right)),
1266
+ windowed: windowedNodes.sort((left, right) => byId(left, right))
340
1267
  },
341
1268
  edges: {
342
1269
  new: newEdges.sort((left, right) => byId(left, right)),
343
1270
  modified: modifiedEdges.sort((left, right) => byId(left, right)),
344
- deleted: deletedEdges.sort((left, right) => byId(left, right))
1271
+ deleted: deletedEdges.sort((left, right) => byId(left, right)),
1272
+ windowed: windowedEdges.sort((left, right) => byId(left, right))
1273
+ },
1274
+ identity: {
1275
+ // Ids present on BOTH sides are compared by COMPLETE truth, not
1276
+ // presence: a fork can hard-delete an assertion's endpoint (physically
1277
+ // removing the row), recreate it, and legally import the same id for
1278
+ // different truth. Presence-only comparison would diff that replacement
1279
+ // as empty and the merge would silently keep the base truth. A shared
1280
+ // id with changed truth surfaces as BOTH retracted (the base row) and
1281
+ // new (the fork row), so planning sees the replacement and can refuse
1282
+ // unsupported id reuse as a typed conflict.
1283
+ new: forkIdentity.filter((assertion) => {
1284
+ const base = baseIdentityById.get(assertion.id);
1285
+ return base === void 0 || assertionTruthKey(base) !== assertionTruthKey(assertion);
1286
+ }).toSorted((left, right) => chunkXMQSEJCF_cjs.compareStrings(left.id, right.id)),
1287
+ retracted: classifiedRetractions
345
1288
  },
346
1289
  forkNodeVersions,
347
1290
  forkEdgeSignatures
@@ -355,9 +1298,11 @@ function asBranchId(value) {
355
1298
  function asBaseVersion(value) {
356
1299
  return value;
357
1300
  }
1301
+ var VALIDITY_END_TARGET_PRECEDENCE = "target";
358
1302
 
359
1303
  // src/graph-merge/base-version.ts
360
1304
  var TOKEN_SEPARATOR = "\0";
1305
+ var SCHEMA_VERSION_TAG = "#s";
361
1306
  var REVISION_COMPONENT_PREFIX = "revision:";
362
1307
  var REVISION_COMPONENT_SEPARATOR = ":";
363
1308
  var INITIAL_REVISION = "initial";
@@ -368,19 +1313,19 @@ async function readActiveSchemaVersion(backend, graphId) {
368
1313
  }
369
1314
  async function computeSchemaComponent(store) {
370
1315
  const version = await readActiveSchemaVersion(
371
- chunk7V2FGGI2_cjs.storeBackend(store),
1316
+ chunkTTAITEPJ_cjs.storeBackend(store),
372
1317
  store.graphId
373
1318
  );
374
- return chunk2VLBGQBY_cjs.computeSchemaHash(chunk2VLBGQBY_cjs.serializeSchema(store.graph, version));
1319
+ return chunkN3257XE6_cjs.computeSchemaHash(chunkN3257XE6_cjs.serializeSchema(store.graph, version));
375
1320
  }
376
1321
  function byDigestEntry(left, right) {
377
- const byKind = chunkTRF4EBJT_cjs.compareStrings(left.kind, right.kind);
378
- return byKind === 0 ? chunkTRF4EBJT_cjs.compareStrings(left.id, right.id) : byKind;
1322
+ const byKind = chunkXMQSEJCF_cjs.compareStrings(left.kind, right.kind);
1323
+ return byKind === 0 ? chunkXMQSEJCF_cjs.compareStrings(left.id, right.id) : byKind;
379
1324
  }
380
1325
  var CONTENT_FINGERPRINT_BYTES = 16;
381
- async function computeContentComponent(backend, graphId, graph) {
382
- const nodeKinds = chunkQB6VMOJ2_cjs.getNodeKinds(graph);
383
- const edgeKinds = chunkQB6VMOJ2_cjs.getEdgeKinds(graph);
1326
+ async function computeContentComponent(backend, graphId, graph, identityAssertions) {
1327
+ const nodeKinds = chunkCXBHOOIQ_cjs.getNodeKinds(graph);
1328
+ const edgeKinds = chunkCXBHOOIQ_cjs.getEdgeKinds(graph);
384
1329
  const nodeDigest = [];
385
1330
  for (const kind of nodeKinds) {
386
1331
  const rows = await enumerateAllNodes(backend, graphId, kind);
@@ -418,30 +1363,41 @@ async function computeContentComponent(backend, graphId, graph) {
418
1363
  return chunkZY4GXIVN_cjs.sha256Hex(
419
1364
  canonicalizeProps({
420
1365
  nodes: nodeDigest.sort((left, right) => byDigestEntry(left, right)),
421
- edges: edgeDigest.sort((left, right) => byDigestEntry(left, right))
1366
+ edges: edgeDigest.sort((left, right) => byDigestEntry(left, right)),
1367
+ ...identityAssertions.length === 0 ? {} : { identity: identityAssertions }
422
1368
  }),
423
1369
  CONTENT_FINGERPRINT_BYTES
424
1370
  );
425
1371
  }
426
1372
  async function computeBaseVersion(store) {
427
1373
  if (store.revisionTrackingEnabled) {
428
- const [schemaComponent2, origin, revision] = await Promise.all([
1374
+ const [schemaComponent2, origin, revision, activeVersion] = await Promise.all([
429
1375
  computeSchemaComponent(store),
430
1376
  store.revisionOriginNow(),
431
- store.revisionNow()
1377
+ store.revisionNow(),
1378
+ readActiveSchemaVersion(chunkTTAITEPJ_cjs.storeBackend(store), store.graphId)
432
1379
  ]);
433
1380
  return asBaseVersion(
434
- `${schemaComponent2}${TOKEN_SEPARATOR}${revisionComponent(origin, revision)}`
1381
+ `${schemaComponent2}${SCHEMA_VERSION_TAG}${activeVersion}${TOKEN_SEPARATOR}${revisionComponent(origin, revision)}`
435
1382
  );
436
1383
  }
437
1384
  const [schemaComponent, contentComponent] = await Promise.all([
438
1385
  computeSchemaComponent(store),
439
- computeContentComponent(chunk7V2FGGI2_cjs.storeBackend(store), store.graphId, store.graph)
1386
+ computeStoreContentComponent(store)
440
1387
  ]);
441
1388
  return asBaseVersion(
442
1389
  `${schemaComponent}${TOKEN_SEPARATOR}${contentComponent}`
443
1390
  );
444
1391
  }
1392
+ async function computeStoreContentComponent(store) {
1393
+ const identityAssertions = await chunkTTAITEPJ_cjs.storeRuntime(store).readCurrentIdentityAssertions("state");
1394
+ return computeContentComponent(
1395
+ chunkTTAITEPJ_cjs.storeBackend(store),
1396
+ store.graphId,
1397
+ store.graph,
1398
+ identityAssertions
1399
+ );
1400
+ }
445
1401
  function revisionComponent(origin, revision) {
446
1402
  return `${REVISION_COMPONENT_PREFIX}${origin}${REVISION_COMPONENT_SEPARATOR}${revision ?? INITIAL_REVISION}`;
447
1403
  }
@@ -471,70 +1427,6 @@ function contentComponentOf(version) {
471
1427
  return separatorIndex === -1 ? version : version.slice(separatorIndex + 1);
472
1428
  }
473
1429
 
474
- // src/graph-merge/errors.ts
475
- var MERGE_ERROR_CODES = {
476
- merge: "GRAPH_MERGE_ERROR",
477
- branch: "GRAPH_MERGE_BRANCH_ERROR",
478
- similarityUnavailable: "GRAPH_MERGE_SIMILARITY_UNAVAILABLE",
479
- conflict: "GRAPH_MERGE_CONFLICT",
480
- baseVersionMismatch: "GRAPH_MERGE_BASE_VERSION_MISMATCH"
481
- };
482
- function toTypeGraphErrorOptions(category, options) {
483
- return {
484
- category,
485
- ...options.details === void 0 ? {} : { details: options.details },
486
- ...options.suggestion === void 0 ? {} : { suggestion: options.suggestion },
487
- ...options.cause === void 0 ? {} : { cause: options.cause }
488
- };
489
- }
490
- var MergeError = class extends chunkC4F7VJ5D_cjs.TypeGraphError {
491
- constructor(message, options = {}) {
492
- super(
493
- message,
494
- MERGE_ERROR_CODES.merge,
495
- toTypeGraphErrorOptions("system", options)
496
- );
497
- this.name = "MergeError";
498
- }
499
- };
500
- var BranchError = class extends chunkC4F7VJ5D_cjs.TypeGraphError {
501
- constructor(message, options = {}) {
502
- super(
503
- message,
504
- MERGE_ERROR_CODES.branch,
505
- toTypeGraphErrorOptions("system", options)
506
- );
507
- this.name = "BranchError";
508
- }
509
- };
510
- var SimilarityUnavailableError = class extends MergeError {
511
- code = MERGE_ERROR_CODES.similarityUnavailable;
512
- constructor(message, options = {}) {
513
- super(message, {
514
- ...options,
515
- suggestion: options.suggestion ?? "Pass MergeOptions.embedder (a local model), or use a fulltext/custom similarity strategy."
516
- });
517
- this.name = "SimilarityUnavailableError";
518
- }
519
- };
520
- var MergeConflictError = class extends MergeError {
521
- code = MERGE_ERROR_CODES.conflict;
522
- constructor(message, options = {}) {
523
- super(message, options);
524
- this.name = "MergeConflictError";
525
- }
526
- };
527
- var BaseVersionMismatchError = class extends MergeError {
528
- code = MERGE_ERROR_CODES.baseVersionMismatch;
529
- constructor(message, options = {}) {
530
- super(message, {
531
- ...options,
532
- suggestion: options.suggestion ?? "Re-branch from the current target so the branch base matches before merging."
533
- });
534
- this.name = "BaseVersionMismatchError";
535
- }
536
- };
537
-
538
1430
  // src/graph-merge/working-copy.ts
539
1431
  var CLONE_IMPORT_BATCH_SIZE = 1e3;
540
1432
  function cloneWorkingCopyStrategy(makeBackend) {
@@ -542,7 +1434,7 @@ function cloneWorkingCopyStrategy(makeBackend) {
542
1434
  create: async (baseStore) => {
543
1435
  const backend = await makeBackend();
544
1436
  try {
545
- const [freshStore] = await chunkXR4YZFKW_cjs.createStoreWithSchema(
1437
+ const [freshStore] = await chunkXDF2UPEQ_cjs.createStoreWithSchema(
546
1438
  baseStore.graph,
547
1439
  backend,
548
1440
  {
@@ -551,20 +1443,29 @@ function cloneWorkingCopyStrategy(makeBackend) {
551
1443
  revisionTracking: baseStore.revisionTrackingEnabled
552
1444
  }
553
1445
  );
554
- const result = await chunkALFUGRYB_cjs.importGraphStream(
1446
+ const exportOptions = {
1447
+ includeMeta: true,
1448
+ includeTemporal: true,
1449
+ includeDeleted: false,
1450
+ batchSize: CLONE_IMPORT_BATCH_SIZE
1451
+ };
1452
+ const importOptions = {
1453
+ onConflict: "error",
1454
+ onUnknownProperty: "error",
1455
+ validateReferences: true,
1456
+ batchSize: CLONE_IMPORT_BATCH_SIZE
1457
+ };
1458
+ const result = chunkXBYVV3MP_cjs.snapshotExportContention(
1459
+ chunkTTAITEPJ_cjs.storeBackend(baseStore),
1460
+ chunkTTAITEPJ_cjs.storeBackend(freshStore)
1461
+ ) === void 0 ? await chunkONU3HIED_cjs.importGraphStream(
555
1462
  freshStore,
556
- chunkALFUGRYB_cjs.exportGraphStream(baseStore, {
557
- includeMeta: true,
558
- includeTemporal: true,
559
- includeDeleted: false,
560
- batchSize: CLONE_IMPORT_BATCH_SIZE
561
- }),
562
- {
563
- onConflict: "error",
564
- onUnknownProperty: "error",
565
- validateReferences: true,
566
- batchSize: CLONE_IMPORT_BATCH_SIZE
567
- }
1463
+ chunkONU3HIED_cjs.exportGraphStream(baseStore, exportOptions),
1464
+ importOptions
1465
+ ) : await chunkONU3HIED_cjs.importGraph(
1466
+ freshStore,
1467
+ await chunkONU3HIED_cjs.exportGraph(baseStore, exportOptions),
1468
+ importOptions
568
1469
  );
569
1470
  if (!result.success) {
570
1471
  throw new BranchError(
@@ -588,18 +1489,36 @@ function cloneWorkingCopyStrategy(makeBackend) {
588
1489
  async function branch(baseStore, makeBackend, options, strategy) {
589
1490
  try {
590
1491
  const base = await computeBaseVersion(baseStore);
591
- const id = options?.id ?? asBranchId(chunk7V2FGGI2_cjs.generateId());
1492
+ const id = options?.id ?? asBranchId(chunkXMQSEJCF_cjs.generateId());
592
1493
  const workingCopyStrategy = strategy ?? cloneWorkingCopyStrategy(makeBackend);
593
1494
  const store = await workingCopyStrategy.create(baseStore);
594
- return chunkQYWINYEA_cjs.ok({ id, base, store });
1495
+ const schemaAnchor = await readSchemaAnchor(store);
1496
+ return chunk7BQXPCGN_cjs.ok({
1497
+ id,
1498
+ base,
1499
+ store,
1500
+ ...schemaAnchor === void 0 ? { schemaAnchor: void 0 } : { schemaAnchor }
1501
+ });
595
1502
  } catch (error) {
596
- return chunkQYWINYEA_cjs.err(
1503
+ return chunk7BQXPCGN_cjs.err(
597
1504
  new BranchError("Failed to create working-copy branch of base store", {
598
1505
  cause: error
599
1506
  })
600
1507
  );
601
1508
  }
602
1509
  }
1510
+ async function readSchemaAnchor(store) {
1511
+ try {
1512
+ const schemaRow = await chunkTTAITEPJ_cjs.storeBackend(store).getActiveSchema(store.graphId);
1513
+ return schemaRow === void 0 ? void 0 : { version: schemaRow.version, hash: schemaRow.schema_hash };
1514
+ } catch (error) {
1515
+ try {
1516
+ await chunkTTAITEPJ_cjs.storeBackend(store).close();
1517
+ } catch {
1518
+ }
1519
+ throw error;
1520
+ }
1521
+ }
603
1522
 
604
1523
  // src/graph-merge/blocking.ts
605
1524
  var UNBLOCKED_BUCKET_KEY = "unblocked";
@@ -612,12 +1531,12 @@ function isUniqueBucketKey(key) {
612
1531
  function constraintSignature(node, constraint) {
613
1532
  const props = node;
614
1533
  for (const field of constraint.fields) {
615
- const value = props[field];
1534
+ const value = chunkN66HCGCY_cjs.readOwnProperty(props, field);
616
1535
  if (value === void 0 || value === null) {
617
1536
  return void 0;
618
1537
  }
619
1538
  }
620
- return `${constraint.name}${KEY_PART_SEPARATOR}${chunk7V2FGGI2_cjs.computeUniqueKey(
1539
+ return `${constraint.name}${KEY_PART_SEPARATOR}${chunkE4WNQBEF_cjs.computeUniqueKey(
621
1540
  props,
622
1541
  constraint.fields,
623
1542
  constraint.collation
@@ -654,12 +1573,12 @@ function blockNodes(newNodes, resolveConfig, uniqueConstraints = []) {
654
1573
  }
655
1574
  }
656
1575
  const sortedKeys = [...buckets.keys()].sort(
657
- (left, right) => chunkTRF4EBJT_cjs.compareStrings(left, right)
1576
+ (left, right) => chunkXMQSEJCF_cjs.compareStrings(left, right)
658
1577
  );
659
1578
  const ordered = /* @__PURE__ */ new Map();
660
1579
  for (const key of sortedKeys) {
661
- const members = [...chunk764JHTLT_cjs.requireDefined(buckets.get(key))].sort(
662
- (left, right) => chunkTRF4EBJT_cjs.compareStrings(left.id, right.id)
1580
+ const members = [...chunkN66HCGCY_cjs.requireDefined(buckets.get(key))].sort(
1581
+ (left, right) => chunkXMQSEJCF_cjs.compareStrings(left.id, right.id)
663
1582
  );
664
1583
  ordered.set(key, members);
665
1584
  }
@@ -676,7 +1595,7 @@ function buildBranchRank(branchOrder, allBranchIds) {
676
1595
  next += 1;
677
1596
  }
678
1597
  }
679
- const remaining = allBranchIds.filter((branchId) => !rank.has(branchId)).sort((left, right) => chunkTRF4EBJT_cjs.compareStrings(left, right));
1598
+ const remaining = allBranchIds.filter((branchId) => !rank.has(branchId)).sort((left, right) => chunkXMQSEJCF_cjs.compareStrings(left, right));
680
1599
  for (const branchId of remaining) {
681
1600
  if (!rank.has(branchId)) {
682
1601
  rank.set(branchId, next);
@@ -686,7 +1605,7 @@ function buildBranchRank(branchOrder, allBranchIds) {
686
1605
  return rank;
687
1606
  }
688
1607
  function pickByPriority(values, branchRank) {
689
- let chosen = chunk764JHTLT_cjs.requireDefined(values[0]);
1608
+ let chosen = chunkN66HCGCY_cjs.requireDefined(values[0]);
690
1609
  let chosenRank = branchRank.get(chosen.branchId) ?? Number.MAX_SAFE_INTEGER;
691
1610
  for (const candidate of values.slice(1)) {
692
1611
  const candidateRank = branchRank.get(candidate.branchId) ?? Number.MAX_SAFE_INTEGER;
@@ -700,7 +1619,7 @@ function pickByPriority(values, branchRank) {
700
1619
  return chosen.value;
701
1620
  }
702
1621
  function pickByWeight(values, weights, branchRank) {
703
- let chosen = chunk764JHTLT_cjs.requireDefined(values[0]);
1622
+ let chosen = chunkN66HCGCY_cjs.requireDefined(values[0]);
704
1623
  let chosenWeight = weights.get(chosen.branchId) ?? 0;
705
1624
  let chosenRank = branchRank.get(chosen.branchId) ?? Number.MAX_SAFE_INTEGER;
706
1625
  for (const candidate of values.slice(1)) {
@@ -727,7 +1646,7 @@ function allValuesEqual(values) {
727
1646
  if (values.length <= 1) {
728
1647
  return true;
729
1648
  }
730
- const first = canonicalValueKey(chunk764JHTLT_cjs.requireDefined(values[0]).value);
1649
+ const first = canonicalValueKey(chunkN66HCGCY_cjs.requireDefined(values[0]).value);
731
1650
  return values.every(
732
1651
  (candidate) => canonicalValueKey(candidate.value) === first
733
1652
  );
@@ -736,7 +1655,7 @@ function collectConflictingValues(property, contributions) {
736
1655
  const seen = /* @__PURE__ */ new Set();
737
1656
  const values = [];
738
1657
  for (const { branchId, props } of contributions) {
739
- if (!(property in props)) {
1658
+ if (!chunkN66HCGCY_cjs.hasOwnKey(props, property)) {
740
1659
  continue;
741
1660
  }
742
1661
  const value = props[property];
@@ -748,8 +1667,8 @@ function collectConflictingValues(property, contributions) {
748
1667
  values.push({ branchId, value });
749
1668
  }
750
1669
  return [...values].sort((left, right) => {
751
- const byBranch = chunkTRF4EBJT_cjs.compareStrings(left.branchId, right.branchId);
752
- return byBranch === 0 ? chunkTRF4EBJT_cjs.compareStrings(
1670
+ const byBranch = chunkXMQSEJCF_cjs.compareStrings(left.branchId, right.branchId);
1671
+ return byBranch === 0 ? chunkXMQSEJCF_cjs.compareStrings(
753
1672
  canonicalValueKey(left.value),
754
1673
  canonicalValueKey(right.value)
755
1674
  ) : byBranch;
@@ -809,11 +1728,14 @@ function resolvePropertyUnion(input, context, branchRank) {
809
1728
 
810
1729
  // src/graph-merge/canonicalize.ts
811
1730
  var BASE_PROVENANCE_BRANCH = asBranchId("__committed_base__");
1731
+ var COMMITTED_TARGET_BRANCH = asBranchId(
1732
+ "__committed_target__"
1733
+ );
812
1734
  function pickClusterSurvivor(members, cluster, canonicalOverride, preferKind) {
813
1735
  const byKey = (left, right) => compareMergeKeys(mergeKeyOf(left), mergeKeyOf(right));
814
1736
  const baseMembers = members.filter((member) => member.origin === "base").sort(byKey);
815
1737
  if (baseMembers.length > 0) {
816
- return chunk764JHTLT_cjs.requireDefined(baseMembers[0]);
1738
+ return chunkN66HCGCY_cjs.requireDefined(baseMembers[0]);
817
1739
  }
818
1740
  let canonicalId;
819
1741
  if (canonicalOverride !== void 0) {
@@ -826,26 +1748,26 @@ function pickClusterSurvivor(members, cluster, canonicalOverride, preferKind) {
826
1748
  const minIdentity = [...cluster.members].sort(
827
1749
  (left, right) => compareMergeKeys(left, right)
828
1750
  )[0];
829
- canonicalId = minIdentity === void 0 ? chunk764JHTLT_cjs.requireDefined(members[0]).id : idOf(minIdentity);
1751
+ canonicalId = minIdentity === void 0 ? chunkN66HCGCY_cjs.requireDefined(members[0]).id : idOf(minIdentity);
830
1752
  }
831
1753
  const membersAtId = members.filter((member) => member.id === canonicalId);
832
1754
  if (membersAtId.length === 0) {
833
- return chunk764JHTLT_cjs.requireDefined([...members].sort(byKey)[0]);
1755
+ return chunkN66HCGCY_cjs.requireDefined([...members].sort(byKey)[0]);
834
1756
  }
835
1757
  const kinds = [...new Set(membersAtId.map((member) => member.kind))];
836
1758
  const chosenKind = preferKind !== void 0 && kinds.length > 1 ? preferKind(kinds) : void 0;
837
- return (chosenKind === void 0 ? void 0 : membersAtId.find((member) => member.kind === chosenKind)) ?? chunk764JHTLT_cjs.requireDefined([...membersAtId].sort(byKey)[0]);
1759
+ return (chosenKind === void 0 ? void 0 : membersAtId.find((member) => member.kind === chosenKind)) ?? chunkN66HCGCY_cjs.requireDefined([...membersAtId].sort(byKey)[0]);
838
1760
  }
839
1761
  function findPreferredMember(members, property, preferredBranchId) {
840
1762
  if (preferredBranchId === void 0) {
841
1763
  return void 0;
842
1764
  }
843
1765
  return members.find(
844
- (member) => member.branchId === preferredBranchId && property in member.props
1766
+ (member) => member.branchId === preferredBranchId && chunkN66HCGCY_cjs.hasOwnKey(member.props, property)
845
1767
  );
846
1768
  }
847
1769
  function memberPropertyValue(member, property) {
848
- if (!(property in member.props)) {
1770
+ if (!chunkN66HCGCY_cjs.hasOwnKey(member.props, property)) {
849
1771
  return void 0;
850
1772
  }
851
1773
  return member.props[property];
@@ -861,7 +1783,7 @@ function pickCanonicalPropertyValue(canonicalMember, members, property, values,
861
1783
  return preferredValue;
862
1784
  }
863
1785
  const canonicalValue = memberPropertyValue(canonicalMember, property);
864
- return canonicalValue === void 0 ? chunk764JHTLT_cjs.requireDefined(values[0]).value : canonicalValue;
1786
+ return canonicalValue === void 0 ? chunkN66HCGCY_cjs.requireDefined(values[0]).value : canonicalValue;
865
1787
  }
866
1788
  function unionProperties(canonicalMember, members, context, baseContext, branchRank, preferredBranchId) {
867
1789
  const canonicalId = canonicalMember.id;
@@ -873,10 +1795,10 @@ function unionProperties(canonicalMember, members, context, baseContext, branchR
873
1795
  propertyNames.add(name);
874
1796
  }
875
1797
  }
876
- const props = {};
1798
+ const props = chunkN66HCGCY_cjs.createDataKeyedBag();
877
1799
  const conflicts = [];
878
1800
  for (const property of [...propertyNames].sort(
879
- (left, right) => chunkTRF4EBJT_cjs.compareStrings(left, right)
1801
+ (left, right) => chunkXMQSEJCF_cjs.compareStrings(left, right)
880
1802
  )) {
881
1803
  const values = collectConflictingValues(property, members);
882
1804
  if (values.length === 0) {
@@ -890,7 +1812,7 @@ function unionProperties(canonicalMember, members, context, baseContext, branchR
890
1812
  preferredBranchId
891
1813
  );
892
1814
  const baseInvolved = hasBaseMember && members.some(
893
- (member) => member.origin === "base" && property in member.props
1815
+ (member) => member.origin === "base" && chunkN66HCGCY_cjs.hasOwnKey(member.props, property)
894
1816
  );
895
1817
  const reportedValues = values.filter(
896
1818
  (value2) => value2.branchId !== BASE_PROVENANCE_BRANCH && value2.branchId !== preferredBranchId
@@ -931,89 +1853,56 @@ function canonicalizeCluster(cluster, members, policy, branchRank, weights, cano
931
1853
  policy: basePolicy,
932
1854
  ...weights === void 0 ? {} : { weights }
933
1855
  };
934
- const { props, conflicts } = unionProperties(
935
- survivor,
936
- members,
937
- context,
938
- baseContext,
939
- branchRank,
940
- preferredBranchId
941
- );
942
- const memberIds = [
943
- ...new Set(cluster.members.map((member) => idOf(member)))
944
- ].sort((left, right) => chunkTRF4EBJT_cjs.compareStrings(left, right));
945
- const branchOrigins = [
946
- ...new Set(
947
- members.map((member) => member.branchId).filter(
948
- (branchId) => branchId !== BASE_PROVENANCE_BRANCH && branchId !== preferredBranchId
949
- )
950
- )
951
- ].sort((left, right) => chunkTRF4EBJT_cjs.compareStrings(left, right));
952
- const resolution = {
953
- canonicalId,
954
- memberIds,
955
- kind,
956
- branchOrigins
957
- };
958
- return { canonicalId, kind, props, resolution, conflicts };
959
- }
960
-
961
- // src/graph-merge/union-find.ts
962
- var UnionFind = class {
963
- constructor(compare) {
964
- this.compare = compare;
965
- }
966
- compare;
967
- parent = /* @__PURE__ */ new Map();
968
- /** Adds `value` as its own singleton set if it is not already present. */
969
- add(value) {
970
- if (!this.parent.has(value)) {
971
- this.parent.set(value, value);
972
- }
973
- }
974
- /** Returns the representative of `value`'s set, compressing the path to it. */
975
- find(value) {
976
- this.add(value);
977
- let root = value;
978
- while (this.parent.get(root) !== root) {
979
- root = chunk764JHTLT_cjs.requireDefined(this.parent.get(root));
980
- }
981
- let cursor = value;
982
- while (cursor !== root) {
983
- const next = chunk764JHTLT_cjs.requireDefined(this.parent.get(cursor));
984
- this.parent.set(cursor, root);
985
- cursor = next;
986
- }
987
- return root;
988
- }
989
- /** Merges the sets of `left` and `right`; the `compare`-minimal root wins. */
990
- union(left, right) {
991
- const leftRoot = this.find(left);
992
- const rightRoot = this.find(right);
993
- if (leftRoot === rightRoot) {
994
- return;
995
- }
996
- if (this.compare(leftRoot, rightRoot) <= 0) {
997
- this.parent.set(rightRoot, leftRoot);
998
- } else {
999
- this.parent.set(leftRoot, rightRoot);
1000
- }
1001
- }
1002
- /** Every value seen by {@link add}/{@link find}/{@link union}, insertion order. */
1003
- members() {
1004
- return [...this.parent.keys()];
1005
- }
1006
- };
1856
+ const { props, conflicts } = unionProperties(
1857
+ survivor,
1858
+ members,
1859
+ context,
1860
+ baseContext,
1861
+ branchRank,
1862
+ preferredBranchId
1863
+ );
1864
+ const memberIds = [
1865
+ ...new Set(cluster.members.map((member) => idOf(member)))
1866
+ ].sort((left, right) => chunkXMQSEJCF_cjs.compareStrings(left, right));
1867
+ const branchOrigins = [
1868
+ ...new Set(
1869
+ members.map((member) => member.branchId).filter(
1870
+ (branchId) => branchId !== BASE_PROVENANCE_BRANCH && branchId !== preferredBranchId
1871
+ )
1872
+ )
1873
+ ].sort((left, right) => chunkXMQSEJCF_cjs.compareStrings(left, right));
1874
+ const resolution = {
1875
+ canonicalId,
1876
+ memberIds,
1877
+ kind,
1878
+ branchOrigins
1879
+ };
1880
+ const windowSource = members.find(
1881
+ (member) => member.branchId === COMMITTED_TARGET_BRANCH && member.kind === kind && member.id === canonicalId
1882
+ ) ?? survivor;
1883
+ return {
1884
+ canonicalId,
1885
+ kind,
1886
+ props,
1887
+ resolution,
1888
+ conflicts,
1889
+ ...windowSource.validFrom === void 0 ? {} : { validFrom: windowSource.validFrom },
1890
+ ...windowSource.validTo === void 0 ? {} : { validTo: windowSource.validTo }
1891
+ };
1892
+ }
1007
1893
 
1008
1894
  // src/graph-merge/closures.ts
1009
1895
  var SUB_CLASS_OF_META_EDGE = "subClassOf";
1010
- var EQUIVALENT_TO_META_EDGE = "equivalentTo";
1896
+ var EQUIVALENCE_META_EDGES = /* @__PURE__ */ new Set([
1897
+ chunkXUO3KQFO_cjs.META_EDGE_EQUIVALENT_TO,
1898
+ chunkXUO3KQFO_cjs.META_EDGE_SAME_AS
1899
+ ]);
1011
1900
  function buildSubClassClosure(ontology) {
1012
- const unionFind = new UnionFind(chunkTRF4EBJT_cjs.compareStrings);
1901
+ const unionFind = new UnionFind(chunkXMQSEJCF_cjs.compareStrings);
1013
1902
  for (const relation of ontology) {
1014
1903
  unionFind.add(relation.from);
1015
1904
  unionFind.add(relation.to);
1016
- if (relation.metaEdge === EQUIVALENT_TO_META_EDGE) {
1905
+ if (EQUIVALENCE_META_EDGES.has(relation.metaEdge)) {
1017
1906
  unionFind.union(relation.from, relation.to);
1018
1907
  }
1019
1908
  }
@@ -1040,7 +1929,7 @@ function buildSubClassClosure(ontology) {
1040
1929
  relations.push([child, parent]);
1041
1930
  }
1042
1931
  return {
1043
- closure: chunkQYWINYEA_cjs.computeTransitiveClosure(relations),
1932
+ closure: chunk7BQXPCGN_cjs.computeTransitiveClosure(relations),
1044
1933
  canonicalOf
1045
1934
  };
1046
1935
  }
@@ -1053,7 +1942,7 @@ function isReachable2(closure, from, to) {
1053
1942
  if (fromRep === toRep) {
1054
1943
  return from !== to;
1055
1944
  }
1056
- return chunkQYWINYEA_cjs.isReachable(closure.closure, fromRep, toRep);
1945
+ return chunk7BQXPCGN_cjs.isReachable(closure.closure, fromRep, toRep);
1057
1946
  }
1058
1947
 
1059
1948
  // src/graph-merge/similarity.ts
@@ -1075,7 +1964,7 @@ function clampScore(value) {
1075
1964
  return value;
1076
1965
  }
1077
1966
  function readField(node, field) {
1078
- return node[field];
1967
+ return chunkN66HCGCY_cjs.readOwnProperty(node, field);
1079
1968
  }
1080
1969
  function fieldText(node, fields) {
1081
1970
  const parts = [];
@@ -1166,8 +2055,8 @@ function cosineSimilarity(left, right) {
1166
2055
  let leftMagnitude = 0;
1167
2056
  let rightMagnitude = 0;
1168
2057
  for (let index = 0; index < left.length; index += 1) {
1169
- const leftComponent = chunk764JHTLT_cjs.requireDefined(left[index]);
1170
- const rightComponent = chunk764JHTLT_cjs.requireDefined(right[index]);
2058
+ const leftComponent = chunkN66HCGCY_cjs.requireDefined(left[index]);
2059
+ const rightComponent = chunkN66HCGCY_cjs.requireDefined(right[index]);
1171
2060
  dot += leftComponent * rightComponent;
1172
2061
  leftMagnitude += leftComponent * leftComponent;
1173
2062
  rightMagnitude += rightComponent * rightComponent;
@@ -1236,37 +2125,37 @@ function scorePrepared(left, right, strategy, ctx) {
1236
2125
  switch (strategy.kind) {
1237
2126
  case "custom": {
1238
2127
  const raw = strategy.score(left.node, right.node);
1239
- return chunkQYWINYEA_cjs.ok(clampScore(raw));
2128
+ return chunk7BQXPCGN_cjs.ok(clampScore(raw));
1240
2129
  }
1241
2130
  case "fulltext": {
1242
2131
  if (left.text.length === 0 || right.text.length === 0) {
1243
- return chunkQYWINYEA_cjs.ok(NO_EVIDENCE_SCORE);
2132
+ return chunk7BQXPCGN_cjs.ok(NO_EVIDENCE_SCORE);
1244
2133
  }
1245
- return chunkQYWINYEA_cjs.ok(clampScore(diceFromMultisets(left.grams, right.grams)));
2134
+ return chunk7BQXPCGN_cjs.ok(clampScore(diceFromMultisets(left.grams, right.grams)));
1246
2135
  }
1247
2136
  case "vector": {
1248
2137
  if (ctx.embeddings === void 0) {
1249
- return chunkQYWINYEA_cjs.err(embedderUnavailable("vector", ctx));
2138
+ return chunk7BQXPCGN_cjs.err(embedderUnavailable("vector", ctx));
1250
2139
  }
1251
2140
  if (left.text.length === 0 || right.text.length === 0) {
1252
- return chunkQYWINYEA_cjs.ok(NO_EVIDENCE_SCORE);
2141
+ return chunk7BQXPCGN_cjs.ok(NO_EVIDENCE_SCORE);
1253
2142
  }
1254
2143
  const cosine = cosineFromLookup(ctx.embeddings, left.text, right.text);
1255
- return chunkQYWINYEA_cjs.ok(clampScore(cosine));
2144
+ return chunk7BQXPCGN_cjs.ok(clampScore(cosine));
1256
2145
  }
1257
2146
  case "hybrid": {
1258
2147
  if (ctx.embeddings === void 0) {
1259
- return chunkQYWINYEA_cjs.err(embedderUnavailable("hybrid", ctx));
2148
+ return chunk7BQXPCGN_cjs.err(embedderUnavailable("hybrid", ctx));
1260
2149
  }
1261
2150
  if (left.text.length === 0 || right.text.length === 0) {
1262
- return chunkQYWINYEA_cjs.ok(NO_EVIDENCE_SCORE);
2151
+ return chunk7BQXPCGN_cjs.ok(NO_EVIDENCE_SCORE);
1263
2152
  }
1264
2153
  const vectorScore = clampScore(
1265
2154
  cosineFromLookup(ctx.embeddings, left.text, right.text)
1266
2155
  );
1267
2156
  const fulltextScore = diceFromMultisets(left.grams, right.grams);
1268
2157
  const weights = normalizeHybridWeights(strategy.weights);
1269
- return chunkQYWINYEA_cjs.ok(
2158
+ return chunk7BQXPCGN_cjs.ok(
1270
2159
  clampScore(
1271
2160
  weights.vector * vectorScore + weights.fulltext * fulltextScore
1272
2161
  )
@@ -1324,7 +2213,7 @@ function scoreCandidates(input, resolveConfig, ctx, ceilingPolicy, maxComparison
1324
2213
  }
1325
2214
  if (maxComparisonsPerKind !== void 0 && fuzzy.length > maxComparisonsPerKind) {
1326
2215
  if (ceilingPolicy === "error") {
1327
- return chunkQYWINYEA_cjs.err(
2216
+ return chunk7BQXPCGN_cjs.err(
1328
2217
  new MergeError(
1329
2218
  `Comparison ceiling exceeded: ${fuzzy.length} candidate pairs > maxComparisonsPerKind ${maxComparisonsPerKind}.`,
1330
2219
  {
@@ -1337,7 +2226,7 @@ function scoreCandidates(input, resolveConfig, ctx, ceilingPolicy, maxComparison
1337
2226
  )
1338
2227
  );
1339
2228
  }
1340
- return chunkQYWINYEA_cjs.ok({
2229
+ return chunk7BQXPCGN_cjs.ok({
1341
2230
  edges: [...forced].sort(
1342
2231
  (left, right) => compareCandidateEdges(left, right)
1343
2232
  ),
@@ -1355,14 +2244,14 @@ function scoreCandidates(input, resolveConfig, ctx, ceilingPolicy, maxComparison
1355
2244
  const edges = [...forced];
1356
2245
  for (const { left, right, a, b } of fuzzy) {
1357
2246
  const scored = scorer(a, left, b, right);
1358
- if (chunkQYWINYEA_cjs.isErr(scored)) {
1359
- return chunkQYWINYEA_cjs.err(scored.error);
2247
+ if (chunk7BQXPCGN_cjs.isErr(scored)) {
2248
+ return chunk7BQXPCGN_cjs.err(scored.error);
1360
2249
  }
1361
2250
  if (scored.data >= threshold) {
1362
2251
  edges.push({ a, b, score: scored.data });
1363
2252
  }
1364
2253
  }
1365
- return chunkQYWINYEA_cjs.ok({
2254
+ return chunk7BQXPCGN_cjs.ok({
1366
2255
  edges: edges.sort((left, right) => compareCandidateEdges(left, right)),
1367
2256
  warnings: []
1368
2257
  });
@@ -1402,8 +2291,8 @@ function buildComponents(edges, nodeIds, edgesSorted = false) {
1402
2291
  }
1403
2292
  clusters.sort(
1404
2293
  (left, right) => compareMergeKeys(
1405
- chunk764JHTLT_cjs.requireDefined(left.members[0]),
1406
- chunk764JHTLT_cjs.requireDefined(right.members[0])
2294
+ chunkN66HCGCY_cjs.requireDefined(left.members[0]),
2295
+ chunkN66HCGCY_cjs.requireDefined(right.members[0])
1407
2296
  )
1408
2297
  );
1409
2298
  return clusters;
@@ -1416,8 +2305,8 @@ function adjacencyOf(members, edges) {
1416
2305
  }
1417
2306
  for (const edge of edges) {
1418
2307
  if (memberSet.has(edge.a) && memberSet.has(edge.b)) {
1419
- chunk764JHTLT_cjs.requireDefined(adjacency.get(edge.a)).add(edge.b);
1420
- chunk764JHTLT_cjs.requireDefined(adjacency.get(edge.b)).add(edge.a);
2308
+ chunkN66HCGCY_cjs.requireDefined(adjacency.get(edge.a)).add(edge.b);
2309
+ chunkN66HCGCY_cjs.requireDefined(adjacency.get(edge.b)).add(edge.a);
1421
2310
  }
1422
2311
  }
1423
2312
  return adjacency;
@@ -1432,10 +2321,10 @@ function exceedsDiameter(members, edges, maxDiameter) {
1432
2321
  const queue = [source];
1433
2322
  let head = 0;
1434
2323
  while (head < queue.length) {
1435
- const current = chunk764JHTLT_cjs.requireDefined(queue[head]);
2324
+ const current = chunkN66HCGCY_cjs.requireDefined(queue[head]);
1436
2325
  head += 1;
1437
- const currentDistance = chunk764JHTLT_cjs.requireDefined(distance.get(current));
1438
- for (const neighbor of chunk764JHTLT_cjs.requireDefined(adjacency.get(current))) {
2326
+ const currentDistance = chunkN66HCGCY_cjs.requireDefined(distance.get(current));
2327
+ for (const neighbor of chunkN66HCGCY_cjs.requireDefined(adjacency.get(current))) {
1439
2328
  if (!distance.has(neighbor)) {
1440
2329
  const neighborDistance = currentDistance + 1;
1441
2330
  if (neighborDistance > maxDiameter) {
@@ -1519,8 +2408,8 @@ function enforceDiameter(clusters, candidateEdges, clusterMaxDiameter) {
1519
2408
  }
1520
2409
  guarded.sort(
1521
2410
  (left, right) => compareMergeKeys(
1522
- chunk764JHTLT_cjs.requireDefined(left.members[0]),
1523
- chunk764JHTLT_cjs.requireDefined(right.members[0])
2411
+ chunkN66HCGCY_cjs.requireDefined(left.members[0]),
2412
+ chunkN66HCGCY_cjs.requireDefined(right.members[0])
1524
2413
  )
1525
2414
  );
1526
2415
  return guarded;
@@ -1567,8 +2456,8 @@ function enforceBaseGuard(clusters, candidateEdges, baseIds) {
1567
2456
  }
1568
2457
  result.sort(
1569
2458
  (left, right) => compareMergeKeys(
1570
- chunk764JHTLT_cjs.requireDefined(left.members[0]),
1571
- chunk764JHTLT_cjs.requireDefined(right.members[0])
2459
+ chunkN66HCGCY_cjs.requireDefined(left.members[0]),
2460
+ chunkN66HCGCY_cjs.requireDefined(right.members[0])
1572
2461
  )
1573
2462
  );
1574
2463
  return { clusters: result, events };
@@ -1577,11 +2466,11 @@ function enforceBaseGuard(clusters, candidateEdges, baseIds) {
1577
2466
  // src/graph-merge/delete-modify.ts
1578
2467
  var DELETED_NODE_DROP_REASON = "delete-modify:deleteWins";
1579
2468
  function pickHighestPriorityBranch(branchIds, branchRank) {
1580
- let chosen = chunk764JHTLT_cjs.requireDefined(branchIds[0]);
2469
+ let chosen = chunkN66HCGCY_cjs.requireDefined(branchIds[0]);
1581
2470
  let chosenRank = branchRank.get(chosen) ?? Number.MAX_SAFE_INTEGER;
1582
2471
  for (const candidate of branchIds.slice(1)) {
1583
2472
  const candidateRank = branchRank.get(candidate) ?? Number.MAX_SAFE_INTEGER;
1584
- if (candidateRank < chosenRank || candidateRank === chosenRank && chunkTRF4EBJT_cjs.compareStrings(candidate, chosen) < 0) {
2473
+ if (candidateRank < chosenRank || candidateRank === chosenRank && chunkXMQSEJCF_cjs.compareStrings(candidate, chosen) < 0) {
1585
2474
  chosen = candidate;
1586
2475
  chosenRank = candidateRank;
1587
2476
  }
@@ -1613,7 +2502,7 @@ function groupByEntity(items, entityOf) {
1613
2502
  }
1614
2503
  return grouped;
1615
2504
  }
1616
- function resolveDeleteModifyOver(modified, deleted, modifiedEntity, deletedEntity, droppedKind, policy, branchRank, preferredBranchId) {
2505
+ function resolveDeleteModifyOver(modified, deleted, modifiedEntity, deletedEntity, dropDeleted, policy, branchRank, preferredBranchId) {
1617
2506
  const modifiedByKey = groupByEntity(modified, modifiedEntity);
1618
2507
  const deletedByKey = groupByEntity(deleted, deletedEntity);
1619
2508
  const survivingModifications = [];
@@ -1633,8 +2522,8 @@ function resolveDeleteModifyOver(modified, deleted, modifiedEntity, deletedEntit
1633
2522
  }
1634
2523
  continue;
1635
2524
  }
1636
- const deletionsForKey = chunk764JHTLT_cjs.requireDefined(deletedByKey.get(key));
1637
- const { id, kind } = modifiedEntity(chunk764JHTLT_cjs.requireDefined(modifications[0]));
2525
+ const deletionsForKey = chunkN66HCGCY_cjs.requireDefined(deletedByKey.get(key));
2526
+ const { id, kind } = modifiedEntity(chunkN66HCGCY_cjs.requireDefined(modifications[0]));
1638
2527
  const deletedBy = pickHighestPriorityBranch(
1639
2528
  deletionsForKey.map((deletion) => deletion.branchId),
1640
2529
  branchRank
@@ -1658,7 +2547,7 @@ function resolveDeleteModifyOver(modified, deleted, modifiedEntity, deletedEntit
1658
2547
  });
1659
2548
  if (effectivePolicy === "deleteWins") {
1660
2549
  deletions.push({ id, kind });
1661
- dropped.push({ kind: droppedKind, id, reason: DELETED_NODE_DROP_REASON });
2550
+ dropped.push(dropDeleted(id));
1662
2551
  continue;
1663
2552
  }
1664
2553
  for (const modification of modifications) {
@@ -1669,25 +2558,25 @@ function resolveDeleteModifyOver(modified, deleted, modifiedEntity, deletedEntit
1669
2558
  if (conflictedKeys.has(key)) {
1670
2559
  continue;
1671
2560
  }
1672
- const { id, kind } = deletedEntity(chunk764JHTLT_cjs.requireDefined(deletionsForKey[0]));
2561
+ const { id, kind } = deletedEntity(chunkN66HCGCY_cjs.requireDefined(deletionsForKey[0]));
1673
2562
  deletions.push({ id, kind });
1674
2563
  }
1675
2564
  return {
1676
2565
  survivingModifications: [...survivingModifications].sort((left, right) => {
1677
- const byId2 = chunkTRF4EBJT_cjs.compareStrings(
2566
+ const byId2 = chunkXMQSEJCF_cjs.compareStrings(
1678
2567
  modifiedEntity(left).id,
1679
2568
  modifiedEntity(right).id
1680
2569
  );
1681
- return byId2 === 0 ? chunkTRF4EBJT_cjs.compareStrings(left.branchId, right.branchId) : byId2;
2570
+ return byId2 === 0 ? chunkXMQSEJCF_cjs.compareStrings(left.branchId, right.branchId) : byId2;
1682
2571
  }),
1683
2572
  deletions: [...deletions].sort(
1684
- (left, right) => chunkTRF4EBJT_cjs.compareStrings(left.id, right.id)
2573
+ (left, right) => chunkXMQSEJCF_cjs.compareStrings(left.id, right.id)
1685
2574
  ),
1686
2575
  conflicts: [...conflicts].sort(
1687
- (left, right) => chunkTRF4EBJT_cjs.compareStrings(left.entityId, right.entityId)
2576
+ (left, right) => chunkXMQSEJCF_cjs.compareStrings(left.entityId, right.entityId)
1688
2577
  ),
1689
2578
  dropped: [...dropped].sort(
1690
- (left, right) => chunkTRF4EBJT_cjs.compareStrings(left.id, right.id)
2579
+ (left, right) => chunkXMQSEJCF_cjs.compareStrings(left.id, right.id)
1691
2580
  )
1692
2581
  };
1693
2582
  }
@@ -1701,10 +2590,10 @@ function reconcileOver(survivingModifications, entityOf, rebuild, policy, branch
1701
2590
  const conflicts = [];
1702
2591
  for (const modifications of grouped.values()) {
1703
2592
  if (modifications.length === 1) {
1704
- out.push(chunk764JHTLT_cjs.requireDefined(modifications[0]));
2593
+ out.push(chunkN66HCGCY_cjs.requireDefined(modifications[0]));
1705
2594
  continue;
1706
2595
  }
1707
- const first = entityOf(chunk764JHTLT_cjs.requireDefined(modifications[0]));
2596
+ const first = entityOf(chunkN66HCGCY_cjs.requireDefined(modifications[0]));
1708
2597
  const { props, conflicts: propertyConflicts } = threeWayMergeProps(
1709
2598
  first.id,
1710
2599
  first.kind,
@@ -1723,7 +2612,7 @@ function reconcileOver(survivingModifications, entityOf, rebuild, policy, branch
1723
2612
  );
1724
2613
  const representative = modifications.find(
1725
2614
  (modification) => modification.branchId === chosenBranch
1726
- ) ?? chunk764JHTLT_cjs.requireDefined(modifications[0]);
2615
+ ) ?? chunkN66HCGCY_cjs.requireDefined(modifications[0]);
1727
2616
  out.push(rebuild(representative, chosenBranch, props));
1728
2617
  for (const conflict of propertyConflicts) {
1729
2618
  conflicts.push(conflict);
@@ -1731,11 +2620,11 @@ function reconcileOver(survivingModifications, entityOf, rebuild, policy, branch
1731
2620
  }
1732
2621
  return {
1733
2622
  survivingModifications: [...out].sort((left, right) => {
1734
- const byId2 = chunkTRF4EBJT_cjs.compareStrings(entityOf(left).id, entityOf(right).id);
1735
- return byId2 === 0 ? chunkTRF4EBJT_cjs.compareStrings(left.branchId, right.branchId) : byId2;
2623
+ const byId2 = chunkXMQSEJCF_cjs.compareStrings(entityOf(left).id, entityOf(right).id);
2624
+ return byId2 === 0 ? chunkXMQSEJCF_cjs.compareStrings(left.branchId, right.branchId) : byId2;
1736
2625
  }),
1737
2626
  conflicts: conflicts.sort(
1738
- (left, right) => chunkTRF4EBJT_cjs.compareStrings(
2627
+ (left, right) => chunkXMQSEJCF_cjs.compareStrings(
1739
2628
  `${left.entityId}|${left.property}`,
1740
2629
  `${right.entityId}|${right.property}`
1741
2630
  )
@@ -1748,7 +2637,7 @@ function resolveDeleteModify(staging, policy, branchRank, preferredBranchId) {
1748
2637
  staging.deletedNodes,
1749
2638
  (item) => item.node,
1750
2639
  (item) => item.node,
1751
- "node",
2640
+ (id) => ({ kind: "node", id, reason: DELETED_NODE_DROP_REASON }),
1752
2641
  policy,
1753
2642
  branchRank,
1754
2643
  preferredBranchId
@@ -1761,7 +2650,7 @@ function resolveDeleteModify(staging, policy, branchRank, preferredBranchId) {
1761
2650
  };
1762
2651
  }
1763
2652
  function threeWayMergeProps(entityId, kind, baseProps, contributions, context, branchRank, preferredBranchId) {
1764
- const merged = {};
2653
+ const merged = chunkN66HCGCY_cjs.createDataKeyedBag();
1765
2654
  const conflicts = [];
1766
2655
  const propertyNames = new Set(Object.keys(baseProps));
1767
2656
  for (const contribution of contributions) {
@@ -1769,11 +2658,11 @@ function threeWayMergeProps(entityId, kind, baseProps, contributions, context, b
1769
2658
  propertyNames.add(name);
1770
2659
  }
1771
2660
  }
1772
- for (const property of [...propertyNames].sort(chunkTRF4EBJT_cjs.compareStrings)) {
1773
- const baseHas = property in baseProps;
1774
- const baseKey = baseHas ? canonicalValueKey(chunk764JHTLT_cjs.requireDefined(baseProps[property])) : void 0;
2661
+ for (const property of [...propertyNames].sort(chunkXMQSEJCF_cjs.compareStrings)) {
2662
+ const baseHas = chunkN66HCGCY_cjs.hasOwnKey(baseProps, property);
2663
+ const baseKey = baseHas ? canonicalValueKey(chunkN66HCGCY_cjs.requireDefined(baseProps[property])) : void 0;
1775
2664
  const changed = contributions.filter((contribution) => {
1776
- if (!(property in contribution.forkProps)) {
2665
+ if (!chunkN66HCGCY_cjs.hasOwnKey(contribution.forkProps, property)) {
1777
2666
  return false;
1778
2667
  }
1779
2668
  const value2 = contribution.forkProps[property];
@@ -1785,10 +2674,10 @@ function threeWayMergeProps(entityId, kind, baseProps, contributions, context, b
1785
2674
  const values = collectConflictingValues(property, changed);
1786
2675
  if (values.length === 0) {
1787
2676
  const deletedByFork = baseHas && contributions.some(
1788
- (contribution) => !(property in contribution.forkProps)
2677
+ (contribution) => !chunkN66HCGCY_cjs.hasOwnKey(contribution.forkProps, property)
1789
2678
  );
1790
2679
  if (baseHas && !deletedByFork) {
1791
- merged[property] = chunk764JHTLT_cjs.requireDefined(baseProps[property]);
2680
+ merged[property] = chunkN66HCGCY_cjs.requireDefined(baseProps[property]);
1792
2681
  }
1793
2682
  continue;
1794
2683
  }
@@ -1796,13 +2685,13 @@ function threeWayMergeProps(entityId, kind, baseProps, contributions, context, b
1796
2685
  values.map((candidate) => canonicalValueKey(candidate.value))
1797
2686
  );
1798
2687
  if (distinctValues.size === 1) {
1799
- merged[property] = chunk764JHTLT_cjs.requireDefined(values[0]).value;
2688
+ merged[property] = chunkN66HCGCY_cjs.requireDefined(values[0]).value;
1800
2689
  continue;
1801
2690
  }
1802
2691
  const preferredValue = values.find(
1803
2692
  (value2) => value2.branchId === preferredBranchId
1804
2693
  )?.value;
1805
- const canonicalValue = preferredValue ?? (baseHas ? chunk764JHTLT_cjs.requireDefined(baseProps[property]) : chunk764JHTLT_cjs.requireDefined(values[0]).value);
2694
+ const canonicalValue = preferredValue ?? (baseHas ? chunkN66HCGCY_cjs.requireDefined(baseProps[property]) : chunkN66HCGCY_cjs.requireDefined(values[0]).value);
1806
2695
  const reportedValues = preferredBranchId === void 0 ? values : values.filter((value2) => value2.branchId !== preferredBranchId);
1807
2696
  const { value, conflict } = resolvePropertyUnion(
1808
2697
  { entityId, kind, property, values, reportedValues, canonicalValue },
@@ -1836,7 +2725,7 @@ function resolveEdgeDeleteModify(staging, policy, branchRank, preferredBranchId)
1836
2725
  staging.deletedEdges,
1837
2726
  (item) => item.edge,
1838
2727
  (item) => item.edge,
1839
- "edge",
2728
+ (id) => ({ kind: "edge", id, reason: DELETED_NODE_DROP_REASON }),
1840
2729
  policy,
1841
2730
  branchRank,
1842
2731
  preferredBranchId
@@ -1863,8 +2752,166 @@ function reconcileEdgeModifications(survivingModifications, policy, branchRank,
1863
2752
  );
1864
2753
  }
1865
2754
 
2755
+ // src/graph-merge/valid-window.ts
2756
+ var WINDOW_NOT_APPLICABLE_DROP_REASON = "window-not-applicable";
2757
+ function earliestEnd(claims) {
2758
+ let earliest;
2759
+ for (const claim of claims) {
2760
+ if (earliest === void 0 || chunkXMQSEJCF_cjs.compareStrings(claim.validTo, earliest) < 0) {
2761
+ earliest = claim.validTo;
2762
+ }
2763
+ }
2764
+ return earliest;
2765
+ }
2766
+ function resolveEndClaims(claims, preferredBranchId) {
2767
+ const preferred = claims.filter(
2768
+ (claim) => claim.branchId === preferredBranchId
2769
+ );
2770
+ return earliestEnd(preferred.length > 0 ? preferred : claims);
2771
+ }
2772
+ function claimingBranches(claims) {
2773
+ return [...new Set(claims.map((claim) => claim.branchId))].sort(
2774
+ (left, right) => chunkXMQSEJCF_cjs.compareStrings(left, right)
2775
+ );
2776
+ }
2777
+ function classifyDelta(base, fork) {
2778
+ const endCleared = fork.validTo === void 0 && base.validTo !== void 0;
2779
+ return {
2780
+ applicableEnd: fork.validTo !== void 0 && fork.validTo !== base.validTo ? fork.validTo : void 0,
2781
+ unapplicable: endCleared || fork.validFrom !== base.validFrom
2782
+ };
2783
+ }
2784
+ function resolvePopulation(entity, deltas, deletions, preferredBranchId, dropItem) {
2785
+ const byIdentity = /* @__PURE__ */ new Map();
2786
+ for (const delta of deltas) {
2787
+ const identity = mergeKey(delta.kind, delta.id);
2788
+ if (deletions.has(identity)) {
2789
+ continue;
2790
+ }
2791
+ const bucket = byIdentity.get(identity);
2792
+ if (bucket === void 0) {
2793
+ byIdentity.set(identity, [delta]);
2794
+ } else {
2795
+ bucket.push(delta);
2796
+ }
2797
+ }
2798
+ const ends = /* @__PURE__ */ new Map();
2799
+ const credits = /* @__PURE__ */ new Map();
2800
+ const resolutions = [];
2801
+ const dropped = [];
2802
+ for (const [identity, group] of byIdentity) {
2803
+ const claims = [];
2804
+ let reportedUnapplicable = false;
2805
+ let targetEnd;
2806
+ for (const delta of group) {
2807
+ const { applicableEnd, unapplicable } = classifyDelta(
2808
+ delta.base,
2809
+ delta.fork
2810
+ );
2811
+ if (delta.branchId === preferredBranchId) {
2812
+ targetEnd ??= applicableEnd;
2813
+ continue;
2814
+ }
2815
+ if (applicableEnd !== void 0) {
2816
+ claims.push({ branchId: delta.branchId, validTo: applicableEnd });
2817
+ }
2818
+ if (unapplicable && !reportedUnapplicable) {
2819
+ reportedUnapplicable = true;
2820
+ dropped.push(dropItem(delta.id));
2821
+ }
2822
+ }
2823
+ const first = chunkN66HCGCY_cjs.requireDefined(group[0]);
2824
+ if (targetEnd !== void 0) {
2825
+ if (claims.length > 0) {
2826
+ resolutions.push({
2827
+ entity,
2828
+ kind: first.kind,
2829
+ id: first.id,
2830
+ validTo: targetEnd,
2831
+ claimedBy: claimingBranches(claims),
2832
+ precedence: VALIDITY_END_TARGET_PRECEDENCE
2833
+ });
2834
+ }
2835
+ continue;
2836
+ }
2837
+ const resolved = earliestEnd(claims);
2838
+ if (resolved === void 0) {
2839
+ continue;
2840
+ }
2841
+ ends.set(identity, resolved);
2842
+ credits.set(
2843
+ identity,
2844
+ claimingBranches(claims.filter((claim) => claim.validTo === resolved))
2845
+ );
2846
+ resolutions.push({
2847
+ entity,
2848
+ kind: first.kind,
2849
+ id: first.id,
2850
+ validTo: resolved,
2851
+ claimedBy: claimingBranches(claims)
2852
+ });
2853
+ }
2854
+ return {
2855
+ ends,
2856
+ credits,
2857
+ resolutions: resolutions.sort(
2858
+ (left, right) => compareMergeKeys(
2859
+ mergeKey(left.kind, left.id),
2860
+ mergeKey(right.kind, right.id)
2861
+ )
2862
+ ),
2863
+ dropped: dropped.sort((left, right) => chunkXMQSEJCF_cjs.compareStrings(left.id, right.id))
2864
+ };
2865
+ }
2866
+ function resolveValidWindows(staging, nodeDeletions, edgeDeletions, preferredBranchId) {
2867
+ const nodes = resolvePopulation(
2868
+ "node",
2869
+ staging.windowedNodes.map((staged) => ({
2870
+ branchId: staged.branchId,
2871
+ kind: staged.node.kind,
2872
+ id: staged.node.id,
2873
+ base: staged.node.base,
2874
+ fork: staged.node.fork
2875
+ })),
2876
+ nodeDeletions,
2877
+ preferredBranchId,
2878
+ (id) => ({
2879
+ kind: "node",
2880
+ id,
2881
+ reason: WINDOW_NOT_APPLICABLE_DROP_REASON
2882
+ })
2883
+ );
2884
+ const edges = resolvePopulation(
2885
+ "edge",
2886
+ staging.windowedEdges.map((staged) => ({
2887
+ branchId: staged.branchId,
2888
+ kind: staged.edge.kind,
2889
+ id: staged.edge.id,
2890
+ base: staged.edge.base,
2891
+ fork: staged.edge.fork
2892
+ })),
2893
+ edgeDeletions,
2894
+ preferredBranchId,
2895
+ (id) => ({
2896
+ kind: "edge",
2897
+ id,
2898
+ reason: WINDOW_NOT_APPLICABLE_DROP_REASON
2899
+ })
2900
+ );
2901
+ return {
2902
+ nodeEnds: nodes.ends,
2903
+ edgeEnds: edges.ends,
2904
+ nodeCredits: nodes.credits,
2905
+ edgeCredits: edges.credits,
2906
+ resolutions: [...nodes.resolutions, ...edges.resolutions],
2907
+ dropped: [...nodes.dropped, ...edges.dropped]
2908
+ };
2909
+ }
2910
+
1866
2911
  // src/graph-merge/edge-repoint.ts
1867
2912
  var ENDPOINT_DELETED_DROP_REASON = "edge:endpoint-deleted";
2913
+ var INHERITED_EDGE_ORIGIN = "inherited";
2914
+ var BRANCH_CREATED_EDGE_ORIGIN = "branch-created";
1868
2915
  function buildCanonicalMap(clusters, canonicalOf) {
1869
2916
  const map = /* @__PURE__ */ new Map();
1870
2917
  for (const cluster of clusters) {
@@ -1884,16 +2931,97 @@ function dedupeKey(fromKey, type, toKey, props) {
1884
2931
  function groupKey(fromKey, type, toKey) {
1885
2932
  return JSON.stringify([fromKey, type, toKey]);
1886
2933
  }
2934
+ function sourcePairKey(fromKey, toKey) {
2935
+ return JSON.stringify([fromKey, toKey]);
2936
+ }
2937
+ function rowsById(groupEdges) {
2938
+ const rows = /* @__PURE__ */ new Map();
2939
+ for (const edge of groupEdges) {
2940
+ const row = rows.get(edge.staged.id);
2941
+ if (row === void 0) {
2942
+ rows.set(edge.staged.id, [edge]);
2943
+ } else {
2944
+ row.push(edge);
2945
+ }
2946
+ }
2947
+ return rows;
2948
+ }
2949
+ function sourcePairByRow(rows) {
2950
+ const pairs = /* @__PURE__ */ new Map();
2951
+ for (const [id, members] of rows) {
2952
+ const sorted = members.map((member) => member.sourcePair).sort((left, right) => chunkXMQSEJCF_cjs.compareStrings(left, right));
2953
+ pairs.set(id, chunkN66HCGCY_cjs.requireDefined(sorted[0]));
2954
+ }
2955
+ return pairs;
2956
+ }
2957
+ function foldSets(groupEdges) {
2958
+ const rows = rowsById(groupEdges);
2959
+ const sourcePairs = sourcePairByRow(rows);
2960
+ const representatives = /* @__PURE__ */ new Map();
2961
+ for (const [id, pair] of sourcePairs) {
2962
+ const representative = representatives.get(pair);
2963
+ if (representative === void 0 || chunkXMQSEJCF_cjs.compareStrings(id, representative) < 0) {
2964
+ representatives.set(pair, id);
2965
+ }
2966
+ }
2967
+ const collapsed = [];
2968
+ const parallel = [];
2969
+ for (const id of [...rows.keys()].sort(
2970
+ (left, right) => chunkXMQSEJCF_cjs.compareStrings(left, right)
2971
+ )) {
2972
+ const members = chunkN66HCGCY_cjs.requireDefined(rows.get(id));
2973
+ const pair = chunkN66HCGCY_cjs.requireDefined(sourcePairs.get(id));
2974
+ if (representatives.get(pair) === id) {
2975
+ collapsed.push(...members);
2976
+ } else {
2977
+ parallel.push(members);
2978
+ }
2979
+ }
2980
+ return [collapsed, ...parallel];
2981
+ }
2982
+ function compareMembers(left, right, preferredBranchId) {
2983
+ const byId2 = chunkXMQSEJCF_cjs.compareStrings(left.staged.id, right.staged.id);
2984
+ if (byId2 !== 0) {
2985
+ return byId2;
2986
+ }
2987
+ const leftPreferred = left.staged.branchId === preferredBranchId;
2988
+ const rightPreferred = right.staged.branchId === preferredBranchId;
2989
+ if (leftPreferred !== rightPreferred) {
2990
+ return leftPreferred ? -1 : 1;
2991
+ }
2992
+ return chunkXMQSEJCF_cjs.compareStrings(left.staged.branchId, right.staged.branchId);
2993
+ }
1887
2994
  function pickSurvivor(edges, preferredBranchId) {
2995
+ const inherited = edges.filter(
2996
+ (edge) => edge.staged.origin === INHERITED_EDGE_ORIGIN
2997
+ );
1888
2998
  const preferred = preferredBranchId === void 0 ? [] : edges.filter((edge) => edge.staged.branchId === preferredBranchId);
1889
- const candidates = preferred.length > 0 ? preferred : edges;
1890
- let survivor = chunk764JHTLT_cjs.requireDefined(candidates[0]);
1891
- for (const candidate of candidates.slice(1)) {
1892
- if (candidate.staged.id < survivor.staged.id) {
1893
- survivor = candidate;
1894
- }
2999
+ const candidates = inherited.length > 0 ? inherited : preferred.length > 0 ? preferred : edges;
3000
+ return chunkN66HCGCY_cjs.requireDefined(
3001
+ [...candidates].sort(
3002
+ (left, right) => compareMembers(left, right, preferredBranchId)
3003
+ )[0]
3004
+ );
3005
+ }
3006
+ function authoredProperty(edge, property) {
3007
+ const { props, baseProps } = edge.staged;
3008
+ if (!chunkN66HCGCY_cjs.hasOwnKey(props, property)) {
3009
+ return false;
3010
+ }
3011
+ if (baseProps === void 0 || !chunkN66HCGCY_cjs.hasOwnKey(baseProps, property)) {
3012
+ return true;
1895
3013
  }
1896
- return survivor;
3014
+ return canonicalValueKey(props[property]) !== canonicalValueKey(baseProps[property]);
3015
+ }
3016
+ function unauthoredValue(property, edges) {
3017
+ const carriers = edges.filter((edge) => chunkN66HCGCY_cjs.hasOwnKey(edge.staged.props, property)).sort((left, right) => {
3018
+ const byId2 = chunkXMQSEJCF_cjs.compareStrings(left.staged.id, right.staged.id);
3019
+ return byId2 === 0 ? chunkXMQSEJCF_cjs.compareStrings(
3020
+ canonicalValueKey(left.staged.props[property]),
3021
+ canonicalValueKey(right.staged.props[property])
3022
+ ) : byId2;
3023
+ });
3024
+ return chunkN66HCGCY_cjs.requireDefined(carriers[0]).staged.props[property];
1897
3025
  }
1898
3026
  function unionEdgeProps(survivorId, kind, survivor, edges, context, branchRank, preferredBranchId) {
1899
3027
  const propertyNames = /* @__PURE__ */ new Set();
@@ -1902,17 +3030,18 @@ function unionEdgeProps(survivorId, kind, survivor, edges, context, branchRank,
1902
3030
  propertyNames.add(name);
1903
3031
  }
1904
3032
  }
1905
- const props = {};
3033
+ const props = chunkN66HCGCY_cjs.createDataKeyedBag();
1906
3034
  const conflicts = [];
1907
- const contributions = edges.map((edge) => edge.staged);
1908
3035
  for (const property of [...propertyNames].sort(
1909
- (left, right) => chunkTRF4EBJT_cjs.compareStrings(left, right)
3036
+ (left, right) => chunkXMQSEJCF_cjs.compareStrings(left, right)
1910
3037
  )) {
1911
- const values = collectConflictingValues(property, contributions);
3038
+ const claimants = edges.filter((edge) => authoredProperty(edge, property)).map((edge) => edge.staged);
3039
+ const values = collectConflictingValues(property, claimants);
1912
3040
  if (values.length === 0) {
3041
+ props[property] = chunkN66HCGCY_cjs.hasOwnKey(survivor.staged.props, property) ? survivor.staged.props[property] : unauthoredValue(property, edges);
1913
3042
  continue;
1914
3043
  }
1915
- const survivorValue = property in survivor.staged.props ? survivor.staged.props[property] : chunk764JHTLT_cjs.requireDefined(values[0]).value;
3044
+ const survivorValue = chunkN66HCGCY_cjs.hasOwnKey(survivor.staged.props, property) ? survivor.staged.props[property] : chunkN66HCGCY_cjs.requireDefined(values[0]).value;
1916
3045
  const canonicalValue = values.find((value2) => value2.branchId === preferredBranchId)?.value ?? survivorValue;
1917
3046
  const reportedValues = preferredBranchId === void 0 ? values : values.filter((value2) => value2.branchId !== preferredBranchId);
1918
3047
  const { value, conflict } = resolvePropertyUnion(
@@ -1934,16 +3063,75 @@ function unionEdgeProps(survivorId, kind, survivor, edges, context, branchRank,
1934
3063
  }
1935
3064
  return { props, conflicts };
1936
3065
  }
3066
+ function foldEdgeSet(foldSet, context, branchRank, preferredBranchId) {
3067
+ const survivor = pickSurvivor(foldSet, preferredBranchId);
3068
+ const survivorId = survivor.staged.id;
3069
+ const mergedIds = foldSet.map((edge) => edge.staged.id).sort((left, right) => chunkXMQSEJCF_cjs.compareStrings(left, right));
3070
+ const fromId = idOf(survivor.fromKey);
3071
+ const fromKind = kindOf(survivor.fromKey);
3072
+ const toId = idOf(survivor.toKey);
3073
+ const toKind = kindOf(survivor.toKey);
3074
+ const preferredSurvivorEnd = survivor.staged.branchId === preferredBranchId ? survivor.staged.validTo : void 0;
3075
+ const foldedEnd = preferredSurvivorEnd ?? resolveEndClaims(
3076
+ foldSet.filter((edge) => edge.staged.validTo !== void 0).map((edge) => ({
3077
+ branchId: edge.staged.branchId,
3078
+ validTo: chunkN66HCGCY_cjs.requireDefined(edge.staged.validTo)
3079
+ })),
3080
+ preferredBranchId
3081
+ );
3082
+ const window = {
3083
+ ...survivor.staged.validFrom === void 0 ? {} : { validFrom: survivor.staged.validFrom },
3084
+ ...foldedEnd === void 0 ? {} : { validTo: foldedEnd }
3085
+ };
3086
+ const contentKeys = new Set(foldSet.map((edge) => edge.dedupeKey));
3087
+ if (contentKeys.size === 1) {
3088
+ return {
3089
+ edge: {
3090
+ id: survivorId,
3091
+ kind: survivor.staged.kind,
3092
+ fromId,
3093
+ toId,
3094
+ fromKind,
3095
+ toKind,
3096
+ props: survivor.staged.props,
3097
+ mergedIds,
3098
+ ...window
3099
+ },
3100
+ conflicts: []
3101
+ };
3102
+ }
3103
+ const { props, conflicts } = unionEdgeProps(
3104
+ survivorId,
3105
+ survivor.staged.kind,
3106
+ survivor,
3107
+ foldSet,
3108
+ context,
3109
+ branchRank,
3110
+ preferredBranchId
3111
+ );
3112
+ return {
3113
+ edge: {
3114
+ id: survivorId,
3115
+ kind: survivor.staged.kind,
3116
+ fromId,
3117
+ toId,
3118
+ fromKind,
3119
+ toKind,
3120
+ props,
3121
+ mergedIds,
3122
+ ...window
3123
+ },
3124
+ conflicts
3125
+ };
3126
+ }
1937
3127
  function repointEdges(stagedEdges, canonicalOf, deletedNodeIds, policy, branchRank, weights, preferredBranchId) {
1938
3128
  const dropped = [];
1939
- const liveByDedupeKey = /* @__PURE__ */ new Map();
1940
- const dedupeKeyByGroup = /* @__PURE__ */ new Map();
3129
+ const liveByGroup = /* @__PURE__ */ new Map();
1941
3130
  for (const staged of stagedEdges) {
1942
- const fromKey = repoint(
1943
- mergeKey(staged.fromKind, staged.fromId),
1944
- canonicalOf
1945
- );
1946
- const toKey = repoint(mergeKey(staged.toKind, staged.toId), canonicalOf);
3131
+ const sourceFromKey = mergeKey(staged.fromKind, staged.fromId);
3132
+ const sourceToKey = mergeKey(staged.toKind, staged.toId);
3133
+ const fromKey = repoint(sourceFromKey, canonicalOf);
3134
+ const toKey = repoint(sourceToKey, canonicalOf);
1947
3135
  if (deletedNodeIds.has(fromKey) || deletedNodeIds.has(toKey)) {
1948
3136
  dropped.push({
1949
3137
  kind: "edge",
@@ -1952,21 +3140,20 @@ function repointEdges(stagedEdges, canonicalOf, deletedNodeIds, policy, branchRa
1952
3140
  });
1953
3141
  continue;
1954
3142
  }
1955
- const repointed = { staged, fromKey, toKey };
1956
- const key = dedupeKey(fromKey, staged.kind, toKey, staged.props);
1957
- const bucket = liveByDedupeKey.get(key);
3143
+ const repointed = {
3144
+ staged,
3145
+ fromKey,
3146
+ toKey,
3147
+ sourcePair: sourcePairKey(sourceFromKey, sourceToKey),
3148
+ dedupeKey: dedupeKey(fromKey, staged.kind, toKey, staged.props)
3149
+ };
3150
+ const group = groupKey(fromKey, staged.kind, toKey);
3151
+ const bucket = liveByGroup.get(group);
1958
3152
  if (bucket === void 0) {
1959
- liveByDedupeKey.set(key, [repointed]);
3153
+ liveByGroup.set(group, [repointed]);
1960
3154
  } else {
1961
3155
  bucket.push(repointed);
1962
3156
  }
1963
- const group = groupKey(fromKey, staged.kind, toKey);
1964
- const keysForGroup = dedupeKeyByGroup.get(group);
1965
- if (keysForGroup === void 0) {
1966
- dedupeKeyByGroup.set(group, /* @__PURE__ */ new Set([key]));
1967
- } else {
1968
- keysForGroup.add(key);
1969
- }
1970
3157
  }
1971
3158
  const context = {
1972
3159
  policy,
@@ -1974,74 +3161,41 @@ function repointEdges(stagedEdges, canonicalOf, deletedNodeIds, policy, branchRa
1974
3161
  };
1975
3162
  const merged = [];
1976
3163
  const conflicts = [];
1977
- const sortedGroups = [...dedupeKeyByGroup.keys()].sort(
1978
- (left, right) => chunkTRF4EBJT_cjs.compareStrings(left, right)
3164
+ const sortedGroups = [...liveByGroup.keys()].sort(
3165
+ (left, right) => chunkXMQSEJCF_cjs.compareStrings(left, right)
1979
3166
  );
1980
3167
  for (const group of sortedGroups) {
1981
- const dedupeKeys = [...chunk764JHTLT_cjs.requireDefined(dedupeKeyByGroup.get(group))];
1982
- const groupEdges = [];
1983
- for (const key of dedupeKeys) {
1984
- for (const edge of chunk764JHTLT_cjs.requireDefined(liveByDedupeKey.get(key))) {
1985
- groupEdges.push(edge);
3168
+ const groupEdges = chunkN66HCGCY_cjs.requireDefined(liveByGroup.get(group));
3169
+ for (const foldSet of foldSets(groupEdges)) {
3170
+ const folded = foldEdgeSet(
3171
+ foldSet,
3172
+ context,
3173
+ branchRank,
3174
+ preferredBranchId
3175
+ );
3176
+ merged.push(folded.edge);
3177
+ for (const conflict of folded.conflicts) {
3178
+ conflicts.push(conflict);
1986
3179
  }
1987
3180
  }
1988
- const survivor = pickSurvivor(groupEdges, preferredBranchId);
1989
- const survivorId = survivor.staged.id;
1990
- const mergedIds = [...groupEdges].map((edge) => edge.staged.id).sort((left, right) => chunkTRF4EBJT_cjs.compareStrings(left, right));
1991
- const fromId = idOf(survivor.fromKey);
1992
- const fromKind = kindOf(survivor.fromKey);
1993
- const toId = idOf(survivor.toKey);
1994
- const toKind = kindOf(survivor.toKey);
1995
- if (dedupeKeys.length === 1) {
1996
- merged.push({
1997
- id: survivorId,
1998
- kind: survivor.staged.kind,
1999
- fromId,
2000
- toId,
2001
- fromKind,
2002
- toKind,
2003
- props: survivor.staged.props,
2004
- mergedIds
2005
- });
2006
- continue;
2007
- }
2008
- const { props, conflicts: groupConflicts } = unionEdgeProps(
2009
- survivorId,
2010
- survivor.staged.kind,
2011
- survivor,
2012
- groupEdges,
2013
- context,
2014
- branchRank,
2015
- preferredBranchId
2016
- );
2017
- for (const conflict of groupConflicts) {
2018
- conflicts.push(conflict);
2019
- }
2020
- merged.push({
2021
- id: survivorId,
2022
- kind: survivor.staged.kind,
2023
- fromId,
2024
- toId,
2025
- fromKind,
2026
- toKind,
2027
- props,
2028
- mergedIds
2029
- });
2030
3181
  }
2031
3182
  const sortedEdges = merged.map((edge) => ({
2032
3183
  edge,
2033
- sortKey: dedupeKey(
2034
- mergeKey(edge.fromKind, edge.fromId),
2035
- edge.kind,
2036
- mergeKey(edge.toKind, edge.toId),
2037
- edge.props
2038
- )
2039
- })).sort((left, right) => chunkTRF4EBJT_cjs.compareStrings(left.sortKey, right.sortKey)).map(({ edge }) => edge);
3184
+ sortKey: JSON.stringify([
3185
+ dedupeKey(
3186
+ mergeKey(edge.fromKind, edge.fromId),
3187
+ edge.kind,
3188
+ mergeKey(edge.toKind, edge.toId),
3189
+ edge.props
3190
+ ),
3191
+ edge.id
3192
+ ])
3193
+ })).sort((left, right) => chunkXMQSEJCF_cjs.compareStrings(left.sortKey, right.sortKey)).map(({ edge }) => edge);
2040
3194
  return {
2041
3195
  edges: sortedEdges,
2042
- dropped: dropped.sort((left, right) => chunkTRF4EBJT_cjs.compareStrings(left.id, right.id)),
3196
+ dropped: dropped.sort((left, right) => chunkXMQSEJCF_cjs.compareStrings(left.id, right.id)),
2043
3197
  conflicts: conflicts.sort(
2044
- (left, right) => chunkTRF4EBJT_cjs.compareStrings(
3198
+ (left, right) => chunkXMQSEJCF_cjs.compareStrings(
2045
3199
  `${left.entityId}|${left.property}`,
2046
3200
  `${right.entityId}|${right.property}`
2047
3201
  )
@@ -2087,7 +3241,7 @@ function validateResolveMap(resolve) {
2087
3241
  return {};
2088
3242
  }
2089
3243
  const configs = resolve;
2090
- const validated = {};
3244
+ const validated = chunkN66HCGCY_cjs.createDataKeyedBag();
2091
3245
  for (const [kind, config] of Object.entries(configs)) {
2092
3246
  const parsed = resolveConfigScalarSchema.safeParse({
2093
3247
  threshold: config.threshold
@@ -2115,7 +3269,7 @@ function validateResolveMap(resolve) {
2115
3269
  }
2116
3270
  validated[kind] = config;
2117
3271
  }
2118
- return validated;
3272
+ return { ...validated };
2119
3273
  }
2120
3274
  function validateProvenanceWeights(weights) {
2121
3275
  for (const [branchId, weight] of weights) {
@@ -2170,7 +3324,9 @@ function normalizeMergeOptions(options = {}) {
2170
3324
  ...provenanceWeights === void 0 ? {} : { provenanceWeights }
2171
3325
  };
2172
3326
  }
2173
- var Provenance = chunkEE7N5XXQ_cjs.defineNode("Provenance", {
3327
+ var PROVENANCE_KIND = "Provenance";
3328
+ var PROVENANCE_OWNER_KIND = "ProvenanceOwner";
3329
+ var Provenance = chunkNK5Q7UNE_cjs.defineNode(PROVENANCE_KIND, {
2174
3330
  schema: zod.z.object({
2175
3331
  targetGraphId: zod.z.string(),
2176
3332
  role: zod.z.enum(["node", "edge"]),
@@ -2180,38 +3336,308 @@ var Provenance = chunkEE7N5XXQ_cjs.defineNode("Provenance", {
2180
3336
  sourceId: zod.z.string()
2181
3337
  })
2182
3338
  });
3339
+ var PROVENANCE_OWNER = "@nicia-ai/typegraph/merge-provenance";
3340
+ var PROVENANCE_OWNER_VERSION = 1;
3341
+ var PROVENANCE_OWNER_ID = "merge-provenance-owner";
3342
+ var ProvenanceOwner = chunkNK5Q7UNE_cjs.defineNode(PROVENANCE_OWNER_KIND, {
3343
+ schema: zod.z.object({
3344
+ owner: zod.z.literal(PROVENANCE_OWNER),
3345
+ version: zod.z.literal(PROVENANCE_OWNER_VERSION),
3346
+ targetGraphId: zod.z.string()
3347
+ })
3348
+ });
2183
3349
  function provenanceGraphId(targetGraphId) {
2184
3350
  return `${targetGraphId}::merge-provenance`;
2185
3351
  }
2186
- function buildProvenanceGraph(targetGraphId) {
2187
- return chunkQB6VMOJ2_cjs.defineGraph({
2188
- id: provenanceGraphId(targetGraphId),
2189
- nodes: { Provenance: { type: Provenance } },
2190
- edges: {}
3352
+ function buildOwnedProvenanceGraph(targetGraphId) {
3353
+ return chunkCXBHOOIQ_cjs.defineInternalGraph({
3354
+ id: provenanceGraphId(targetGraphId),
3355
+ nodes: {
3356
+ Provenance: { type: Provenance },
3357
+ ProvenanceOwner: { type: ProvenanceOwner }
3358
+ },
3359
+ edges: {}
3360
+ });
3361
+ }
3362
+ function buildProvenanceGraph(targetGraphId) {
3363
+ return chunkCXBHOOIQ_cjs.defineInternalGraph({
3364
+ id: provenanceGraphId(targetGraphId),
3365
+ nodes: { Provenance: { type: Provenance } },
3366
+ edges: {}
3367
+ });
3368
+ }
3369
+ async function openProvenanceStore(...args) {
3370
+ const [backend, targetGraphId] = args.length === 1 ? [chunkTTAITEPJ_cjs.storeBackend(args[0]), args[0].graphId] : args;
3371
+ const graph = buildOwnedProvenanceGraph(targetGraphId);
3372
+ const preflight = await inspectSidecarGraphId(backend, graph, targetGraphId);
3373
+ if (preflight.state === "refuse") {
3374
+ throw provenanceGraphIdCollision(graph.id, targetGraphId, preflight.reason);
3375
+ }
3376
+ if (preflight.state !== "owned") {
3377
+ const claim = await claimSidecarOwnership(backend, graph, targetGraphId);
3378
+ if (claim.state === "refuse") {
3379
+ throw provenanceGraphIdCollision(graph.id, targetGraphId, claim.reason);
3380
+ }
3381
+ }
3382
+ const [store] = await chunkXDF2UPEQ_cjs.createStoreWithSchema(graph, backend);
3383
+ return store;
3384
+ }
3385
+ async function claimSidecarOwnership(backend, graph, targetGraphId) {
3386
+ const fence = backend.schemaWriteTransaction;
3387
+ if (fence === void 0) {
3388
+ throw provenanceClaimUnfenced(graph.id, targetGraphId);
3389
+ }
3390
+ return fence(graph.id, async (tx) => {
3391
+ await drainUnfencedRowWriters(tx);
3392
+ const verdict = await inspectSidecarGraphId(tx, graph, targetGraphId);
3393
+ if (verdict.state === "refuse" || verdict.state === "owned") return verdict;
3394
+ await tx.insertNode({
3395
+ graphId: graph.id,
3396
+ kind: PROVENANCE_OWNER_KIND,
3397
+ id: PROVENANCE_OWNER_ID,
3398
+ props: {
3399
+ owner: PROVENANCE_OWNER,
3400
+ version: PROVENANCE_OWNER_VERSION,
3401
+ targetGraphId
3402
+ }
3403
+ });
3404
+ return verdict;
3405
+ });
3406
+ }
3407
+ async function drainUnfencedRowWriters(tx) {
3408
+ if (tx.dialect !== "postgres") return;
3409
+ const schema = chunkNFCVHQ5P_cjs.createSqlSchema(tx.tableNames);
3410
+ await tx.executeStatement(
3411
+ chunkVCRRKBLN_cjs.asCompiledStatementSql(
3412
+ chunkVCRRKBLN_cjs.sql`LOCK TABLE ${schema.nodesTable}, ${schema.edgesTable} IN SHARE ROW EXCLUSIVE MODE`
3413
+ )
3414
+ );
3415
+ }
3416
+ async function inspectSidecarGraphId(port, graph, targetGraphId) {
3417
+ const activeSchema = await port.getActiveSchema(graph.id);
3418
+ if (activeSchema === void 0 && !await hasRowsUnderGraphId(port, graph.id, "any")) {
3419
+ return { state: "create" };
3420
+ }
3421
+ const marker = await inspectOwnerMarker(port, graph.id, targetGraphId);
3422
+ if (marker === "foreign") {
3423
+ return { state: "refuse", reason: "corrupt-ownership-marker" };
3424
+ }
3425
+ if (marker === "ours") {
3426
+ return { state: "owned" };
3427
+ }
3428
+ if (activeSchema === void 0) {
3429
+ return { state: "refuse", reason: "application-graph" };
3430
+ }
3431
+ const ownedHash = await chunkN3257XE6_cjs.computeSchemaHash(
3432
+ chunkN3257XE6_cjs.serializeSchema(graph, activeSchema.version)
3433
+ );
3434
+ if (activeSchema.schema_hash === ownedHash) {
3435
+ return { state: "refuse", reason: "unowned-exact-schema-graph" };
3436
+ }
3437
+ const legacyHash = await chunkN3257XE6_cjs.computeSchemaHash(
3438
+ chunkN3257XE6_cjs.serializeSchema(buildProvenanceGraph(targetGraphId), activeSchema.version)
3439
+ );
3440
+ if (activeSchema.schema_hash !== legacyHash) {
3441
+ return { state: "refuse", reason: "application-graph" };
3442
+ }
3443
+ return LEGACY_SCHEMA_DISPOSITION[await inspectSidecarContents(port, graph.id, targetGraphId)];
3444
+ }
3445
+ var LEGACY_SCHEMA_DISPOSITION = {
3446
+ provenance: { state: "upgrade" },
3447
+ empty: { state: "refuse", reason: "empty-legacy-sidecar" },
3448
+ "unrecognized-provenance": {
3449
+ state: "refuse",
3450
+ reason: "unupgradeable-legacy-sidecar"
3451
+ },
3452
+ "foreign-rows": { state: "refuse", reason: "application-graph" }
3453
+ };
3454
+ var SIDECAR_REFUSALS = {
3455
+ "application-graph": {
3456
+ describe: (graphId) => `Graph id "${graphId}" is already used by an application graph and cannot host merge provenance.`,
3457
+ suggestion: () => "Rename the colliding application graph before enabling persisted merge provenance for this target."
3458
+ },
3459
+ "corrupt-ownership-marker": {
3460
+ describe: (graphId, targetGraphId) => `Graph id "${graphId}" holds a "${PROVENANCE_OWNER_KIND}" row that is not a valid ownership claim for target "${targetGraphId}" \u2014 it is soft-deleted, does not validate against the marker schema, names a different target, or sits under a different row id.`,
3461
+ suggestion: (graphId) => `Do not re-run: an unverifiable marker is never overwritten or resurrected, because it may be an application's row. Inspect the "${PROVENANCE_OWNER_KIND}" rows under graph id "${graphId}" and hard-delete the invalid one, or drop that graph id entirely \u2014 persisted provenance is derived, so re-running the merge rebuilds it.`
3462
+ },
3463
+ "empty-legacy-sidecar": {
3464
+ describe: (graphId) => `Graph id "${graphId}" holds an EMPTY provenance sidecar from a release that wrote no ownership marker, which cannot be told apart from an application graph of the same shape.`,
3465
+ suggestion: (graphId) => `Drop graph id "${graphId}" \u2014 it holds no provenance records, so nothing is lost \u2014 and re-run the merge to create an owned sidecar.`
3466
+ },
3467
+ "unupgradeable-legacy-sidecar": {
3468
+ describe: (graphId, targetGraphId) => `Graph id "${graphId}" holds a pre-marker provenance sidecar whose rows do not verify as provenance for target "${targetGraphId}", so it cannot be upgraded to an owned sidecar.`,
3469
+ suggestion: (graphId) => `Export anything you still need from graph id "${graphId}", then drop it: provenance is derived, and re-running the merge rebuilds an owned sidecar.`
3470
+ },
3471
+ "unowned-exact-schema-graph": {
3472
+ describe: (graphId) => `Graph id "${graphId}" carries the merge-provenance schema but no ownership marker, so this library did not create it.`,
3473
+ suggestion: (graphId) => `Drop graph id "${graphId}" (or rename the graph that occupies it) and re-run the merge: a sidecar this library owns writes its "${PROVENANCE_OWNER}" marker row BEFORE the schema, so a marker-less one carrying this schema was written either by an application \u2014 which is never adopted \u2014 or by a crash of an unreleased build between those two writes. Persisted provenance is derived, so re-running the merge rebuilds it.`
3474
+ }
3475
+ };
3476
+ function provenanceGraphIdCollision(graphId, targetGraphId, reason) {
3477
+ const refusal = SIDECAR_REFUSALS[reason];
3478
+ return new chunkNI72YOJB_cjs.ConfigurationError(
3479
+ refusal.describe(graphId, targetGraphId),
3480
+ {
3481
+ code: "GRAPH_MERGE_PROVENANCE_ID_COLLISION",
3482
+ reason,
3483
+ graphId,
3484
+ targetGraphId
3485
+ },
3486
+ { suggestion: refusal.suggestion(graphId) }
3487
+ );
3488
+ }
3489
+ function provenanceClaimUnfenced(graphId, targetGraphId) {
3490
+ return new chunkNI72YOJB_cjs.ConfigurationError(
3491
+ `Claiming graph id "${graphId}" for merge provenance requires a transactional schema fence, which this backend does not provide.`,
3492
+ {
3493
+ code: "GRAPH_MERGE_PROVENANCE_CLAIM_UNFENCED",
3494
+ graphId,
3495
+ targetGraphId
3496
+ },
3497
+ {
3498
+ suggestion: "Use a backend that implements schemaWriteTransaction (both bundled Drizzle backends do when transactions are enabled); without it the sidecar's emptiness check and its ownership write cannot be committed as one unit. An ALREADY-owned sidecar opens without a claim."
3499
+ }
3500
+ );
3501
+ }
3502
+ function isOwnedMarkerRow(row, targetGraphId) {
3503
+ if (row.id !== PROVENANCE_OWNER_ID) return false;
3504
+ if (row.deleted_at !== void 0) return false;
3505
+ const parsed = ProvenanceOwner.schema.safeParse(parseRowProps(row.props));
3506
+ return parsed.success && parsed.data.targetGraphId === targetGraphId;
3507
+ }
3508
+ async function inspectOwnerMarker(port, graphId, targetGraphId) {
3509
+ let ours = false;
3510
+ for await (const row of readRowsOfKind(
3511
+ port,
3512
+ graphId,
3513
+ PROVENANCE_OWNER_KIND
3514
+ )) {
3515
+ if (!isOwnedMarkerRow(row, targetGraphId)) return "foreign";
3516
+ ours = true;
3517
+ }
3518
+ return ours ? "ours" : "absent";
3519
+ }
3520
+ var SIDECAR_PAGE_SIZE = 500;
3521
+ async function* readRowsOfKind(port, graphId, kind) {
3522
+ let after;
3523
+ for (; ; ) {
3524
+ const rows = await port.findNodesByKind({
3525
+ graphId,
3526
+ kind,
3527
+ temporalMode: "includeTombstones",
3528
+ excludeDeleted: false,
3529
+ orderBy: "id",
3530
+ ...after === void 0 ? {} : { after },
3531
+ limit: SIDECAR_PAGE_SIZE
3532
+ });
3533
+ for (const row of rows) {
3534
+ yield row;
3535
+ }
3536
+ if (rows.length < SIDECAR_PAGE_SIZE) return;
3537
+ after = rows.at(-1)?.id;
3538
+ if (after === void 0) return;
3539
+ }
3540
+ }
3541
+ async function hasRowsUnderGraphId(port, graphId, scope) {
3542
+ const schema = chunkNFCVHQ5P_cjs.createSqlSchema(port.tableNames);
3543
+ const kindFilter = scope === "any" ? chunkVCRRKBLN_cjs.sql.empty() : chunkVCRRKBLN_cjs.sql` AND kind <> ${PROVENANCE_KIND}`;
3544
+ if (await hasRowsInTable(port, schema.tables.nodes, graphId, kindFilter)) {
3545
+ return true;
3546
+ }
3547
+ if (await hasRowsInTable(port, schema.tables.edges, graphId, chunkVCRRKBLN_cjs.sql.empty())) {
3548
+ return true;
3549
+ }
3550
+ for (const tableName of secondaryRowTableNames(schema.tables)) {
3551
+ if (await hasRowsInSecondaryTable(port, tableName, graphId)) return true;
3552
+ }
3553
+ return false;
3554
+ }
3555
+ function secondaryRowTableNames(tables) {
3556
+ return [
3557
+ .../* @__PURE__ */ new Set([
3558
+ tables.recordedNodes,
3559
+ tables.recordedEdges,
3560
+ tables.recordedClock,
3561
+ tables.revisionOrigins,
3562
+ tables.identityAssertions,
3563
+ tables.recordedIdentityAssertions,
3564
+ tables.identityClosure,
3565
+ tables.identitySeparation,
3566
+ tables.fulltext,
3567
+ tables.uniques
3568
+ ])
3569
+ ];
3570
+ }
3571
+ async function hasRowsInTable(port, tableName, graphId, filter) {
3572
+ const rows = await port.execute(
3573
+ chunkVCRRKBLN_cjs.asCompiledRowsSql(
3574
+ chunkVCRRKBLN_cjs.sql`SELECT 1 AS present FROM ${chunkVCRRKBLN_cjs.sql.identifier(tableName)} WHERE graph_id = ${graphId}${filter} LIMIT 1`
3575
+ )
3576
+ );
3577
+ return rows.length > 0;
3578
+ }
3579
+ async function hasRowsInSecondaryTable(port, tableName, graphId) {
3580
+ const tableExists = port.tableExists;
3581
+ if (tableExists !== void 0) {
3582
+ return await tableExists(tableName) && await hasRowsInTable(port, tableName, graphId, chunkVCRRKBLN_cjs.sql.empty());
3583
+ }
3584
+ try {
3585
+ return await hasRowsInTable(port, tableName, graphId, chunkVCRRKBLN_cjs.sql.empty());
3586
+ } catch {
3587
+ return false;
3588
+ }
3589
+ }
3590
+ async function inspectSidecarContents(port, graphId, targetGraphId) {
3591
+ if (await hasRowsUnderGraphId(port, graphId, "foreign")) {
3592
+ return "foreign-rows";
3593
+ }
3594
+ let rowCount = 0;
3595
+ for await (const row of readRowsOfKind(port, graphId, PROVENANCE_KIND)) {
3596
+ if (!await isOwnedProvenanceRow(row, targetGraphId)) {
3597
+ return "unrecognized-provenance";
3598
+ }
3599
+ rowCount += 1;
3600
+ }
3601
+ return rowCount > 0 ? "provenance" : "empty";
3602
+ }
3603
+ async function isOwnedProvenanceRow(row, targetGraphId) {
3604
+ if (row.deleted_at !== void 0) return false;
3605
+ const parsed = Provenance.schema.safeParse(parseRowProps(row.props));
3606
+ if (!parsed.success || parsed.data.targetGraphId !== targetGraphId) {
3607
+ return false;
3608
+ }
3609
+ const expectedId = await provenanceNodeId(targetGraphId, {
3610
+ role: parsed.data.role,
3611
+ canonicalId: parsed.data.canonicalId,
3612
+ canonicalKind: parsed.data.canonicalKind,
3613
+ branchId: asBranchId(parsed.data.branchId),
3614
+ sourceId: parsed.data.sourceId
2191
3615
  });
2192
- }
2193
- async function openProvenanceStore(...args) {
2194
- const [backend, targetGraphId] = args.length === 1 ? [chunk7V2FGGI2_cjs.storeBackend(args[0]), args[0].graphId] : args;
2195
- const [store] = await chunkXR4YZFKW_cjs.createStoreWithSchema(
2196
- buildProvenanceGraph(targetGraphId),
2197
- backend
2198
- );
2199
- return store;
3616
+ return row.id === expectedId;
2200
3617
  }
2201
3618
  var ID_SEPARATOR = "\0";
2202
3619
  var ID_DIGEST_BYTES = 16;
3620
+ function contributionKey(record) {
3621
+ return encodeProvenanceTuple([
3622
+ record.role,
3623
+ record.canonicalKind,
3624
+ record.canonicalId,
3625
+ record.branchId,
3626
+ record.sourceId
3627
+ ]);
3628
+ }
3629
+ function encodeProvenanceTuple(values) {
3630
+ return values.some((value) => value.includes(ID_SEPARATOR)) ? chunkXNLIZYRZ_cjs.encodeTupleKey(values) : values.join(ID_SEPARATOR);
3631
+ }
2203
3632
  async function provenanceNodeId(targetGraphId, record) {
2204
- const tuple = [
3633
+ const tuple = encodeProvenanceTuple([
2205
3634
  targetGraphId,
2206
3635
  record.role,
2207
- // canonicalKind is part of node identity: two contributions to different-kind
2208
- // canonicals that share a bare id (e.g. base Patient:x and Encounter:x) must NOT
2209
- // hash to the same sidecar row and clobber each other (the (kind,id) identity model).
2210
3636
  record.canonicalKind,
2211
3637
  record.canonicalId,
2212
3638
  record.branchId,
2213
3639
  record.sourceId
2214
- ].join(ID_SEPARATOR);
3640
+ ]);
2215
3641
  const digest = await chunkZY4GXIVN_cjs.sha256Hex(tuple, ID_DIGEST_BYTES);
2216
3642
  return `prov_${digest}`;
2217
3643
  }
@@ -2219,7 +3645,7 @@ async function persistProvenanceRecords(store, targetGraphId, records) {
2219
3645
  if (records.length === 0) {
2220
3646
  return 0;
2221
3647
  }
2222
- const items = await Promise.all(
3648
+ const identified = await Promise.all(
2223
3649
  records.map(async (record) => ({
2224
3650
  id: await provenanceNodeId(targetGraphId, record),
2225
3651
  props: {
@@ -2232,6 +3658,11 @@ async function persistProvenanceRecords(store, targetGraphId, records) {
2232
3658
  }
2233
3659
  }))
2234
3660
  );
3661
+ const itemsById = /* @__PURE__ */ new Map();
3662
+ for (const item of identified) {
3663
+ itemsById.set(item.id, item);
3664
+ }
3665
+ const items = [...itemsById.values()];
2235
3666
  await store.nodes.Provenance.bulkUpsertById(items);
2236
3667
  return items.length;
2237
3668
  }
@@ -2239,7 +3670,7 @@ async function readProvenance(store, query = {}) {
2239
3670
  const all = await store.nodes.Provenance.find();
2240
3671
  return all.filter(
2241
3672
  (node) => (query.branchId === void 0 || node.branchId === query.branchId) && (query.canonicalId === void 0 || node.canonicalId === query.canonicalId) && (query.role === void 0 || node.role === query.role)
2242
- ).sort((left, right) => chunkTRF4EBJT_cjs.compareStrings(left.id, right.id));
3673
+ ).sort((left, right) => chunkXMQSEJCF_cjs.compareStrings(left.id, right.id));
2243
3674
  }
2244
3675
 
2245
3676
  // src/graph-merge/sources.ts
@@ -2249,14 +3680,14 @@ function orderEndpoints(left, right) {
2249
3680
  return compareMergeKeys(leftKey, rightKey) <= 0 ? { a: leftKey, b: rightKey, left, right } : { a: rightKey, b: leftKey, left: right, right: left };
2250
3681
  }
2251
3682
  function sortMembersById(members) {
2252
- return [...members].sort((left, right) => chunkTRF4EBJT_cjs.compareStrings(left.id, right.id));
3683
+ return [...members].sort((left, right) => chunkXMQSEJCF_cjs.compareStrings(left.id, right.id));
2253
3684
  }
2254
3685
  function sortedBucketKeys(blocks) {
2255
- return [...blocks.keys()].sort((left, right) => chunkTRF4EBJT_cjs.compareStrings(left, right));
3686
+ return [...blocks.keys()].sort((left, right) => chunkXMQSEJCF_cjs.compareStrings(left, right));
2256
3687
  }
2257
3688
  var NODE_SYSTEM_FIELDS = /* @__PURE__ */ new Set(["id", "kind", "meta"]);
2258
3689
  function nodeProps(node) {
2259
- const props = {};
3690
+ const props = chunkN66HCGCY_cjs.createDataKeyedBag();
2260
3691
  for (const [key, value] of Object.entries(
2261
3692
  node
2262
3693
  )) {
@@ -2280,7 +3711,7 @@ function windowedPairs(members, config) {
2280
3711
  key: fieldText(node, config.sortFields)
2281
3712
  }));
2282
3713
  keyed.sort(
2283
- (left, right) => left.key === right.key ? chunkTRF4EBJT_cjs.compareStrings(left.node.id, right.node.id) : chunkTRF4EBJT_cjs.compareStrings(left.key, right.key)
3714
+ (left, right) => left.key === right.key ? chunkXMQSEJCF_cjs.compareStrings(left.node.id, right.node.id) : chunkXMQSEJCF_cjs.compareStrings(left.key, right.key)
2284
3715
  );
2285
3716
  const pairs = [];
2286
3717
  for (let index = 0; index < keyed.length; index += 1) {
@@ -2288,8 +3719,8 @@ function windowedPairs(members, config) {
2288
3719
  for (let index_ = index + 1; index_ <= last; index_ += 1) {
2289
3720
  pairs.push(
2290
3721
  orderEndpoints(
2291
- chunk764JHTLT_cjs.requireDefined(keyed[index]).node,
2292
- chunk764JHTLT_cjs.requireDefined(keyed[index_]).node
3722
+ chunkN66HCGCY_cjs.requireDefined(keyed[index]).node,
3723
+ chunkN66HCGCY_cjs.requireDefined(keyed[index_]).node
2293
3724
  )
2294
3725
  );
2295
3726
  }
@@ -2311,8 +3742,8 @@ function pairsFromBlocks(blocks, keyless) {
2311
3742
  for (let index_ = index + 1; index_ < members.length; index_ += 1) {
2312
3743
  pairs.push(
2313
3744
  orderEndpoints(
2314
- chunk764JHTLT_cjs.requireDefined(members[index]),
2315
- chunk764JHTLT_cjs.requireDefined(members[index_])
3745
+ chunkN66HCGCY_cjs.requireDefined(members[index]),
3746
+ chunkN66HCGCY_cjs.requireDefined(members[index_])
2316
3747
  )
2317
3748
  );
2318
3749
  }
@@ -2330,8 +3761,8 @@ function forcedEdgesFromBlocks(blocks) {
2330
3761
  for (let index = 0; index < members.length; index += 1) {
2331
3762
  for (let index_ = index + 1; index_ < members.length; index_ += 1) {
2332
3763
  const { a, b } = orderEndpoints(
2333
- chunk764JHTLT_cjs.requireDefined(members[index]),
2334
- chunk764JHTLT_cjs.requireDefined(members[index_])
3764
+ chunkN66HCGCY_cjs.requireDefined(members[index]),
3765
+ chunkN66HCGCY_cjs.requireDefined(members[index_])
2335
3766
  );
2336
3767
  edges.push({ a, b, score: FORCED_MATCH_SCORE });
2337
3768
  }
@@ -2351,7 +3782,7 @@ function ontologyRetypeEdges(stagedIdentities, isRetypeCompatible) {
2351
3782
  }
2352
3783
  }
2353
3784
  const edges = [];
2354
- for (const id of [...identitiesById.keys()].sort(chunkTRF4EBJT_cjs.compareStrings)) {
3785
+ for (const id of [...identitiesById.keys()].sort(chunkXMQSEJCF_cjs.compareStrings)) {
2355
3786
  const identities = [...new Set(identitiesById.get(id))].sort(
2356
3787
  compareMergeKeys
2357
3788
  );
@@ -2365,8 +3796,8 @@ function ontologyRetypeEdges(stagedIdentities, isRetypeCompatible) {
2365
3796
  }
2366
3797
  for (let index = 1; index < members.length; index += 1) {
2367
3798
  edges.push({
2368
- a: chunk764JHTLT_cjs.requireDefined(members[0]),
2369
- b: chunk764JHTLT_cjs.requireDefined(members[index]),
3799
+ a: chunkN66HCGCY_cjs.requireDefined(members[0]),
3800
+ b: chunkN66HCGCY_cjs.requireDefined(members[index]),
2370
3801
  score: FORCED_MATCH_SCORE
2371
3802
  });
2372
3803
  }
@@ -2382,12 +3813,12 @@ function unionByCompatibility(identities, isRetypeCompatible) {
2382
3813
  for (let index = 0; index < identities.length; index += 1) {
2383
3814
  for (let index_ = index + 1; index_ < identities.length; index_ += 1) {
2384
3815
  if (isRetypeCompatible([
2385
- kindOf(chunk764JHTLT_cjs.requireDefined(identities[index])),
2386
- kindOf(chunk764JHTLT_cjs.requireDefined(identities[index_]))
3816
+ kindOf(chunkN66HCGCY_cjs.requireDefined(identities[index])),
3817
+ kindOf(chunkN66HCGCY_cjs.requireDefined(identities[index_]))
2387
3818
  ])) {
2388
3819
  forest.union(
2389
- chunk764JHTLT_cjs.requireDefined(identities[index]),
2390
- chunk764JHTLT_cjs.requireDefined(identities[index_])
3820
+ chunkN66HCGCY_cjs.requireDefined(identities[index]),
3821
+ chunkN66HCGCY_cjs.requireDefined(identities[index_])
2391
3822
  );
2392
3823
  }
2393
3824
  }
@@ -2399,7 +3830,7 @@ function unionByCompatibility(identities, isRetypeCompatible) {
2399
3830
  function groupsOf(identities, representativeOf) {
2400
3831
  const byRoot = /* @__PURE__ */ new Map();
2401
3832
  for (const identity of identities) {
2402
- const root = chunk764JHTLT_cjs.requireDefined(representativeOf.get(identity));
3833
+ const root = chunkN66HCGCY_cjs.requireDefined(representativeOf.get(identity));
2403
3834
  const bucket = byRoot.get(root);
2404
3835
  if (bucket === void 0) {
2405
3836
  byRoot.set(root, [identity]);
@@ -2446,7 +3877,7 @@ var baseUniqueSource = {
2446
3877
  const forcedEdges = [];
2447
3878
  const baseMembers = /* @__PURE__ */ new Map();
2448
3879
  const constraints = [...uniqueConstraints].sort(
2449
- (left, right) => chunkTRF4EBJT_cjs.compareStrings(left.name, right.name)
3880
+ (left, right) => chunkXMQSEJCF_cjs.compareStrings(left.name, right.name)
2450
3881
  );
2451
3882
  const items = nodes.map((node) => ({ props: nodeProps(node) }));
2452
3883
  const matchesByConstraint = await Promise.all(
@@ -2489,7 +3920,7 @@ var baseUniqueSource = {
2489
3920
  pairs: [],
2490
3921
  forcedEdges,
2491
3922
  baseMembers: [...baseMembers.values()].sort(
2492
- (left, right) => chunkTRF4EBJT_cjs.compareStrings(left.id, right.id)
3923
+ (left, right) => chunkXMQSEJCF_cjs.compareStrings(left.id, right.id)
2493
3924
  )
2494
3925
  };
2495
3926
  }
@@ -2546,7 +3977,7 @@ var baseKeySource = {
2546
3977
  pairs,
2547
3978
  forcedEdges: [],
2548
3979
  baseMembers: [...baseMembers.values()].sort(
2549
- (left, right) => chunkTRF4EBJT_cjs.compareStrings(left.id, right.id)
3980
+ (left, right) => chunkXMQSEJCF_cjs.compareStrings(left.id, right.id)
2550
3981
  )
2551
3982
  };
2552
3983
  }
@@ -2558,16 +3989,16 @@ var CANDIDATE_SOURCES = [
2558
3989
 
2559
3990
  // src/graph-merge/staging.ts
2560
3991
  function compareByIdThenBranch(left, right) {
2561
- const byId2 = chunkTRF4EBJT_cjs.compareStrings(left.id, right.id);
2562
- return byId2 === 0 ? chunkTRF4EBJT_cjs.compareStrings(left.branchId, right.branchId) : byId2;
3992
+ const byId2 = chunkXMQSEJCF_cjs.compareStrings(left.id, right.id);
3993
+ return byId2 === 0 ? chunkXMQSEJCF_cjs.compareStrings(left.branchId, right.branchId) : byId2;
2563
3994
  }
2564
3995
  function compareByKindIdBranch(left, right) {
2565
- const byKind = chunkTRF4EBJT_cjs.compareStrings(left.kind, right.kind);
3996
+ const byKind = chunkXMQSEJCF_cjs.compareStrings(left.kind, right.kind);
2566
3997
  if (byKind !== 0) {
2567
3998
  return byKind;
2568
3999
  }
2569
- const byId2 = chunkTRF4EBJT_cjs.compareStrings(left.id, right.id);
2570
- return byId2 === 0 ? chunkTRF4EBJT_cjs.compareStrings(left.branchId, right.branchId) : byId2;
4000
+ const byId2 = chunkXMQSEJCF_cjs.compareStrings(left.id, right.id);
4001
+ return byId2 === 0 ? chunkXMQSEJCF_cjs.compareStrings(left.branchId, right.branchId) : byId2;
2571
4002
  }
2572
4003
  function groupByKind(items) {
2573
4004
  const buckets = /* @__PURE__ */ new Map();
@@ -2581,11 +4012,11 @@ function groupByKind(items) {
2581
4012
  }
2582
4013
  const ordered = /* @__PURE__ */ new Map();
2583
4014
  for (const kind of [...buckets.keys()].sort(
2584
- (left, right) => chunkTRF4EBJT_cjs.compareStrings(left, right)
4015
+ (left, right) => chunkXMQSEJCF_cjs.compareStrings(left, right)
2585
4016
  )) {
2586
4017
  ordered.set(
2587
4018
  kind,
2588
- [...chunk764JHTLT_cjs.requireDefined(buckets.get(kind))].sort(
4019
+ [...chunkN66HCGCY_cjs.requireDefined(buckets.get(kind))].sort(
2589
4020
  (left, right) => compareByIdThenBranch(left, right)
2590
4021
  )
2591
4022
  );
@@ -2599,6 +4030,11 @@ async function stageBranches(baseStore, branches, captureTargetStateFor) {
2599
4030
  const newEdges = [];
2600
4031
  const modifiedEdges = [];
2601
4032
  const deletedEdges = [];
4033
+ const windowedNodes = [];
4034
+ const windowedEdges = [];
4035
+ const newIdentityAssertions = [];
4036
+ const retractedIdentityAssertions = [];
4037
+ const baseIdentityAssertions = await chunkTTAITEPJ_cjs.storeRuntime(baseStore).readCurrentIdentityAssertions("state");
2602
4038
  let targetNodeVersions = /* @__PURE__ */ new Map();
2603
4039
  let targetEdgeSignatures = /* @__PURE__ */ new Map();
2604
4040
  for (const branch2 of branches) {
@@ -2630,6 +4066,22 @@ async function stageBranches(baseStore, branches, captureTargetStateFor) {
2630
4066
  for (const edge of diff.edges.deleted) {
2631
4067
  deletedEdges.push({ branchId, edge, kind: edge.kind, id: edge.id });
2632
4068
  }
4069
+ for (const node of diff.nodes.windowed) {
4070
+ windowedNodes.push({ branchId, node, kind: node.kind, id: node.id });
4071
+ }
4072
+ for (const edge of diff.edges.windowed) {
4073
+ windowedEdges.push({ branchId, edge, kind: edge.kind, id: edge.id });
4074
+ }
4075
+ for (const assertion of diff.identity.new) {
4076
+ newIdentityAssertions.push({ branchId, assertion });
4077
+ }
4078
+ for (const retraction of diff.identity.retracted) {
4079
+ retractedIdentityAssertions.push({
4080
+ branchId,
4081
+ assertion: retraction.assertion,
4082
+ cause: retraction.cause
4083
+ });
4084
+ }
2633
4085
  }
2634
4086
  return {
2635
4087
  newNodesByKind: groupByKind(newNodes),
@@ -2646,6 +4098,25 @@ async function stageBranches(baseStore, branches, captureTargetStateFor) {
2646
4098
  deletedEdges: [...deletedEdges].sort(
2647
4099
  (left, right) => compareByKindIdBranch(left, right)
2648
4100
  ),
4101
+ windowedNodes: [...windowedNodes].sort(
4102
+ (left, right) => compareByKindIdBranch(left, right)
4103
+ ),
4104
+ windowedEdges: [...windowedEdges].sort(
4105
+ (left, right) => compareByKindIdBranch(left, right)
4106
+ ),
4107
+ newIdentityAssertions: newIdentityAssertions.toSorted((left, right) => {
4108
+ const byId2 = chunkXMQSEJCF_cjs.compareStrings(left.assertion.id, right.assertion.id);
4109
+ return byId2 === 0 ? chunkXMQSEJCF_cjs.compareStrings(left.branchId, right.branchId) : byId2;
4110
+ }),
4111
+ retractedIdentityAssertions: retractedIdentityAssertions.toSorted(
4112
+ (left, right) => {
4113
+ const byId2 = chunkXMQSEJCF_cjs.compareStrings(left.assertion.id, right.assertion.id);
4114
+ return byId2 === 0 ? chunkXMQSEJCF_cjs.compareStrings(left.branchId, right.branchId) : byId2;
4115
+ }
4116
+ ),
4117
+ baseIdentityAssertions: baseIdentityAssertions.toSorted(
4118
+ (left, right) => chunkXMQSEJCF_cjs.compareStrings(left.id, right.id)
4119
+ ),
2649
4120
  targetNodeVersions,
2650
4121
  targetEdgeSignatures
2651
4122
  };
@@ -2696,7 +4167,7 @@ async function withTxConflictRetry(commit) {
2696
4167
  // src/graph-merge/type-reconcile.ts
2697
4168
  var INCOMPATIBLE_TYPES_FLAG_REASON = "type-reconcile:incompatible-kinds";
2698
4169
  function distinctKinds(kinds) {
2699
- return [...new Set(kinds)].sort((left, right) => chunkTRF4EBJT_cjs.compareStrings(left, right));
4170
+ return [...new Set(kinds)].sort((left, right) => chunkXMQSEJCF_cjs.compareStrings(left, right));
2700
4171
  }
2701
4172
  function areEquivalent(closure, left, right) {
2702
4173
  return left !== right && isReachable2(closure, left, right) && isReachable2(closure, right, left);
@@ -2714,8 +4185,8 @@ function mostSpecificCommonKind(closure, kinds) {
2714
4185
  if (qualifiers.length === 0) {
2715
4186
  return void 0;
2716
4187
  }
2717
- return chunk764JHTLT_cjs.requireDefined(
2718
- [...qualifiers].sort((left, right) => chunkTRF4EBJT_cjs.compareStrings(left, right))[0]
4188
+ return chunkN66HCGCY_cjs.requireDefined(
4189
+ [...qualifiers].sort((left, right) => chunkXMQSEJCF_cjs.compareStrings(left, right))[0]
2719
4190
  );
2720
4191
  }
2721
4192
  function reconcileTypes(clusters, closure, mode) {
@@ -2753,15 +4224,14 @@ function reconcileTypes(clusters, closure, mode) {
2753
4224
  }
2754
4225
  return {
2755
4226
  reconciliations: reconciliations.sort(
2756
- (left, right) => chunkTRF4EBJT_cjs.compareStrings(left.entityId, right.entityId)
4227
+ (left, right) => chunkXMQSEJCF_cjs.compareStrings(left.entityId, right.entityId)
2757
4228
  ),
2758
4229
  retypeMap,
2759
- dropped: dropped.sort((left, right) => chunkTRF4EBJT_cjs.compareStrings(left.id, right.id))
4230
+ dropped: dropped.sort((left, right) => chunkXMQSEJCF_cjs.compareStrings(left.id, right.id))
2760
4231
  };
2761
4232
  }
2762
4233
 
2763
4234
  // src/graph-merge/merge.ts
2764
- var COMMITTED_TARGET_BRANCH = asBranchId("__committed_target__");
2765
4235
  function asNode(staged) {
2766
4236
  return {
2767
4237
  kind: staged.node.kind,
@@ -2775,8 +4245,8 @@ function newNodesByKind(staging) {
2775
4245
  ordered.set(
2776
4246
  kind,
2777
4247
  [...items].sort((left, right) => {
2778
- const byId2 = chunkTRF4EBJT_cjs.compareStrings(left.node.id, right.node.id);
2779
- return byId2 === 0 ? chunkTRF4EBJT_cjs.compareStrings(left.branchId, right.branchId) : byId2;
4248
+ const byId2 = chunkXMQSEJCF_cjs.compareStrings(left.node.id, right.node.id);
4249
+ return byId2 === 0 ? chunkXMQSEJCF_cjs.compareStrings(left.branchId, right.branchId) : byId2;
2780
4250
  })
2781
4251
  );
2782
4252
  }
@@ -2803,12 +4273,14 @@ async function precomputeEmbeddings(byKind, resolve, embedder) {
2803
4273
  }
2804
4274
  }
2805
4275
  }
2806
- const lookup = /* @__PURE__ */ new Map();
2807
4276
  if (texts.size === 0) {
2808
- return lookup;
4277
+ return /* @__PURE__ */ new Map();
2809
4278
  }
4279
+ return embedSortedTexts(texts, embedder);
4280
+ }
4281
+ async function embedSortedTexts(texts, embedder) {
2810
4282
  const orderedTexts = [...texts].sort(
2811
- (left, right) => chunkTRF4EBJT_cjs.compareStrings(left, right)
4283
+ (left, right) => chunkXMQSEJCF_cjs.compareStrings(left, right)
2812
4284
  );
2813
4285
  const vectors = await embedder(orderedTexts);
2814
4286
  if (vectors.length !== orderedTexts.length) {
@@ -2820,8 +4292,9 @@ async function precomputeEmbeddings(byKind, resolve, embedder) {
2820
4292
  }
2821
4293
  );
2822
4294
  }
4295
+ const lookup = /* @__PURE__ */ new Map();
2823
4296
  for (const [index, text] of orderedTexts.entries()) {
2824
- lookup.set(text, chunk764JHTLT_cjs.requireDefined(vectors[index]));
4297
+ lookup.set(text, chunkN66HCGCY_cjs.requireDefined(vectors[index]));
2825
4298
  }
2826
4299
  return lookup;
2827
4300
  }
@@ -2843,24 +4316,7 @@ async function embedMissingPairTexts(base, pairs, strategy, embedder) {
2843
4316
  if (missing.size === 0) {
2844
4317
  return existing;
2845
4318
  }
2846
- const orderedTexts = [...missing].sort(
2847
- (left, right) => chunkTRF4EBJT_cjs.compareStrings(left, right)
2848
- );
2849
- const vectors = await embedder(orderedTexts);
2850
- if (vectors.length !== orderedTexts.length) {
2851
- throw new MergeError(
2852
- `Embedder returned ${vectors.length} vectors for ${orderedTexts.length} texts; expected exactly one per text.`,
2853
- {
2854
- details: { texts: orderedTexts.length, vectors: vectors.length },
2855
- suggestion: "Ensure MergeOptions.embedder returns one vector per input text, in order."
2856
- }
2857
- );
2858
- }
2859
- const augmented = new Map(existing);
2860
- for (const [index, text] of orderedTexts.entries()) {
2861
- augmented.set(text, chunk764JHTLT_cjs.requireDefined(vectors[index]));
2862
- }
2863
- return augmented;
4319
+ return new Map([...existing, ...await embedSortedTexts(missing, embedder)]);
2864
4320
  }
2865
4321
  async function generateAllCandidates(target, staging, options, introspectionKinds, ctx, useBaseSources, embedder) {
2866
4322
  const allEdges = [];
@@ -2874,7 +4330,7 @@ async function generateAllCandidates(target, staging, options, introspectionKind
2874
4330
  async ([kind, items]) => {
2875
4331
  const resolveConfig = options.resolve[kind];
2876
4332
  if (resolveConfig === void 0) {
2877
- return chunkQYWINYEA_cjs.ok({ edges: [], warnings: [], baseMembers: [] });
4333
+ return chunk7BQXPCGN_cjs.ok({ edges: [], warnings: [], baseMembers: [] });
2878
4334
  }
2879
4335
  const nodes = items.map((staged) => asNode(staged));
2880
4336
  const uniqueConstraints = uniqueConstraintsFor(
@@ -2917,10 +4373,10 @@ async function generateAllCandidates(target, staging, options, introspectionKind
2917
4373
  options.onComparisonCeiling,
2918
4374
  options.maxComparisonsPerKind
2919
4375
  );
2920
- if (chunkQYWINYEA_cjs.isErr(scored)) {
2921
- return chunkQYWINYEA_cjs.err(scored.error);
4376
+ if (chunk7BQXPCGN_cjs.isErr(scored)) {
4377
+ return chunk7BQXPCGN_cjs.err(scored.error);
2922
4378
  }
2923
- return chunkQYWINYEA_cjs.ok({
4379
+ return chunk7BQXPCGN_cjs.ok({
2924
4380
  edges: scored.data.edges,
2925
4381
  warnings: scored.data.warnings.map(
2926
4382
  (warning) => `[${kind}] ${warning.message}`
@@ -2931,14 +4387,14 @@ async function generateAllCandidates(target, staging, options, introspectionKind
2931
4387
  )
2932
4388
  );
2933
4389
  for (const result of perKind) {
2934
- if (chunkQYWINYEA_cjs.isErr(result)) {
2935
- return chunkQYWINYEA_cjs.err(result.error);
4390
+ if (chunk7BQXPCGN_cjs.isErr(result)) {
4391
+ return chunk7BQXPCGN_cjs.err(result.error);
2936
4392
  }
2937
4393
  allEdges.push(...result.data.edges);
2938
4394
  warnings.push(...result.data.warnings);
2939
4395
  baseMembers.push(...result.data.baseMembers);
2940
4396
  }
2941
- return chunkQYWINYEA_cjs.ok({
4397
+ return chunk7BQXPCGN_cjs.ok({
2942
4398
  // The ONE shared `(a, b)` edge comparator (id-first `(kind, id)` order), so this
2943
4399
  // stage emits edges in exactly the order clustering consumes them.
2944
4400
  edges: allEdges.sort((left, right) => compareCandidateEdges(left, right)),
@@ -2959,7 +4415,9 @@ function clusterMembersFor(cluster, newNodesById, baseMembersById) {
2959
4415
  id: staged.node.id,
2960
4416
  kind: staged.node.kind,
2961
4417
  branchId: staged.branchId,
2962
- props: staged.node.props
4418
+ props: staged.node.props,
4419
+ ...staged.node.row.valid_from === void 0 ? {} : { validFrom: staged.node.row.valid_from },
4420
+ ...staged.node.row.valid_to === void 0 ? {} : { validTo: staged.node.row.valid_to }
2963
4421
  });
2964
4422
  }
2965
4423
  const base = baseMembersById.get(key);
@@ -2990,37 +4448,70 @@ function indexNewNodesById(staging) {
2990
4448
  }
2991
4449
  return index;
2992
4450
  }
2993
- function buildStagedEdges(staging, modifiedEdges) {
4451
+ function buildStagedEdges(staging, modifiedEdges, edgeValidityEnds, edgeDeletions) {
2994
4452
  const staged = [];
4453
+ const stagedIdentities = /* @__PURE__ */ new Set();
4454
+ const windowOnlyCarried = /* @__PURE__ */ new Set();
2995
4455
  for (const items of staging.newEdgesByKind.values()) {
2996
4456
  for (const item of items) {
2997
4457
  staged.push(toStagedEdge(item.branchId, item));
2998
4458
  }
2999
4459
  }
3000
4460
  for (const item of modifiedEdges) {
4461
+ const identity = mergeKeyOf(item.edge);
4462
+ stagedIdentities.add(identity);
4463
+ const validTo = edgeValidityEnds.get(identity);
3001
4464
  staged.push({
3002
4465
  id: item.edge.id,
3003
4466
  kind: item.edge.kind,
4467
+ origin: INHERITED_EDGE_ORIGIN,
3004
4468
  fromId: item.edge.fromId,
3005
4469
  toId: item.edge.toId,
3006
4470
  fromKind: item.edge.fromKind,
3007
4471
  toKind: item.edge.toKind,
3008
4472
  props: item.edge.forkProps,
3009
- branchId: item.branchId
4473
+ baseProps: item.edge.baseProps,
4474
+ branchId: item.branchId,
4475
+ ...validTo === void 0 ? {} : { validTo }
4476
+ });
4477
+ }
4478
+ for (const item of staging.windowedEdges) {
4479
+ const identity = mergeKeyOf(item.edge);
4480
+ const validTo = edgeValidityEnds.get(identity);
4481
+ if (validTo === void 0 || stagedIdentities.has(identity) || edgeDeletions.has(identity)) {
4482
+ continue;
4483
+ }
4484
+ stagedIdentities.add(identity);
4485
+ windowOnlyCarried.add(identity);
4486
+ staged.push({
4487
+ id: item.edge.id,
4488
+ kind: item.edge.kind,
4489
+ origin: INHERITED_EDGE_ORIGIN,
4490
+ fromId: item.edge.fromId,
4491
+ toId: item.edge.toId,
4492
+ fromKind: item.edge.fromKind,
4493
+ toKind: item.edge.toKind,
4494
+ props: item.edge.props,
4495
+ baseProps: item.edge.baseProps,
4496
+ branchId: item.branchId,
4497
+ validTo
3010
4498
  });
3011
4499
  }
3012
- return staged;
4500
+ return { edges: staged, windowOnlyCarried };
3013
4501
  }
3014
4502
  function toStagedEdge(branchId, item) {
3015
4503
  return {
3016
4504
  id: item.edge.id,
3017
4505
  kind: item.edge.kind,
4506
+ origin: BRANCH_CREATED_EDGE_ORIGIN,
3018
4507
  fromId: item.edge.fromId,
3019
4508
  toId: item.edge.toId,
3020
4509
  fromKind: item.edge.fromKind,
3021
4510
  toKind: item.edge.toKind,
3022
4511
  props: item.edge.props,
3023
- branchId
4512
+ branchId,
4513
+ ...item.edge.row.valid_from === void 0 ? {} : { validFrom: item.edge.row.valid_from },
4514
+ ...item.edge.row.valid_to === void 0 ? {} : { validTo: item.edge.row.valid_to }
3024
4515
  };
3025
4516
  }
3026
4517
  function buildProvenanceIndex(records) {
@@ -3041,34 +4532,38 @@ function buildProvenanceIndex(records) {
3041
4532
  for (const [branchId, sets] of byBranch) {
3042
4533
  frozen.set(branchId, {
3043
4534
  nodeIds: [...sets.nodeIds].sort(
3044
- (left, right) => chunkTRF4EBJT_cjs.compareStrings(left, right)
4535
+ (left, right) => chunkXMQSEJCF_cjs.compareStrings(left, right)
3045
4536
  ),
3046
- edgeIds: [...sets.edgeIds].sort((left, right) => chunkTRF4EBJT_cjs.compareStrings(left, right)).map((id) => id)
4537
+ edgeIds: [...sets.edgeIds].sort((left, right) => chunkXMQSEJCF_cjs.compareStrings(left, right)).map((id) => id)
3047
4538
  });
3048
4539
  }
3049
4540
  return {
3050
4541
  byBranch: (branchId) => frozen.get(branchId) ?? { nodeIds: [], edgeIds: [] }
3051
4542
  };
3052
4543
  }
3053
- function pushProvenance(records, role, branchId, canonicalId, canonicalKind, sourceId) {
3054
- records.push({ role, canonicalId, canonicalKind, branchId, sourceId });
3055
- }
3056
4544
  var EMPTY_WEIGHTS = /* @__PURE__ */ new Map();
3057
- function planMerge(staging, candidateEdges, candidateWarnings, baseMembers, options, branchRank, subClassClosure, preferredBranchId) {
4545
+ function planMerge(staging, candidateEdges, candidateWarnings, baseMembers, options, branchRank, subClassClosure, identityContext, storedIdentityRowsById, targetPeers, preferredBranchId) {
4546
+ const identity = planIdentityChanges(staging, storedIdentityRowsById);
3058
4547
  const provenanceRecords = [];
4548
+ const recordedContributions = /* @__PURE__ */ new Set();
3059
4549
  const weights = options.provenanceWeights ?? EMPTY_WEIGHTS;
3060
4550
  const recordProvenance = (role, branchId, canonicalId, canonicalKind, sourceId) => {
3061
4551
  if (branchId === preferredBranchId) {
3062
4552
  return;
3063
4553
  }
3064
- pushProvenance(
3065
- provenanceRecords,
4554
+ const record = {
3066
4555
  role,
3067
- branchId,
3068
4556
  canonicalId,
3069
4557
  canonicalKind,
4558
+ branchId,
3070
4559
  sourceId
3071
- );
4560
+ };
4561
+ const key = contributionKey(record);
4562
+ if (recordedContributions.has(key)) {
4563
+ return;
4564
+ }
4565
+ recordedContributions.add(key);
4566
+ provenanceRecords.push(record);
3072
4567
  };
3073
4568
  const newNodesById = indexNewNodesById(staging);
3074
4569
  const acceptedEndpointKeys = /* @__PURE__ */ new Set();
@@ -3161,6 +4656,34 @@ function planMerge(staging, candidateEdges, candidateWarnings, baseMembers, opti
3161
4656
  for (const deletion of deleteModify.nodeDeletions) {
3162
4657
  nodeDeletions.set(mergeKey(deletion.kind, deletion.id), deletion.kind);
3163
4658
  }
4659
+ const anyDeletionOverruled = staging.deletedNodes.some(
4660
+ (deletion) => !nodeDeletions.has(mergeKey(deletion.node.kind, deletion.node.id))
4661
+ );
4662
+ const stagedRetractionsById = /* @__PURE__ */ new Map();
4663
+ for (const staged of staging.retractedIdentityAssertions) {
4664
+ const contributions = stagedRetractionsById.get(staged.assertion.id) ?? [];
4665
+ contributions.push(staged);
4666
+ stagedRetractionsById.set(staged.assertion.id, contributions);
4667
+ }
4668
+ const overruledRetractionDrops = [];
4669
+ const survivingRetractions = anyDeletionOverruled ? identity.retractions.filter((retraction) => {
4670
+ const contributions = stagedRetractionsById.get(retraction.id) ?? [];
4671
+ const everyContributionOverruled = contributions.length > 0 && contributions.every(
4672
+ (staged) => staged.cause.kind === "cascade" && !nodeDeletions.has(
4673
+ mergeKey(
4674
+ staged.cause.deletedNode.kind,
4675
+ staged.cause.deletedNode.id
4676
+ )
4677
+ )
4678
+ );
4679
+ if (!everyContributionOverruled) return true;
4680
+ overruledRetractionDrops.push({
4681
+ kind: "identity",
4682
+ id: retraction.id,
4683
+ reason: RETRACTION_DELETION_OVERRULED_DROP_REASON
4684
+ });
4685
+ return false;
4686
+ }) : identity.retractions;
3164
4687
  for (const modification of deleteModify.survivingModifications) {
3165
4688
  recordProvenance(
3166
4689
  "node",
@@ -3209,6 +4732,31 @@ function planMerge(staging, candidateEdges, candidateWarnings, baseMembers, opti
3209
4732
  for (const conflict of reconciledEdgeModifications.conflicts) {
3210
4733
  propertyConflicts.push(conflict);
3211
4734
  }
4735
+ const validWindows = resolveValidWindows(
4736
+ staging,
4737
+ new Set(nodeDeletions.keys()),
4738
+ new Set(edgeDeletions.keys()),
4739
+ preferredBranchId
4740
+ );
4741
+ const creditedNodeIdentities = /* @__PURE__ */ new Map();
4742
+ for (const record of provenanceRecords) {
4743
+ if (record.role !== "node" || record.sourceId !== record.canonicalId) {
4744
+ continue;
4745
+ }
4746
+ const identity2 = mergeKey(record.canonicalKind, record.canonicalId);
4747
+ const credited = creditedNodeIdentities.get(identity2) ?? /* @__PURE__ */ new Set();
4748
+ credited.add(record.branchId);
4749
+ creditedNodeIdentities.set(identity2, credited);
4750
+ }
4751
+ for (const [identity2, branchIds] of validWindows.nodeCredits) {
4752
+ for (const branchId of branchIds) {
4753
+ if (creditedNodeIdentities.get(identity2)?.has(branchId) === true) {
4754
+ continue;
4755
+ }
4756
+ const id = idOf(identity2);
4757
+ recordProvenance("node", branchId, id, kindOf(identity2), id);
4758
+ }
4759
+ }
3212
4760
  const reconciliation = reconcileTypes(
3213
4761
  reconcileInputs,
3214
4762
  subClassClosure,
@@ -3222,18 +4770,57 @@ function planMerge(staging, candidateEdges, candidateWarnings, baseMembers, opti
3222
4770
  clusters,
3223
4771
  (cluster) => pickClusterCanonical(cluster, entityByIdentity)
3224
4772
  );
3225
- const stagedEdges = buildStagedEdges(
4773
+ const identityRemap = remapIdentityAssertionEndpoints(
4774
+ identity.assertions,
4775
+ canonicalOf,
4776
+ reconciliation.retypeMap,
4777
+ storedIdentityRowsById
4778
+ );
4779
+ assertIdentityEndpointsNotDeleted(
4780
+ identityRemap.assertions,
4781
+ nodeDeletions,
4782
+ reconciliation.retypeMap
4783
+ );
4784
+ const identityNodeUniverse = [
4785
+ ...canonicalEntities.filter(
4786
+ (entity) => !nodeDeletions.has(mergeKey(entity.kind, entity.canonicalId))
4787
+ ).map((entity) => ({
4788
+ kind: reconciliation.retypeMap.get(
4789
+ mergeKey(entity.kind, entity.canonicalId)
4790
+ ) ?? entity.kind,
4791
+ id: entity.canonicalId
4792
+ })),
4793
+ ...targetPeers.filter(
4794
+ (node) => !nodeDeletions.has(mergeKey(node.kind, node.id))
4795
+ )
4796
+ ];
4797
+ assertNoContradictoryIdentityClosure(
4798
+ identityRemap.assertions,
4799
+ survivingRetractions.map((retraction) => retraction.id),
4800
+ staging.baseIdentityAssertions,
4801
+ new Set(nodeDeletions.keys()),
4802
+ canonicalOf,
4803
+ reconciliation.retypeMap,
4804
+ identityContext,
4805
+ identityNodeUniverse
4806
+ );
4807
+ const { edges: stagedEdges, windowOnlyCarried } = buildStagedEdges(
3226
4808
  staging,
3227
- reconciledEdgeModifications.survivingModifications
4809
+ reconciledEdgeModifications.survivingModifications,
4810
+ validWindows.edgeEnds,
4811
+ edgeDeletions
3228
4812
  );
3229
4813
  const stagedEdgeBranches = /* @__PURE__ */ new Map();
3230
4814
  for (const staged of stagedEdges) {
3231
- const branches = stagedEdgeBranches.get(staged.id);
3232
- if (branches === void 0) {
3233
- stagedEdgeBranches.set(staged.id, /* @__PURE__ */ new Set([staged.branchId]));
3234
- } else {
4815
+ const identity2 = mergeKeyOf(staged);
4816
+ const branches = stagedEdgeBranches.get(staged.id) ?? /* @__PURE__ */ new Set();
4817
+ if (!windowOnlyCarried.has(identity2)) {
3235
4818
  branches.add(staged.branchId);
3236
4819
  }
4820
+ for (const branchId of validWindows.edgeCredits.get(identity2) ?? []) {
4821
+ branches.add(branchId);
4822
+ }
4823
+ stagedEdgeBranches.set(staged.id, branches);
3237
4824
  }
3238
4825
  const deletedNodeIdSet = new Set(nodeDeletions.keys());
3239
4826
  const repoint2 = repointEdges(
@@ -3256,9 +4843,13 @@ function planMerge(staging, candidateEdges, candidateWarnings, baseMembers, opti
3256
4843
  ...deleteModify.dropped,
3257
4844
  ...edgeDeleteModify.dropped,
3258
4845
  ...repoint2.dropped,
3259
- ...reconciliation.dropped
4846
+ ...reconciliation.dropped,
4847
+ ...identity.dropped,
4848
+ ...overruledRetractionDrops,
4849
+ ...identityRemap.dropped,
4850
+ ...validWindows.dropped
3260
4851
  ].sort(
3261
- (left, right) => chunkTRF4EBJT_cjs.compareStrings(`${left.kind}|${left.id}`, `${right.kind}|${right.id}`)
4852
+ (left, right) => chunkXMQSEJCF_cjs.compareStrings(`${left.kind}|${left.id}`, `${right.kind}|${right.id}`)
3262
4853
  );
3263
4854
  return {
3264
4855
  canonicalEntities,
@@ -3273,6 +4864,10 @@ function planMerge(staging, candidateEdges, candidateWarnings, baseMembers, opti
3273
4864
  ])
3274
4865
  ),
3275
4866
  retypeMap: reconciliation.retypeMap,
4867
+ canonicalOf,
4868
+ nodeValidityEnds: validWindows.nodeEnds,
4869
+ edgeValidityEnds: validWindows.edgeEnds,
4870
+ validityEnds: validWindows.resolutions,
3276
4871
  // Order report arrays by the composite (kind, id) identity — never a bare id
3277
4872
  // or a `|`-joined string. A bare id ties two different-kind entities that
3278
4873
  // share an id, and a `|` separator collides on caller-supplied ids/property
@@ -3291,7 +4886,7 @@ function planMerge(staging, candidateEdges, candidateWarnings, baseMembers, opti
3291
4886
  mergeKey(left.kind, left.entityId),
3292
4887
  mergeKey(right.kind, right.entityId)
3293
4888
  );
3294
- return byEntity === 0 ? chunkTRF4EBJT_cjs.compareStrings(left.property, right.property) : byEntity;
4889
+ return byEntity === 0 ? chunkXMQSEJCF_cjs.compareStrings(left.property, right.property) : byEntity;
3295
4890
  }
3296
4891
  ),
3297
4892
  deleteModifyConflicts: [
@@ -3308,17 +4903,19 @@ function planMerge(staging, candidateEdges, candidateWarnings, baseMembers, opti
3308
4903
  baseAmbiguities: baseAmbiguities.sort(
3309
4904
  (left, right) => compareMergeKeys(
3310
4905
  mergeKey(
3311
- chunk764JHTLT_cjs.requireDefined(left.baseIds[0]).kind,
3312
- chunk764JHTLT_cjs.requireDefined(left.baseIds[0]).id
4906
+ chunkN66HCGCY_cjs.requireDefined(left.baseIds[0]).kind,
4907
+ chunkN66HCGCY_cjs.requireDefined(left.baseIds[0]).id
3313
4908
  ),
3314
4909
  mergeKey(
3315
- chunk764JHTLT_cjs.requireDefined(right.baseIds[0]).kind,
3316
- chunk764JHTLT_cjs.requireDefined(right.baseIds[0]).id
4910
+ chunkN66HCGCY_cjs.requireDefined(right.baseIds[0]).kind,
4911
+ chunkN66HCGCY_cjs.requireDefined(right.baseIds[0]).id
3317
4912
  )
3318
4913
  )
3319
4914
  ),
3320
4915
  provenanceRecords,
3321
- warnings: candidateWarnings
4916
+ warnings: candidateWarnings,
4917
+ identityAssertions: identityRemap.assertions,
4918
+ identityRetractions: survivingRetractions
3322
4919
  };
3323
4920
  }
3324
4921
  function pickClusterCanonical(cluster, entityByIdentity) {
@@ -3333,78 +4930,125 @@ function pickClusterCanonical(cluster, entityByIdentity) {
3333
4930
  );
3334
4931
  }
3335
4932
  function commitModificationProps(baseProps, forkProps) {
3336
- const props = { ...forkProps };
4933
+ const props = chunkN66HCGCY_cjs.createDataKeyedBag();
4934
+ for (const key of Object.keys(forkProps)) {
4935
+ props[key] = forkProps[key];
4936
+ }
3337
4937
  for (const key of Object.keys(baseProps)) {
3338
- if (!(key in forkProps)) {
4938
+ if (!chunkN66HCGCY_cjs.hasOwnKey(forkProps, key)) {
3339
4939
  props[key] = void 0;
3340
4940
  }
3341
4941
  }
3342
4942
  return props;
3343
4943
  }
3344
- async function applyMergePlan(plan, nodesApi, edgesApi) {
3345
- const committedNodeIds = /* @__PURE__ */ new Set();
4944
+ function finalEdgeEndpoint(plan, kind, id) {
4945
+ return { kind: plan.retypeMap.get(mergeKey(kind, id)) ?? kind, id };
4946
+ }
4947
+ function plannedNodeWrites(plan) {
3346
4948
  const canonicalIdentities = /* @__PURE__ */ new Set();
3347
4949
  for (const entity of plan.canonicalEntities) {
3348
4950
  canonicalIdentities.add(mergeKey(entity.kind, entity.canonicalId));
3349
4951
  }
3350
- const survivingModProps = /* @__PURE__ */ new Map();
4952
+ const modificationsByIdentity = /* @__PURE__ */ new Map();
3351
4953
  for (const modification of plan.survivingModifications) {
3352
- survivingModProps.set(mergeKeyOf(modification.node), {
3353
- baseProps: modification.node.baseProps,
3354
- forkProps: modification.node.forkProps
3355
- });
4954
+ modificationsByIdentity.set(
4955
+ mergeKeyOf(modification.node),
4956
+ modification.node
4957
+ );
3356
4958
  }
4959
+ const writes = [];
4960
+ const written = /* @__PURE__ */ new Set();
3357
4961
  for (const modification of plan.survivingModifications) {
3358
4962
  const identity = mergeKeyOf(modification.node);
3359
4963
  if (plan.nodeDeletions.has(identity) || canonicalIdentities.has(identity)) {
3360
4964
  continue;
3361
4965
  }
3362
- const collection = nodeCollection(nodesApi, modification.node.kind);
3363
- await collection.upsertByIdFromRecord(
3364
- modification.node.id,
3365
- commitModificationProps(
3366
- modification.node.baseProps,
3367
- modification.node.forkProps
3368
- )
3369
- );
3370
- committedNodeIds.add(identity);
4966
+ written.add(identity);
4967
+ const validTo = plan.nodeValidityEnds.get(identity);
4968
+ writes.push({
4969
+ identity,
4970
+ kind: modification.node.kind,
4971
+ id: modification.node.id,
4972
+ modification: modification.node,
4973
+ ...validTo === void 0 ? {} : { validTo }
4974
+ });
3371
4975
  }
3372
4976
  for (const entity of plan.canonicalEntities) {
3373
- const identity = mergeKey(entity.kind, entity.canonicalId);
3374
- if (plan.nodeDeletions.has(identity)) {
4977
+ const sourceIdentity = mergeKey(entity.kind, entity.canonicalId);
4978
+ if (plan.nodeDeletions.has(sourceIdentity)) {
3375
4979
  continue;
3376
4980
  }
3377
- const kind = plan.retypeMap.get(identity) ?? entity.kind;
3378
- const modification = survivingModProps.get(identity);
3379
- const props = modification === void 0 ? entity.props : {
3380
- ...entity.props,
3381
- ...commitModificationProps(
3382
- modification.baseProps,
3383
- modification.forkProps
3384
- )
3385
- };
3386
- const collection = nodeCollection(nodesApi, kind);
3387
- await collection.upsertByIdFromRecord(entity.canonicalId, props);
3388
- committedNodeIds.add(mergeKey(kind, entity.canonicalId));
4981
+ const kind = plan.retypeMap.get(sourceIdentity) ?? entity.kind;
4982
+ const modification = modificationsByIdentity.get(sourceIdentity);
4983
+ written.add(sourceIdentity);
4984
+ const validTo = entity.validTo ?? plan.nodeValidityEnds.get(sourceIdentity);
4985
+ writes.push({
4986
+ identity: mergeKey(kind, entity.canonicalId),
4987
+ kind,
4988
+ id: entity.canonicalId,
4989
+ entity,
4990
+ ...modification === void 0 ? {} : { modification },
4991
+ ...entity.validFrom === void 0 ? {} : { validFrom: entity.validFrom },
4992
+ ...validTo === void 0 ? {} : { validTo }
4993
+ });
4994
+ }
4995
+ for (const identity of [...plan.nodeValidityEnds.keys()].sort(
4996
+ (left, right) => compareMergeKeys(left, right)
4997
+ )) {
4998
+ if (written.has(identity) || plan.nodeDeletions.has(identity)) {
4999
+ continue;
5000
+ }
5001
+ const kind = plan.retypeMap.get(identity) ?? kindOf(identity);
5002
+ writes.push({
5003
+ identity: mergeKey(kind, idOf(identity)),
5004
+ kind,
5005
+ id: idOf(identity),
5006
+ validTo: chunkN66HCGCY_cjs.requireDefined(plan.nodeValidityEnds.get(identity))
5007
+ });
3389
5008
  }
5009
+ return writes;
5010
+ }
5011
+ function nodeWriteProps(write, modificationProps) {
5012
+ return {
5013
+ ...write.entity?.props,
5014
+ ...write.modification === void 0 ? void 0 : modificationProps(write.modification)
5015
+ };
5016
+ }
5017
+ async function applyMergePlan(plan, nodesApi, edgesApi, target, txBackend) {
5018
+ const committedNodeIds = /* @__PURE__ */ new Set();
3390
5019
  for (const [identity, kind] of plan.nodeDeletions) {
3391
5020
  const collection = nodeCollection(nodesApi, kind);
3392
5021
  await collection.delete(idOf(identity));
3393
5022
  }
5023
+ for (const write of plannedNodeWrites(plan)) {
5024
+ const collection = nodeCollection(nodesApi, write.kind);
5025
+ await collection.upsertByIdFromRecord(
5026
+ write.id,
5027
+ nodeWriteProps(
5028
+ write,
5029
+ (modification) => commitModificationProps(modification.baseProps, modification.forkProps)
5030
+ ),
5031
+ {
5032
+ ...write.validFrom === void 0 ? {} : { validFrom: write.validFrom },
5033
+ ...write.validTo === void 0 ? {} : { validTo: write.validTo }
5034
+ }
5035
+ );
5036
+ committedNodeIds.add(write.identity);
5037
+ }
3394
5038
  for (const [identity, kind] of plan.edgeDeletions) {
3395
5039
  await edgeCollection(edgesApi, kind).delete(idOf(identity));
3396
5040
  }
3397
5041
  const edgesByKind = /* @__PURE__ */ new Map();
3398
5042
  for (const edge of plan.mergedEdges) {
3399
- const fromKind = plan.retypeMap.get(mergeKey(edge.fromKind, edge.fromId));
3400
- const toKind = plan.retypeMap.get(mergeKey(edge.toKind, edge.toId));
3401
5043
  const edgeBaseProps = plan.inheritedEdgeBaseProps.get(edge.id);
3402
5044
  const props = edgeBaseProps === void 0 ? edge.props : commitModificationProps(edgeBaseProps, edge.props);
3403
5045
  const item = {
3404
5046
  id: edge.id,
3405
- from: { kind: fromKind ?? edge.fromKind, id: edge.fromId },
3406
- to: { kind: toKind ?? edge.toKind, id: edge.toId },
3407
- props
5047
+ from: finalEdgeEndpoint(plan, edge.fromKind, edge.fromId),
5048
+ to: finalEdgeEndpoint(plan, edge.toKind, edge.toId),
5049
+ props,
5050
+ ...edge.validFrom === void 0 ? {} : { validFrom: edge.validFrom },
5051
+ ...edge.validTo === void 0 ? {} : { validTo: edge.validTo }
3408
5052
  };
3409
5053
  const existing = edgesByKind.get(edge.kind);
3410
5054
  if (existing === void 0) {
@@ -3418,10 +5062,34 @@ async function applyMergePlan(plan, nodesApi, edgesApi) {
3418
5062
  await edgeCollection(edgesApi, kind).bulkUpsertById(items);
3419
5063
  committedEdges += items.length;
3420
5064
  }
3421
- return { nodes: committedNodeIds.size, edges: committedEdges };
5065
+ let appliedIdentity;
5066
+ try {
5067
+ appliedIdentity = await chunkTTAITEPJ_cjs.storeRuntime(target).applyIdentityMergeAtTarget(
5068
+ txBackend,
5069
+ plan.identityRetractions.map((retraction) => retraction.id),
5070
+ plan.identityAssertions
5071
+ );
5072
+ await assertMergedIdentityClassesConsistent(target, txBackend, plan);
5073
+ } catch (error) {
5074
+ throw translateIdentityCommitError(error);
5075
+ }
5076
+ return {
5077
+ nodes: committedNodeIds.size,
5078
+ edges: committedEdges,
5079
+ // ACTUAL ledger effects from the applier: rows created (idempotent
5080
+ // exact/pair matches the target already held are excluded — the normal
5081
+ // incremental case, where the target's own additions are staged back at
5082
+ // it) and rows ended (already-ended or unknown ids excluded). Any apply
5083
+ // failure aborts the whole merge, so the counts never describe a
5084
+ // partial commit.
5085
+ identity: {
5086
+ asserted: appliedIdentity.created,
5087
+ retracted: appliedIdentity.retracted
5088
+ }
5089
+ };
3422
5090
  }
3423
5091
  async function commitPlan(target, plan, expectedBaseVersion) {
3424
- if (!chunk7V2FGGI2_cjs.storeBackend(target).capabilities.transactions) {
5092
+ if (!chunkTTAITEPJ_cjs.storeBackend(target).capabilities.transactions) {
3425
5093
  throw new MergeError(
3426
5094
  "merge() requires a transaction-capable target backend. The merged plan (canonical upserts, soft-deletes, edge upserts) must commit atomically; a non-transactional fallback would leave a partially-merged graph on a mid-commit failure. (mergeIncremental() enforces the same requirement.)",
3427
5095
  { details: { capability: "transactions" } }
@@ -3431,15 +5099,18 @@ async function commitPlan(target, plan, expectedBaseVersion) {
3431
5099
  () => target.transaction(async (tx) => {
3432
5100
  if (expectedBaseVersion !== void 0) {
3433
5101
  await assertTargetUnchanged(
3434
- chunk7V2FGGI2_cjs.transactionBackend(tx),
5102
+ chunkTTAITEPJ_cjs.transactionBackend(tx),
3435
5103
  target,
3436
5104
  expectedBaseVersion
3437
5105
  );
3438
5106
  }
5107
+ await assertPlannedIdentityIdsFresh(target, chunkTTAITEPJ_cjs.transactionBackend(tx), plan);
3439
5108
  return applyMergePlan(
3440
5109
  plan,
3441
5110
  tx.nodes,
3442
- tx.edges
5111
+ tx.edges,
5112
+ target,
5113
+ chunkTTAITEPJ_cjs.transactionBackend(tx)
3443
5114
  );
3444
5115
  }, mergeCommitTransactionOptions(target))
3445
5116
  );
@@ -3452,9 +5123,9 @@ function mergeCommitTransactionOptions(target) {
3452
5123
  }
3453
5124
  async function assertTargetUnchanged(txBackend, target, expectedBaseVersion) {
3454
5125
  if (hasRevisionAnchor(expectedBaseVersion)) {
3455
- await chunk7V2FGGI2_cjs.lockRecordedGraphWrite(txBackend, target.graphId);
5126
+ await chunkXMQSEJCF_cjs.lockRecordedGraphWrite(txBackend, target.graphId);
3456
5127
  const expectedOrigin = revisionOriginOf(expectedBaseVersion);
3457
- const liveOrigin = await chunk7V2FGGI2_cjs.readRevisionOrigin(
5128
+ const liveOrigin = await chunkXMQSEJCF_cjs.readRevisionOrigin(
3458
5129
  txBackend,
3459
5130
  target.revisionSchema,
3460
5131
  target.graphId
@@ -3468,7 +5139,7 @@ async function assertTargetUnchanged(txBackend, target, expectedBaseVersion) {
3468
5139
  }
3469
5140
  );
3470
5141
  }
3471
- const liveRevision = await chunk7V2FGGI2_cjs.readRecordedClock(
5142
+ const liveRevision = await chunkXMQSEJCF_cjs.readRecordedClock(
3472
5143
  txBackend,
3473
5144
  target.revisionSchema,
3474
5145
  target.graphId
@@ -3488,7 +5159,8 @@ async function assertTargetUnchanged(txBackend, target, expectedBaseVersion) {
3488
5159
  const liveContent = await computeContentComponent(
3489
5160
  txBackend,
3490
5161
  target.graphId,
3491
- target.graph
5162
+ target.graph,
5163
+ await chunkTTAITEPJ_cjs.storeRuntime(target).identityAssertionsAtTarget(txBackend, "state")
3492
5164
  );
3493
5165
  const expectedContent = contentComponentOf(expectedBaseVersion);
3494
5166
  if (liveContent !== expectedContent) {
@@ -3526,7 +5198,7 @@ async function validateBaseVersions(target, branches) {
3526
5198
  const targetVersion = await computeBaseVersion(target);
3527
5199
  for (const branch2 of branches) {
3528
5200
  if (branch2.base !== targetVersion) {
3529
- return chunkQYWINYEA_cjs.err(
5201
+ return chunk7BQXPCGN_cjs.err(
3530
5202
  new BaseVersionMismatchError(
3531
5203
  `Branch "${branch2.id}" forked from base@V "${branch2.base}", which does not match the merge target's current base@V "${targetVersion}".`,
3532
5204
  {
@@ -3540,20 +5212,50 @@ async function validateBaseVersions(target, branches) {
3540
5212
  );
3541
5213
  }
3542
5214
  }
3543
- return chunkQYWINYEA_cjs.ok(targetVersion);
5215
+ return chunk7BQXPCGN_cjs.ok(targetVersion);
5216
+ }
5217
+ function tryNormalize(optionsInput, refusedOptions = []) {
5218
+ const refusedOption = refusedOptions.find(
5219
+ (option) => chunkN66HCGCY_cjs.hasOwnKey(optionsInput, option)
5220
+ );
5221
+ if (refusedOption !== void 0) {
5222
+ return chunk7BQXPCGN_cjs.err(
5223
+ new InvalidMergeOptionsError(
5224
+ `This merge operation does not accept options.${refusedOption}.`,
5225
+ { details: { option: refusedOption } }
5226
+ )
5227
+ );
5228
+ }
5229
+ try {
5230
+ return chunk7BQXPCGN_cjs.ok(normalizeMergeOptions(optionsInput));
5231
+ } catch (error) {
5232
+ return chunk7BQXPCGN_cjs.err(
5233
+ new InvalidMergeOptionsError("Invalid merge options.", { cause: error })
5234
+ );
5235
+ }
3544
5236
  }
3545
- function tryNormalize(optionsInput) {
5237
+ async function tryOpenProvenanceStore(target) {
3546
5238
  try {
3547
- return chunkQYWINYEA_cjs.ok(normalizeMergeOptions(optionsInput));
5239
+ return chunk7BQXPCGN_cjs.ok(await openProvenanceStore(target));
3548
5240
  } catch (error) {
3549
- return chunkQYWINYEA_cjs.err(new MergeError("Invalid merge options.", { cause: error }));
5241
+ const code = error instanceof chunkNI72YOJB_cjs.TypeGraphError ? error.details?.code : void 0;
5242
+ const details = {
5243
+ option: "persistProvenance",
5244
+ graphId: provenanceGraphId(target.graphId),
5245
+ targetGraphId: target.graphId,
5246
+ ...typeof code === "string" ? { provenanceErrorCode: code } : {}
5247
+ };
5248
+ const message = `options.persistProvenance was requested but the merge-provenance sidecar cannot be opened: ${describeCause(error)}`;
5249
+ return chunk7BQXPCGN_cjs.err(
5250
+ code === "GRAPH_MERGE_PROVENANCE_ID_COLLISION" || code === "GRAPH_MERGE_PROVENANCE_CLAIM_UNFENCED" ? new InvalidMergeOptionsError(message, { details, cause: error }) : new MergeError(message, { details, cause: error })
5251
+ );
3550
5252
  }
3551
5253
  }
3552
5254
  async function resolveMerge(store, target, branches, options, useBaseSources, incremental, expectedBaseVersion) {
3553
5255
  let targetBranchSeen = false;
3554
5256
  for (const branch2 of branches) {
3555
5257
  if (branch2.id === BASE_PROVENANCE_BRANCH) {
3556
- return chunkQYWINYEA_cjs.err(
5258
+ return chunk7BQXPCGN_cjs.err(
3557
5259
  new MergeError(
3558
5260
  `Branch id "${BASE_PROVENANCE_BRANCH}" is reserved for committed-base provenance and cannot be used as a branch id.`,
3559
5261
  { details: { branchId: branch2.id } }
@@ -3562,7 +5264,7 @@ async function resolveMerge(store, target, branches, options, useBaseSources, in
3562
5264
  }
3563
5265
  if (branch2.id === COMMITTED_TARGET_BRANCH) {
3564
5266
  if (incremental?.targetBranchId !== COMMITTED_TARGET_BRANCH || targetBranchSeen) {
3565
- return chunkQYWINYEA_cjs.err(
5267
+ return chunk7BQXPCGN_cjs.err(
3566
5268
  new MergeError(
3567
5269
  `Branch id "${COMMITTED_TARGET_BRANCH}" is reserved for the committed incremental target and cannot be used as a branch id.`,
3568
5270
  { details: { branchId: branch2.id } }
@@ -3572,9 +5274,44 @@ async function resolveMerge(store, target, branches, options, useBaseSources, in
3572
5274
  targetBranchSeen = true;
3573
5275
  }
3574
5276
  }
5277
+ for (const branch2 of branches) {
5278
+ const branchSchemaRow = await chunkTTAITEPJ_cjs.storeBackend(branch2.store).getActiveSchema(
5279
+ branch2.store.graphId
5280
+ );
5281
+ let drifted;
5282
+ if ("schemaAnchor" in branch2) {
5283
+ const anchor = branch2.schemaAnchor;
5284
+ drifted = anchor === void 0 ? branchSchemaRow !== void 0 : branchSchemaRow?.version !== anchor.version || branchSchemaRow.schema_hash !== anchor.hash;
5285
+ } else {
5286
+ const sourceSchemaRow = await chunkTTAITEPJ_cjs.storeBackend(store).getActiveSchema(
5287
+ store.graphId
5288
+ );
5289
+ drifted = branchSchemaRow?.schema_hash !== sourceSchemaRow?.schema_hash;
5290
+ }
5291
+ if (drifted) {
5292
+ return chunk7BQXPCGN_cjs.err(
5293
+ new BaseVersionMismatchError(
5294
+ `Branch "${branch2.id}"'s store has a committed schema different from its at-fork state \u2014 a schema operation ran on the branch after forking. Merge carries data changes only; apply the schema change to the target first (or re-fork), then merge.`,
5295
+ {
5296
+ details: {
5297
+ branchId: branch2.id,
5298
+ branchSchemaVersion: branchSchemaRow?.version,
5299
+ branchSchemaHash: branchSchemaRow?.schema_hash,
5300
+ anchor: "schemaAnchor" in branch2 ? branch2.schemaAnchor : "absent"
5301
+ }
5302
+ }
5303
+ )
5304
+ );
5305
+ }
5306
+ }
5307
+ const provenanceStore = options.persistProvenance ? await tryOpenProvenanceStore(target) : void 0;
5308
+ if (provenanceStore !== void 0 && chunk7BQXPCGN_cjs.isErr(provenanceStore)) {
5309
+ return provenanceStore;
5310
+ }
3575
5311
  try {
3576
5312
  const preferredBranchId = incremental?.targetBranchId;
3577
5313
  const staging = await stageBranches(store, branches, preferredBranchId);
5314
+ const stagedNewByKind = newNodesByKind(staging);
3578
5315
  const branchIds = branches.map((branch2) => branch2.id);
3579
5316
  const branchOrder = preferredBranchId === void 0 ? options.branchOrder ?? [] : [
3580
5317
  preferredBranchId,
@@ -3590,12 +5327,12 @@ async function resolveMerge(store, target, branches, options, useBaseSources, in
3590
5327
  }
3591
5328
  const subClassClosure = buildSubClassClosure(introspection.ontology);
3592
5329
  const embeddings = options.embedder === void 0 ? void 0 : await precomputeEmbeddings(
3593
- newNodesByKind(staging),
5330
+ stagedNewByKind,
3594
5331
  options.resolve,
3595
5332
  options.embedder
3596
5333
  );
3597
5334
  const ctx = {
3598
- backend: chunk7V2FGGI2_cjs.storeBackend(store),
5335
+ backend: chunkTTAITEPJ_cjs.storeBackend(store),
3599
5336
  ...embeddings === void 0 ? {} : { embeddings }
3600
5337
  };
3601
5338
  const candidates = await generateAllCandidates(
@@ -3607,9 +5344,38 @@ async function resolveMerge(store, target, branches, options, useBaseSources, in
3607
5344
  useBaseSources,
3608
5345
  options.embedder
3609
5346
  );
3610
- if (chunkQYWINYEA_cjs.isErr(candidates)) {
3611
- return chunkQYWINYEA_cjs.err(candidates.error);
5347
+ if (chunk7BQXPCGN_cjs.isErr(candidates)) {
5348
+ return chunk7BQXPCGN_cjs.err(candidates.error);
3612
5349
  }
5350
+ const identityProbeIds = target.graph.identity === void 0 ? void 0 : [
5351
+ .../* @__PURE__ */ new Set([
5352
+ ...[...stagedNewByKind.values()].flatMap(
5353
+ (entries) => entries.map((entry) => entry.node.id)
5354
+ ),
5355
+ ...staging.modifiedNodes.map((entry) => entry.node.id),
5356
+ ...candidates.data.baseMembers.map((member) => member.id),
5357
+ ...staging.newIdentityAssertions.flatMap((staged) => [
5358
+ staged.assertion.a.id,
5359
+ staged.assertion.b.id
5360
+ ])
5361
+ ])
5362
+ ];
5363
+ const targetPeers = identityProbeIds === void 0 ? [] : await chunkTTAITEPJ_cjs.storeRuntime(target).liveNodesSharingIds(identityProbeIds);
5364
+ const stagedIdentityIds = [
5365
+ .../* @__PURE__ */ new Set([
5366
+ ...staging.newIdentityAssertions.map((staged) => staged.assertion.id),
5367
+ ...staging.retractedIdentityAssertions.map(
5368
+ (staged) => staged.assertion.id
5369
+ )
5370
+ ])
5371
+ ];
5372
+ const storedIdentityRowsById = stagedIdentityIds.length === 0 || target.graph.identity === void 0 ? NO_STORED_ASSERTIONS : await chunkTTAITEPJ_cjs.storeRuntime(target).identityAssertionRowsByIds(
5373
+ stagedIdentityIds
5374
+ );
5375
+ const identityContext = {
5376
+ sameIdAcrossKinds: target.graph.identity?.sameIdAcrossKinds,
5377
+ areDisjoint: (left, right) => target.registry.areDisjoint(left, right)
5378
+ };
3613
5379
  const plan = planMerge(
3614
5380
  staging,
3615
5381
  candidates.data.edges,
@@ -3618,12 +5384,63 @@ async function resolveMerge(store, target, branches, options, useBaseSources, in
3618
5384
  options,
3619
5385
  branchRank,
3620
5386
  subClassClosure,
5387
+ identityContext,
5388
+ storedIdentityRowsById,
5389
+ targetPeers,
3621
5390
  preferredBranchId
3622
5391
  );
5392
+ if (plan.identityAssertions.length > 0) {
5393
+ assertOneIdOneTruth(
5394
+ plan.identityAssertions,
5395
+ await chunkTTAITEPJ_cjs.storeRuntime(target).identityAssertionRowsByIds(
5396
+ plan.identityAssertions.map((assertion) => assertion.id)
5397
+ )
5398
+ );
5399
+ }
5400
+ let identityGuard;
5401
+ if (identityProbeIds !== void 0 && incremental !== void 0) {
5402
+ const freshPeers = await chunkTTAITEPJ_cjs.storeRuntime(target).liveNodesSharingIds(identityProbeIds);
5403
+ const built = await buildIdentityPeerProbe(
5404
+ target,
5405
+ identityProbeIds,
5406
+ freshPeers,
5407
+ plan,
5408
+ target.graph.identity?.sameIdAcrossKinds ?? "ignore"
5409
+ );
5410
+ const canonicalIdentityOf = plan.canonicalOf;
5411
+ assertNoContradictoryIdentityClosure(
5412
+ plan.identityAssertions,
5413
+ plan.identityRetractions.map((retraction) => retraction.id),
5414
+ // The FRESH target ledger, not the pre-planning staging capture —
5415
+ // a `different` committed in the window must invalidate the plan
5416
+ // here, as a typed conflict, before it can become the baseline.
5417
+ // Connectivity is REBUILT from this deletion-filtered ledger (plus
5418
+ // the fold unions inside the checker) rather than from the old
5419
+ // closure's member lists: filtering a deleted member out of a class
5420
+ // does not model the post-deletion state — deleting a bridge ends
5421
+ // its assertions and SPLITS the class, so pre-linking the filtered
5422
+ // remainder would falsely reject a plan that deletes the bridge and
5423
+ // asserts the ends different.
5424
+ built.ledger,
5425
+ new Set(plan.nodeDeletions.keys()),
5426
+ canonicalIdentityOf,
5427
+ plan.retypeMap,
5428
+ identityContext,
5429
+ // The snapshot's (deletion-filtered) class MEMBERS join the universe
5430
+ // as unlinked refs: their same-id fold links at ids outside the probe
5431
+ // range are re-derived by the checker's fold union, and their
5432
+ // assertion links come from the fresh ledger — never from the old
5433
+ // class shape itself.
5434
+ [...built.probe.seeds, ...built.snapshot.groups.flat()]
5435
+ );
5436
+ identityGuard = built.probe;
5437
+ }
3623
5438
  const merged = incremental === void 0 ? await commitPlan(target, plan, expectedBaseVersion) : await commitIncrementalPlan(target, plan, {
3624
- stagedNewByKind: newNodesByKind(staging),
5439
+ stagedNewByKind,
3625
5440
  options,
3626
5441
  introspectionKinds,
5442
+ forkPoint: incremental.forkPoint,
5443
+ ...identityGuard === void 0 ? {} : { identityPeerProbe: identityGuard },
3627
5444
  // The committed (kind, id) keys the base sources matched at PLAN time;
3628
5445
  // anything NEW the in-tx re-probe surfaces is a window write.
3629
5446
  plannedBaseMatchKeys: new Set(
@@ -3635,11 +5452,10 @@ async function resolveMerge(store, target, branches, options, useBaseSources, in
3635
5452
  const provenance = options.provenance ? buildProvenanceIndex(plan.provenanceRecords) : { byBranch: () => ({ nodeIds: [], edgeIds: [] }) };
3636
5453
  const warnings = [...plan.warnings];
3637
5454
  let provenancePersisted;
3638
- if (options.persistProvenance) {
5455
+ if (provenanceStore !== void 0 && !chunk7BQXPCGN_cjs.isErr(provenanceStore)) {
3639
5456
  try {
3640
- const provenanceStore = await openProvenanceStore(target);
3641
5457
  const count = await persistProvenanceRecords(
3642
- provenanceStore,
5458
+ provenanceStore.data,
3643
5459
  target.graphId,
3644
5460
  plan.provenanceRecords
3645
5461
  );
@@ -3660,17 +5476,18 @@ async function resolveMerge(store, target, branches, options, useBaseSources, in
3660
5476
  deleteModifyConflicts: plan.deleteModifyConflicts,
3661
5477
  typeReconciliations: plan.typeReconciliations,
3662
5478
  dropped: plan.dropped,
5479
+ validityEnds: plan.validityEnds,
3663
5480
  baseAmbiguities: plan.baseAmbiguities,
3664
5481
  provenance,
3665
5482
  warnings,
3666
5483
  ...provenancePersisted === void 0 ? {} : { provenancePersisted }
3667
5484
  };
3668
- return chunkQYWINYEA_cjs.ok(report);
5485
+ return chunk7BQXPCGN_cjs.ok(report);
3669
5486
  } catch (error) {
3670
5487
  if (error instanceof MergeError) {
3671
- return chunkQYWINYEA_cjs.err(error);
5488
+ return chunk7BQXPCGN_cjs.err(error);
3672
5489
  }
3673
- return chunkQYWINYEA_cjs.err(
5490
+ return chunk7BQXPCGN_cjs.err(
3674
5491
  new MergeError(
3675
5492
  `Merge failed while staging or committing: ${describeCause(error)}`,
3676
5493
  { cause: error }
@@ -3680,14 +5497,14 @@ async function resolveMerge(store, target, branches, options, useBaseSources, in
3680
5497
  }
3681
5498
  async function merge(store, branches, optionsInput = {}) {
3682
5499
  const normalized = tryNormalize(optionsInput);
3683
- if (chunkQYWINYEA_cjs.isErr(normalized)) {
3684
- return chunkQYWINYEA_cjs.err(normalized.error);
5500
+ if (chunk7BQXPCGN_cjs.isErr(normalized)) {
5501
+ return chunk7BQXPCGN_cjs.err(normalized.error);
3685
5502
  }
3686
5503
  const options = normalized.data;
3687
5504
  const target = options.target ?? store;
3688
5505
  const precondition = await validateBaseVersions(target, branches);
3689
- if (chunkQYWINYEA_cjs.isErr(precondition)) {
3690
- return chunkQYWINYEA_cjs.err(precondition.error);
5506
+ if (chunk7BQXPCGN_cjs.isErr(precondition)) {
5507
+ return chunk7BQXPCGN_cjs.err(precondition.error);
3691
5508
  }
3692
5509
  return resolveMerge(
3693
5510
  store,
@@ -3703,7 +5520,7 @@ async function validateForkPointVersions(forkPoint, branches) {
3703
5520
  const forkVersion = await computeBaseVersion(forkPoint);
3704
5521
  for (const branch2 of branches) {
3705
5522
  if (branch2.base !== forkVersion) {
3706
- return chunkQYWINYEA_cjs.err(
5523
+ return chunk7BQXPCGN_cjs.err(
3707
5524
  new BaseVersionMismatchError(
3708
5525
  `Branch "${branch2.id}" forked from base@V "${branch2.base}", which does not match the fork-point's base@V "${forkVersion}". mergeIncremental() requires every branch to have forked from the supplied forkPoint.`,
3709
5526
  {
@@ -3717,7 +5534,7 @@ async function validateForkPointVersions(forkPoint, branches) {
3717
5534
  );
3718
5535
  }
3719
5536
  }
3720
- return chunkQYWINYEA_cjs.ok(forkVersion);
5537
+ return chunk7BQXPCGN_cjs.ok(forkVersion);
3721
5538
  }
3722
5539
  function nodeSchemaFor(target, kind) {
3723
5540
  const registry = target.graph.nodes;
@@ -3753,7 +5570,7 @@ function analyzeRevalidatingWrite(schema, current, planned) {
3753
5570
  };
3754
5571
  }
3755
5572
  function nodeProps2(node) {
3756
- const props = {};
5573
+ const props = chunkN66HCGCY_cjs.createDataKeyedBag();
3757
5574
  for (const [key, value] of Object.entries(node)) {
3758
5575
  if (key === "id" || key === "kind" || key === "meta") continue;
3759
5576
  props[key] = value;
@@ -3761,7 +5578,7 @@ function nodeProps2(node) {
3761
5578
  return props;
3762
5579
  }
3763
5580
  function edgeProps(edge) {
3764
- const props = {};
5581
+ const props = chunkN66HCGCY_cjs.createDataKeyedBag();
3765
5582
  for (const [key, value] of Object.entries(edge)) {
3766
5583
  if (key === "id" || key === "kind" || key === "fromKind" || key === "fromId" || key === "toKind" || key === "toId" || key === "meta") {
3767
5584
  continue;
@@ -3771,70 +5588,14 @@ function edgeProps(edge) {
3771
5588
  return props;
3772
5589
  }
3773
5590
  var INCLUDE_TOMBSTONES = { temporalMode: "includeTombstones" };
3774
- function finalEdgeFrom(edge, plan) {
3775
- return {
3776
- kind: plan.retypeMap.get(mergeKey(edge.fromKind, edge.fromId)) ?? edge.fromKind,
3777
- id: edge.fromId
3778
- };
3779
- }
3780
- function finalEdgeTo(edge, plan) {
3781
- return {
3782
- kind: plan.retypeMap.get(mergeKey(edge.toKind, edge.toId)) ?? edge.toKind,
3783
- id: edge.toId
3784
- };
3785
- }
3786
5591
  function assertValidRevalidatingWrite(analysis, message, details) {
3787
5592
  if (analysis.status === "invalid") {
3788
5593
  throw new MergeError(message, { details });
3789
5594
  }
3790
5595
  }
3791
- function describeCause(cause) {
3792
- return cause instanceof Error ? cause.message : String(cause);
3793
- }
3794
- function plannedNodeWrites(plan) {
3795
- const canonicalIdentities = /* @__PURE__ */ new Set();
3796
- for (const entity of plan.canonicalEntities) {
3797
- canonicalIdentities.add(mergeKey(entity.kind, entity.canonicalId));
3798
- }
3799
- const survivingModProps = /* @__PURE__ */ new Map();
3800
- for (const modification of plan.survivingModifications) {
3801
- survivingModProps.set(
3802
- mergeKeyOf(modification.node),
3803
- modification.node.forkProps
3804
- );
3805
- }
3806
- const writes = [];
3807
- for (const modification of plan.survivingModifications) {
3808
- const identity = mergeKeyOf(modification.node);
3809
- if (plan.nodeDeletions.has(identity) || canonicalIdentities.has(identity)) {
3810
- continue;
3811
- }
3812
- writes.push({
3813
- identity,
3814
- kind: modification.node.kind,
3815
- id: modification.node.id,
3816
- props: modification.node.forkProps
3817
- });
3818
- }
3819
- for (const entity of plan.canonicalEntities) {
3820
- const sourceIdentity = mergeKey(entity.kind, entity.canonicalId);
3821
- if (plan.nodeDeletions.has(sourceIdentity)) {
3822
- continue;
3823
- }
3824
- const kind = plan.retypeMap.get(sourceIdentity) ?? entity.kind;
3825
- const forkProps = survivingModProps.get(sourceIdentity);
3826
- writes.push({
3827
- identity: mergeKey(kind, entity.canonicalId),
3828
- kind,
3829
- id: entity.canonicalId,
3830
- props: forkProps === void 0 ? entity.props : { ...entity.props, ...forkProps }
3831
- });
3832
- }
3833
- return writes;
3834
- }
3835
5596
  function edgeWriteSignature(edge, plan) {
3836
- const from = finalEdgeFrom(edge, plan);
3837
- const to = finalEdgeTo(edge, plan);
5597
+ const from = finalEdgeEndpoint(plan, edge.fromKind, edge.fromId);
5598
+ const to = finalEdgeEndpoint(plan, edge.toKind, edge.toId);
3838
5599
  return JSON.stringify([
3839
5600
  edge.kind,
3840
5601
  from.kind,
@@ -3876,7 +5637,7 @@ async function validateIncrementalNodeWrites(target, nodesApi, plan) {
3876
5637
  const analysis = analyzeRevalidatingWrite(
3877
5638
  nodeSchemaFor(target, write.kind),
3878
5639
  nodeProps2(current),
3879
- write.props
5640
+ nodeWriteProps(write, (modification) => modification.forkProps)
3880
5641
  );
3881
5642
  assertValidRevalidatingWrite(
3882
5643
  analysis,
@@ -3928,7 +5689,7 @@ async function validateIncrementalEdgeWrites(target, edgesApi, plan) {
3928
5689
  }
3929
5690
  }
3930
5691
  }
3931
- const notFound = [...plannedKindById.keys()].filter((id) => !existingById.has(id)).sort((left, right) => chunkTRF4EBJT_cjs.compareStrings(left, right));
5692
+ const notFound = [...plannedKindById.keys()].filter((id) => !existingById.has(id)).sort((left, right) => chunkXMQSEJCF_cjs.compareStrings(left, right));
3932
5693
  if (notFound.length > 0) {
3933
5694
  const crossKindById = /* @__PURE__ */ new Map();
3934
5695
  for (const kind of Object.keys(target.graph.edges)) {
@@ -3955,12 +5716,12 @@ async function validateIncrementalEdgeWrites(target, edgesApi, plan) {
3955
5716
  );
3956
5717
  }
3957
5718
  throw new MergeError(
3958
- `mergeIncremental() would overwrite committed edge "${id}" (kind "${row.kind}") with a different-kind edge "${chunk764JHTLT_cjs.requireDefined(plannedKindById.get(id))}" of the same id.`,
5719
+ `mergeIncremental() would overwrite committed edge "${id}" (kind "${row.kind}") with a different-kind edge "${chunkN66HCGCY_cjs.requireDefined(plannedKindById.get(id))}" of the same id.`,
3959
5720
  {
3960
5721
  details: {
3961
5722
  id,
3962
5723
  committedKind: row.kind,
3963
- plannedKind: chunk764JHTLT_cjs.requireDefined(plannedKindById.get(id))
5724
+ plannedKind: chunkN66HCGCY_cjs.requireDefined(plannedKindById.get(id))
3964
5725
  }
3965
5726
  }
3966
5727
  );
@@ -3977,8 +5738,8 @@ async function validateIncrementalEdgeWrites(target, edgesApi, plan) {
3977
5738
  { details: { id: edge.id, committedKind: current.kind } }
3978
5739
  );
3979
5740
  }
3980
- const from = finalEdgeFrom(edge, plan);
3981
- const to = finalEdgeTo(edge, plan);
5741
+ const from = finalEdgeEndpoint(plan, edge.fromKind, edge.fromId);
5742
+ const to = finalEdgeEndpoint(plan, edge.toKind, edge.toId);
3982
5743
  if (current.fromId !== from.id || current.fromKind !== from.kind || current.toId !== to.id || current.toKind !== to.kind) {
3983
5744
  throw new MergeError(
3984
5745
  `mergeIncremental() would overwrite committed edge "${edge.id}" (kind "${edge.kind}") with different endpoints.`,
@@ -4080,7 +5841,7 @@ async function assertInheritedUnchanged(args) {
4080
5841
  for (const [kind, ids] of idsByKind) {
4081
5842
  const rows = await args.fetchRows(kind, ids);
4082
5843
  for (const [index, id] of ids.entries()) {
4083
- const expected = chunk764JHTLT_cjs.requireDefined(args.expected.get(mergeKey(kind, id)));
5844
+ const expected = chunkN66HCGCY_cjs.requireDefined(args.expected.get(mergeKey(kind, id)));
4084
5845
  const current = args.deriveValue(rows[index]);
4085
5846
  if (current === expected) {
4086
5847
  continue;
@@ -4150,8 +5911,22 @@ async function assertInheritedEdgesUnchanged(edgesApi, guard, plan) {
4150
5911
  )
4151
5912
  });
4152
5913
  }
5914
+ async function assertForkPointUnchanged(precondition) {
5915
+ const liveVersion = await computeBaseVersion(precondition.store);
5916
+ if (liveVersion === precondition.version) return;
5917
+ throw new BaseVersionMismatchError(
5918
+ "The mergeIncremental() fork point was modified between the fork-point precondition and the commit transaction; every branch diff was computed against the previous fork-point state, so the resolved plan was not applied.",
5919
+ {
5920
+ details: {
5921
+ expectedForkPointBase: precondition.version,
5922
+ liveForkPointBase: liveVersion
5923
+ },
5924
+ suggestion: "Keep the fork-point store immutable for the duration of the merge (it is the diff reference, not a merge target), then re-run mergeIncremental()."
5925
+ }
5926
+ );
5927
+ }
4153
5928
  async function commitIncrementalPlan(target, plan, guard) {
4154
- if (!chunk7V2FGGI2_cjs.storeBackend(target).capabilities.transactions) {
5929
+ if (!chunkTTAITEPJ_cjs.storeBackend(target).capabilities.transactions) {
4155
5930
  throw new MergeError(
4156
5931
  "mergeIncremental() requires a transaction-capable target backend. Incremental writes must preflight existing rows and commit atomically; non-transactional fallback would allow partial graph writes.",
4157
5932
  { details: { capability: "transactions" } }
@@ -4160,36 +5935,56 @@ async function commitIncrementalPlan(target, plan, guard) {
4160
5935
  return withTxConflictRetry(
4161
5936
  () => target.transaction(async (tx) => {
4162
5937
  if (target.revisionTrackingEnabled) {
4163
- await chunk7V2FGGI2_cjs.lockRecordedGraphWrite(chunk7V2FGGI2_cjs.transactionBackend(tx), target.graphId);
5938
+ await chunkXMQSEJCF_cjs.lockRecordedGraphWrite(chunkTTAITEPJ_cjs.transactionBackend(tx), target.graphId);
4164
5939
  }
5940
+ await assertForkPointUnchanged(guard.forkPoint);
4165
5941
  const nodesApi = tx.nodes;
4166
5942
  const edgesApi = tx.edges;
4167
5943
  await assertBaseResolutionStable(tx, guard);
5944
+ await assertPlannedIdentityIdsFresh(target, chunkTTAITEPJ_cjs.transactionBackend(tx), plan);
5945
+ await assertIdentityPeersStable(
5946
+ target,
5947
+ chunkTTAITEPJ_cjs.transactionBackend(tx),
5948
+ guard.identityPeerProbe,
5949
+ plan
5950
+ );
4168
5951
  await assertInheritedTargetUnchanged(nodesApi, edgesApi, guard, plan);
4169
5952
  await validateIncrementalNodeWrites(target, nodesApi, plan);
4170
5953
  await validateIncrementalEdgeWrites(target, edgesApi, plan);
4171
- return applyMergePlan(plan, nodesApi, edgesApi);
5954
+ return applyMergePlan(
5955
+ plan,
5956
+ nodesApi,
5957
+ edgesApi,
5958
+ target,
5959
+ chunkTTAITEPJ_cjs.transactionBackend(tx)
5960
+ );
4172
5961
  }, mergeCommitTransactionOptions(target))
4173
5962
  );
4174
5963
  }
4175
5964
  async function mergeIncremental(args) {
4176
5965
  const { forkPoint, target, branches } = args;
4177
- const normalized = tryNormalize(args.options ?? {});
4178
- if (chunkQYWINYEA_cjs.isErr(normalized)) {
4179
- return chunkQYWINYEA_cjs.err(normalized.error);
5966
+ const normalized = tryNormalize(args.options ?? {}, ["target"]);
5967
+ if (chunk7BQXPCGN_cjs.isErr(normalized)) {
5968
+ return chunk7BQXPCGN_cjs.err(normalized.error);
4180
5969
  }
4181
5970
  const options = normalized.data;
4182
5971
  if (options.onBasePropertyConflict !== "flag") {
4183
- return chunkQYWINYEA_cjs.err(
4184
- new MergeError(
5972
+ return chunk7BQXPCGN_cjs.err(
5973
+ new InvalidMergeOptionsError(
4185
5974
  'mergeIncremental() requires onBasePropertyConflict: "flag" (keep-base); a non-keep-base policy could overwrite a newer committed base value with a stale branch value.',
4186
- { details: {} }
5975
+ {
5976
+ details: {
5977
+ option: "onBasePropertyConflict",
5978
+ accepted: "flag",
5979
+ received: options.onBasePropertyConflict
5980
+ }
5981
+ }
4187
5982
  )
4188
5983
  );
4189
5984
  }
4190
5985
  const forkPrecondition = await validateForkPointVersions(forkPoint, branches);
4191
- if (chunkQYWINYEA_cjs.isErr(forkPrecondition)) {
4192
- return chunkQYWINYEA_cjs.err(forkPrecondition.error);
5986
+ if (chunk7BQXPCGN_cjs.isErr(forkPrecondition)) {
5987
+ return chunk7BQXPCGN_cjs.err(forkPrecondition.error);
4193
5988
  }
4194
5989
  const forkVersion = forkPrecondition.data;
4195
5990
  const [forkSchema, targetSchema] = await Promise.all([
@@ -4197,7 +5992,7 @@ async function mergeIncremental(args) {
4197
5992
  computeSchemaComponent(target)
4198
5993
  ]);
4199
5994
  if (forkSchema !== targetSchema) {
4200
- return chunkQYWINYEA_cjs.err(
5995
+ return chunk7BQXPCGN_cjs.err(
4201
5996
  new MergeError(
4202
5997
  "mergeIncremental() requires target and forkPoint to share a schema; schema drift is not supported (the target content may differ \u2014 only the schema must match).",
4203
5998
  { details: {} }
@@ -4215,29 +6010,38 @@ async function mergeIncremental(args) {
4215
6010
  [targetBranch, ...branches],
4216
6011
  options,
4217
6012
  true,
4218
- { targetBranchId: COMMITTED_TARGET_BRANCH }
6013
+ {
6014
+ targetBranchId: COMMITTED_TARGET_BRANCH,
6015
+ // The fork-point precondition just validated, carried to the commit so
6016
+ // it is re-established there rather than assumed to have held for the
6017
+ // whole of planning (see `assertForkPointUnchanged`).
6018
+ forkPoint: { store: forkPoint, version: forkVersion }
6019
+ }
4219
6020
  );
4220
6021
  }
4221
6022
 
4222
6023
  Object.defineProperty(exports, "isErr", {
4223
6024
  enumerable: true,
4224
- get: function () { return chunkQYWINYEA_cjs.isErr; }
6025
+ get: function () { return chunk7BQXPCGN_cjs.isErr; }
4225
6026
  });
4226
6027
  Object.defineProperty(exports, "isOk", {
4227
6028
  enumerable: true,
4228
- get: function () { return chunkQYWINYEA_cjs.isOk; }
6029
+ get: function () { return chunk7BQXPCGN_cjs.isOk; }
4229
6030
  });
4230
6031
  Object.defineProperty(exports, "unwrap", {
4231
6032
  enumerable: true,
4232
- get: function () { return chunkQYWINYEA_cjs.unwrap; }
6033
+ get: function () { return chunk7BQXPCGN_cjs.unwrap; }
4233
6034
  });
4234
6035
  exports.BaseVersionMismatchError = BaseVersionMismatchError;
4235
6036
  exports.BranchError = BranchError;
6037
+ exports.IdentityMergeConflictError = IdentityMergeConflictError;
6038
+ exports.InvalidMergeOptionsError = InvalidMergeOptionsError;
4236
6039
  exports.MERGE_ERROR_CODES = MERGE_ERROR_CODES;
4237
6040
  exports.MERGE_OPTION_DEFAULTS = MERGE_OPTION_DEFAULTS;
4238
6041
  exports.MergeConflictError = MergeConflictError;
4239
6042
  exports.MergeError = MergeError;
4240
6043
  exports.SimilarityUnavailableError = SimilarityUnavailableError;
6044
+ exports.VALIDITY_END_TARGET_PRECEDENCE = VALIDITY_END_TARGET_PRECEDENCE;
4241
6045
  exports.asBaseVersion = asBaseVersion;
4242
6046
  exports.asBranchId = asBranchId;
4243
6047
  exports.branch = branch;