@nicia-ai/typegraph 0.37.0 → 0.38.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.
- package/README.md +12 -10
- package/dist/backend/drizzle/indexes.cjs +32 -0
- package/dist/backend/drizzle/indexes.cjs.map +1 -0
- package/dist/backend/drizzle/indexes.d.cts +43 -0
- package/dist/backend/drizzle/indexes.d.ts +43 -0
- package/dist/backend/drizzle/indexes.js +11 -0
- package/dist/backend/drizzle/indexes.js.map +1 -0
- package/dist/backend/index.cjs +161 -0
- package/dist/backend/index.cjs.map +1 -0
- package/dist/backend/index.d.cts +3 -0
- package/dist/backend/index.d.ts +3 -0
- package/dist/backend/index.js +8 -0
- package/dist/backend/index.js.map +1 -0
- package/dist/backend/postgres/index.cjs +32 -28
- package/dist/backend/postgres/index.d.cts +13 -12
- package/dist/backend/postgres/index.d.ts +13 -12
- package/dist/backend/postgres/index.js +19 -15
- package/dist/backend/postgres/pglite-store.cjs +67 -0
- package/dist/backend/postgres/pglite-store.cjs.map +1 -0
- package/dist/backend/postgres/pglite-store.d.cts +38 -0
- package/dist/backend/postgres/pglite-store.d.ts +38 -0
- package/dist/backend/postgres/pglite-store.js +65 -0
- package/dist/backend/postgres/pglite-store.js.map +1 -0
- package/dist/backend/postgres/pglite.cjs +25 -50
- package/dist/backend/postgres/pglite.cjs.map +1 -1
- package/dist/backend/postgres/pglite.d.cts +10 -9
- package/dist/backend/postgres/pglite.d.ts +10 -9
- package/dist/backend/postgres/pglite.js +20 -52
- package/dist/backend/postgres/pglite.js.map +1 -1
- package/dist/backend/sqlite/index.cjs +29 -25
- package/dist/backend/sqlite/index.d.cts +11 -11
- package/dist/backend/sqlite/index.d.ts +11 -11
- package/dist/backend/sqlite/index.js +17 -13
- package/dist/backend/sqlite/libsql.cjs +23 -19
- package/dist/backend/sqlite/libsql.cjs.map +1 -1
- package/dist/backend/sqlite/libsql.d.cts +9 -10
- package/dist/backend/sqlite/libsql.d.ts +9 -10
- package/dist/backend/sqlite/libsql.js +19 -15
- package/dist/backend/sqlite/libsql.js.map +1 -1
- package/dist/backend/sqlite/local-store.cjs +72 -0
- package/dist/backend/sqlite/local-store.cjs.map +1 -0
- package/dist/backend/sqlite/local-store.d.cts +42 -0
- package/dist/backend/sqlite/local-store.d.ts +42 -0
- package/dist/backend/sqlite/local-store.js +67 -0
- package/dist/backend/sqlite/local-store.js.map +1 -0
- package/dist/backend/sqlite/local.cjs +28 -183
- package/dist/backend/sqlite/local.cjs.map +1 -1
- package/dist/backend/sqlite/local.d.cts +8 -81
- package/dist/backend/sqlite/local.d.ts +8 -81
- package/dist/backend/sqlite/local.js +20 -180
- package/dist/backend/sqlite/local.js.map +1 -1
- package/dist/chunk-2EBMPJBO.js +16 -0
- package/dist/chunk-2EBMPJBO.js.map +1 -0
- package/dist/{chunk-NBP2WTJW.cjs → chunk-2SL7OGPR.cjs} +2900 -1597
- package/dist/chunk-2SL7OGPR.cjs.map +1 -0
- package/dist/chunk-35S6P5ZU.js +27 -0
- package/dist/chunk-35S6P5ZU.js.map +1 -0
- package/dist/chunk-3LKL3S6X.js +50 -0
- package/dist/chunk-3LKL3S6X.js.map +1 -0
- package/dist/chunk-6G5CQ6JX.js +47 -0
- package/dist/chunk-6G5CQ6JX.js.map +1 -0
- package/dist/chunk-6XDBRDZE.js +312 -0
- package/dist/chunk-6XDBRDZE.js.map +1 -0
- package/dist/chunk-764JHTLT.cjs +15 -0
- package/dist/chunk-764JHTLT.cjs.map +1 -0
- package/dist/chunk-76HE7DJP.js +68 -0
- package/dist/chunk-76HE7DJP.js.map +1 -0
- package/dist/{chunk-VGDDG3XJ.cjs → chunk-7M3NACL3.cjs} +12 -12
- package/dist/{chunk-VGDDG3XJ.cjs.map → chunk-7M3NACL3.cjs.map} +1 -1
- package/dist/{chunk-NXQFATMF.cjs → chunk-7VLCN3JB.cjs} +153 -123
- package/dist/chunk-7VLCN3JB.cjs.map +1 -0
- package/dist/{chunk-552KNYQJ.js → chunk-A2FGSWMQ.js} +1907 -607
- package/dist/chunk-A2FGSWMQ.js.map +1 -0
- package/dist/chunk-AOL64O4Z.js +165 -0
- package/dist/chunk-AOL64O4Z.js.map +1 -0
- package/dist/{chunk-27SSDCEP.cjs → chunk-B63IFHXR.cjs} +53 -74
- package/dist/chunk-B63IFHXR.cjs.map +1 -0
- package/dist/{chunk-3XXGYU62.cjs → chunk-BKAKAVRW.cjs} +56 -53
- package/dist/chunk-BKAKAVRW.cjs.map +1 -0
- package/dist/{chunk-YTSN73ND.js → chunk-BQITNFQJ.js} +3 -3
- package/dist/{chunk-YTSN73ND.js.map → chunk-BQITNFQJ.js.map} +1 -1
- package/dist/{chunk-NUIG3BCV.cjs → chunk-CQC6VBAF.cjs} +93 -155
- package/dist/chunk-CQC6VBAF.cjs.map +1 -0
- package/dist/{chunk-6EEO3OVU.cjs → chunk-CWX77JB4.cjs} +22 -59
- package/dist/chunk-CWX77JB4.cjs.map +1 -0
- package/dist/{chunk-UGZUAYAR.js → chunk-D7PG5D5K.js} +4 -3
- package/dist/chunk-D7PG5D5K.js.map +1 -0
- package/dist/chunk-DDCIXXOO.js +9 -0
- package/dist/chunk-DDCIXXOO.js.map +1 -0
- package/dist/chunk-DDCYVIVV.cjs +44 -0
- package/dist/chunk-DDCYVIVV.cjs.map +1 -0
- package/dist/{chunk-XPCZADMT.cjs → chunk-DOVMTPKE.cjs} +89 -27
- package/dist/chunk-DOVMTPKE.cjs.map +1 -0
- package/dist/{chunk-5PNMDJ7J.js → chunk-DPNA466P.js} +14 -9
- package/dist/chunk-DPNA466P.js.map +1 -0
- package/dist/{chunk-BYPOGQWK.js → chunk-DRACN6XG.js} +6 -4
- package/dist/chunk-DRACN6XG.js.map +1 -0
- package/dist/chunk-E6TXEISH.cjs +175 -0
- package/dist/chunk-E6TXEISH.cjs.map +1 -0
- package/dist/{chunk-TKT2XHED.js → chunk-E6YZRKMM.js} +13 -12
- package/dist/chunk-E6YZRKMM.js.map +1 -0
- package/dist/{chunk-3C2RYI6L.cjs → chunk-EOJFGECD.cjs} +11 -11
- package/dist/chunk-EOJFGECD.cjs.map +1 -0
- package/dist/{chunk-XWV4JT34.js → chunk-ERZ4QPQX.js} +27 -22
- package/dist/chunk-ERZ4QPQX.js.map +1 -0
- package/dist/{chunk-DFVLCOP6.js → chunk-EZH7FNUS.js} +3 -3
- package/dist/{chunk-DFVLCOP6.js.map → chunk-EZH7FNUS.js.map} +1 -1
- package/dist/{chunk-WWFHO375.cjs → chunk-FJMPR3OH.cjs} +4 -3
- package/dist/chunk-FJMPR3OH.cjs.map +1 -0
- package/dist/chunk-FMNUSGZ4.cjs +12 -0
- package/dist/chunk-FMNUSGZ4.cjs.map +1 -0
- package/dist/{chunk-K3Q3LJY3.js → chunk-G32AO634.js} +201 -100
- package/dist/chunk-G32AO634.js.map +1 -0
- package/dist/{chunk-EXU3RASM.js → chunk-G3CSQLLT.js} +20 -474
- package/dist/chunk-G3CSQLLT.js.map +1 -0
- package/dist/chunk-GNPGGLAE.cjs +212 -0
- package/dist/chunk-GNPGGLAE.cjs.map +1 -0
- package/dist/{chunk-QARBLBXT.cjs → chunk-GUUWKPTK.cjs} +7 -7
- package/dist/{chunk-QARBLBXT.cjs.map → chunk-GUUWKPTK.cjs.map} +1 -1
- package/dist/chunk-GYA4JRP5.js +31 -0
- package/dist/chunk-GYA4JRP5.js.map +1 -0
- package/dist/chunk-I6FX7AAG.js +39 -0
- package/dist/chunk-I6FX7AAG.js.map +1 -0
- package/dist/chunk-IMQKXL4E.cjs +12 -0
- package/dist/{chunk-QSXTWU4U.cjs.map → chunk-IMQKXL4E.cjs.map} +1 -1
- package/dist/chunk-J6IJARLG.js +94 -0
- package/dist/chunk-J6IJARLG.js.map +1 -0
- package/dist/{chunk-W63OVYY4.js → chunk-K34OPSJK.js} +3 -3
- package/dist/{chunk-W63OVYY4.js.map → chunk-K34OPSJK.js.map} +1 -1
- package/dist/{chunk-TGOMW4MB.cjs → chunk-KCLZHYPU.cjs} +110 -109
- package/dist/chunk-KCLZHYPU.cjs.map +1 -0
- package/dist/{chunk-XGPUQ56G.js → chunk-KFLXWVUJ.js} +4 -38
- package/dist/chunk-KFLXWVUJ.js.map +1 -0
- package/dist/{chunk-3DS7Z4T4.cjs → chunk-LZ3TVJY4.cjs} +44 -43
- package/dist/chunk-LZ3TVJY4.cjs.map +1 -0
- package/dist/{chunk-UXLSNRYL.js → chunk-MTNEGGM2.js} +4 -4
- package/dist/chunk-MTNEGGM2.js.map +1 -0
- package/dist/{chunk-IP3CGGPA.cjs → chunk-N2V3HJFV.cjs} +92 -185
- package/dist/chunk-N2V3HJFV.cjs.map +1 -0
- package/dist/chunk-NAUA4PW5.cjs +28 -0
- package/dist/chunk-NAUA4PW5.cjs.map +1 -0
- package/dist/chunk-NMQ6C6TS.cjs +61 -0
- package/dist/chunk-NMQ6C6TS.cjs.map +1 -0
- package/dist/{chunk-2N6EOBTH.cjs → chunk-NPWACFQJ.cjs} +58 -53
- package/dist/chunk-NPWACFQJ.cjs.map +1 -0
- package/dist/{chunk-5KEQ74YU.cjs → chunk-NT6ILURI.cjs} +9 -86
- package/dist/chunk-NT6ILURI.cjs.map +1 -0
- package/dist/chunk-NU23DUSJ.cjs +192 -0
- package/dist/chunk-NU23DUSJ.cjs.map +1 -0
- package/dist/{chunk-WOJMKB3N.cjs → chunk-NWYCOFEZ.cjs} +1677 -308
- package/dist/chunk-NWYCOFEZ.cjs.map +1 -0
- package/dist/{chunk-3GH67G4Z.cjs → chunk-O5H62ZWJ.cjs} +4 -42
- package/dist/chunk-O5H62ZWJ.cjs.map +1 -0
- package/dist/{chunk-3SLPDKHQ.js → chunk-PH4IJ3V5.js} +5 -77
- package/dist/chunk-PH4IJ3V5.js.map +1 -0
- package/dist/chunk-PWXGB77L.cjs +56 -0
- package/dist/chunk-PWXGB77L.cjs.map +1 -0
- package/dist/chunk-PZHC5GCD.js +193 -0
- package/dist/chunk-PZHC5GCD.js.map +1 -0
- package/dist/chunk-QMQLUA66.js +12 -0
- package/dist/chunk-QMQLUA66.js.map +1 -0
- package/dist/{chunk-5WWVZMVX.js → chunk-QZ7A6HBM.js} +2 -2
- package/dist/{chunk-5WWVZMVX.js.map → chunk-QZ7A6HBM.js.map} +1 -1
- package/dist/{chunk-VKGKDOKR.js → chunk-RQPRCEIO.js} +1539 -206
- package/dist/chunk-RQPRCEIO.js.map +1 -0
- package/dist/chunk-RW24SAHI.cjs +74 -0
- package/dist/chunk-RW24SAHI.cjs.map +1 -0
- package/dist/{chunk-BVRDGYXQ.cjs → chunk-SAFZ6JTI.cjs} +14 -9
- package/dist/chunk-SAFZ6JTI.cjs.map +1 -0
- package/dist/{chunk-L7HQ2OSI.js → chunk-SCTZRFW5.js} +87 -166
- package/dist/chunk-SCTZRFW5.js.map +1 -0
- package/dist/{chunk-5KPNWT6X.js → chunk-SDHV2MWU.js} +24 -45
- package/dist/chunk-SDHV2MWU.js.map +1 -0
- package/dist/chunk-SVJ5GEXW.cjs +45 -0
- package/dist/chunk-SVJ5GEXW.cjs.map +1 -0
- package/dist/chunk-SVUKGWSN.cjs +102 -0
- package/dist/chunk-SVUKGWSN.cjs.map +1 -0
- package/dist/chunk-TAUGGLNQ.js +59 -0
- package/dist/chunk-TAUGGLNQ.js.map +1 -0
- package/dist/{chunk-J4IUSYFF.js → chunk-TE5ZA4VX.js} +69 -27
- package/dist/chunk-TE5ZA4VX.js.map +1 -0
- package/dist/{chunk-A42GCBGX.cjs → chunk-TRF4EBJT.cjs} +6 -4
- package/dist/chunk-TRF4EBJT.cjs.map +1 -0
- package/dist/{chunk-KQJ54OG5.js → chunk-U4JDJKPD.js} +19 -56
- package/dist/chunk-U4JDJKPD.js.map +1 -0
- package/dist/chunk-UH2USOMG.cjs +627 -0
- package/dist/chunk-UH2USOMG.cjs.map +1 -0
- package/dist/{chunk-RCVLFTCT.js → chunk-UPXDVI3T.js} +13 -12
- package/dist/chunk-UPXDVI3T.js.map +1 -0
- package/dist/{chunk-5VQM6VWP.cjs → chunk-UWG5GX6E.cjs} +2 -2
- package/dist/{chunk-5VQM6VWP.cjs.map → chunk-UWG5GX6E.cjs.map} +1 -1
- package/dist/{chunk-3RWZPJKV.js → chunk-VBH7ZXSZ.js} +21 -78
- package/dist/chunk-VBH7ZXSZ.js.map +1 -0
- package/dist/{chunk-K5UBVGJN.js → chunk-VDYA2HMS.js} +6 -6
- package/dist/{chunk-K5UBVGJN.js.map → chunk-VDYA2HMS.js.map} +1 -1
- package/dist/chunk-X4PVHAZ6.cjs +83 -0
- package/dist/chunk-X4PVHAZ6.cjs.map +1 -0
- package/dist/{chunk-UYQMBBWJ.js → chunk-X6CNEA32.js} +23 -20
- package/dist/chunk-X6CNEA32.js.map +1 -0
- package/dist/chunk-X6RDQ5NB.cjs +335 -0
- package/dist/chunk-X6RDQ5NB.cjs.map +1 -0
- package/dist/chunk-XD6X7O5R.js +184 -0
- package/dist/chunk-XD6X7O5R.js.map +1 -0
- package/dist/{chunk-DIQ3AV5W.cjs → chunk-XFY73JWD.cjs} +324 -224
- package/dist/chunk-XFY73JWD.cjs.map +1 -0
- package/dist/{chunk-DEFQM7JU.cjs → chunk-XRU7V7FF.cjs} +7 -7
- package/dist/{chunk-DEFQM7JU.cjs.map → chunk-XRU7V7FF.cjs.map} +1 -1
- package/dist/{chunk-TPF25IG6.js → chunk-XZA3Y4YH.js} +3 -3
- package/dist/{chunk-TPF25IG6.js.map → chunk-XZA3Y4YH.js.map} +1 -1
- package/dist/chunk-Y7M44XEK.js +462 -0
- package/dist/chunk-Y7M44XEK.js.map +1 -0
- package/dist/{chunk-RRSNR3TP.js → chunk-YIRLBUNN.js} +3 -3
- package/dist/{chunk-RRSNR3TP.js.map → chunk-YIRLBUNN.js.map} +1 -1
- package/dist/{chunk-IXGYRP2P.js → chunk-YJDSPA5E.js} +79 -49
- package/dist/chunk-YJDSPA5E.js.map +1 -0
- package/dist/{chunk-JBNOGRKW.cjs → chunk-YLINFV7Z.cjs} +157 -115
- package/dist/chunk-YLINFV7Z.cjs.map +1 -0
- package/dist/{chunk-QERAIDRJ.js → chunk-Z2PPIVOO.js} +82 -22
- package/dist/chunk-Z2PPIVOO.js.map +1 -0
- package/dist/chunk-Z5QHVL5U.cjs +12 -0
- package/dist/chunk-Z5QHVL5U.cjs.map +1 -0
- package/dist/chunk-ZDH3DX3C.cjs +30 -0
- package/dist/chunk-ZDH3DX3C.cjs.map +1 -0
- package/dist/chunk-ZE6NVENI.js +77 -0
- package/dist/chunk-ZE6NVENI.js.map +1 -0
- package/dist/chunk-ZHX4KEM7.cjs +49 -0
- package/dist/chunk-ZHX4KEM7.cjs.map +1 -0
- package/dist/chunk-ZKZAIX42.cjs +479 -0
- package/dist/chunk-ZKZAIX42.cjs.map +1 -0
- package/dist/{chunk-TEDRJXOG.cjs → chunk-ZY4GXIVN.cjs} +5 -5
- package/dist/{chunk-TEDRJXOG.cjs.map → chunk-ZY4GXIVN.cjs.map} +1 -1
- package/dist/core/index.cjs +117 -0
- package/dist/core/index.cjs.map +1 -0
- package/dist/core/index.d.cts +225 -0
- package/dist/core/index.d.ts +225 -0
- package/dist/core/index.js +12 -0
- package/dist/core/index.js.map +1 -0
- package/dist/{ddl-CS0KUVwB.d.ts → ddl-Dx3Z0_WC.d.ts} +3 -3
- package/dist/{ddl-BD-ZfKeX.d.cts → ddl-J6sDyABg.d.cts} +3 -3
- package/dist/define-graph-CzEvA_8F.d.cts +174 -0
- package/dist/define-graph-DRo9xpYN.d.ts +174 -0
- package/dist/{extension-types-BM2ACfYO.d.cts → extension-types-BLEVH4SG.d.cts} +1 -1
- package/dist/{extension-types-BM2ACfYO.d.ts → extension-types-BLEVH4SG.d.ts} +1 -1
- package/dist/graph-extension/index.cjs +21 -19
- package/dist/graph-extension/index.d.cts +4 -4
- package/dist/graph-extension/index.d.ts +4 -4
- package/dist/graph-extension/index.js +6 -4
- package/dist/graph-merge/index.cjs +265 -214
- package/dist/graph-merge/index.cjs.map +1 -1
- package/dist/graph-merge/index.d.cts +8 -89
- package/dist/graph-merge/index.d.ts +8 -89
- package/dist/graph-merge/index.js +141 -90
- package/dist/graph-merge/index.js.map +1 -1
- package/dist/{index-BeacbPoe.d.ts → index-BD_3TCgh.d.ts} +6 -4
- package/dist/{index-BPM59vsg.d.cts → index-BihFPsPu.d.cts} +6 -4
- package/dist/{fulltext-strategy-C27vXaeB.d.cts → index-Bq7vSPHy.d.ts} +3195 -2646
- package/dist/{fulltext-strategy-DebsMrqg.d.ts → index-CrFL_ENI.d.cts} +3195 -2646
- package/dist/index.cjs +326 -315
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +59 -240
- package/dist/index.d.ts +59 -240
- package/dist/index.js +46 -79
- package/dist/index.js.map +1 -1
- package/dist/indexes/index.cjs +26 -38
- package/dist/indexes/index.d.cts +6 -41
- package/dist/indexes/index.d.ts +6 -41
- package/dist/indexes/index.js +14 -10
- package/dist/interchange/index.cjs +48 -39
- package/dist/interchange/index.cjs.map +1 -1
- package/dist/interchange/index.d.cts +7 -8
- package/dist/interchange/index.d.ts +7 -8
- package/dist/interchange/index.js +23 -14
- package/dist/interchange/index.js.map +1 -1
- package/dist/local-options-CZ1BnIoF.d.cts +29 -0
- package/dist/local-options-CZ1BnIoF.d.ts +29 -0
- package/dist/{manager-D00_NXvT.d.ts → manager-CASfhmzV.d.ts} +4 -173
- package/dist/{manager-nU1vTJLy.d.cts → manager-nCEJiYBb.d.cts} +4 -173
- package/dist/{materialize-indexes-zK2J_flP.d.ts → materialize-indexes-D4iei4Kp.d.ts} +1 -1
- package/dist/{materialize-indexes-CuR3gAZb.d.cts → materialize-indexes-ExQ6OrAh.d.cts} +1 -1
- package/dist/{postgres-IaBA4RgE.d.ts → postgres-Cl1ZAN1G.d.ts} +1 -1
- package/dist/{postgres-YrYmPlaU.d.cts → postgres-DMgIKQU-.d.cts} +1 -1
- package/dist/postgres-execution-fKW0qRiN.d.cts +14 -0
- package/dist/postgres-execution-fKW0qRiN.d.ts +14 -0
- package/dist/profiler/index.cjs +9 -8
- package/dist/profiler/index.cjs.map +1 -1
- package/dist/profiler/index.d.cts +9 -17
- package/dist/profiler/index.d.ts +9 -17
- package/dist/profiler/index.js +8 -7
- package/dist/profiler/index.js.map +1 -1
- package/dist/provenance/index.cjs +61 -55
- package/dist/provenance/index.cjs.map +1 -1
- package/dist/provenance/index.d.cts +7 -8
- package/dist/provenance/index.d.ts +7 -8
- package/dist/provenance/index.js +34 -28
- package/dist/provenance/index.js.map +1 -1
- package/dist/schema/index.cjs +46 -37
- package/dist/schema/index.cjs.map +1 -1
- package/dist/schema/index.d.cts +8 -10
- package/dist/schema/index.d.ts +8 -10
- package/dist/schema/index.js +22 -13
- package/dist/schema/index.js.map +1 -1
- package/dist/{sqlite-BUOHPx7p.d.ts → sqlite-BDkW39aa.d.cts} +1 -1
- package/dist/{sqlite-Pp8O19WE.d.cts → sqlite-CYfhvESj.d.ts} +1 -1
- package/dist/sqlite-execution-DwbE2a9y.d.cts +32 -0
- package/dist/sqlite-execution-DwbE2a9y.d.ts +32 -0
- package/dist/{store-view-X96Rd00T.d.cts → store-view-BoHqdHjB.d.cts} +394 -1393
- package/dist/{store-view-ANL6mTph.d.ts → store-view-Ctq-3OHy.d.ts} +394 -1393
- package/dist/temporal-BC_NQV5Y.d.cts +281 -0
- package/dist/temporal-DqtOEo_B.d.ts +281 -0
- package/dist/{types-r-Zyq2Hz.d.cts → types-COq3-vMC.d.cts} +2 -2
- package/dist/{types-wsvuBgPK.d.ts → types-CUevi_D1.d.ts} +2 -2
- package/dist/{where-CJOpJj3a.d.ts → where-BdE_cYtx.d.ts} +5 -5
- package/dist/{where-K3uBP33l.d.cts → where-C92TXCzT.d.cts} +5 -5
- package/package.json +37 -6
- package/dist/chunk-27SSDCEP.cjs.map +0 -1
- package/dist/chunk-2N6EOBTH.cjs.map +0 -1
- package/dist/chunk-3C2RYI6L.cjs.map +0 -1
- package/dist/chunk-3DS7Z4T4.cjs.map +0 -1
- package/dist/chunk-3GH67G4Z.cjs.map +0 -1
- package/dist/chunk-3RWZPJKV.js.map +0 -1
- package/dist/chunk-3SLPDKHQ.js.map +0 -1
- package/dist/chunk-3XXGYU62.cjs.map +0 -1
- package/dist/chunk-44TA22QT.js +0 -1478
- package/dist/chunk-44TA22QT.js.map +0 -1
- package/dist/chunk-552KNYQJ.js.map +0 -1
- package/dist/chunk-5KEQ74YU.cjs.map +0 -1
- package/dist/chunk-5KPNWT6X.js.map +0 -1
- package/dist/chunk-5PNMDJ7J.js.map +0 -1
- package/dist/chunk-6EEO3OVU.cjs.map +0 -1
- package/dist/chunk-7YSP4V4R.cjs +0 -69
- package/dist/chunk-7YSP4V4R.cjs.map +0 -1
- package/dist/chunk-A42GCBGX.cjs.map +0 -1
- package/dist/chunk-BVRDGYXQ.cjs.map +0 -1
- package/dist/chunk-BYPOGQWK.js.map +0 -1
- package/dist/chunk-CUHM5CWJ.cjs +0 -12
- package/dist/chunk-CUHM5CWJ.cjs.map +0 -1
- package/dist/chunk-DIQ3AV5W.cjs.map +0 -1
- package/dist/chunk-EXU3RASM.js.map +0 -1
- package/dist/chunk-IP3CGGPA.cjs.map +0 -1
- package/dist/chunk-IPSVVTWT.cjs +0 -1540
- package/dist/chunk-IPSVVTWT.cjs.map +0 -1
- package/dist/chunk-IXGYRP2P.js.map +0 -1
- package/dist/chunk-J4IUSYFF.js.map +0 -1
- package/dist/chunk-JBNOGRKW.cjs.map +0 -1
- package/dist/chunk-K3Q3LJY3.js.map +0 -1
- package/dist/chunk-KQJ54OG5.js.map +0 -1
- package/dist/chunk-L7HQ2OSI.js.map +0 -1
- package/dist/chunk-M6VES7V6.js +0 -239
- package/dist/chunk-M6VES7V6.js.map +0 -1
- package/dist/chunk-NBP2WTJW.cjs.map +0 -1
- package/dist/chunk-NUIG3BCV.cjs.map +0 -1
- package/dist/chunk-NXQFATMF.cjs.map +0 -1
- package/dist/chunk-OHMP6N2J.js +0 -47
- package/dist/chunk-OHMP6N2J.js.map +0 -1
- package/dist/chunk-QERAIDRJ.js.map +0 -1
- package/dist/chunk-QSXTWU4U.cjs +0 -12
- package/dist/chunk-RCVLFTCT.js.map +0 -1
- package/dist/chunk-TGOMW4MB.cjs.map +0 -1
- package/dist/chunk-TKT2XHED.js.map +0 -1
- package/dist/chunk-UGZUAYAR.js.map +0 -1
- package/dist/chunk-UXLSNRYL.js.map +0 -1
- package/dist/chunk-UYQMBBWJ.js.map +0 -1
- package/dist/chunk-VKGKDOKR.js.map +0 -1
- package/dist/chunk-VL2V6PEN.cjs +0 -261
- package/dist/chunk-VL2V6PEN.cjs.map +0 -1
- package/dist/chunk-WOJMKB3N.cjs.map +0 -1
- package/dist/chunk-WWFHO375.cjs.map +0 -1
- package/dist/chunk-XGPUQ56G.js.map +0 -1
- package/dist/chunk-XGU7DZDA.cjs +0 -1095
- package/dist/chunk-XGU7DZDA.cjs.map +0 -1
- package/dist/chunk-XPCZADMT.cjs.map +0 -1
- package/dist/chunk-XWV4JT34.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/graph-merge/canonical-props.ts","../../src/graph-merge/node-key.ts","../../src/graph-merge/state-diff.ts","../../src/graph-merge/types.ts","../../src/graph-merge/base-version.ts","../../src/graph-merge/errors.ts","../../src/graph-merge/working-copy.ts","../../src/graph-merge/branch.ts","../../src/graph-merge/blocking.ts","../../src/graph-merge/conflict-policy.ts","../../src/graph-merge/canonicalize.ts","../../src/graph-merge/union-find.ts","../../src/graph-merge/closures.ts","../../src/graph-merge/similarity.ts","../../src/graph-merge/scoring.ts","../../src/graph-merge/clustering.ts","../../src/graph-merge/delete-modify.ts","../../src/graph-merge/edge-repoint.ts","../../src/graph-merge/options.ts","../../src/graph-merge/provenance-store.ts","../../src/graph-merge/sources.ts","../../src/graph-merge/staging.ts","../../src/graph-merge/tx-retry.ts","../../src/graph-merge/type-reconcile.ts","../../src/graph-merge/merge.ts"],"names":["sortedReplacer","compareStrings","getNodeKinds","getEdgeKinds","computeSchemaHash","serializeSchema","sha256Hex","schemaComponent","TypeGraphError","createStoreWithSchema","importGraphStream","exportGraphStream","generateId","ok","err","computeUniqueKey","dedupeKey","value","computeTransitiveClosure","isReachable","isErr","byId","z","defineNode","defineGraph","branch","repoint","lockRecordedGraphWrite","readRevisionOrigin","readRecordedClock","nodeProps"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * The single canonical property serializer for the merge primitive.\n *\n * Hoisted to T2 (rather than living next to the clustering code) because three\n * separate phases must agree byte-for-byte on the serialized form of a property\n * bag:\n *\n * - state-diff (T3) — to detect whether an inherited node's props changed,\n * - clustering / property union (T8) — to compare member values,\n * - edge repoint + dedupe (T9) — to key the `(from|type|to|propsKey)` tuple.\n *\n * {@link canonicalValueKey} is the SINGLE-VALUE sibling: the same recursive\n * key-sort over an arbitrary {@link JsonValue} (scalar / array / object), so the\n * conflict-resolution layer (T8 / `conflict-policy.ts`) decides value equality and\n * tie-breaks on the canonical form too — two branches that wrote a logically-equal\n * nested object with different key order must NOT register as a conflict.\n *\n * Determinism rules:\n * - Object keys are sorted lexicographically at every nesting level, so two\n * objects that differ only by key insertion order serialize identically.\n * - Arrays preserve order (order is semantically meaningful in a list).\n * - `undefined` keys are dropped (JSON has no `undefined`; an absent key and a\n * key set to `undefined` are treated as the same absence).\n * - All other JSON-representable values serialize via their natural form.\n *\n * IMPORTANT contract for callers: the input MUST be a PARSED plain object, never\n * a JSON string. Backend rows store `props` as a JSON string; callers MUST\n * `JSON.parse` first. Passing a string would serialize the string literal (with\n * its own incidental key order) rather than the canonical structure, so the\n * `propsKey` would NOT be stable across staged-vs-committed representations.\n */\n\nimport type { JsonValue } from \"./typegraph-internal\";\nimport { sortedReplacer } from \"./typegraph-internal\";\n\n/**\n * Produces a deterministic, recursively key-sorted JSON serialization of a\n * parsed property object.\n *\n * Delegates to the schema layer's {@link sortedReplacer} — the single canonical\n * JSON serializer in the codebase (also used by `computeSchemaHash` /\n * `computeSchemaDiff`) — so the merge primitive and the schema layer can never\n * drift on what \"canonical form\" means. The replacer sorts object keys at every\n * depth while preserving array order; `JSON.stringify` omits `undefined`-valued\n * keys, matching the \"an absent key and a key set to `undefined` are the same\n * absence\" rule in the module docs.\n *\n * @param props A PARSED plain object (NOT a JSON string). See module docs.\n * @returns A canonical JSON string suitable for equality comparison / dedupe\n * keying. Equivalent objects (key order aside) yield identical strings;\n * objects differing in any value yield differing strings.\n */\nexport function canonicalizeProps(\n props: Readonly<Record<string, unknown>>,\n): string {\n return JSON.stringify(props, sortedReplacer);\n}\n\n/**\n * Produces a deterministic, recursively key-sorted JSON serialization of a single\n * {@link JsonValue} — the per-value analogue of {@link canonicalizeProps}.\n *\n * Used by the conflict layer to compare candidate values, dedupe them, and\n * tie-break, so a nested object's incidental key order can never make two\n * logically-equal values look different (which would surface a spurious conflict).\n *\n * @param value Any parsed JSON value (scalar, array, or object). Not a JSON string.\n * @returns A canonical JSON string suitable for equality / dedupe / ordering.\n */\nexport function canonicalValueKey(value: JsonValue): string {\n return JSON.stringify(value, sortedReplacer);\n}\n\n/**\n * A stable fingerprint of a committed edge's mergeable state — its endpoints,\n * liveness, and canonical props. The incremental lost-update guard captures this\n * for every target edge at plan time and re-derives it inside the commit\n * transaction; a mismatch means the committed edge drifted in the plan→commit\n * window, so applying the plan (built from the plan-time value) would silently\n * overwrite that change. Edges carry no `version` column, so this content\n * fingerprint is the node-`version` analogue for the edge half of the guard.\n *\n * @param edge Endpoints, liveness, and PARSED props (never a JSON string).\n * @returns A canonical string; equal iff the two edge states are mergeably equal.\n */\nexport function edgeStateSignature(\n edge: Readonly<{\n fromKind: string;\n fromId: string;\n toKind: string;\n toId: string;\n live: boolean;\n props: Readonly<Record<string, unknown>>;\n }>,\n): string {\n return JSON.stringify([\n edge.fromKind,\n edge.fromId,\n edge.toKind,\n edge.toId,\n edge.live,\n canonicalizeProps(edge.props),\n ]);\n}\n\n/**\n * Normalizes a stored row's `props` — a JSON string on SQLite, an\n * already-parsed object on Postgres (jsonb rows arrive driver-parsed) — into\n * the plain object that {@link canonicalizeProps} requires. Malformed JSON, a\n * non-object, or an array all collapse to `{}` — a parse error never escapes.\n * Backend-written rows hold valid JSON, but an external / legacy / truncated\n * `props` value must not crash a state diff or a base-version fingerprint.\n * Centralized so the diff and the fingerprint can never disagree on what a\n * malformed row parses to.\n */\nexport function parseRowProps(\n props: string | Readonly<Record<string, unknown>>,\n): Readonly<Record<string, unknown>> {\n let parsed: unknown;\n if (typeof props === \"string\") {\n try {\n parsed = JSON.parse(props);\n } catch {\n return {};\n }\n } else {\n parsed = props;\n }\n if (parsed === null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n return {};\n }\n return parsed as Record<string, unknown>;\n}\n","/**\n * The composite MERGE IDENTITY key for a node: the pair `(kind, id)`.\n *\n * TypeGraph node identity is the PAIR `(kind, id)` — a bare id string is NOT unique\n * on its own (a `Patient` and an `Encounter` may both carry the id \"x\" as two\n * DISTINCT committed nodes; ids are caller-supplied). Every place the merge pipeline\n * groups, clusters, de-dupes, repoints, retypes, or deletes BY NODE IDENTITY must\n * key on this pair — never the bare id — or two different-kind nodes that happen to\n * share an id string silently fuse into one cluster (wrong merge, dropped node,\n * incoherent commit) and the §6.4-A base guard is bypassed.\n *\n * Represented as a NUL-joined string (a branded {@link MergeKey}) so it doubles as a\n * `Map`/`Set` key and a deterministic ordering key. `kind` is a schema identifier\n * (NUL-free), so the FIRST NUL unambiguously delimits kind from id even when a\n * caller-supplied id itself contains a NUL byte. This matches the `(kind, id)`\n * separator the commit-time write guard already uses.\n *\n * {@link compareMergeKeys} orders by the bare id FIRST (kind only breaks a same-id\n * tie), so the merge's \"minimum-id survivor\" / id-sorted-members semantics are\n * preserved unchanged for the common single-kind cluster — the composite key changes\n * WHICH nodes share an identity, never the ordering among genuinely distinct ids.\n */\n\nimport type { NodeId, NodeType } from \"./typegraph-internal\";\n\n/** The `(kind, id)` separator: a NUL byte (0x00), absent from schema kind names. */\nconst SEPARATOR = String.fromCharCode(0);\n\n/** A node id in its untyped (`NodeType`-default) branded form. */\ntype AnyNodeId = NodeId<NodeType>;\n\n/**\n * A composite `(kind, id)` node-identity key. Branded so it cannot be confused with\n * a bare {@link NodeId} at the type level — the whole point is that the two are NOT\n * interchangeable as identities.\n */\nexport type MergeKey = string & { readonly __mergeKey: unique symbol };\n\n/** Builds the composite identity key for a `(kind, id)` pair. */\nexport function mergeKey(kind: string, id: string): MergeKey {\n // `kindOf`/`idOf` split on the FIRST NUL, so a NUL in `kind` would alias distinct\n // identities (`mergeKey(\"a\\0b\",\"c\") === mergeKey(\"a\",\"b\\0c\")`), silently fusing\n // unrelated nodes into one cluster and bypassing the §6.4-A base guard this composite\n // key exists to protect. Kinds are NUL-free schema identifiers; fail loud if not.\n if (kind.includes(SEPARATOR)) {\n throw new Error(\n `Node kind ${JSON.stringify(kind)} contains a NUL byte, which collides the (kind, id) merge-identity separator.`,\n );\n }\n return `${kind}${SEPARATOR}${id}` as MergeKey;\n}\n\n/** Builds the composite identity key for any object carrying a `kind` and `id`. */\nexport function mergeKeyOf(\n node: Readonly<{ kind: string; id: string }>,\n): MergeKey {\n return mergeKey(node.kind, node.id);\n}\n\n/** The kind component of a {@link MergeKey}. */\nexport function kindOf(key: MergeKey): string {\n const separator = key.indexOf(SEPARATOR);\n return separator === -1 ? key : key.slice(0, separator);\n}\n\n/** The bare node id component of a {@link MergeKey}. */\nexport function idOf(key: MergeKey): AnyNodeId {\n const separator = key.indexOf(SEPARATOR);\n return (separator === -1 ? key : key.slice(separator + 1)) as AnyNodeId;\n}\n\n/**\n * Deterministic comparator over two merge keys, BARE ID first and kind only as a\n * same-id tie-break. This keeps the merge's minimum-id survivor selection and\n * id-sorted member order identical to the pre-composite behaviour for any pair of\n * genuinely distinct ids (the overwhelmingly common case), so the re-key changes\n * identity grouping without perturbing deterministic ordering.\n */\nexport function compareMergeKeys(left: MergeKey, right: MergeKey): number {\n const leftId = idOf(left);\n const rightId = idOf(right);\n if (leftId !== rightId) {\n return leftId < rightId ? -1 : 1;\n }\n const leftKind = kindOf(left);\n const rightKind = kindOf(right);\n return (\n leftKind < rightKind ? -1\n : leftKind > rightKind ? 1\n : 0\n );\n}\n\nexport { compareStrings } from \"../utils/compare\";\n","/**\n * State-diff engine: compute the per-fork delta (new / modified / deleted nodes\n * and edges) of a working copy against the IMMUTABLE original base store.\n *\n * Why backend-level enumeration (not `Store.find()`): the collection API\n * silently hides soft-deleted rows, so a node deleted in a fork would be\n * invisible and the diff could never report a deletion. We therefore go through\n * the backend with `excludeDeleted: false` and read the raw `NodeRow`/`EdgeRow`.\n *\n * Row representation contract (verified against `NodeRow`/`EdgeRow`):\n * - `props` is a JSON string (SQLite) or a driver-parsed object (Postgres\n * jsonb) — every comparison routes it through `parseRowProps` before\n * `canonicalizeProps`, never feeding a raw string to the serializer (that\n * would key on incidental string-literal order, not canonical structure).\n * - `deleted_at` is a field, `undefined` for live rows. Liveness is\n * `row.deleted_at === undefined`.\n *\n * Enumeration ordering: both nodes AND edges use KEYSET pagination\n * (`orderBy: \"id\"` + `after` cursor) over the unique `id`, a TOTAL order, so\n * paging can neither skip nor duplicate a row even when many rows share a\n * `created_at`. (Edges previously had only offset paging over the non-unique\n * `created_at`, which could skip a boundary row under a reordering query plan.)\n *\n * Concurrency: P0 assumes quiesced (non-concurrent) forks per design §10.\n * Concurrent-write enumeration is a P1 concern.\n */\n\nimport {\n canonicalizeProps,\n edgeStateSignature,\n parseRowProps,\n} from \"./canonical-props\";\nimport { compareStrings, type MergeKey, mergeKey } from \"./node-key\";\nimport type {\n EdgeId,\n GraphBackend,\n GraphDef,\n NodeId,\n NodeType,\n Store,\n TransactionBackend,\n} from \"./typegraph-internal\";\nimport { getEdgeKinds, getNodeKinds } from \"./typegraph-internal\";\n\n/**\n * Local structural mirror of TypeGraph's internal `NodeRow`. 0.29.0 does NOT\n * re-export `NodeRow`/`EdgeRow` from any public entrypoint, but `GraphBackend`\n * (public) returns rows of exactly this shape from `findNodesByKind`, so the\n * runtime values are structurally assignable. Keep this local mirror until using\n * the backend row type directly buys enough clarity to justify the coupling.\n */\nexport type NodeRow = Readonly<{\n graph_id: string;\n kind: string;\n id: string;\n props: string | Readonly<Record<string, unknown>>;\n version: number;\n valid_from: string | undefined;\n valid_to: string | undefined;\n created_at: string;\n updated_at: string;\n deleted_at: string | undefined;\n}>;\n\n/** Local structural mirror of TypeGraph's internal `EdgeRow`. See {@link NodeRow}. */\nexport type EdgeRow = Readonly<{\n graph_id: string;\n id: string;\n kind: string;\n from_kind: string;\n from_id: string;\n to_kind: string;\n to_id: string;\n props: string | Readonly<Record<string, unknown>>;\n valid_from: string | undefined;\n valid_to: string | undefined;\n created_at: string;\n updated_at: string;\n deleted_at: string | undefined;\n}>;\n\n/**\n * Page size for keyset/offset enumeration. Large enough to keep round-trips low\n * on demo-scale graphs; the algorithm is correct for any positive value.\n */\nconst ENUMERATION_PAGE_SIZE = 1000;\n\n/**\n * A node that exists in both base and fork but whose canonicalized props differ.\n * Carries the parsed fork props so downstream phases (staging, conflict) avoid\n * re-parsing.\n */\nexport type ModifiedNode = Readonly<{\n id: NodeId<NodeType>;\n kind: string;\n baseProps: Readonly<Record<string, unknown>>;\n forkProps: Readonly<Record<string, unknown>>;\n row: NodeRow;\n}>;\n\n/** A node present and live only on one side of the diff. */\nexport type ChangedNode = Readonly<{\n id: NodeId<NodeType>;\n kind: string;\n props: Readonly<Record<string, unknown>>;\n row: NodeRow;\n}>;\n\n/** Identifier of a node that the fork removed (live in base, gone in fork). */\nexport type DeletedNode = Readonly<{\n id: NodeId<NodeType>;\n kind: string;\n}>;\n\n/** An edge present and live only on one side of the diff. */\nexport type ChangedEdge = Readonly<{\n id: EdgeId;\n kind: string;\n fromId: NodeId<NodeType>;\n toId: NodeId<NodeType>;\n fromKind: string;\n toKind: string;\n props: Readonly<Record<string, unknown>>;\n row: EdgeRow;\n}>;\n\n/** An edge present in both base and fork but whose canonicalized props differ. */\nexport type ModifiedEdge = Readonly<{\n id: EdgeId;\n kind: string;\n fromId: NodeId<NodeType>;\n toId: NodeId<NodeType>;\n fromKind: string;\n toKind: string;\n baseProps: Readonly<Record<string, unknown>>;\n forkProps: Readonly<Record<string, unknown>>;\n row: EdgeRow;\n}>;\n\n/** Identifier of an edge the fork removed (live in base, gone in fork). */\nexport type DeletedEdge = Readonly<{\n id: EdgeId;\n kind: string;\n}>;\n\n/**\n * The complete delta of a fork against the original base store.\n */\nexport type StateDiff = Readonly<{\n nodes: Readonly<{\n new: readonly ChangedNode[];\n modified: readonly ModifiedNode[];\n deleted: readonly DeletedNode[];\n }>;\n edges: Readonly<{\n new: readonly ChangedEdge[];\n modified: readonly ModifiedEdge[];\n deleted: readonly DeletedEdge[];\n }>;\n /**\n * `(kind, id) -> version` for every fork-store node observed during this diff\n * (live and soft-deleted). Captured from the same enumeration the diff reads,\n * so it is the fork's exact observed state — the incremental merge uses the\n * target branch's map as the plan-time baseline for its commit-time\n * lost-update guard (see assertInheritedTargetUnchanged in merge.ts).\n */\n forkNodeVersions: ReadonlyMap<MergeKey, number>;\n /**\n * `(kind, id) -> {@link edgeStateSignature}` for every fork-store edge observed\n * during this diff (live and soft-deleted). The edge-half analogue of\n * {@link forkNodeVersions}: edges carry no `version` column, so the guard\n * fingerprints their mergeable content (endpoints, liveness, canonical props)\n * instead. The incremental merge uses the target branch's map as the plan-time\n * baseline for the commit-time lost-update guard.\n */\n forkEdgeSignatures: ReadonlyMap<MergeKey, string>;\n}>;\n\n/**\n * Enumerates EVERY node of `kind` for `graphId` (live and soft-deleted) via\n * keyset pagination on `id`. Returns rows ascending in the BACKEND's own id\n * ordering — byte order on SQLite/PGlite, the database collation on server\n * Postgres. That order is deterministic and pagination-consistent (the cursor\n * comparison uses the same collation as ORDER BY), but it is NOT guaranteed to\n * equal JS code-unit order for mixed-case ids; consumers needing a canonical\n * cross-backend order sort in JS (as `stateDiff` and the base@V fingerprint\n * do).\n */\nexport async function enumerateAllNodes(\n backend: GraphBackend | TransactionBackend,\n graphId: string,\n kind: string,\n): Promise<readonly NodeRow[]> {\n const collected: NodeRow[] = [];\n let after: string | undefined;\n for (;;) {\n const page: readonly NodeRow[] = await backend.findNodesByKind({\n graphId,\n kind,\n excludeDeleted: false,\n orderBy: \"id\",\n limit: ENUMERATION_PAGE_SIZE,\n ...(after === undefined ? {} : { after }),\n });\n for (const row of page) {\n collected.push(row);\n }\n if (page.length < ENUMERATION_PAGE_SIZE) {\n break;\n }\n after = page.at(-1)!.id;\n }\n return collected;\n}\n\n/**\n * Enumerates EVERY edge of `kind` for `graphId` (live and soft-deleted) via\n * keyset pagination on the unique `id` (a TOTAL order), so paging can neither\n * skip nor duplicate a row regardless of how many edges share a `created_at`.\n * Returns rows ascending in the backend's own id ordering (see\n * {@link enumerateAllNodes} for the collation caveat). Mirrors\n * {@link enumerateAllNodes}.\n */\nexport async function enumerateAllEdges(\n backend: GraphBackend | TransactionBackend,\n graphId: string,\n kind: string,\n): Promise<readonly EdgeRow[]> {\n const collected: EdgeRow[] = [];\n let after: string | undefined;\n for (;;) {\n const page: readonly EdgeRow[] = await backend.findEdgesByKind({\n graphId,\n kind,\n excludeDeleted: false,\n orderBy: \"id\",\n limit: ENUMERATION_PAGE_SIZE,\n ...(after === undefined ? {} : { after }),\n });\n for (const row of page) {\n collected.push(row);\n }\n if (page.length < ENUMERATION_PAGE_SIZE) {\n break;\n }\n after = page.at(-1)!.id;\n }\n return collected;\n}\n\n/** True when the row is live (not soft-deleted). */\nfunction isLive(row: Readonly<{ deleted_at: string | undefined }>): boolean {\n return row.deleted_at === undefined;\n}\n\n/** Indexes rows by id for O(1) base-vs-fork lookup. */\nfunction indexById<T extends Readonly<{ id: string }>>(\n rows: readonly T[],\n): ReadonlyMap<string, T> {\n const index = new Map<string, T>();\n for (const row of rows) {\n index.set(row.id, row);\n }\n return index;\n}\n\n/**\n * Diffs the node sets of one kind. `new` = absent-in-base, live-in-fork;\n * `deleted` = live-in-base, absent-or-soft-deleted-in-fork; `modified` =\n * live in both with differing canonicalized props.\n */\nfunction diffNodeKind(\n kind: string,\n baseRows: readonly NodeRow[],\n forkRows: readonly NodeRow[],\n): Readonly<{\n new: ChangedNode[];\n modified: ModifiedNode[];\n deleted: DeletedNode[];\n}> {\n const baseIndex = indexById(baseRows);\n const forkIndex = indexById(forkRows);\n\n const created: ChangedNode[] = [];\n const modified: ModifiedNode[] = [];\n const deleted: DeletedNode[] = [];\n\n for (const forkRow of forkRows) {\n if (!isLive(forkRow)) {\n continue;\n }\n const baseRow = baseIndex.get(forkRow.id);\n const forkProps = parseRowProps(forkRow.props);\n if (baseRow === undefined || !isLive(baseRow)) {\n created.push({\n id: forkRow.id as NodeId<NodeType>,\n kind,\n props: forkProps,\n row: forkRow,\n });\n continue;\n }\n const baseProps = parseRowProps(baseRow.props);\n if (canonicalizeProps(baseProps) !== canonicalizeProps(forkProps)) {\n modified.push({\n id: forkRow.id as NodeId<NodeType>,\n kind,\n baseProps,\n forkProps,\n row: forkRow,\n });\n }\n }\n\n for (const baseRow of baseRows) {\n if (!isLive(baseRow)) {\n continue;\n }\n const forkRow = forkIndex.get(baseRow.id);\n if (forkRow === undefined || !isLive(forkRow)) {\n deleted.push({ id: baseRow.id as NodeId<NodeType>, kind });\n }\n }\n\n return { new: created, modified, deleted };\n}\n\n/**\n * Diffs the edge sets of one kind. Same liveness/modification rules as nodes,\n * carrying endpoint ids/kinds for the downstream repoint phase.\n */\nfunction diffEdgeKind(\n kind: string,\n baseRows: readonly EdgeRow[],\n forkRows: readonly EdgeRow[],\n): Readonly<{\n new: ChangedEdge[];\n modified: ModifiedEdge[];\n deleted: DeletedEdge[];\n}> {\n const baseIndex = indexById(baseRows);\n const forkIndex = indexById(forkRows);\n\n const created: ChangedEdge[] = [];\n const modified: ModifiedEdge[] = [];\n const deleted: DeletedEdge[] = [];\n\n for (const forkRow of forkRows) {\n if (!isLive(forkRow)) {\n continue;\n }\n const baseRow = baseIndex.get(forkRow.id);\n const forkProps = parseRowProps(forkRow.props);\n if (baseRow === undefined || !isLive(baseRow)) {\n created.push({\n id: forkRow.id as EdgeId,\n kind,\n fromId: forkRow.from_id as NodeId<NodeType>,\n toId: forkRow.to_id as NodeId<NodeType>,\n fromKind: forkRow.from_kind,\n toKind: forkRow.to_kind,\n props: forkProps,\n row: forkRow,\n });\n continue;\n }\n const baseProps = parseRowProps(baseRow.props);\n if (canonicalizeProps(baseProps) !== canonicalizeProps(forkProps)) {\n modified.push({\n id: forkRow.id as EdgeId,\n kind,\n fromId: forkRow.from_id as NodeId<NodeType>,\n toId: forkRow.to_id as NodeId<NodeType>,\n fromKind: forkRow.from_kind,\n toKind: forkRow.to_kind,\n baseProps,\n forkProps,\n row: forkRow,\n });\n }\n }\n\n for (const baseRow of baseRows) {\n if (!isLive(baseRow)) {\n continue;\n }\n const forkRow = forkIndex.get(baseRow.id);\n if (forkRow === undefined || !isLive(forkRow)) {\n deleted.push({ id: baseRow.id as EdgeId, kind });\n }\n }\n\n return { new: created, modified, deleted };\n}\n\n/** Stable id-ascending comparator over any `{ id: string }`. */\nfunction byId<T extends Readonly<{ id: string }>>(left: T, right: T): number {\n return compareStrings(left.id, right.id);\n}\n\n/**\n * Computes the full {@link StateDiff} of `forkStore` against `baseStore`.\n *\n * Both stores MUST share the same graph definition (the fork is a clone of the\n * base). The diff is keyed by id and sorted by `(kind, id)` so its shape is a\n * pure function of the stores' content, independent of enumeration order. No\n * branch tag is attached here — provenance tagging happens in T7 (staging).\n *\n * @param captureForkState Whether to populate {@link StateDiff.forkNodeVersions}\n * / {@link StateDiff.forkEdgeSignatures}. `stageBranches` only ever keeps these\n * maps for the one branch matching `captureTargetStateFor`, and computing the\n * edge signatures (canonicalizing props + stringifying every edge) is real\n * work — so callers that don't need them for this branch can skip it. Defaults\n * to `true` so direct callers (e.g. tests) get the full diff without having to\n * know this parameter exists.\n */\nexport async function diffAgainstBase<G extends GraphDef>(\n baseStore: Store<G>,\n forkStore: Store<G>,\n captureForkState = true,\n): Promise<StateDiff> {\n const graph = baseStore.graph;\n const nodeKinds = getNodeKinds(graph);\n const edgeKinds = getEdgeKinds(graph);\n\n const newNodes: ChangedNode[] = [];\n const modifiedNodes: ModifiedNode[] = [];\n const deletedNodes: DeletedNode[] = [];\n // Version snapshot of the fork store as observed by THIS diff's enumeration\n // (the same read the plan resolves against), keyed by merge identity.\n const forkNodeVersions = new Map<MergeKey, number>();\n\n for (const kind of nodeKinds) {\n const baseRows = await enumerateAllNodes(\n baseStore.backend,\n baseStore.graphId,\n kind,\n );\n const forkRows = await enumerateAllNodes(\n forkStore.backend,\n forkStore.graphId,\n kind,\n );\n if (captureForkState) {\n for (const row of forkRows) {\n forkNodeVersions.set(mergeKey(kind, row.id), row.version);\n }\n }\n const delta = diffNodeKind(kind, baseRows, forkRows);\n for (const entry of delta.new) {\n newNodes.push(entry);\n }\n for (const entry of delta.modified) {\n modifiedNodes.push(entry);\n }\n for (const entry of delta.deleted) {\n deletedNodes.push(entry);\n }\n }\n\n const newEdges: ChangedEdge[] = [];\n const modifiedEdges: ModifiedEdge[] = [];\n const deletedEdges: DeletedEdge[] = [];\n // Content fingerprint of the fork store's edges as observed by THIS diff's\n // enumeration — the edge-half baseline for the commit-time lost-update guard\n // (edges have no version, so we key on mergeable content instead).\n const forkEdgeSignatures = new Map<MergeKey, string>();\n\n for (const kind of edgeKinds) {\n const baseRows = await enumerateAllEdges(\n baseStore.backend,\n baseStore.graphId,\n kind,\n );\n const forkRows = await enumerateAllEdges(\n forkStore.backend,\n forkStore.graphId,\n kind,\n );\n if (captureForkState) {\n for (const row of forkRows) {\n forkEdgeSignatures.set(\n mergeKey(kind, row.id),\n edgeStateSignature({\n fromKind: row.from_kind,\n fromId: row.from_id,\n toKind: row.to_kind,\n toId: row.to_id,\n live: isLive(row),\n props: parseRowProps(row.props),\n }),\n );\n }\n }\n const delta = diffEdgeKind(kind, baseRows, forkRows);\n for (const entry of delta.new) {\n newEdges.push(entry);\n }\n for (const entry of delta.modified) {\n modifiedEdges.push(entry);\n }\n for (const entry of delta.deleted) {\n deletedEdges.push(entry);\n }\n }\n\n return {\n nodes: {\n new: newNodes.sort((left, right) => byId(left, right)),\n modified: modifiedNodes.sort((left, right) => byId(left, right)),\n deleted: deletedNodes.sort((left, right) => byId(left, right)),\n },\n edges: {\n new: newEdges.sort((left, right) => byId(left, right)),\n modified: modifiedEdges.sort((left, right) => byId(left, right)),\n deleted: deletedEdges.sort((left, right) => byId(left, right)),\n },\n forkNodeVersions,\n forkEdgeSignatures,\n };\n}\n","/**\n * Core type model for the graph-merge primitive.\n *\n * Finalized against TypeGraph's real generic machinery: the design's illustrative\n * `Node<G, K>` / `NodeId<NodeKinds<G>>` collapse onto TypeGraph's public\n * `Node` / `Edge` / `NodeId<NodeType>` / `EdgeId` (which are themselves branded\n * over `NodeType` / `EdgeType`). The merge surface is parameterized over\n * `G extends GraphDef` so `Store<G>` and `GraphBranch<G>` thread the caller's\n * concrete graph definition end-to-end.\n *\n * This module is pure type declarations plus the two branding helpers — no\n * runtime merge logic.\n */\n\nimport type {\n EdgeId,\n GetNodeType,\n GraphDef,\n JsonValue,\n Node,\n NodeId,\n NodeKinds,\n NodeType,\n Store,\n} from \"./typegraph-internal\";\n\n/**\n * Opaque identifier for a branch (working copy) of a base store. Branded so a\n * raw string cannot be passed where a deliberately-minted branch id is required.\n */\nexport type BranchId = string & Readonly<{ readonly __brand: \"BranchId\" }>;\n\n/**\n * Opaque token identifying the immutable `base@V` a branch was forked from.\n * Combines a schema hash with a staleness component. Branded so it cannot be\n * confused with an arbitrary string. The second component is a\n * durable revision anchor for stores with revision tracking enabled and a\n * compatibility content fingerprint otherwise.\n */\nexport type BaseVersion = string &\n Readonly<{ readonly __brand: \"BaseVersion\" }>;\n\n/**\n * Mints a {@link BranchId} from a raw string. Centralizes the brand cast so the\n * unsafe assertion lives in exactly one place.\n */\nexport function asBranchId(value: string): BranchId {\n return value as BranchId;\n}\n\n/**\n * Mints a {@link BaseVersion} from a raw string. Centralizes the brand cast so\n * the unsafe assertion lives in exactly one place.\n */\nexport function asBaseVersion(value: string): BaseVersion {\n return value as BaseVersion;\n}\n\n/**\n * A working-copy handle for one branch: its id, the `base@V` it forked from, and\n * a {@link Store} over the branch's own backend.\n */\nexport type GraphBranch<G extends GraphDef> = Readonly<{\n id: BranchId;\n base: BaseVersion;\n store: Store<G>;\n}>;\n\n/**\n * Options for {@link GraphBranch} creation. `id` is optional — when omitted a\n * fresh id is generated.\n */\nexport type BranchOptions = Readonly<{\n id?: BranchId;\n}>;\n\n/**\n * Turns text into an embedding vector. Injected via {@link MergeOptions.embedder}\n * and used by the `vector` / `hybrid` similarity strategies to score candidate\n * pairs by cosine IN MEMORY — the staged candidate nodes are unindexed in the\n * working copy, so a backend ANN index cannot score them pairwise (see\n * `scorePair`). Exact in-memory cosine over real model vectors is both the right\n * scale for bounded candidate dedup and deterministic, which the merge contract\n * requires.\n *\n * Batched and async: given N texts it returns N vectors in the SAME order, each a\n * fixed-dimension `Float32Array` (every vector a given embedder returns shares one\n * length — the model's embedding dimension). The function MUST be deterministic —\n * the same text always yields the same vector — because the whole merge is\n * order-independent and reproducible. Vectors need NOT be pre-normalized; cosine\n * scoring normalizes internally.\n *\n * The concrete local model lives in the CONSUMER (the harness ships an\n * all-MiniLM-L6-v2 embedder); this package depends only on the function shape, so\n * it stays model-agnostic and lean inside the TypeGraph core package.\n */\nexport type Embedder = (\n texts: readonly string[],\n) => Promise<readonly Float32Array[]>;\n\n/**\n * Pluggable per-kind similarity strategy (design §8).\n *\n * - `vector` / `hybrid` score candidate pairs by cosine over an injected\n * {@link Embedder} ({@link MergeOptions.embedder}), computed in memory; they\n * fail with `SimilarityUnavailableError` when no embedder is configured.\n * - `fulltext` and `custom` run with ZERO embeddings — the cross-DB-safe\n * default. `fulltext` uses an in-memory Sørensen–Dice trigram scorer (T6).\n *\n * The generic mirrors the design's `SimilarityStrategy<G, K>`: `K` constrains the\n * `custom` score function's node arguments to the resolved kind.\n */\nexport type SimilarityStrategy<\n G extends GraphDef = GraphDef,\n K extends NodeType = NodeType,\n> =\n | Readonly<{\n kind: \"hybrid\";\n fields: readonly string[];\n weights?: Readonly<{ vector?: number; fulltext?: number }>;\n // Phantom binding to the caller's graph, matching the design's\n // `SimilarityStrategy<G, K>` two-parameter shape. Never set at runtime.\n readonly __graph?: G;\n }>\n | Readonly<{ kind: \"vector\"; field: string; readonly __graph?: G }>\n | Readonly<{\n kind: \"fulltext\";\n fields: readonly string[];\n readonly __graph?: G;\n }>\n | Readonly<{\n kind: \"custom\";\n score: (a: Node<K>, b: Node<K>) => number;\n readonly __graph?: G;\n }>;\n\n/**\n * Per-kind entity-resolution configuration.\n */\nexport type ResolveConfig<\n G extends GraphDef = GraphDef,\n K extends NodeType = NodeType,\n> = Readonly<{\n /**\n * Cheap exact-equality blocking key, evaluated before similarity to bound the\n * O(n²) candidate comparisons. Returning `undefined` places the node in the\n * shared `\"unblocked\"` bucket (compared all-vs-all within its kind).\n *\n * STAGED-vs-staged only: it is an arbitrary JS function, so it cannot be queried\n * against the committed base. To recall committed entities by a block key\n * (new-vs-base, the `baseKey` source §6.2), declare the key as a TypeGraph node\n * index and name it via {@link ResolveConfig.blockIndex} instead.\n */\n block?: (node: Node<K>) => string | undefined;\n /**\n * Name of a declared TypeGraph node index (`defineNodeIndex`) whose key is this\n * kind's NEW-vs-BASE block key (design §6.2). When set and the new-vs-base scope is\n * driven, the `baseKey` source issues an indexed `bulkFindByIndex` lookup of\n * committed nodes sharing each staged node's index key and proposes them as scored\n * candidate pairs (a shared block key is a candidate, not a definitional match).\n *\n * The index keys on real fields (a field-set + scope + optional partial-`where`), so\n * only a FIELD-SET block key migrates here; a transform key (`slice`/`soundex`/…)\n * stays on the staged-only {@link block}. Unused on the public snapshot `merge()`\n * path. An undeclared name surfaces a typed error at lookup time.\n */\n blockIndex?: string;\n /**\n * Bounded coarse candidate generation for the NO-KEY case (design §6.2, the\n * `keyless` source). A node whose {@link block} returns `undefined` (and has no\n * unique signature) lands in the shared `\"unblocked\"` bucket, which is otherwise\n * compared ALL-vs-all — an O(n²) cliff that `maxComparisonsPerKind` then truncates\n * to id-only. Set `keyless` to bound that bucket by single-pass SORTED-NEIGHBOURHOOD\n * instead: the unblocked nodes are sorted by their similarity-field text (tie-broken\n * by id) and each is proposed only against its next `window` neighbours — O(n·window),\n * deterministic. Unset preserves today's all-vs-all behaviour. Only the `\"unblocked\"`\n * bucket is affected; keyed `block()` buckets are unchanged.\n */\n keyless?: Readonly<{\n /** Forward-neighbour window: each unblocked node is paired with its next `window`\n * neighbours in the sort. Must be a positive integer. Larger → more recall, more\n * comparisons (→ all-vs-all as `window` ≥ bucket size). */\n window: number;\n }>;\n /** Similarity strategy (design §8). */\n similarity: SimilarityStrategy<G, K>;\n /** Candidate-merge threshold in `[0, 1]`. */\n threshold: number;\n}>;\n\n/**\n * A resolved cluster of node ids that the merge collapses into one canonical\n * survivor.\n */\nexport type ResolvedCluster = Readonly<{\n members: readonly NodeId<NodeType>[];\n}>;\n\n/**\n * Policy for resolving conflicting property values across cluster members.\n *\n * - `\"flag\"` keeps the canonical's value and records a {@link PropertyConflict}\n * without auto-resolving.\n * - `\"lastWriteWins\"` picks by the stable branch/logical total order — NEVER\n * wall-clock arrival.\n * - `\"provenanceWeighted\"` picks by per-branch trust weight.\n * - A function delegates the decision, returning the surviving {@link JsonValue}.\n */\nexport type PropertyConflictPolicy<G extends GraphDef = GraphDef> =\n | \"flag\"\n | \"lastWriteWins\"\n | \"provenanceWeighted\"\n | ((conflict: PropertyConflict<G>) => JsonValue);\n\n/**\n * Policy for resolving an inherited node that is deleted by one branch and\n * modified by another (design §6.2).\n *\n * - `\"deleteWins\"` — the node is finally DELETED; the modification is discarded.\n * - `\"modifyWins\"` — the node is RESURRECTED; the modification survives.\n * - `\"flag\"` (default) — the **modification SURVIVES in the merged output** (as\n * with `\"modifyWins\"`) AND an **unresolved {@link DeleteModifyConflict} is\n * recorded** in `report.deleteModifyConflicts` for human review. `\"flag\"` is\n * therefore NOT neutral — it keeps data and surfaces the disagreement, on the\n * posture that a merge must never silently destroy the only branch still\n * carrying data. Choose `\"deleteWins\"` to honor the delete by default instead.\n */\nexport type DeleteModifyPolicy = \"deleteWins\" | \"modifyWins\" | \"flag\";\n\n/**\n * Behavior when `maxComparisonsPerKind` is exceeded for a kind.\n *\n * - `\"error\"` fails the merge with a typed error (default).\n * - `\"mergeByIdOnly\"` skips similarity for that kind, emits no candidate edges,\n * and records a report warning.\n */\nexport type ComparisonCeilingPolicy = \"error\" | \"mergeByIdOnly\";\n\n/**\n * Ontology type-reconciliation mode. `\"off\"` is a no-op (default); `\"ontology\"`\n * collapses compatible types to the most-specific via the public subClassOf\n * closure (T2a / T10).\n */\nexport type ReconcileTypesMode = \"ontology\" | \"off\";\n\n/**\n * Map of node kind name → its {@link ResolveConfig}. Keys are constrained to the\n * graph's node kinds (`keyof G[\"nodes\"]`), so a typo or a kind that does not\n * belong to the graph is a COMPILE error rather than a silently-ignored config\n * (which would let those nodes merge by id only without warning). Each kind's\n * config is bound to that kind's concrete `NodeType`, so `block(node)` and the\n * `custom` scorer see the right node shape. All keys are optional: kinds omitted\n * from this map merge by ID only (new fork nodes added as-is, no fuzzy\n * resolution). For the default unparameterized `GraphDef` the keys widen back to\n * `string`.\n */\nexport type ResolveMap<G extends GraphDef = GraphDef> = Readonly<\n Partial<{\n [K in NodeKinds<G>]: ResolveConfig<G, GetNodeType<G, K>>;\n }>\n>;\n\n/**\n * Caller-facing options for {@link merge}. All fields are optional with frozen\n * defaults applied by `normalizeMergeOptions` (see `options.ts`).\n */\nexport type MergeOptions<G extends GraphDef = GraphDef> = Readonly<{\n /** Per-kind entity resolution. Omitted kinds merge by ID only. */\n resolve?: ResolveMap<G>;\n /** Reconcile differing types across forks. Default `\"off\"`. */\n reconcileTypes?: ReconcileTypesMode;\n /** Property-conflict policy for staged-vs-staged disagreements. Default `\"flag\"`. */\n onPropertyConflict?: PropertyConflictPolicy<G>;\n /**\n * Property-conflict policy for BASE↔branch disagreements in a new-vs-base merge\n * (§6.4-C). DISTINCT from {@link onPropertyConflict} and DOES NOT inherit it:\n * `onPropertyConflict` can be `\"lastWriteWins\"` / `\"provenanceWeighted\"` / a\n * function, any of which would let a fuzzy branch match silently OVERWRITE\n * committed data. Default `\"flag\"` keeps the committed base value (and records the\n * conflict). Mirrors how `onDeleteModifyConflict` is kept separate. Only consulted\n * when a cluster contains a base member; the staged path never uses it.\n */\n onBasePropertyConflict?: PropertyConflictPolicy<G>;\n /** Delete/modify-conflict policy. Default `\"flag\"`. */\n onDeleteModifyConflict?: DeleteModifyPolicy;\n /** Comparison-ceiling behavior. Default `\"error\"`. */\n onComparisonCeiling?: ComparisonCeilingPolicy;\n /**\n * Deterministic survivor selection within a cluster. Default: the member with\n * the lexicographically-minimal node id.\n */\n canonical?: (cluster: ResolvedCluster) => NodeId<NodeType>;\n /** Populate the report-only provenance index. Default `true`. */\n provenance?: boolean;\n /**\n * Persist provenance ON-GRAPH: after the commit, upsert one `{branch, sourceId}`\n * row per contribution into a sidecar provenance graph on the target's backend\n * (queryable via `openProvenanceStore` / `readProvenance`). Default `false`\n * (report-only). Best-effort and post-commit — a persistence failure surfaces as\n * a {@link MergeReport.warnings} entry, never a failed merge.\n */\n persistProvenance?: boolean;\n /**\n * Local embedder for `vector` / `hybrid` similarity (in-memory cosine over the\n * staged candidate pairs). Required ONLY when a kind's resolve strategy is\n * `vector` or `hybrid`; `fulltext` / `custom` ignore it. A vector/hybrid\n * strategy with no embedder configured fails with a typed\n * {@link import(\"./errors\").SimilarityUnavailableError}.\n */\n embedder?: Embedder;\n /** Merge receiver. Default: the base `store`, written transactionally. */\n target?: Store<G>;\n /** Safety ceiling on candidate comparisons per kind. Default: unbounded. */\n maxComparisonsPerKind?: number;\n /**\n * Optional single-link diameter guard. When set, clusters whose pairwise\n * distance exceeds it are split by the deterministic drop-weakest rule (T8).\n */\n clusterMaxDiameter?: number;\n /**\n * Explicit stable branch order used by `lastWriteWins` / tie-breaking. When\n * omitted, branch ids sorted lexicographically are used. NEVER wall-clock.\n */\n branchOrder?: readonly BranchId[];\n /**\n * Per-branch trust weights consulted ONLY by the `\"provenanceWeighted\"`\n * property-conflict policy ({@link onPropertyConflict} /\n * {@link onBasePropertyConflict}): when branches disagree on a property value,\n * the value contributed by the highest-weight branch wins. Ties fall back to\n * {@link branchOrder} (then canonical value order); branches absent from the map\n * default to weight `0`. Ignored by every other policy. Keyed by\n * {@link BranchId}, like {@link branchOrder}. Without this map,\n * `\"provenanceWeighted\"` has no weights to consult and degrades to\n * `\"lastWriteWins\"` semantics.\n */\n provenanceWeights?: ReadonlyMap<BranchId, number>;\n}>;\n\n/**\n * Object-form arguments for {@link mergeIncremental} (§6.6). The two same-typed\n * stores are NAMED so `forkPoint` (the frozen ancestor the branches forked from, the\n * diff reference) and `target` (the live committed graph that base lookups and the\n * commit land on) cannot be swapped. `options.target` is ignored — `target` is the\n * explicit arg.\n */\nexport type MergeIncrementalArgs<G extends GraphDef = GraphDef> = Readonly<{\n forkPoint: Store<G>;\n target: Store<G>;\n branches: readonly GraphBranch<G>[];\n options?: MergeOptions<G>;\n}>;\n\n/**\n * Records that a set of fork node ids resolved to a single canonical survivor.\n */\nexport type EntityResolution = Readonly<{\n canonicalId: NodeId<NodeType>;\n memberIds: readonly NodeId<NodeType>[];\n kind: string;\n branchOrigins: readonly BranchId[];\n}>;\n\n/**\n * One candidate value contributing to a property conflict, tagged by its origin\n * branch.\n */\nexport type ConflictingValue = Readonly<{\n branchId: BranchId;\n value: JsonValue;\n}>;\n\n/**\n * A property whose value differed across cluster members (or across the two\n * collapsed edges for an edge conflict). `resolution` records the value the\n * policy selected.\n */\nexport type PropertyConflict<G extends GraphDef = GraphDef> = Readonly<{\n entityId: NodeId<NodeType> | EdgeId;\n kind: string;\n property: string;\n values: readonly ConflictingValue[];\n resolution: JsonValue;\n // `G` keeps the public conflict type parameterized by the caller's graph\n // (matching the design's `PropertyConflict<G>`); it carries no runtime field.\n readonly __graph?: G;\n}>;\n\n/**\n * An inherited node OR edge deleted by one branch and modified by another, with\n * the resolution the {@link DeleteModifyPolicy} produced. `entityId` is a\n * {@link NodeId} for a node conflict and an {@link EdgeId} for an edge conflict.\n */\nexport type DeleteModifyConflict = Readonly<{\n entityId: NodeId<NodeType> | EdgeId;\n kind: string;\n deletedBy: BranchId;\n modifiedBy: BranchId;\n resolution: DeleteModifyPolicy;\n}>;\n\n/**\n * Records that a cluster's mixed member kinds were collapsed to a single\n * canonical (most-specific) type via ontology reconciliation.\n */\nexport type TypeReconciliation = Readonly<{\n entityId: NodeId<NodeType>;\n fromTypes: readonly string[];\n toType: string;\n}>;\n\n/**\n * An item omitted from the merged result (e.g. an edge whose endpoint was\n * deleted, or an incompatible-typed cluster member).\n */\nexport type DroppedItem = Readonly<{\n kind: \"edge\" | \"node\";\n id: NodeId<NodeType> | EdgeId;\n reason: string;\n}>;\n\n/**\n * A `(kind, id)` node identity as surfaced in the merge report. Node identity is the\n * PAIR, never the bare id (a `Doctor` and a `SpecialistDoctor` can share an id string),\n * so report shapes that name nodes carry both halves.\n */\ntype ReportNodeIdentity = Readonly<{\n kind: string;\n id: NodeId<NodeType>;\n}>;\n\n/**\n * An AMBIGUOUS new-vs-base match (design §6.4-A): a connected component that\n * bridged ≥2 distinct committed base entities (directly, `baseA ~ new ~ baseB`, or\n * through staged hops, `baseA ~ new1 ~ new2 ~ baseB`). `baseIds` are the committed\n * entities the component spanned; `memberIds` are all of its members. Both are full\n * `(kind, id)` identities — the guard keys on the composite identity, so a component\n * spanning two SAME-id/different-kind bases stays distinguishable in the report. The\n * base↔base collapse is ALWAYS REFUSED — the component is split so the committed\n * entities stay separate. Reported regardless of how the component split. (A\n * deliberate-collapse trust path is deferred until committed-entity re-keying + edge\n * repoint exist; §6.4-C.)\n */\nexport type BaseAmbiguity = Readonly<{\n baseIds: readonly ReportNodeIdentity[];\n memberIds: readonly ReportNodeIdentity[];\n}>;\n\n/**\n * The contribution one branch made to the merged result. Returned by\n * {@link ProvenanceIndex.byBranch}. EXPLICITLY in-memory / report-only for P0 —\n * no on-graph prop tagging (deferred to the AgentFS phase).\n */\nexport type BranchProvenance = Readonly<{\n nodeIds: readonly NodeId<NodeType>[];\n edgeIds: readonly EdgeId[];\n}>;\n\n/**\n * Report-only, in-memory provenance index. `byBranch` answers \"which\n * nodes/edges did this branch contribute to the merged result?\".\n */\nexport type ProvenanceIndex = Readonly<{\n byBranch: (branchId: BranchId) => BranchProvenance;\n}>;\n\n/**\n * One `{branch, sourceId}` → canonical contribution — the unit of provenance.\n *\n * The in-memory {@link ProvenanceIndex} collapses these to `branch → {canonical\n * ids}`; the full record (which keeps the contributing `sourceId` and kind) is what\n * `persistProvenance` writes to the sidecar provenance graph. `sourceId` is the\n * fork-local id the contribution had in its branch BEFORE the merge collapsed it to\n * `canonicalId` (equal to `canonicalId` for an in-place modification).\n */\nexport type ProvenanceRecord = Readonly<{\n role: \"node\" | \"edge\";\n canonicalId: string;\n canonicalKind: string;\n branchId: BranchId;\n sourceId: string;\n}>;\n\n/**\n * The full result of a {@link merge}: counts, every resolution/conflict/\n * reconciliation/drop, and the report-only provenance index.\n */\nexport type MergeReport<G extends GraphDef = GraphDef> = Readonly<{\n merged: Readonly<{ nodes: number; edges: number }>;\n resolutions: readonly EntityResolution[];\n conflicts: readonly PropertyConflict<G>[];\n deleteModifyConflicts: readonly DeleteModifyConflict[];\n typeReconciliations: readonly TypeReconciliation[];\n dropped: readonly DroppedItem[];\n /**\n * Ambiguous new-vs-base matches (§6.4-A): components that bridged ≥2 committed\n * base entities. Empty on the staged-vs-staged snapshot path.\n */\n baseAmbiguities: readonly BaseAmbiguity[];\n provenance: ProvenanceIndex;\n /**\n * Non-fatal advisories from the merge — comparison-ceiling skips and, when\n * `persistProvenance` is set, a best-effort provenance-persistence failure (the\n * graph still committed). Empty on a clean merge.\n */\n warnings: readonly string[];\n /**\n * Present only when `persistProvenance` ran and SUCCEEDED: the sidecar provenance\n * graph id and how many `{branch, sourceId}` rows were upserted. Absent when\n * persistence was off or failed (a failure adds a {@link MergeReport.warnings}).\n */\n provenancePersisted?: Readonly<{ graphId: string; count: number }>;\n}>;\n","/**\n * `base@V` stamping.\n *\n * A {@link BaseVersion} is the immutable token a branch is forked from. It must\n * change whenever either the schema OR the live content of the base store\n * changes, so that `merge()`'s precondition check (T11) can reject a branch that\n * forked from a divergent base.\n *\n * The token is two stable components joined by a separator:\n *\n * 1. A **schema hash** — `computeSchemaHash(serializeSchema(graph, version))`.\n * This is content-addressed (the public `computeSchemaHash` deliberately\n * excludes the version number and `generatedAt`, so it is stable across\n * re-saves of the same schema).\n * 2. A **revision anchor** when the Store has `revisionTracking` (or\n * `history`) enabled — a durable random per-graph origin plus the\n * monotonic revision clock. This is O(1) to read and changes after every\n * successful Store write; the origin prevents independent stores with\n * coincident timestamps from sharing an anchor.\n * Stores without tracking retain the compatibility fallback: a\n * **content fingerprint**, a SHA-256 digest (truncated to a fixed-width\n * hex string) of every LIVE node and edge over the base store (`id`,\n * `updated_at`, the bitemporal `valid_from`/`valid_to`, and canonicalized\n * `props`; edges also carry their endpoint ids), sorted by id, so two stores\n * with identical live content fingerprint identically regardless of row\n * enumeration order or insertion order. Props AND validity are folded in so\n * the token changes on a content or validity edit even when `updated_at` ties\n * at millisecond granularity. Hashing keeps the token fixed-width instead of\n * growing linearly with store size.\n *\n * The token MUST be computed off the ORIGINAL base store, never off a clone:\n * `exportGraph`/`importGraph` regenerate `created_at`/`updated_at`, so a clone's\n * fingerprint would not match its source. (See the working-copy fidelity note in\n * T4.)\n *\n * `computeBaseVersion` is async because schema hashing, revision reads, and the\n * compatibility live-content enumeration go through async TypeGraph internals.\n * The design's synchronous illustrative signature does not survive contact with\n * the real store surface.\n */\n\nimport { canonicalizeProps, parseRowProps } from \"./canonical-props\";\nimport { compareStrings } from \"./node-key\";\nimport { enumerateAllEdges, enumerateAllNodes } from \"./state-diff\";\nimport type {\n GraphBackend,\n GraphDef,\n Store,\n TransactionBackend,\n} from \"./typegraph-internal\";\nimport { getEdgeKinds, getNodeKinds, sha256Hex } from \"./typegraph-internal\";\nimport { computeSchemaHash, serializeSchema } from \"./typegraph-internal\";\nimport type { BaseVersion } from \"./types\";\nimport { asBaseVersion } from \"./types\";\n\n/**\n * Separator between the schema-hash and revision-or-content token components.\n * The schema hash contains no NUL byte, so one NUL unambiguously delimits the\n * two components.\n */\nconst TOKEN_SEPARATOR = \"\\0\";\nconst REVISION_COMPONENT_PREFIX = \"revision:\";\nconst REVISION_COMPONENT_SEPARATOR = \":\";\nconst INITIAL_REVISION = \"initial\";\n\n/**\n * Falls back to schema version `1` when the backend has not recorded an active\n * schema version. `serializeSchema` only uses the version for the serialized\n * doc; the hash deliberately excludes it, so the exact value never affects the\n * resulting `BaseVersion`.\n */\nconst FALLBACK_SCHEMA_VERSION = 1;\n\n/**\n * Reads the active schema version from the backend, defaulting when absent. The\n * value is informational for `serializeSchema`; `computeSchemaHash` excludes the\n * version, so this never destabilizes the token.\n */\nasync function readActiveSchemaVersion(\n backend: GraphBackend,\n graphId: string,\n): Promise<number> {\n const active = await backend.getActiveSchema(graphId);\n return active?.version ?? FALLBACK_SCHEMA_VERSION;\n}\n\n/**\n * Computes the schema-hash component of the base version token — the SCHEMA half of\n * `base@V`, independent of live content. Exported so `mergeIncremental()` can assert\n * `forkPoint` and `target` share a schema (the hard half of its precondition) without\n * re-parsing the token separator or recomputing the content fingerprint (§6.6).\n */\nexport async function computeSchemaComponent<G extends GraphDef>(\n store: Store<G>,\n): Promise<string> {\n const version = await readActiveSchemaVersion(store.backend, store.graphId);\n return computeSchemaHash(serializeSchema(store.graph, version));\n}\n\n/**\n * Stable TOTAL comparator over `{ kind, id }` digest entries. Keyed on `(kind, id)`\n * because the node primary key is `(graph_id, kind, id)` — two nodes of different\n * kinds may legitimately share an `id` (e.g. `Person:x` and `Company:x`), so an\n * id-only comparator is non-total and would leave same-id/different-kind entries at\n * the mercy of sort stability. `(kind, id)` makes the digest order fully canonical.\n */\nfunction byDigestEntry(\n left: Readonly<{ kind: string; id: string }>,\n right: Readonly<{ kind: string; id: string }>,\n): number {\n const byKind = compareStrings(left.kind, right.kind);\n return byKind === 0 ? compareStrings(left.id, right.id) : byKind;\n}\n\n/**\n * Number of SHA-256 bytes retained for the content fingerprint. 16 bytes (128\n * bits) makes an accidental collision — which would let a divergent base pass\n * the merge precondition — negligible, while keeping the token fixed-width\n * regardless of store size.\n */\nconst CONTENT_FINGERPRINT_BYTES = 16;\n\n/**\n * Builds the deterministic content fingerprint over the base store's LIVE rows.\n *\n * Each live node contributes `(id, updatedAt, validFrom, validTo, props)` and\n * each live edge contributes `(id, updatedAt, validFrom, validTo, endpoints,\n * props)`; both lists are sorted by id before serialization so the fingerprint is\n * independent of enumeration order. Props are canonicalized so the token changes\n * whenever live content changes even when two writes land on the same millisecond\n * `updated_at` (timestamp granularity must never be the sole change signal). The\n * bitemporal `valid_from`/`valid_to` are folded in for the same reason — they are\n * user-mutable row content, so a validity-only edit that leaves `updated_at`\n * unchanged must still move the token. Soft-deleted rows are intentionally\n * excluded — the fingerprint describes the live base a branch forks from.\n *\n * Takes the backend rather than a `Store` so the SAME fingerprint can be\n * re-computed inside a commit transaction (via the tx-scoped backend) for the\n * in-transaction `base@V` re-validation — the reads then observe the\n * transaction's snapshot, not whatever a concurrent writer has since committed.\n */\nexport async function computeContentComponent<G extends GraphDef>(\n backend: GraphBackend | TransactionBackend,\n graphId: string,\n graph: G,\n): Promise<string> {\n const nodeKinds = getNodeKinds(graph);\n const edgeKinds = getEdgeKinds(graph);\n\n const nodeDigest: Readonly<{\n id: string;\n kind: string;\n updatedAt: string;\n validFrom: string | undefined;\n validTo: string | undefined;\n props: string;\n }>[] = [];\n for (const kind of nodeKinds) {\n const rows = await enumerateAllNodes(backend, graphId, kind);\n for (const row of rows) {\n if (row.deleted_at === undefined) {\n nodeDigest.push({\n id: row.id,\n kind: row.kind,\n updatedAt: row.updated_at,\n validFrom: row.valid_from,\n validTo: row.valid_to,\n props: canonicalizeProps(parseRowProps(row.props)),\n });\n }\n }\n }\n\n const edgeDigest: Readonly<{\n id: string;\n kind: string;\n fromId: string;\n toId: string;\n updatedAt: string;\n validFrom: string | undefined;\n validTo: string | undefined;\n props: string;\n }>[] = [];\n for (const kind of edgeKinds) {\n const rows = await enumerateAllEdges(backend, graphId, kind);\n for (const row of rows) {\n if (row.deleted_at === undefined) {\n edgeDigest.push({\n id: row.id,\n kind: row.kind,\n fromId: row.from_id,\n toId: row.to_id,\n updatedAt: row.updated_at,\n validFrom: row.valid_from,\n validTo: row.valid_to,\n props: canonicalizeProps(parseRowProps(row.props)),\n });\n }\n }\n }\n\n return sha256Hex(\n canonicalizeProps({\n nodes: nodeDigest.sort((left, right) => byDigestEntry(left, right)),\n edges: edgeDigest.sort((left, right) => byDigestEntry(left, right)),\n }),\n CONTENT_FINGERPRINT_BYTES,\n );\n}\n\n/**\n * Computes the immutable `base@V` token for a store. Combines the schema hash\n * with a durable revision anchor when tracking is enabled, otherwise with the\n * compatibility live-content fingerprint.\n *\n * MUST be called on the ORIGINAL base store, not a clone (clones regenerate\n * timestamps and would fingerprint differently when the compatibility path is\n * in use).\n */\nexport async function computeBaseVersion<G extends GraphDef>(\n store: Store<G>,\n): Promise<BaseVersion> {\n if (store.revisionTrackingEnabled) {\n const [schemaComponent, origin, revision] = await Promise.all([\n computeSchemaComponent(store),\n store.revisionOriginNow(),\n store.revisionNow(),\n ]);\n return asBaseVersion(\n `${schemaComponent}${TOKEN_SEPARATOR}${revisionComponent(origin, revision)}`,\n );\n }\n const [schemaComponent, contentComponent] = await Promise.all([\n computeSchemaComponent(store),\n computeContentComponent(store.backend, store.graphId, store.graph),\n ]);\n return asBaseVersion(\n `${schemaComponent}${TOKEN_SEPARATOR}${contentComponent}`,\n );\n}\n\nfunction revisionComponent(\n origin: string,\n revision: string | undefined,\n): string {\n return `${REVISION_COMPONENT_PREFIX}${origin}${REVISION_COMPONENT_SEPARATOR}${revision ?? INITIAL_REVISION}`;\n}\n\n/** True when a base token uses the O(1) durable revision-anchor component. */\nexport function hasRevisionAnchor(version: BaseVersion): boolean {\n return contentComponentOf(version).startsWith(REVISION_COMPONENT_PREFIX);\n}\n\n/**\n * Extracts the durable revision from a revision-anchored base token. Undefined\n * represents the stable initial state before the first tracked write.\n */\nexport function revisionAnchorOf(version: BaseVersion): string | undefined {\n const revision = revisionPartsOf(version)?.revision;\n return revision === undefined || revision === INITIAL_REVISION ?\n undefined\n : revision;\n}\n\n/**\n * Extracts the durable store-specific namespace from a revision-anchored base\n * token. Undefined denotes a legacy timestamp-only anchor, which must never\n * be treated as equivalent to a current store's namespaced revision.\n */\nexport function revisionOriginOf(version: BaseVersion): string | undefined {\n return revisionPartsOf(version)?.origin;\n}\n\nfunction revisionPartsOf(\n version: BaseVersion,\n): Readonly<{ origin: string; revision: string }> | undefined {\n const component = contentComponentOf(version);\n if (!component.startsWith(REVISION_COMPONENT_PREFIX)) return undefined;\n const encoded = component.slice(REVISION_COMPONENT_PREFIX.length);\n const separator = encoded.indexOf(REVISION_COMPONENT_SEPARATOR);\n if (separator <= 0 || separator === encoded.length - 1) return undefined;\n return {\n origin: encoded.slice(0, separator),\n revision: encoded.slice(separator + 1),\n };\n}\n\n/**\n * Extracts the second component from a `base@V` token. The schema component\n * contains no NUL byte, so the substring after the separator is exactly the\n * durable revision or compatibility content fingerprint.\n *\n * Used by both revision-token parsing and legacy in-transaction content\n * re-validation. The schema component is a pure function of the in-memory\n * graph definition, so only the second component needs runtime checking.\n */\nexport function contentComponentOf(version: BaseVersion): string {\n const separatorIndex = (version as string).indexOf(TOKEN_SEPARATOR);\n return separatorIndex === -1 ? version : (\n (version as string).slice(separatorIndex + 1)\n );\n}\n","import type { TypeGraphErrorOptions } from \"./typegraph-internal\";\nimport { TypeGraphError } from \"./typegraph-internal\";\n\n/**\n * Error hierarchy for the graph-merge primitive.\n *\n * Every error extends the publicly-exported {@link TypeGraphError}, so consumers\n * can use the same `isTypeGraphError`/category machinery they already use for\n * TypeGraph itself. Each subclass carries a stable machine-readable `code`, a\n * fixed `ErrorCategory`, and a cause chain for debugging.\n */\n\n/**\n * Machine-readable error codes for the merge primitive. Stable identifiers so\n * callers can branch on `error.code` without string-matching messages.\n */\nexport const MERGE_ERROR_CODES = {\n merge: \"GRAPH_MERGE_ERROR\",\n branch: \"GRAPH_MERGE_BRANCH_ERROR\",\n similarityUnavailable: \"GRAPH_MERGE_SIMILARITY_UNAVAILABLE\",\n conflict: \"GRAPH_MERGE_CONFLICT\",\n baseVersionMismatch: \"GRAPH_MERGE_BASE_VERSION_MISMATCH\",\n} as const;\n\n/**\n * Options shared by every merge error. Mirrors the relevant subset of\n * TypeGraphError's options while making `cause`/`details`/`suggestion`\n * uniformly optional at the merge-error boundary.\n */\nexport type MergeErrorOptions = Readonly<{\n details?: Record<string, unknown>;\n suggestion?: string;\n cause?: unknown;\n}>;\n\n/**\n * Builds a {@link TypeGraphErrorOptions} for a fixed category, threading only\n * the optional fields that are actually present. Omitting undefined keys (rather\n * than assigning `undefined`) keeps the result valid under\n * `exactOptionalPropertyTypes`.\n */\nfunction toTypeGraphErrorOptions(\n category: TypeGraphErrorOptions[\"category\"],\n options: MergeErrorOptions,\n): TypeGraphErrorOptions {\n return {\n category,\n ...(options.details === undefined ? {} : { details: options.details }),\n ...(options.suggestion === undefined ?\n {}\n : { suggestion: options.suggestion }),\n ...(options.cause === undefined ? {} : { cause: options.cause }),\n };\n}\n\n/**\n * Generic failure raised while computing or committing a merge. The catch-all\n * for the orchestrator (comparison-ceiling overruns, commit failures, etc.).\n */\nexport class MergeError extends TypeGraphError {\n constructor(message: string, options: MergeErrorOptions = {}) {\n super(\n message,\n MERGE_ERROR_CODES.merge,\n toTypeGraphErrorOptions(\"system\", options),\n );\n this.name = \"MergeError\";\n }\n}\n\n/**\n * Failure raised while creating a working-copy branch of a base store\n * (clone/export/import failures, backend construction failures).\n */\nexport class BranchError extends TypeGraphError {\n constructor(message: string, options: MergeErrorOptions = {}) {\n super(\n message,\n MERGE_ERROR_CODES.branch,\n toTypeGraphErrorOptions(\"system\", options),\n );\n this.name = \"BranchError\";\n }\n}\n\n/**\n * Raised when a `vector`/`hybrid` similarity strategy is requested but no\n * {@link import(\"./types\").Embedder} was configured (`MergeOptions.embedder` is\n * absent). The `vector`/`hybrid` scorers compute cosine over real embeddings in\n * memory, so an embedder is mandatory for them; `fulltext`/`custom` need none.\n */\nexport class SimilarityUnavailableError extends MergeError {\n override readonly code = MERGE_ERROR_CODES.similarityUnavailable;\n\n constructor(message: string, options: MergeErrorOptions = {}) {\n super(message, {\n ...options,\n suggestion:\n options.suggestion ??\n \"Pass MergeOptions.embedder (a local model), or use a fulltext/custom similarity strategy.\",\n });\n this.name = \"SimilarityUnavailableError\";\n }\n}\n\n/**\n * Raised when a conflict cannot be resolved by the configured policy and the\n * caller has opted into hard-failing rather than flagging.\n */\nexport class MergeConflictError extends MergeError {\n override readonly code = MERGE_ERROR_CODES.conflict;\n\n constructor(message: string, options: MergeErrorOptions = {}) {\n super(message, options);\n this.name = \"MergeConflictError\";\n }\n}\n\n/**\n * Raised by the `merge()` precondition check when a branch's `base@V` token\n * does not match the merge target's current base version (the branch forked\n * from a divergent schema or content fingerprint).\n */\nexport class BaseVersionMismatchError extends MergeError {\n override readonly code = MERGE_ERROR_CODES.baseVersionMismatch;\n\n constructor(message: string, options: MergeErrorOptions = {}) {\n super(message, {\n ...options,\n suggestion:\n options.suggestion ??\n \"Re-branch from the current target so the branch base matches before merging.\",\n });\n this.name = \"BaseVersionMismatchError\";\n }\n}\n","/**\n * Pluggable working-copy strategy: how `branch()` produces an isolated,\n * independently-mutable copy of a base store.\n *\n * The P0 default is a faithful CLONE via streamed public interchange\n * ({@link cloneWorkingCopyStrategy}): `exportGraphStream` the base, then\n * `importGraphStream` into a fresh store on a caller-provided backend. IDs are\n * preserved by interchange, so the diff engine (T3) can key on stable ids across\n * base and fork. This leverages public entrypoints only, needs zero schema\n * changes, and behaves identically across SQLite and Postgres.\n *\n * INTERCHANGE FIDELITY LIMITATION (verified, design §13.x): the interchange\n * `meta` schema has no `deletedAt` field, so a base row that is already\n * soft-deleted would round-trip into the clone as LIVE (its tombstone lost). A\n * resurrected row would then read as a spurious `new` node in the fork's diff —\n * the base row is non-live, so `diffNodeKind` takes its `!isLive(base)` branch and\n * reports the (live, clone-resurrected) row as an addition — silently re-creating a\n * deleted node on commit. We therefore export with `includeDeleted: false`: the\n * clone carries only the base's LIVE state, exactly what `branch()` needs. The\n * merge state-diff is still computed against the ORIGINAL base store (live rows\n * only) as the immutable reference, never against the clone (clones regenerate\n * `created_at`/`updated_at`, which would otherwise destabilize `base@V`).\n *\n * `includeTemporal: true` carries `validFrom`/`validTo` through unchanged,\n * preserving the base's exact valid-time window on the clone: create-time\n * paths default an omitted `validFrom` to the row's own creation instant\n * (see #240), and export/import round-trip a still-open-left `valid_from`\n * (e.g. a row that predates the #240 fix) as an explicit `null` rather than\n * silently dropping it — see `InterchangeNodeSchema.validFrom`'s doc.\n * Without either half of this, the clone's re-import would re-stamp the\n * affected base rows to the CLONE's creation instant instead — narrowing\n * their validity window and making `asOf` reads on the fork diverge from\n * identical reads on the base for any instant between the row's real\n * creation and the clone.\n *\n * Logical-namespace (copy-on-write within one backend, no full data copy) is a\n * future strategy slot — see the `WorkingCopyStrategy` interface — deferred past\n * P0.\n */\n\nimport { BranchError } from \"./errors\";\nimport type { GraphBackend, GraphDef, Store } from \"./typegraph-internal\";\nimport { createStoreWithSchema } from \"./typegraph-internal\";\nimport { exportGraphStream, importGraphStream } from \"./typegraph-internal\";\n\n/**\n * Batch size for the clone's `importGraphStream` pass. Large enough to keep\n * round-trips low on demo-scale graphs; correctness is independent of the value.\n */\nconst CLONE_IMPORT_BATCH_SIZE = 1000;\n\n/**\n * How `branch()` materializes a working copy of a base store.\n *\n * `create` receives the live base store and returns a fresh, independently\n * mutable {@link Store} over the SAME graph definition, seeded with the base's\n * current state. Mutating the returned store MUST NOT affect the base.\n *\n * The single method is the only extension point: alternative strategies\n * (e.g. a future logical-namespace copy-on-write within one backend) implement\n * the same contract.\n */\nexport type WorkingCopyStrategy<G extends GraphDef> = Readonly<{\n create: (baseStore: Store<G>) => Promise<Store<G>>;\n}>;\n\n/**\n * Factory for a caller-provided backend. `branch()` stays backend-agnostic by\n * delegating backend construction to the caller: the clone strategy calls this\n * once per `create()` to obtain the fresh backend that backs the working copy.\n *\n * Returning a promise lets async backends (e.g. PGlite, which boots an\n * in-process Postgres engine) be constructed lazily at branch time.\n *\n * The returned backend MUST be EMPTY (no rows for the base graph): the clone\n * seeds it from the base via `importGraphStream` with `onConflict: \"error\"`, so a\n * pre-existing row is surfaced as a {@link BranchError} rather than silently\n * skipped (which would leave the working copy diverging from the base).\n * When the source store uses `revisionTracking`, the backend must also satisfy\n * that option's transactional revision-clock requirements because the clone\n * preserves the source's branchability contract.\n */\nexport type MakeBackend = () => Promise<GraphBackend>;\n\n/**\n * The P0 default working-copy strategy: faithful clone via streamed interchange.\n *\n * On each `create(baseStore)`:\n * 1. `exportGraphStream(baseStore, { includeMeta: true, includeTemporal: true,\n * includeDeleted: false })` — `includeMeta: true` carries\n * `created_at`/`updated_at`; `includeTemporal: true` carries\n * `validFrom`/`validTo` so the clone's valid-time window matches the base's\n * exactly (see the fidelity note above); `includeDeleted: false` keeps the\n * clone to LIVE rows only. Shipping soft-deleted rows is unsafe: the meta\n * schema has no `deletedAt`, so they would import as live and resurrect on\n * the fork's diff (see the fidelity note above). `branch()` only needs the\n * base's live state.\n * 2. Create a fresh store over the caller-provided backend with the SAME graph\n * definition via `createStoreWithSchema`.\n * 3. `importGraphStream(freshStore, data, { onConflict: \"error\", ... })` — ids are\n * preserved so the diff engine can key on them. `onConflict: \"error\"`\n * requires the backend to be EMPTY: a pre-existing row is a contract\n * violation that must surface loudly, never be silently skipped (a skipped\n * row would leave the clone diverging from the base, so the fork's diff would\n * report phantom modifications/deletions). `importGraphStream` RETURNS\n * `{ success, errors }` rather than throwing on a per-row rejection, so its\n * result is checked and any failure fails the branch.\n *\n * The backend `makeBackend()` returns is opened here, so any failure AFTER it is\n * created closes it before rethrowing — only the success path hands the backend\n * (via the returned store) to the caller, who then owns its lifecycle.\n *\n * @param makeBackend - Constructs the fresh, EMPTY backend the working copy is\n * built on.\n */\nexport function cloneWorkingCopyStrategy<G extends GraphDef>(\n makeBackend: MakeBackend,\n): WorkingCopyStrategy<G> {\n return {\n create: async (baseStore: Store<G>): Promise<Store<G>> => {\n const backend = await makeBackend();\n try {\n const [freshStore] = await createStoreWithSchema(\n baseStore.graph,\n backend,\n {\n // Keep descendants branchable with the same O(1) anchor contract,\n // but do not copy recorded-time history into the disposable fork.\n revisionTracking: baseStore.revisionTrackingEnabled,\n },\n );\n const result = await importGraphStream(\n freshStore,\n exportGraphStream(baseStore, {\n includeMeta: true,\n includeTemporal: true,\n includeDeleted: false,\n batchSize: CLONE_IMPORT_BATCH_SIZE,\n }),\n {\n onConflict: \"error\",\n onUnknownProperty: \"error\",\n validateReferences: true,\n batchSize: CLONE_IMPORT_BATCH_SIZE,\n },\n );\n if (!result.success) {\n throw new BranchError(\n \"Clone import failed: the working copy could not be seeded from the base store. The backend returned by makeBackend() must be empty.\",\n { details: { errors: result.errors } },\n );\n }\n return freshStore;\n } catch (error) {\n // The backend was opened above; close it on any failure so its\n // connection / file handle / in-process engine cannot leak. A close\n // failure must not mask the original error.\n try {\n await backend.close();\n } catch {\n // Intentionally ignored — surface the original branch failure.\n }\n throw error;\n }\n },\n };\n}\n","/**\n * `branch()` — fork an isolated, independently-mutable working copy of a base\n * store (design §7.1).\n *\n * A branch is a {@link GraphBranch}: a fresh {@link BranchId}, the immutable\n * `base@V` token the copy forked from (computed off the ORIGINAL base store via\n * {@link computeBaseVersion}, never off the clone), and a {@link Store} over the\n * branch's own backend seeded with the base's live state.\n *\n * The copy mechanism is pluggable behind {@link WorkingCopyStrategy}. The P0\n * default is the faithful streamed-interchange clone\n * ({@link cloneWorkingCopyStrategy}),\n * which keeps this primitive backend-agnostic: the caller supplies a\n * `makeBackend` factory, and `branch()` never names a concrete backend.\n */\n\nimport { computeBaseVersion } from \"./base-version\";\nimport { BranchError } from \"./errors\";\nimport type { Result } from \"./result\";\nimport { err, ok } from \"./result\";\nimport type { GraphDef } from \"./typegraph-internal\";\nimport { generateId } from \"./typegraph-internal\";\nimport type { BranchOptions, GraphBranch } from \"./types\";\nimport { asBranchId } from \"./types\";\nimport type { MakeBackend, WorkingCopyStrategy } from \"./working-copy\";\nimport { cloneWorkingCopyStrategy } from \"./working-copy\";\n\n/**\n * Creates an isolated working-copy branch of `baseStore`.\n *\n * Stamps the `base@V` token off the original base store, mints (or accepts) a\n * {@link BranchId}, and materializes the working copy via the resolved strategy.\n * The default strategy is a faithful clone over a fresh backend produced by\n * `makeBackend`; pass an explicit `strategy` to override (e.g. a future\n * logical-namespace copy-on-write).\n *\n * Returns a {@link Result}: success yields the {@link GraphBranch}; any failure\n * (base-version stamping, backend construction, streamed interchange) is wrapped in a\n * {@link BranchError} with the underlying cause attached. Errors are returned,\n * never thrown — this is internal-logic surface (the caller converts to a thrown\n * error at the framework boundary).\n *\n * @param baseStore - The store to fork. Remains untouched.\n * @param makeBackend - Factory for the working copy's backend (keeps the\n * primitive backend-agnostic). Used only by the default clone strategy; ignored\n * when an explicit `strategy` is supplied.\n * @param options - Optional `{ id }` to set an explicit branch id.\n * @param strategy - Optional working-copy strategy override.\n */\nexport async function branch<G extends GraphDef>(\n baseStore: GraphBranch<G>[\"store\"],\n makeBackend: MakeBackend,\n options?: BranchOptions,\n strategy?: WorkingCopyStrategy<G>,\n): Promise<Result<GraphBranch<G>, BranchError>> {\n try {\n const base = await computeBaseVersion(baseStore);\n const id = options?.id ?? asBranchId(generateId());\n const workingCopyStrategy =\n strategy ?? cloneWorkingCopyStrategy<G>(makeBackend);\n const store = await workingCopyStrategy.create(baseStore);\n return ok({ id, base, store });\n } catch (error) {\n return err(\n new BranchError(\"Failed to create working-copy branch of base store\", {\n cause: error,\n }),\n );\n }\n}\n","/**\n * Per-kind blocking (design §9 phase 2): bucket a kind's NEW nodes by a cheap\n * exact-equality key so candidate-gen (T6) only compares pairs that could\n * plausibly be the same entity, bounding the otherwise-O(n²) work.\n *\n * A node is placed into a bucket for EACH key it produces, so it can belong to\n * MULTIPLE buckets — two key sources combined as a UNION (not a composite key):\n *\n * 1. The caller's `ResolveConfig.block(node)` — an application-defined cheap\n * pre-filter (e.g. a Patient's `birthDate`) → its ONE block bucket.\n * 2. The kind's declared `unique` constraints, read from the PUBLIC\n * `store.introspect().kinds[k].unique` → ONE bucket per constraint the node\n * fully satisfies. A unique constraint is an exact-match short-circuit: two\n * nodes sharing all of a constraint's field values are definitionally the\n * same entity, so they co-bucket THERE regardless of their block keys or any\n * OTHER constraint.\n *\n * Composing the two sources into a single key (the old behavior) was a bug: a\n * differing `block()` key — or a differing EARLIER constraint — split two nodes\n * that share a unique value into separate buckets, so candidate-gen never compared\n * them and a real duplicate survived the merge. The UNION fixes this: a shared\n * unique value always co-buckets, independent of `block()`.\n *\n * candidate-gen compares pairs within each bucket and DEDUPS pairs across buckets,\n * so a node in several buckets is compared against the UNION of its bucket-mates,\n * each pair scored exactly once.\n *\n * Determinism is load-bearing — candidate-gen order must never leak into merge\n * results — so bucket keys are emitted sorted lexicographically, each bucket's\n * member list is sorted by `node.id`, and each unique signature is built in the\n * constraint's declared field order.\n *\n * A node that produces NO key (no `block()`, no satisfied constraint) lands in the\n * shared {@link UNBLOCKED_BUCKET_KEY} bucket, compared all-vs-all within its kind.\n * This is the safe (no false-negative) fallback: blocking only ever prunes pairs\n * that are guaranteed non-matches.\n *\n * This module is a PURE function over its inputs (the introspection snapshot is\n * read synchronously by the caller and passed in); it performs no I/O.\n */\n\nimport { compareStrings } from \"./node-key\";\nimport type { Node, NodeType, UniqueIntrospection } from \"./typegraph-internal\";\nimport { computeUniqueKey } from \"./typegraph-internal\";\nimport type { ResolveConfig } from \"./types\";\n\n/**\n * Bucket key for nodes that produced no blocking key from either `block()` or a\n * unique constraint. Members of this bucket are compared all-vs-all within their\n * kind by candidate-gen.\n */\nexport const UNBLOCKED_BUCKET_KEY = \"unblocked\";\n\n/**\n * Separator joining the parts of a bucket key (its prefix, and a unique\n * signature's constraint name + field values). Chosen as a control character so it\n * cannot collide with ordinary stringified property values.\n */\nconst KEY_PART_SEPARATOR = \"\\0\";\n\n/**\n * Prefix marking a `block()`-key bucket, so a `block()` value can never be confused\n * with a unique-constraint value that happens to stringify the same.\n */\nconst BLOCK_KEY_PREFIX = \"b\";\n\n/** Prefix marking a unique-constraint bucket. See {@link BLOCK_KEY_PREFIX}. */\nconst UNIQUE_KEY_PREFIX = \"u\";\n\n/**\n * True when a bucket key denotes a UNIQUE-constraint bucket (vs. a `block()` or the\n * unblocked bucket). candidate-gen FORCE-MERGES every pair in such a bucket: a\n * shared unique value is definitionally the same entity (the exact-match\n * short-circuit), so the pair is a GUARANTEED merge candidate regardless of the\n * similarity threshold — differing properties are then reported as conflicts\n * normally. This also keeps the merged graph from violating its own uniqueness:\n * two unmerged same-unique rows could never commit.\n */\nexport function isUniqueBucketKey(key: string): boolean {\n return key.startsWith(`${UNIQUE_KEY_PREFIX}${KEY_PART_SEPARATOR}`);\n}\n\n/**\n * Builds the exact-match signature for one unique constraint from a node's\n * field values, or `undefined` when ANY of the constraint's fields is `null` /\n * `undefined` (a partial key cannot establish exact-match equality, and — since\n * the introspection snapshot does not expose a constraint's `where` predicate —\n * skipping absent values keeps a partial unique constraint from silently\n * over-merging two distinct rows that the database would treat as a non-match;\n * a genuine non-partial null collision still surfaces loudly at commit).\n *\n * The signature delegates to {@link computeUniqueKey} — the SAME key the store\n * enforces uniqueness with — so a blocking bucket co-buckets EXACTLY the values\n * the commit-time uniqueness check treats as equal. Hand-rolling a separate\n * canonical encoding here drifted from enforcement: it distinguished the number\n * `1` from the string `\"1\"` (which `computeUniqueKey` collapses, so the merge\n * aborted with a `UniquenessError`) and key-sorted object values (which\n * `computeUniqueKey` does not, so distinct rows were silently over-merged).\n */\nfunction constraintSignature(\n node: Node<NodeType>,\n constraint: UniqueIntrospection,\n): string | undefined {\n const props = node as unknown as Record<string, unknown>;\n for (const field of constraint.fields) {\n const value = props[field];\n if (value === undefined || value === null) {\n return undefined;\n }\n }\n return `${constraint.name}${KEY_PART_SEPARATOR}${computeUniqueKey(\n props,\n constraint.fields,\n constraint.collation,\n )}`;\n}\n\n/**\n * Computes the SET of bucket keys a node belongs to: its `block()` key bucket (if\n * `block()` returned a key) PLUS one bucket per unique constraint the node fully\n * satisfies. Because a shared unique value gets its OWN bucket — never intersected\n * with the block key or other constraints — two nodes sharing it always co-bucket.\n * Returns `[UNBLOCKED_BUCKET_KEY]` when the node produces no key at all.\n *\n * Each unique signature already embeds its constraint name, so distinct constraints\n * yield distinct keys; the `b`/`u` prefixes keep block and unique keyspaces\n * disjoint. No constraint ordering is needed — each is an independent bucket.\n */\nfunction bucketKeysFor(\n node: Node<NodeType>,\n block: ResolveConfig[\"block\"],\n constraints: readonly UniqueIntrospection[],\n): readonly string[] {\n const keys: string[] = [];\n\n const blockKey = block?.(node);\n if (blockKey !== undefined) {\n keys.push(`${BLOCK_KEY_PREFIX}${KEY_PART_SEPARATOR}${blockKey}`);\n }\n\n for (const constraint of constraints) {\n const signature = constraintSignature(node, constraint);\n if (signature !== undefined) {\n keys.push(`${UNIQUE_KEY_PREFIX}${KEY_PART_SEPARATOR}${signature}`);\n }\n }\n\n return keys.length === 0 ? [UNBLOCKED_BUCKET_KEY] : keys;\n}\n\n/**\n * Buckets a kind's NEW nodes by their blocking key(s). A node may land in MORE\n * THAN ONE bucket — its `block()` bucket plus a bucket for each unique constraint\n * it satisfies — so two nodes sharing any blocking key co-bucket and are compared.\n *\n * @param newNodes The kind's new (fork-introduced) nodes. All nodes SHOULD be of\n * one kind; the caller invokes `blockNodes` once per resolved kind.\n * @param resolveConfig The kind's resolution config; its optional `block`\n * function supplies the application blocking key.\n * @param uniqueConstraints The kind's `unique` constraints from\n * `store.introspect().kinds[k].unique`. Pass an empty array when blocking\n * should rely on `block()` alone.\n * @returns A map from bucket key → that bucket's nodes. Iteration order of the\n * returned map is the lexicographic order of bucket keys, and each bucket's\n * node list is sorted by `node.id`, so the result is a pure, order-independent\n * function of the input node SET. A node may appear in several buckets;\n * candidate-gen dedups pairs so each is scored once.\n */\nexport function blockNodes<K extends NodeType>(\n newNodes: readonly Node<K>[],\n resolveConfig: Pick<ResolveConfig, \"block\">,\n uniqueConstraints: readonly UniqueIntrospection[] = [],\n): Map<string, Node<K>[]> {\n const buckets = new Map<string, Node<K>[]>();\n\n for (const node of newNodes) {\n for (const key of bucketKeysFor(\n node,\n resolveConfig.block,\n uniqueConstraints,\n )) {\n const bucket = buckets.get(key);\n if (bucket === undefined) {\n buckets.set(key, [node]);\n } else {\n bucket.push(node);\n }\n }\n }\n\n const sortedKeys = [...buckets.keys()].sort((left, right) =>\n compareStrings(left, right),\n );\n const ordered = new Map<string, Node<K>[]>();\n for (const key of sortedKeys) {\n const members = [...buckets.get(key)!].sort((left, right) =>\n compareStrings(left.id, right.id),\n );\n ordered.set(key, members);\n }\n return ordered;\n}\n","/**\n * The centralized property-conflict resolution rule (design §6.4 rule 4 / §7.3,\n * T8). Shared by canonical node-property union (T8 / `canonicalize.ts`) and edge\n * property-collision resolution (T9), so the determinism contract lives in\n * exactly one place.\n *\n * DETERMINISM CONTRACT — the single most important invariant of the merge:\n * Conflict resolution NEVER consults wall-clock arrival time. When a value\n * must be chosen among differing per-branch candidates, the choice is made on\n * a STABLE branch total order — either the caller-supplied\n * `MergeOptions.branchOrder`, or branch ids sorted lexicographically — captured\n * ONCE before any resolution runs. Two merges of the same branch set in any\n * order therefore resolve every conflict identically.\n */\n\nimport { canonicalValueKey } from \"./canonical-props\";\nimport { compareStrings } from \"./node-key\";\nimport type {\n EdgeId,\n GraphDef,\n JsonValue,\n NodeId,\n NodeType,\n} from \"./typegraph-internal\";\nimport type {\n BranchId,\n ConflictingValue,\n PropertyConflict,\n PropertyConflictPolicy,\n} from \"./types\";\n\n/**\n * The candidate values for one conflicted property, each tagged with the branch\n * that contributed it. Built by the union phases (node/edge) before delegating\n * to {@link resolveConflictValue}.\n */\ntype ConflictInput = Readonly<{\n /** The property name in conflict. */\n property: string;\n /** Every distinct contributing `(branchId, value)`, one per source. */\n values: readonly ConflictingValue[];\n /** The canonical survivor's own value — kept under the `\"flag\"` policy. */\n canonicalValue: JsonValue;\n}>;\n\n/**\n * Per-branch trust weights for the `\"provenanceWeighted\"` policy. Branches absent\n * from the map default to weight `0`. Ties are broken by the stable branch order.\n */\nexport type ProvenanceWeights = ReadonlyMap<BranchId, number>;\n\n/**\n * The captured, immutable resolution context. The stable branch order is passed\n * separately as a precomputed `branchRank` (built once via {@link buildBranchRank}\n * and shared across every conflict), so this context carries only the policy and\n * the optional `\"provenanceWeighted\"` weights.\n *\n * BRANCH ORDER IS A PRIORITY ORDER: the branch appearing EARLIER in\n * `MergeOptions.branchOrder` (lower rank) has higher precedence. `\"lastWriteWins\"`\n * therefore picks the value of the HIGHEST-PRIORITY branch (lowest rank / first\n * in the order) — the \"winning write\" is defined by the stable order, NOT by\n * wall-clock arrival. There is no wall-clock anywhere in this module.\n */\nexport type ResolutionContext<G extends GraphDef = GraphDef> = Readonly<{\n policy: PropertyConflictPolicy<G>;\n weights?: ProvenanceWeights;\n}>;\n\n/**\n * The outcome of resolving one property conflict: the surviving value and\n * whether the values actually differed (so callers know whether to record a\n * {@link PropertyConflict}).\n */\ntype ConflictResolution = Readonly<{\n value: JsonValue;\n conflicted: boolean;\n}>;\n\n/**\n * Builds the rank lookup for a stable branch order. Branch ids not present in\n * the supplied order are appended in lexicographic order after the explicit\n * ones, so an incomplete `branchOrder` is still total and deterministic.\n */\nexport function buildBranchRank(\n branchOrder: readonly BranchId[],\n allBranchIds: readonly BranchId[],\n): ReadonlyMap<BranchId, number> {\n const rank = new Map<BranchId, number>();\n let next = 0;\n for (const branchId of branchOrder) {\n if (!rank.has(branchId)) {\n rank.set(branchId, next);\n next += 1;\n }\n }\n const remaining = allBranchIds\n .filter((branchId) => !rank.has(branchId))\n .sort((left, right) => compareStrings(left, right));\n for (const branchId of remaining) {\n if (!rank.has(branchId)) {\n rank.set(branchId, next);\n next += 1;\n }\n }\n return rank;\n}\n\n/**\n * Returns the value contributed by the HIGHEST-PRIORITY branch — the one with\n * the lowest rank (earliest in the stable branch order). Ties (two contributions\n * sharing a rank, e.g. when the same branch staged two values) are broken by the\n * canonical serialization of the value, so the choice is fully deterministic.\n */\nfunction pickByPriority(\n values: readonly ConflictingValue[],\n branchRank: ReadonlyMap<BranchId, number>,\n): JsonValue {\n let chosen = values[0]!;\n let chosenRank = branchRank.get(chosen.branchId) ?? Number.MAX_SAFE_INTEGER;\n for (const candidate of values.slice(1)) {\n const candidateRank =\n branchRank.get(candidate.branchId) ?? Number.MAX_SAFE_INTEGER;\n if (candidateRank < chosenRank) {\n chosen = candidate;\n chosenRank = candidateRank;\n } else if (\n candidateRank === chosenRank &&\n canonicalValueKey(candidate.value) < canonicalValueKey(chosen.value)\n ) {\n chosen = candidate;\n }\n }\n return chosen.value;\n}\n\n/**\n * Picks the value contributed by the highest-weight branch under\n * `\"provenanceWeighted\"`. Ties on weight fall back to the stable branch order\n * (highest-priority / lowest rank wins), then to canonical value order — never\n * wall-clock.\n */\nfunction pickByWeight(\n values: readonly ConflictingValue[],\n weights: ProvenanceWeights,\n branchRank: ReadonlyMap<BranchId, number>,\n): JsonValue {\n let chosen = values[0]!;\n let chosenWeight = weights.get(chosen.branchId) ?? 0;\n let chosenRank = branchRank.get(chosen.branchId) ?? Number.MAX_SAFE_INTEGER;\n for (const candidate of values.slice(1)) {\n const candidateWeight = weights.get(candidate.branchId) ?? 0;\n const candidateRank =\n branchRank.get(candidate.branchId) ?? Number.MAX_SAFE_INTEGER;\n if (candidateWeight > chosenWeight) {\n chosen = candidate;\n chosenWeight = candidateWeight;\n chosenRank = candidateRank;\n continue;\n }\n if (candidateWeight === chosenWeight) {\n if (candidateRank < chosenRank) {\n chosen = candidate;\n chosenRank = candidateRank;\n } else if (\n candidateRank === chosenRank &&\n canonicalValueKey(candidate.value) < canonicalValueKey(chosen.value)\n ) {\n chosen = candidate;\n }\n }\n }\n return chosen.value;\n}\n\n/**\n * Returns whether every contributing value is deeply equal (so there is no real\n * conflict). Compares the {@link canonicalValueKey} (recursively key-sorted) form\n * so two branches that wrote a logically-equal object with different key order do\n * NOT register as a conflict.\n */\nfunction allValuesEqual(values: readonly ConflictingValue[]): boolean {\n if (values.length <= 1) {\n return true;\n }\n const first = canonicalValueKey(values[0]!.value);\n return values.every(\n (candidate) => canonicalValueKey(candidate.value) === first,\n );\n}\n\n/**\n * A single `(branchId, props)` contribution to a property union — a cluster\n * member (node) or a collision-group member (edge's staged record). The union\n * phases differ in their surrounding base/survivor logic but agree on HOW to\n * gather a property's candidate values, so they share {@link collectConflictingValues}.\n */\ntype Contribution = Readonly<{\n branchId: BranchId;\n props: Readonly<Record<string, JsonValue>>;\n}>;\n\n/**\n * Collects the distinct `(branchId, value)` contributions for one property across\n * a set of contributions, in stable `(branchId, canonical-value)` order. Distinct\n * on `(branchId, value)`: two contributions from the same branch carrying the same\n * value collapse to one entry, but the same branch contributing two different\n * values is preserved (so an intra-branch contradiction stays visible).\n *\n * Shared by the node property union (T8) and the edge property union (T9) so the\n * determinism-critical dedupe + sort is defined exactly once and node/edge conflict\n * records are shaped identically.\n */\nexport function collectConflictingValues(\n property: string,\n contributions: readonly Contribution[],\n): readonly ConflictingValue[] {\n const seen = new Set<string>();\n const values: ConflictingValue[] = [];\n for (const { branchId, props } of contributions) {\n if (!(property in props)) {\n continue;\n }\n const value = props[property] as JsonValue;\n const dedupeKey = `${branchId}\\0${canonicalValueKey(value)}`;\n if (seen.has(dedupeKey)) {\n continue;\n }\n seen.add(dedupeKey);\n values.push({ branchId, value });\n }\n return [...values].sort((left, right) => {\n const byBranch = compareStrings(left.branchId, right.branchId);\n return byBranch === 0 ?\n compareStrings(\n canonicalValueKey(left.value),\n canonicalValueKey(right.value),\n )\n : byBranch;\n });\n}\n\n/**\n * Resolves one property conflict under the captured {@link ResolutionContext}.\n *\n * - If all contributing values are equal → that value, `conflicted: false`.\n * - `\"flag\"` → keep the canonical's value, `conflicted: true` (caller records a\n * {@link PropertyConflict}; no auto-resolution).\n * - `\"lastWriteWins\"` → the value of the HIGHEST-PRIORITY branch (earliest in the\n * stable order / lowest rank). NEVER wall-clock.\n * - `\"provenanceWeighted\"` → the value of the highest-weight branch (ties →\n * highest-priority branch → canonical value order).\n * - function policy → the value returned by the delegate.\n *\n * @param input The conflicted property, its tagged candidate values, and the\n * canonical survivor's own value.\n * @param context The captured policy + stable branch order + optional weights.\n * @param makeConflict Builds the {@link PropertyConflict}-shaped record passed to\n * a function policy. Kept as a callback so this module needs no knowledge of\n * the node-vs-edge entity shape.\n * @returns The surviving value and whether the values genuinely differed.\n */\nfunction resolveConflictValue<G extends GraphDef = GraphDef>(\n input: ConflictInput,\n context: ResolutionContext<G>,\n branchRank: ReadonlyMap<BranchId, number>,\n makeConflict: (\n resolution: JsonValue,\n ) => Parameters<\n Extract<PropertyConflictPolicy<G>, (...args: never[]) => unknown>\n >[0],\n): ConflictResolution {\n if (allValuesEqual(input.values)) {\n return {\n value: input.values[0]?.value ?? input.canonicalValue,\n conflicted: false,\n };\n }\n\n const { policy } = context;\n\n if (policy === \"flag\") {\n return { value: input.canonicalValue, conflicted: true };\n }\n if (policy === \"lastWriteWins\") {\n return {\n value: pickByPriority(input.values, branchRank),\n conflicted: true,\n };\n }\n if (policy === \"provenanceWeighted\") {\n const weights = context.weights ?? new Map<BranchId, number>();\n return {\n value: pickByWeight(input.values, weights, branchRank),\n conflicted: true,\n };\n }\n // Function policy: delegate, but first resolve a stable provisional value so\n // the conflict record handed to the delegate is itself deterministic.\n const provisional = pickByPriority(input.values, branchRank);\n const resolved = policy(makeConflict(provisional));\n return { value: resolved, conflicted: true };\n}\n\n/**\n * The resolve-and-record tail every property union shares (node cluster union T8,\n * edge collision union T9, inherited 3-way merge T8a): resolve the conflict, then —\n * if the values genuinely differed — build the public {@link PropertyConflict}. The\n * SINGLE place the conflict record is shaped, so the value the function policy sees\n * and the value recorded can never drift.\n *\n * `values` is the FULL contributing set the policy resolves over; `reportedValues`\n * is the PUBLIC subset (synthetic sentinels excluded) recorded on the conflict.\n */\nexport function resolvePropertyUnion<G extends GraphDef = GraphDef>(\n input: Readonly<{\n entityId: NodeId<NodeType> | EdgeId;\n kind: string;\n property: string;\n values: readonly ConflictingValue[];\n reportedValues: readonly ConflictingValue[];\n canonicalValue: JsonValue;\n }>,\n context: ResolutionContext<G>,\n branchRank: ReadonlyMap<BranchId, number>,\n): Readonly<{ value: JsonValue; conflict: PropertyConflict<G> | undefined }> {\n const makeRecord = (resolution: JsonValue): PropertyConflict<G> => ({\n entityId: input.entityId,\n kind: input.kind,\n property: input.property,\n values: input.reportedValues,\n resolution,\n });\n const resolved = resolveConflictValue(\n {\n property: input.property,\n values: input.values,\n canonicalValue: input.canonicalValue,\n },\n context,\n branchRank,\n (resolution) => makeRecord(resolution),\n );\n return {\n value: resolved.value,\n conflict: resolved.conflicted ? makeRecord(resolved.value) : undefined,\n };\n}\n","/**\n * Canonical survivor selection + commutative property union (design §6.4 rule 3\n * & rule 4 / §7.3, T8).\n *\n * Given a {@link ClusterResult} (member ids) and the per-member, per-branch\n * property contributions, this module:\n *\n * 1. Picks the CANONICAL survivor — by default the member with the\n * lexicographically-minimal node id (`MergeOptions.canonical` overrides).\n * Because `generateId()` is nanoid (random, NOT time-prefixed), min-id is\n * independent of creation order — the canonical choice cannot leak the\n * order nodes were created or branches were merged in.\n * 2. UNIONS properties across all members: per property, collect every\n * `(branchId, value)`; if all agree → that value; if they differ → defer to\n * the conflict policy on a STABLE non-wall-clock branch order (T8 /\n * `conflict-policy.ts`), recording a {@link PropertyConflict}.\n *\n * The result is a pure function of the (unordered) member set + the captured\n * branch order, so shuffling members or branches yields an identical resolution.\n */\n\nimport type { ClusterResult } from \"./clustering\";\nimport type { ProvenanceWeights, ResolutionContext } from \"./conflict-policy\";\nimport {\n collectConflictingValues,\n resolvePropertyUnion,\n} from \"./conflict-policy\";\nimport { compareMergeKeys, compareStrings, idOf, mergeKeyOf } from \"./node-key\";\nimport type {\n GraphDef,\n JsonValue,\n NodeId,\n NodeType,\n} from \"./typegraph-internal\";\nimport type {\n BranchId,\n ConflictingValue,\n EntityResolution,\n PropertyConflict,\n PropertyConflictPolicy,\n ResolvedCluster,\n} from \"./types\";\nimport { asBranchId } from \"./types\";\n\n/**\n * Reserved provenance \"branch\" for a BASE contribution (§6.4-D). A committed base\n * member has no real branch; this BranchId-shaped sentinel is the key its\n * contributions carry through the value union and the provenance records, so those\n * paths tolerate a base member without a separate code path. It is NOT a real branch\n * id — it is EXCLUDED from the public {@link EntityResolution.branchOrigins} (which\n * lists only real contributing branches), and callers must never mint a branch with\n * this reserved value (rejected at the merge boundary; kept NUL-free so it round-trips\n * through `persistProvenance` on every backend).\n */\nexport const BASE_PROVENANCE_BRANCH: BranchId =\n asBranchId(\"__committed_base__\");\n\n/** A node id in its untyped (`NodeType`-default) branded form. */\ntype AnyNodeId = NodeId<NodeType>;\n\n/**\n * Where a {@link ClusterMember}'s contribution originated: a branch's STAGED diff,\n * or a committed BASE node a base source pulled into the cluster (design §6.4-C).\n * The mandatory `branchId` cannot represent a base member, so this discriminator is\n * what lets the reconciler tell the two apart — it enforces base-id-wins (§6.4-C: a\n * base member is the canonical survivor, see {@link pickClusterSurvivor}) and tags\n * base provenance with {@link BASE_PROVENANCE_BRANCH} (§6.4-D). The new-vs-base\n * sources (`baseUnique`) emit `\"base\"` members; the public snapshot `merge()` path\n * stays staged-only, so every member there is `\"staged\"`.\n */\ntype MemberOrigin = \"staged\" | \"base\";\n\n/**\n * One member of a cluster, with the parsed props the contributing branch staged\n * for it. A node that appears in several branches contributes several\n * {@link ClusterMember} entries (one per branch), so property differences across\n * branches surface as conflicts.\n */\nexport type ClusterMember = Readonly<{\n origin: MemberOrigin;\n id: AnyNodeId;\n kind: string;\n branchId: BranchId;\n props: Readonly<Record<string, JsonValue>>;\n}>;\n\n/**\n * The fully-resolved canonical entity for one cluster: the survivor id, the\n * unioned property bag, the {@link EntityResolution} record, and any\n * {@link PropertyConflict}s the union surfaced.\n */\nexport type CanonicalEntity = Readonly<{\n canonicalId: AnyNodeId;\n kind: string;\n props: Readonly<Record<string, JsonValue>>;\n resolution: EntityResolution;\n conflicts: readonly PropertyConflict[];\n}>;\n\n/**\n * Bare-id reference selector over a PUBLIC {@link ResolvedCluster}: the member with\n * the lexicographically-minimal node id, or the caller's override. It is NOT the\n * live survivor selector — the merge path selects survivors via\n * {@link pickClusterSurvivor}, which is cross-kind-aware (composite `(kind, id)`\n * keys), enforces base-id-wins, and is where the {@link MergeOptions.canonical} hook\n * is actually consulted. Kept as the documented bare-id default a `canonical` hook\n * mirrors; do not wire new phases onto this helper.\n */\nexport function pickCanonical(\n cluster: ResolvedCluster,\n override?: (cluster: ResolvedCluster) => AnyNodeId,\n): AnyNodeId {\n if (override !== undefined) {\n return override(cluster);\n }\n return [...cluster.members].sort((left, right) =>\n compareStrings(left, right),\n )[0]!;\n}\n\n/**\n * Selects a cluster's canonical survivor MEMBER, enforcing BASE-ID-WINS (§6.4-C)\n * UPSTREAM of the `MergeOptions.canonical` hook. Returning the member (not just its\n * id) carries the survivor's KIND alongside its id, so the canonical entity's kind is\n * the survivor's own kind — never a different-kind member that merely shares the id\n * string (the cross-kind identity hazard).\n *\n * - if the cluster contains a BASE member, the committed base identity is the\n * survivor and the hook is BYPASSED — the committed identity (and everything\n * pointing at it) must stay stable, so this is a commit-correctness invariant,\n * not a survivor preference. By §6.4-A a merged cluster holds ≤1 base member; the\n * min base `(id, kind)` is taken defensively so selection is deterministic even\n * before that guard lands.\n * - otherwise the cluster is pure staged-vs-staged and the hook (mapped over the\n * bare-id view of the cluster) or the min-`(id, kind)` default applies.\n */\nfunction pickClusterSurvivor(\n members: readonly ClusterMember[],\n cluster: ClusterResult,\n canonicalOverride?: (cluster: ResolvedCluster) => AnyNodeId,\n preferKind?: (kinds: readonly string[]) => string | undefined,\n): ClusterMember {\n const byKey = (left: ClusterMember, right: ClusterMember): number =>\n compareMergeKeys(mergeKeyOf(left), mergeKeyOf(right));\n\n // base-id-wins (§6.4-C): the committed identity is the survivor outright. By the\n // staged-only ontology-retype rule, a base member never shares an id with a\n // different-kind member, so no cross-kind kind choice arises here.\n const baseMembers = members\n .filter((member) => member.origin === \"base\")\n .sort(byKey);\n if (baseMembers.length > 0) {\n return baseMembers[0]!;\n }\n\n // The survivor's bare id: the override's pick (mapped over the bare-id view of the\n // cluster) when it names a real member, else the minimum identity's id.\n let canonicalId: AnyNodeId | undefined;\n if (canonicalOverride !== undefined) {\n const chosen = canonicalOverride({ members: cluster.members.map(idOf) });\n if (members.some((member) => member.id === chosen)) {\n canonicalId = chosen;\n }\n }\n if (canonicalId === undefined) {\n const minIdentity = [...cluster.members].sort((left, right) =>\n compareMergeKeys(left, right),\n )[0];\n canonicalId =\n minIdentity === undefined ? members[0]!.id : idOf(minIdentity);\n }\n\n // Among the members AT that id, choose the KIND. An ontology-retype cluster carries\n // several subtype-compatible kinds under one id; `preferKind` selects the\n // MOST-SPECIFIC one, BYPASSING the bare-id hook (which cannot tell `Doctor:x` from\n // `SpecialistDoctor:x`). Otherwise the id has a single kind and the min `(id, kind)`\n // member is taken.\n const membersAtId = members.filter((member) => member.id === canonicalId);\n if (membersAtId.length === 0) {\n return [...members].sort(byKey)[0]!;\n }\n const kinds = [...new Set(membersAtId.map((member) => member.kind))];\n const chosenKind =\n preferKind !== undefined && kinds.length > 1 ?\n preferKind(kinds)\n : undefined;\n return (\n (chosenKind === undefined ? undefined : (\n membersAtId.find((member) => member.kind === chosenKind)\n )) ?? [...membersAtId].sort(byKey)[0]!\n );\n}\n\nfunction findPreferredMember(\n members: readonly ClusterMember[],\n property: string,\n preferredBranchId: BranchId | undefined,\n): ClusterMember | undefined {\n if (preferredBranchId === undefined) {\n return undefined;\n }\n return members.find(\n (member) =>\n member.branchId === preferredBranchId && property in member.props,\n );\n}\n\nfunction memberPropertyValue(\n member: ClusterMember,\n property: string,\n): JsonValue | undefined {\n if (!(property in member.props)) {\n return undefined;\n }\n return member.props[property];\n}\n\nfunction pickCanonicalPropertyValue(\n canonicalMember: ClusterMember,\n members: readonly ClusterMember[],\n property: string,\n values: readonly ConflictingValue[],\n preferredBranchId: BranchId | undefined,\n): JsonValue {\n const preferredMember = findPreferredMember(\n members,\n property,\n preferredBranchId,\n );\n const preferredValue =\n preferredMember === undefined ? undefined : (\n memberPropertyValue(preferredMember, property)\n );\n if (preferredValue !== undefined) {\n return preferredValue;\n }\n\n const canonicalValue = memberPropertyValue(canonicalMember, property);\n return canonicalValue === undefined ? values[0]!.value : canonicalValue;\n}\n\n/**\n * Unions the properties of a cluster's members into a single canonical property\n * bag, resolving any per-property disagreement via the conflict policy on a\n * stable branch order. Returns the merged props plus a {@link PropertyConflict}\n * for every property that genuinely differed.\n *\n * @param canonicalId The survivor id (from {@link pickClusterSurvivor}); the entity id\n * on every recorded conflict.\n * @param kind The canonical entity's kind, recorded on each conflict.\n * @param members Every `(branchId, props)` contribution for this cluster.\n * @param context The captured policy + stable branch order + optional weights.\n * @param branchRank The branch rank lookup (built once, shared across clusters).\n */\nfunction unionProperties(\n canonicalMember: ClusterMember,\n members: readonly ClusterMember[],\n context: ResolutionContext<GraphDef>,\n baseContext: ResolutionContext<GraphDef>,\n branchRank: ReadonlyMap<BranchId, number>,\n preferredBranchId?: BranchId,\n): Readonly<{\n props: Record<string, JsonValue>;\n conflicts: PropertyConflict[];\n}> {\n const canonicalId = canonicalMember.id;\n const kind = canonicalMember.kind;\n const hasBaseMember = members.some((member) => member.origin === \"base\");\n\n const propertyNames = new Set<string>();\n for (const member of members) {\n for (const name of Object.keys(member.props)) {\n propertyNames.add(name);\n }\n }\n\n const props: Record<string, JsonValue> = {};\n const conflicts: PropertyConflict[] = [];\n\n for (const property of [...propertyNames].sort((left, right) =>\n compareStrings(left, right),\n )) {\n const values = collectConflictingValues(property, members);\n if (values.length === 0) {\n continue;\n }\n const canonicalValue = pickCanonicalPropertyValue(\n canonicalMember,\n members,\n property,\n values,\n preferredBranchId,\n );\n\n // A disagreement that involves a committed BASE value is governed by the\n // SEPARATE onBasePropertyConflict policy (§6.4-C) — it must not inherit the\n // staged policy, which could let a branch overwrite committed data. Because\n // base-id-wins makes the base member canonical, `canonicalValue` is already the\n // committed value, so `\"flag\"` keeps it. A property the base lacks is a pure\n // gap-fill / staged-vs-staged conflict and uses the staged policy.\n const baseInvolved =\n hasBaseMember &&\n members.some(\n (member) => member.origin === \"base\" && property in member.props,\n );\n\n // Resolution math sees the FULL contributions (including the base value, so the\n // disagreement is detected and base-id-wins resolves it). But the reserved\n // {@link BASE_PROVENANCE_BRANCH} sentinel is NOT a real branch, so it is excluded\n // from the PUBLIC conflict's `values` — exactly as it is from `branchOrigins`. The\n // committed value the base contributed still surfaces as the conflict `resolution`.\n const reportedValues = values.filter(\n (value) =>\n value.branchId !== BASE_PROVENANCE_BRANCH &&\n value.branchId !== preferredBranchId,\n );\n const { value, conflict } = resolvePropertyUnion(\n {\n entityId: canonicalId,\n kind,\n property,\n values,\n reportedValues,\n canonicalValue,\n },\n baseInvolved ? baseContext : context,\n branchRank,\n );\n props[property] = value;\n if (conflict !== undefined) {\n conflicts.push(conflict);\n }\n }\n\n return { props, conflicts };\n}\n\n/**\n * Resolves a single cluster into its {@link CanonicalEntity}: picks the survivor,\n * unions properties under the conflict policy, and assembles the\n * {@link EntityResolution} record.\n *\n * @param cluster The cluster's member ids (id-sorted from T8 clustering).\n * @param members The per-branch property contributions for those member ids.\n * @param policy The staged-vs-staged property-conflict policy.\n * @param branchRank The captured stable branch rank (built once).\n * @param weights Optional per-branch trust weights for `\"provenanceWeighted\"`.\n * @param canonicalOverride Optional `MergeOptions.canonical` survivor selector.\n * @param basePolicy The SEPARATE base↔branch policy (§6.4-C, `onBasePropertyConflict`)\n * governing conflicts that involve a committed base value. Defaults to `\"flag\"`\n * (keep committed value) — it never inherits `policy`.\n */\nexport function canonicalizeCluster(\n cluster: ClusterResult,\n members: readonly ClusterMember[],\n policy: PropertyConflictPolicy,\n branchRank: ReadonlyMap<BranchId, number>,\n weights?: ProvenanceWeights,\n canonicalOverride?: (cluster: ResolvedCluster) => AnyNodeId,\n basePolicy: PropertyConflictPolicy = \"flag\",\n preferKind?: (kinds: readonly string[]) => string | undefined,\n preferredBranchId?: BranchId,\n): CanonicalEntity {\n const survivor = pickClusterSurvivor(\n members,\n cluster,\n canonicalOverride,\n preferKind,\n );\n const canonicalId = survivor.id;\n const kind = survivor.kind;\n\n const context: ResolutionContext<GraphDef> = {\n policy,\n ...(weights === undefined ? {} : { weights }),\n };\n const baseContext: ResolutionContext<GraphDef> = {\n policy: basePolicy,\n ...(weights === undefined ? {} : { weights }),\n };\n\n const { props, conflicts } = unionProperties(\n survivor,\n members,\n context,\n baseContext,\n branchRank,\n preferredBranchId,\n );\n\n // The public resolution reports the DISTINCT bare member ids; the cluster carries\n // composite `(kind, id)` keys, so project each to its id and dedup (an ontology\n // retype puts several kinds under one id, which collapses to a single member id).\n const memberIds = [\n ...new Set(cluster.members.map((member) => idOf(member))),\n ].sort((left, right) => compareStrings(left, right));\n // `branchOrigins` lists the REAL contributing branches; the reserved\n // {@link BASE_PROVENANCE_BRANCH} sentinel a base member carries is NOT a branch, so\n // it is excluded from this public field (it still flows through the value union and\n // the provenance records, which is where a base contribution is tracked).\n const branchOrigins = [\n ...new Set(\n members\n .map((member) => member.branchId)\n .filter(\n (branchId) =>\n branchId !== BASE_PROVENANCE_BRANCH &&\n branchId !== preferredBranchId,\n ),\n ),\n ].sort((left, right) => compareStrings(left, right));\n\n const resolution: EntityResolution = {\n canonicalId,\n memberIds,\n kind,\n branchOrigins,\n };\n\n return { canonicalId, kind, props, resolution, conflicts };\n}\n","/**\n * A deterministic disjoint-set forest (union-find), shared by every merge phase\n * that folds a set of items into equivalence classes — ontology equivalence\n * (`closures.ts`), candidate clustering (`clustering.ts`), and cross-kind identity\n * grouping (`sources.ts`).\n *\n * Determinism is the load-bearing property: path compression keeps `find` flat,\n * and the union rule makes the chosen representative a pure function of the union\n * SET, not the union order — the item that compares LEAST (by the `compare`\n * supplied at construction) always becomes the root. Two runs that union the same\n * pairs in any order therefore produce identical roots, which is what lets the\n * merge's partitions be order-independent. Callers that only need the partition\n * (and re-sort each group) may pass any total order; callers that expose the\n * representative (e.g. an equivalence-class canonical) pass the comparator whose\n * minimum they want as the representative.\n */\nexport class UnionFind<T> {\n private readonly parent = new Map<T, T>();\n\n constructor(private readonly compare: (left: T, right: T) => number) {}\n\n /** Adds `value` as its own singleton set if it is not already present. */\n add(value: T): void {\n if (!this.parent.has(value)) {\n this.parent.set(value, value);\n }\n }\n\n /** Returns the representative of `value`'s set, compressing the path to it. */\n find(value: T): T {\n this.add(value);\n let root = value;\n while (this.parent.get(root) !== root) {\n root = this.parent.get(root)!;\n }\n // Path compression: point every node on the walk straight at the root.\n let cursor = value;\n while (cursor !== root) {\n const next = this.parent.get(cursor)!;\n this.parent.set(cursor, root);\n cursor = next;\n }\n return root;\n }\n\n /** Merges the sets of `left` and `right`; the `compare`-minimal root wins. */\n union(left: T, right: T): void {\n const leftRoot = this.find(left);\n const rightRoot = this.find(right);\n if (leftRoot === rightRoot) {\n return;\n }\n if (this.compare(leftRoot, rightRoot) <= 0) {\n this.parent.set(rightRoot, leftRoot);\n } else {\n this.parent.set(leftRoot, rightRoot);\n }\n }\n\n /** Every value seen by {@link add}/{@link find}/{@link union}, insertion order. */\n members(): readonly T[] {\n return [...this.parent.keys()];\n }\n}\n","/**\n * Ontology subclass-closure glue over TypeGraph's PUBLIC closure utilities.\n *\n * TypeGraph 0.29.0 exports `computeTransitiveClosure` / `invertClosure` /\n * `isReachable` from the package root, and `store.introspect().ontology` exposes\n * the declared meta-edges as `{ metaEdge, from, to, origin }` records. This\n * module is therefore THIN GLUE: it projects the introspected ontology onto the\n * `[child, parent]` relation pairs the public closure builder expects, folds in\n * `equivalentTo` equivalence classes, and exposes the {@link isReachable}\n * accessor reconcileTypes (T10) consumes. There is deliberately NO local Warshall\n * reimplementation — the transitive work is done entirely by the public\n * `computeTransitiveClosure`.\n *\n * Direction convention (verified against `store.introspect()` at runtime):\n * `subClassOf(Child, Parent)` introspects as `{ metaEdge: \"subClassOf\",\n * from: \"Child\", to: \"Parent\" }`. So `from` is the more-specific (child) type\n * and `to` is the more-general (parent) type, matching the `[child, parent]`\n * relation pairs `computeTransitiveClosure` consumes, where `isReachable(closure,\n * child, ancestor)` answers \"is `child` a (transitive) subclass of `ancestor`?\".\n */\nimport { compareStrings } from \"./node-key\";\nimport type { OntologyIntrospection } from \"./typegraph-internal\";\nimport {\n computeTransitiveClosure,\n isReachable as isReachablePublic,\n} from \"./typegraph-internal\";\nimport { UnionFind } from \"./union-find\";\n\n/**\n * The meta-edge name identifying a subclass relation in `introspect().ontology`.\n */\nexport const SUB_CLASS_OF_META_EDGE = \"subClassOf\";\n\n/**\n * The meta-edge name identifying an equivalence relation in\n * `introspect().ontology`. `equivalentTo` edges are folded into symmetric\n * equivalence classes so that equivalent types share each other's ancestors and\n * descendants.\n */\nconst EQUIVALENT_TO_META_EDGE = \"equivalentTo\";\n\n/**\n * An immutable subclass closure plus the equivalence-class canonicalization used\n * to fold `equivalentTo` relations.\n *\n * - `closure` maps each (canonicalized) child type to the set of all its\n * (canonicalized) transitive ancestors, as produced by the public\n * `computeTransitiveClosure`.\n * - `canonicalOf` maps every type seen in the ontology to its equivalence-class\n * representative (the lexicographically-smallest member). Types not involved\n * in any `equivalentTo` relation map to themselves.\n */\nexport type SubClassClosure = Readonly<{\n closure: ReadonlyMap<string, ReadonlySet<string>>;\n canonicalOf: ReadonlyMap<string, string>;\n}>;\n\n/**\n * Builds the subclass closure from an introspected ontology.\n *\n * Steps:\n * 1. Fold every `equivalentTo` relation into a union-find so equivalent types\n * collapse to a single deterministic representative.\n * 2. Project every `subClassOf` relation onto a `[childRep, parentRep]` pair\n * (each endpoint canonicalized to its equivalence representative). Self\n * loops introduced by equivalence are dropped — a type is never its own\n * strict subclass.\n * 3. Hand the relation pairs to the PUBLIC `computeTransitiveClosure`. No local\n * transitive-closure logic exists here.\n *\n * @param ontology The `store.introspect().ontology` array.\n * @returns A `SubClassClosure` queryable via `isReachable` (which canonicalizes\n * its inputs through the equivalence map).\n */\nexport function buildSubClassClosure(\n ontology: readonly OntologyIntrospection[],\n): SubClassClosure {\n // Union by lexicographically-smaller representative, so each equivalence class's\n // canonical is its lex-min member, independent of relation insertion order.\n const unionFind = new UnionFind<string>(compareStrings);\n\n for (const relation of ontology) {\n unionFind.add(relation.from);\n unionFind.add(relation.to);\n if (relation.metaEdge === EQUIVALENT_TO_META_EDGE) {\n unionFind.union(relation.from, relation.to);\n }\n }\n\n const canonicalOf = new Map<string, string>();\n for (const value of unionFind.members()) {\n canonicalOf.set(value, unionFind.find(value));\n }\n\n const relationKeys = new Set<string>();\n const relations: (readonly [string, string])[] = [];\n for (const relation of ontology) {\n if (relation.metaEdge !== SUB_CLASS_OF_META_EDGE) {\n continue;\n }\n const child = canonicalOf.get(relation.from) ?? relation.from;\n const parent = canonicalOf.get(relation.to) ?? relation.to;\n if (child === parent) {\n continue;\n }\n const key = `${child}\\0${parent}`;\n if (relationKeys.has(key)) {\n continue;\n }\n relationKeys.add(key);\n relations.push([child, parent]);\n }\n\n return {\n closure: computeTransitiveClosure(relations),\n canonicalOf,\n };\n}\n\n/**\n * Resolves a type name to its equivalence-class representative, falling back to\n * the name itself when the type was never seen in the ontology.\n */\nfunction canonicalType(closure: SubClassClosure, type: string): string {\n return closure.canonicalOf.get(type) ?? type;\n}\n\n/**\n * Reports whether `from` is a (transitive) subclass of `to`.\n *\n * Both arguments are canonicalized through the equivalence map first, then the\n * PUBLIC `isReachable` is consulted. Equivalent-but-distinct types (e.g.\n * `equivalentTo(Physician, Doctor)`) are treated as mutually reachable. A type\n * is NOT considered a subclass of itself (the relation is strict / irreflexive),\n * matching the public closure's non-reflexive semantics.\n *\n * @param closure The closure produced by `buildSubClassClosure`.\n * @param from The candidate descendant (more-specific) type.\n * @param to The candidate ancestor (more-general) type.\n */\nexport function isReachable(\n closure: SubClassClosure,\n from: string,\n to: string,\n): boolean {\n const fromRep = canonicalType(closure, from);\n const toRep = canonicalType(closure, to);\n if (fromRep === toRep) {\n // Distinct names that fold to the same equivalence class are mutually\n // reachable; identical names are NOT (strict subclass relation).\n return from !== to;\n }\n return isReachablePublic(closure.closure, fromRep, toRep);\n}\n","/**\n * Pluggable, symmetric candidate-pair similarity scoring (design §8, T6).\n *\n * Four strategy kinds, two of which are the ZERO-EMBEDDING P0 default:\n *\n * - `custom` — the caller's own `score(a, b)` function, clamped to `[0, 1]`.\n * - `fulltext` — an IN-MEMORY Sørensen–Dice trigram coefficient over the\n * configured `fields` of the two staged nodes. No embeddings,\n * no DB round-trips, identical across every backend. This is\n * the portable scorer the FHIR demo runs on.\n * - `vector` / `hybrid` — REAL embeddings scored IN MEMORY. An injected\n * {@link import(\"./types\").Embedder} (precomputed by `merge()`\n * into `ctx.embeddings`, a text→vector lookup) turns each node's\n * configured field text into a vector; the pair is scored by\n * cosine. `vector` is pure cosine over one field; `hybrid` blends\n * cosine with the Dice trigram by `weights` (default 0.5 / 0.5).\n * Staged candidate rows are unindexed, so a backend ANN index\n * cannot score them pairwise — exact in-memory cosine is the right\n * tool at candidate-dedup scale AND is deterministic (the merge\n * contract). With NO embedder configured (`ctx.embeddings`\n * absent), scoring fails with a typed\n * {@link SimilarityUnavailableError}.\n *\n * IMPORTANT: this module never touches `store.search.fulltext`. Staged candidate\n * nodes are unindexed in the working copy, so the DB fulltext index cannot score\n * them; the in-memory Dice scorer is the only correct option for staged\n * candidate generation. `store.search.fulltext` is reserved for the T11 parity\n * probe.\n *\n * Symmetry is a load-bearing invariant: clustering treats candidate edges as\n * undirected, so `scorePair(a, b)` MUST equal `scorePair(b, a)`. The Dice\n * coefficient is symmetric by construction; the `custom` branch documents the\n * requirement and the caller is responsible for honoring it.\n */\n\nimport { canonicalValueKey } from \"./canonical-props\";\nimport { SimilarityUnavailableError } from \"./errors\";\nimport type { MergeKey } from \"./node-key\";\nimport type { Result } from \"./result\";\nimport { err, ok } from \"./result\";\nimport type {\n GraphBackend,\n JsonValue,\n Node,\n NodeType,\n} from \"./typegraph-internal\";\nimport type { SimilarityStrategy } from \"./types\";\n\n/**\n * Ambient context a scorer needs beyond the two nodes.\n *\n * - `backend` is carried for diagnostics (the dialect in error details).\n * - `embeddings` is the precomputed text→vector lookup `merge()` builds by running\n * the injected {@link import(\"./types\").Embedder} over every staged field text of\n * the `vector`/`hybrid` kinds. Its PRESENCE means an embedder was configured;\n * its ABSENCE makes a `vector`/`hybrid` strategy fail with\n * {@link SimilarityUnavailableError}. `fulltext`/`custom` never read it.\n */\nexport type SimilarityContext = Readonly<{\n backend: GraphBackend;\n embeddings?: ReadonlyMap<string, Float32Array>;\n}>;\n\n/** Lower bound of the similarity codomain. */\nconst MIN_SCORE = 0;\n\n/** Upper bound of the similarity codomain. */\nconst MAX_SCORE = 1;\n\n/**\n * Sub-threshold sentinel returned by {@link scorePrepared} for a pair with NO\n * comparable text (one side has no value in the scoring field). It is BELOW\n * {@link MIN_SCORE}, and the kind's `threshold` is validated to `[0, 1]`, so a\n * textless pair can never clear ANY threshold — including `threshold: 0`, where\n * a `MIN_SCORE` (0) return would otherwise pass `score >= threshold` and merge two\n * distinct entities that share no evidence. The standalone {@link scorePair}\n * surfaces this as `MIN_SCORE` to keep its `[0, 1]` contract; only candidate-gen\n * (via {@link createPairScorer} + the threshold gate) treats it as \"never a match\".\n */\nconst NO_EVIDENCE_SCORE = -1;\n\n/** Trigram window length for the Sørensen–Dice coefficient. */\nconst TRIGRAM_LENGTH = 3;\n\n/**\n * Padding character framing a normalized string before trigram extraction, so\n * leading/trailing characters are weighted like interior ones and very short\n * strings still produce trigrams. A space is conventional and cannot appear in a\n * trigram alongside itself for non-trivial inputs.\n */\nconst TRIGRAM_PAD = \" \";\n\n/**\n * Clamps an arbitrary number into the `[0, 1]` similarity codomain. `NaN`\n * collapses to {@link MIN_SCORE} so a misbehaving custom scorer can never inject\n * a non-comparable score into clustering.\n */\nfunction clampScore(value: number): number {\n if (Number.isNaN(value)) {\n return MIN_SCORE;\n }\n if (value < MIN_SCORE) {\n return MIN_SCORE;\n }\n if (value > MAX_SCORE) {\n return MAX_SCORE;\n }\n return value;\n}\n\n/**\n * Reads a single schema field off a node. `Node<N>` spreads its schema\n * properties at the top level (e.g. `node.name`, not `node.props.name`), so a\n * field is indexed directly on the node.\n */\nfunction readField(node: Node<NodeType>, field: string): unknown {\n return (node as unknown as Record<string, unknown>)[field];\n}\n\n/**\n * Concatenates a node's configured `fields` into a single lowercase comparison\n * string. Non-string field values are coerced via `String(...)`; absent /\n * `undefined` fields contribute nothing. Fields are joined with a space so two\n * adjacent fields cannot fuse into a spurious cross-field trigram.\n *\n * Exported so `merge()`'s embedding precompute keys the text→vector lookup by the\n * EXACT same text `scorePair` looks up — there is a single source of truth for \"the\n * text of a node under a strategy's fields\", so the precompute and the scorer can\n * never disagree on what to embed.\n */\nexport function fieldText(\n node: Node<NodeType>,\n fields: readonly string[],\n): string {\n const parts: string[] = [];\n for (const field of fields) {\n const value = readField(node, field);\n if (value === undefined || value === null) {\n continue;\n }\n parts.push(stringifyFieldValue(value));\n }\n return parts.join(TRIGRAM_PAD).toLowerCase();\n}\n\nfunction stringifyFieldValue(value: unknown): string {\n if (typeof value === \"string\") {\n return value;\n }\n if (\n typeof value === \"number\" ||\n typeof value === \"boolean\" ||\n typeof value === \"bigint\"\n ) {\n return String(value);\n }\n // Objects/arrays: canonical (recursively key-sorted) JSON so two\n // logically-equal values written with different key order yield the same\n // comparison text — matching canonicalValueKey used everywhere else.\n return canonicalValueKey(value as JsonValue);\n}\n\n/**\n * Extracts the trigram MULTISET of a normalized string as a count map. A\n * multiset (not a set) is required so repeated trigrams contribute their full\n * multiplicity to the Dice intersection, matching the standard Sørensen–Dice\n * formulation `2·|A∩B| / (|A|+|B|)` over bags.\n */\nfunction trigramMultiset(text: string): Map<string, number> {\n const counts = new Map<string, number>();\n if (text.length === 0) {\n return counts;\n }\n const padded = `${TRIGRAM_PAD}${text}${TRIGRAM_PAD}`;\n for (let index = 0; index + TRIGRAM_LENGTH <= padded.length; index += 1) {\n const gram = padded.slice(index, index + TRIGRAM_LENGTH);\n counts.set(gram, (counts.get(gram) ?? 0) + 1);\n }\n return counts;\n}\n\n/** Total cardinality (with multiplicity) of a trigram multiset. */\nfunction multisetSize(counts: Map<string, number>): number {\n let total = 0;\n for (const count of counts.values()) {\n total += count;\n }\n return total;\n}\n\n/**\n * Multiset intersection cardinality: for every shared trigram, the lesser of\n * the two multiplicities.\n */\nfunction multisetIntersectionSize(\n left: Map<string, number>,\n right: Map<string, number>,\n): number {\n let shared = 0;\n for (const [gram, leftCount] of left) {\n const rightCount = right.get(gram);\n if (rightCount !== undefined) {\n shared += Math.min(leftCount, rightCount);\n }\n }\n return shared;\n}\n\n/**\n * Computes the symmetric Sørensen–Dice trigram coefficient of two raw strings:\n * lowercase, pad, extract trigram multisets, then `2·|A∩B| / (|A|+|B|)`.\n *\n * Edge cases:\n * - Two empty strings score {@link MAX_SCORE} (vacuously identical).\n * - One empty and one non-empty score {@link MIN_SCORE}.\n *\n * Exported so the determinism / acceptance tests can assert the metric directly.\n */\n/**\n * Sørensen–Dice coefficient over two PRECOMPUTED trigram multisets — the metric\n * core, with the same empty-input rules as {@link diceTrigramSimilarity}. The\n * candidate scorer prepares each node's multiset ONCE and calls this directly, so\n * a node's trigrams are built once rather than rebuilt for every pair it joins.\n */\nfunction diceFromMultisets(\n left: Map<string, number>,\n right: Map<string, number>,\n): number {\n const leftSize = multisetSize(left);\n const rightSize = multisetSize(right);\n if (leftSize === 0 && rightSize === 0) {\n return MAX_SCORE;\n }\n if (leftSize === 0 || rightSize === 0) {\n return MIN_SCORE;\n }\n const shared = multisetIntersectionSize(left, right);\n return (2 * shared) / (leftSize + rightSize);\n}\n\nexport function diceTrigramSimilarity(left: string, right: string): number {\n return diceFromMultisets(\n trigramMultiset(left.toLowerCase()),\n trigramMultiset(right.toLowerCase()),\n );\n}\n\n/**\n * The field(s) whose text a `vector`/`hybrid` strategy embeds, or `undefined` for\n * the zero-embedding strategies (`fulltext`/`custom`). `merge()`'s precompute uses\n * this to decide which staged texts to embed; `scorePair` uses the SAME selection\n * implicitly via {@link fieldText}, so the embedded text and the looked-up text\n * match exactly.\n */\nexport function embeddingFields(\n strategy: SimilarityStrategy,\n): readonly string[] | undefined {\n switch (strategy.kind) {\n case \"vector\": {\n return [strategy.field];\n }\n case \"hybrid\": {\n return strategy.fields;\n }\n case \"fulltext\":\n case \"custom\": {\n return undefined;\n }\n default: {\n const exhaustive: never = strategy;\n throw new Error(\n `Unhandled similarity strategy: ${JSON.stringify(exhaustive)}`,\n );\n }\n }\n}\n\n/**\n * Cosine similarity of two equal-length vectors, in `[-1, 1]`. Computed in a fixed\n * index order so it is deterministic. Returns {@link MIN_SCORE} for a dimension\n * mismatch or a zero-magnitude vector (no comparable direction → no evidence),\n * never `NaN`. `scorePair` clamps the result into the `[0, 1]` similarity codomain.\n *\n */\nfunction cosineSimilarity(left: Float32Array, right: Float32Array): number {\n if (left.length !== right.length || left.length === 0) {\n return MIN_SCORE;\n }\n let dot = 0;\n let leftMagnitude = 0;\n let rightMagnitude = 0;\n for (let index = 0; index < left.length; index += 1) {\n const leftComponent = left[index]!;\n const rightComponent = right[index]!;\n dot += leftComponent * rightComponent;\n leftMagnitude += leftComponent * leftComponent;\n rightMagnitude += rightComponent * rightComponent;\n }\n if (leftMagnitude === 0 || rightMagnitude === 0) {\n return MIN_SCORE;\n }\n return dot / (Math.sqrt(leftMagnitude) * Math.sqrt(rightMagnitude));\n}\n\n/**\n * Cosine of the two field texts' precomputed vectors. A text whose vector is\n * absent from the lookup (only possible if the precompute and scorer disagreed —\n * they cannot, since both go through {@link fieldText}) scores {@link MIN_SCORE}\n * defensively rather than throwing.\n */\nfunction cosineFromLookup(\n embeddings: ReadonlyMap<string, Float32Array>,\n leftText: string,\n rightText: string,\n): number {\n const leftVector = embeddings.get(leftText);\n const rightVector = embeddings.get(rightText);\n if (leftVector === undefined || rightVector === undefined) {\n return MIN_SCORE;\n }\n return cosineSimilarity(leftVector, rightVector);\n}\n\n/** Default hybrid blend: equal weight to the vector and fulltext components. */\nconst DEFAULT_HYBRID_WEIGHT = 0.5;\n\n/**\n * Coerces a raw weight into the non-negative finite domain. A non-finite value\n * (`NaN`/`±Infinity`) contributes `0` rather than poisoning the whole blend —\n * `Math.max(0, NaN)` is `NaN`, which would survive the `total === 0` guard and\n * collapse every hybrid score to 0. Valid weights are rejected earlier at the\n * options boundary (`normalizeMergeOptions`); this is the defensive backstop.\n */\nfunction nonNegativeFinite(value: number): number {\n return Number.isFinite(value) ? Math.max(0, value) : 0;\n}\n\n/**\n * Normalizes a hybrid strategy's `weights` so the vector and fulltext components\n * sum to 1, defaulting either omitted side to {@link DEFAULT_HYBRID_WEIGHT}. A\n * degenerate `{0, 0}` (or negative / non-finite) total falls back to an even\n * 0.5/0.5 split so the blend can never divide by zero, invert, or produce `NaN`.\n */\nfunction normalizeHybridWeights(\n weights: Readonly<{ vector?: number; fulltext?: number }> | undefined,\n): Readonly<{ vector: number; fulltext: number }> {\n const vector = nonNegativeFinite(weights?.vector ?? DEFAULT_HYBRID_WEIGHT);\n const fulltext = nonNegativeFinite(\n weights?.fulltext ?? DEFAULT_HYBRID_WEIGHT,\n );\n const total = vector + fulltext;\n if (total === 0) {\n return { vector: DEFAULT_HYBRID_WEIGHT, fulltext: DEFAULT_HYBRID_WEIGHT };\n }\n return { vector: vector / total, fulltext: fulltext / total };\n}\n\n/**\n * Builds the {@link SimilarityUnavailableError} for a `vector`/`hybrid` strategy\n * requested with no configured embedder.\n */\nfunction embedderUnavailable(\n kind: \"vector\" | \"hybrid\",\n ctx: SimilarityContext,\n): SimilarityUnavailableError {\n return new SimilarityUnavailableError(\n `Similarity strategy \"${kind}\" requires a configured embedder (MergeOptions.embedder); none was provided.`,\n { details: { strategy: kind, dialect: ctx.backend.dialect } },\n );\n}\n\n/**\n * The field(s) a strategy reads off a node to form its comparison text: the\n * embedded field(s) for `vector`/`hybrid`, the configured `fields` for `fulltext`,\n * and none for `custom` (which scores the node objects directly).\n */\nfunction scoringFields(strategy: SimilarityStrategy): readonly string[] {\n switch (strategy.kind) {\n case \"fulltext\":\n case \"hybrid\": {\n return strategy.fields;\n }\n case \"vector\": {\n return [strategy.field];\n }\n case \"custom\": {\n return [];\n }\n default: {\n const exhaustive: never = strategy;\n throw new Error(\n `Unhandled similarity strategy: ${JSON.stringify(exhaustive)}`,\n );\n }\n }\n}\n\n/**\n * A node's per-strategy comparison inputs, computed ONCE and reused across every\n * pair the node joins: its lowercase {@link fieldText} (looked up in the embedding\n * map for `vector`/`hybrid`) and, for the trigram strategies, its trigram multiset.\n * The original `node` is retained for the `custom` strategy, which scores nodes\n * directly. {@link createPairScorer} memoizes one of these per node.\n */\ntype PreparedNode<K extends NodeType = NodeType> = Readonly<{\n node: Node<K>;\n text: string;\n grams: Map<string, number>;\n}>;\n\n/** Empty trigram multiset shared by strategies that never consult grams. */\nconst NO_GRAMS: Map<string, number> = new Map<string, number>();\n\n/** Computes a node's {@link PreparedNode} for a strategy (trigrams only when used). */\nfunction prepareNode<K extends NodeType>(\n node: Node<K>,\n strategy: SimilarityStrategy,\n): PreparedNode<K> {\n const text = fieldText(node, scoringFields(strategy));\n const grams =\n strategy.kind === \"fulltext\" || strategy.kind === \"hybrid\" ?\n trigramMultiset(text)\n : NO_GRAMS;\n return { node, text, grams };\n}\n\n/**\n * Scores a candidate pair from its two {@link PreparedNode}s under a\n * {@link SimilarityStrategy}, returning a value in `[0, 1]` (guaranteed symmetric\n * for the built-in strategies). This is the single match-decision switch;\n * {@link scorePair} and {@link createPairScorer} both feed it prepared nodes.\n *\n * @returns `ok(score)` on success, or `err(SimilarityUnavailableError)` when a\n * `vector`/`hybrid` strategy is requested with no configured embedder.\n */\nfunction scorePrepared<K extends NodeType>(\n left: PreparedNode<K>,\n right: PreparedNode<K>,\n strategy: SimilarityStrategy,\n ctx: SimilarityContext,\n): Result<number, SimilarityUnavailableError> {\n switch (strategy.kind) {\n case \"custom\": {\n // The caller owns symmetry here; we only clamp into the codomain so a\n // stray out-of-range or NaN score cannot corrupt clustering.\n const raw = strategy.score(left.node, right.node);\n return ok(clampScore(raw));\n }\n case \"fulltext\": {\n // A node with NO text in the configured fields offers no evidence of a\n // match. Comparing two such nodes must NOT collapse two distinct entities,\n // NOT even at threshold 0 — so it returns the sub-threshold\n // {@link NO_EVIDENCE_SCORE}, never the vacuous diceTrigramSimilarity(\"\",\"\")\n // === 1. The metric itself keeps empty==empty==1 for direct callers / the\n // acceptance tests; this guard is candidate-gen's policy.\n if (left.text.length === 0 || right.text.length === 0) {\n return ok(NO_EVIDENCE_SCORE);\n }\n return ok(clampScore(diceFromMultisets(left.grams, right.grams)));\n }\n case \"vector\": {\n // Presence of `ctx.embeddings` == an embedder was configured. Absent → the\n // caller asked for vector similarity without supplying MergeOptions.embedder.\n if (ctx.embeddings === undefined) {\n return err(embedderUnavailable(\"vector\", ctx));\n }\n // A node with no text in the field offers no evidence of a match —\n // NO_EVIDENCE_SCORE, not the cosine of two zero/absent vectors (mirrors the\n // fulltext guard, and excludes the pair even at threshold 0).\n if (left.text.length === 0 || right.text.length === 0) {\n return ok(NO_EVIDENCE_SCORE);\n }\n const cosine = cosineFromLookup(ctx.embeddings, left.text, right.text);\n return ok(clampScore(cosine));\n }\n case \"hybrid\": {\n if (ctx.embeddings === undefined) {\n return err(embedderUnavailable(\"hybrid\", ctx));\n }\n if (left.text.length === 0 || right.text.length === 0) {\n return ok(NO_EVIDENCE_SCORE);\n }\n // Blend exact in-memory cosine (semantic/spelling proximity) with the Dice\n // trigram (literal character overlap) by the normalized weights. Both\n // components are symmetric, so the blend is too.\n const vectorScore = clampScore(\n cosineFromLookup(ctx.embeddings, left.text, right.text),\n );\n const fulltextScore = diceFromMultisets(left.grams, right.grams);\n const weights = normalizeHybridWeights(strategy.weights);\n return ok(\n clampScore(\n weights.vector * vectorScore + weights.fulltext * fulltextScore,\n ),\n );\n }\n default: {\n // Exhaustiveness guard: a new strategy kind must add a branch above, or\n // this assignment fails to compile.\n const exhaustive: never = strategy;\n throw new Error(\n `Unhandled similarity strategy: ${JSON.stringify(exhaustive)}`,\n );\n }\n }\n}\n\n/**\n * Scores a candidate pair under a {@link SimilarityStrategy}, returning a value\n * in `[0, 1]` (guaranteed symmetric for the built-in strategies). A single-pair\n * convenience over {@link scorePrepared}; the candidate loop uses\n * {@link createPairScorer} instead so per-node work is not repeated across pairs.\n *\n * @param a First staged node.\n * @param b Second staged node.\n * @param strategy The per-kind similarity strategy from the kind's `ResolveConfig`.\n * @param ctx Ambient context (the backend, for vector-capability gating).\n * @returns `ok(score)` on success, or `err(SimilarityUnavailableError)` when a\n * `vector`/`hybrid` strategy is requested with no configured embedder.\n */\nexport function scorePair<K extends NodeType>(\n a: Node<K>,\n b: Node<K>,\n strategy: SimilarityStrategy,\n ctx: SimilarityContext,\n): Result<number, SimilarityUnavailableError> {\n const result = scorePrepared(\n prepareNode(a, strategy),\n prepareNode(b, strategy),\n strategy,\n ctx,\n );\n // The standalone scorer's contract is a [0, 1] score; the internal\n // NO_EVIDENCE_SCORE sentinel (a textless pair) surfaces here as MIN_SCORE. Only\n // candidate-gen needs the sub-threshold value to exclude the pair at threshold 0.\n if (result.success && result.data === NO_EVIDENCE_SCORE) {\n return ok(MIN_SCORE);\n }\n return result;\n}\n\n/**\n * Builds a memoized pair scorer for one kind. Each node's {@link PreparedNode} is\n * computed once, keyed by its `(kind, id)` {@link MergeKey}, so a node appearing in\n * m candidate pairs has its text + trigram multiset built once, not m times — the\n * per-bucket cost drops from O(pairs · text) trigram builds to O(nodes · text).\n * Pair-for-pair equivalent to {@link scorePair}.\n */\nexport function createPairScorer<K extends NodeType>(\n strategy: SimilarityStrategy,\n ctx: SimilarityContext,\n): (\n a: MergeKey,\n left: Node<K>,\n b: MergeKey,\n right: Node<K>,\n) => Result<number, SimilarityUnavailableError> {\n const prepared = new Map<MergeKey, PreparedNode<K>>();\n const prepare = (key: MergeKey, node: Node<K>): PreparedNode<K> => {\n const cached = prepared.get(key);\n if (cached !== undefined) {\n return cached;\n }\n const fresh = prepareNode(node, strategy);\n prepared.set(key, fresh);\n return fresh;\n };\n return (a, left, b, right) =>\n scorePrepared(prepare(a, left), prepare(b, right), strategy, ctx);\n}\n","/**\n * The shared SCORING stage (design §4, the single match-decision point).\n *\n * Candidate generation is three layers — sources → scoring → reconciler (§4).\n * This module is the MIDDLE layer: it turns the candidate PROPOSALS every source\n * emits into the {@link CandidateEdge} set the reconciler consumes, applying the\n * EXACT same scorer + threshold regardless of which source proposed a pair. A\n * source proposes (recall); scoring disposes (the match decision).\n *\n * Two proposal kinds enter:\n *\n * - {@link CandidatePair}s — unscored `(a, b)` node pairs from any source. They\n * are deduped by canonical `(a, b)` and each scored EXACTLY ONCE by\n * {@link scorePair}; only pairs clearing the kind's threshold become edges.\n * - FORCED {@link CandidateEdge}s — DEFINITIONAL matches (a shared unique value)\n * that BYPASS scoring entirely, emitted at {@link FORCED_MATCH_SCORE}. A forced\n * pair is never also fuzzy-scored: forced `(a, b)` keys are reserved first, so\n * a fuzzy pair proposing the same endpoints is dropped before scoring.\n *\n * This was previously fused into `candidate-gen.ts`'s `generateCandidates` (which\n * scored AND thresholded inline); naming scoring as its own stage is what makes\n * \"the scorer — not a source — decides matches\" concrete (§4). `generateCandidates`\n * now composes the bucket sources over this stage.\n *\n * Determinism: the emitted edge set is a pure function of the proposal SETS — pairs\n * are deduped by canonical `(a, b)`, scored by the symmetric {@link scorePair}, and\n * the final list is sorted by `(a, b)`, so neither the order proposals arrive in\n * nor the directionality of a pair affects the result.\n *\n * The {@link ComparisonCeilingPolicy} bounds only the FUZZY scoring work (the\n * embedder step for vector/hybrid); FORCED edges are definitional, not\n * similarity-based, so they are emitted regardless of the ceiling:\n *\n * - `\"error\"` — exceeding the ceiling fails with a typed {@link MergeError}.\n * - `\"mergeByIdOnly\"` — fuzzy similarity is SKIPPED for the kind (no\n * threshold-scored edges), FORCED edges are still emitted,\n * and a {@link CandidateWarning} is recorded.\n */\n\nimport { MergeError } from \"./errors\";\nimport { compareMergeKeys, type MergeKey } from \"./node-key\";\nimport type { Result } from \"./result\";\nimport { err, isErr, ok } from \"./result\";\nimport type { SimilarityContext } from \"./similarity\";\nimport { createPairScorer } from \"./similarity\";\nimport type { Node, NodeType } from \"./typegraph-internal\";\nimport type { ComparisonCeilingPolicy, ResolveConfig } from \"./types\";\n\n/**\n * An undirected candidate-merge edge between two nodes that should merge.\n * Endpoints are stored in ascending id order (`a < b`) so the edge has a single\n * canonical representation. Fuzzy edges carry their similarity score; FORCED\n * (definitional) edges carry {@link FORCED_MATCH_SCORE}.\n */\nexport type CandidateEdge = Readonly<{\n a: MergeKey;\n b: MergeKey;\n score: number;\n}>;\n\n/**\n * A non-fatal advisory raised during scoring — currently only the\n * `\"mergeByIdOnly\"` comparison-ceiling skip. Surfaced in the merge report.\n */\ntype CandidateWarning = Readonly<{\n kind: \"comparisonCeiling\";\n comparisons: number;\n limit: number;\n message: string;\n}>;\n\n/**\n * The scoring result for one kind: the emitted edges plus any advisories.\n * Returned inside a {@link Result} so the `vector`/`hybrid` guard and the\n * `\"error\"` ceiling path can fail without throwing.\n */\nexport type CandidateGenResult = Readonly<{\n edges: readonly CandidateEdge[];\n warnings: readonly CandidateWarning[];\n}>;\n\n/**\n * An unscored candidate pair a source proposes for scoring: the canonical\n * endpoint ids `(a, b)` (`a < b`) plus the two node objects the scorer reads\n * fields off of. `left`/`right` carry the nodes whose ids are `a`/`b`\n * respectively, but {@link scorePair} is symmetric so their roles are\n * interchangeable for scoring.\n */\nexport type CandidatePair<K extends NodeType = NodeType> = Readonly<{\n a: MergeKey;\n b: MergeKey;\n left: Node<K>;\n right: Node<K>;\n}>;\n\n/**\n * The proposals the scoring stage consumes for one kind: the fuzzy pairs to score\n * and the forced (definitional) edges to pass through unscored.\n */\nexport type ScoringInput<K extends NodeType = NodeType> = Readonly<{\n pairs: readonly CandidatePair<K>[];\n forcedEdges: readonly CandidateEdge[];\n}>;\n\n/**\n * Score for a FORCED (definitional, unique-match) edge — the maximum, so the pair\n * always clears any threshold and is never the weakest edge a diameter guard would\n * drop. Sources that emit forced edges stamp this score; scoring passes it through.\n */\nexport const FORCED_MATCH_SCORE = 1;\n\n/**\n * Stable `(a, b)` ascending comparator over {@link CandidateEdge}. Endpoints are\n * `(kind, id)` MergeKeys, so ordering uses the SAME id-first {@link compareMergeKeys}\n * the clustering stage uses — never raw kind-first string order. The SINGLE shared\n * definition: clustering and `merge()`'s candidate generation import this instead of\n * re-deriving it, so every stage orders the edge set identically by construction.\n */\nexport function compareCandidateEdges(\n left: CandidateEdge,\n right: CandidateEdge,\n): number {\n const byA = compareMergeKeys(left.a, right.a);\n return byA === 0 ? compareMergeKeys(left.b, right.b) : byA;\n}\n\n/** The canonical dedup key for a pair / edge's ordered endpoints. */\nfunction endpointKey(a: MergeKey, b: MergeKey): string {\n return JSON.stringify([a, b]);\n}\n\n/**\n * Scores the proposed candidates for a single kind into a {@link CandidateEdge}\n * set, applying the kind's threshold and the comparison-ceiling policy.\n *\n * FORCED endpoint keys are reserved FIRST, so a fuzzy pair proposing the same\n * `(a, b)` is dropped before scoring — a forced (definitional) match is never also\n * fuzzy-scored. The remaining fuzzy pairs are deduped by canonical `(a, b)` and\n * scored exactly once; only those clearing `threshold` become edges. The combined\n * forced + passing-fuzzy edge list is sorted by `(a, b)`.\n *\n * @param input The fuzzy pairs + forced edges every source proposed for the kind.\n * @param resolveConfig The kind's resolution config (similarity strategy + threshold).\n * @param ctx Ambient context (the backend, for vector-capability gating).\n * @param ceilingPolicy Behavior when `maxComparisonsPerKind` is exceeded.\n * @param maxComparisonsPerKind Optional per-kind FUZZY-comparison ceiling.\n * `undefined` means unbounded. Forced edges are never bounded by it.\n * @returns `ok({ edges, warnings })`, or `err(...)` when the `\"error\"` ceiling\n * fires or a `vector`/`hybrid` guard trips.\n */\nexport function scoreCandidates<K extends NodeType>(\n input: ScoringInput<K>,\n resolveConfig: ResolveConfig,\n ctx: SimilarityContext,\n ceilingPolicy: ComparisonCeilingPolicy,\n maxComparisonsPerKind?: number,\n): Result<CandidateGenResult, MergeError> {\n const { similarity, threshold } = resolveConfig;\n\n // Reserve forced endpoint keys FIRST so a fuzzy pair proposing the same pair is\n // dropped — a definitional match is never also fuzzy-scored (the old Phase-1\n // before Phase-2 dedup, now source-agnostic).\n const seen = new Set<string>();\n const forced: CandidateEdge[] = [];\n for (const edge of input.forcedEdges) {\n const key = endpointKey(edge.a, edge.b);\n if (!seen.has(key)) {\n seen.add(key);\n forced.push(edge);\n }\n }\n\n const fuzzy: CandidatePair<K>[] = [];\n for (const pair of input.pairs) {\n const key = endpointKey(pair.a, pair.b);\n if (!seen.has(key)) {\n seen.add(key);\n fuzzy.push(pair);\n }\n }\n\n if (\n maxComparisonsPerKind !== undefined &&\n fuzzy.length > maxComparisonsPerKind\n ) {\n if (ceilingPolicy === \"error\") {\n return err(\n new MergeError(\n `Comparison ceiling exceeded: ${fuzzy.length} candidate pairs > maxComparisonsPerKind ${maxComparisonsPerKind}.`,\n {\n details: {\n comparisons: fuzzy.length,\n limit: maxComparisonsPerKind,\n },\n suggestion:\n 'Tighten the kind\\'s block() to shrink buckets, or set onComparisonCeiling: \"mergeByIdOnly\".',\n },\n ),\n );\n }\n // \"mergeByIdOnly\": skip FUZZY similarity for this kind, but KEEP the forced\n // edges — those are definitional, not similarity-based.\n return ok({\n edges: [...forced].sort((left, right) =>\n compareCandidateEdges(left, right),\n ),\n warnings: [\n {\n kind: \"comparisonCeiling\",\n comparisons: fuzzy.length,\n limit: maxComparisonsPerKind,\n message: `Skipped similarity for this kind: ${fuzzy.length} candidate pairs exceeded maxComparisonsPerKind ${maxComparisonsPerKind}; nodes will merge by id and exact unique match only.`,\n },\n ],\n });\n }\n\n // One memoized scorer per kind so each node's text + trigram multiset is built\n // once, not once per pair it joins (the within-bucket pair count is ~O(n²)).\n const scorer = createPairScorer<K>(similarity, ctx);\n const edges: CandidateEdge[] = [...forced];\n for (const { left, right, a, b } of fuzzy) {\n const scored = scorer(a, left, b, right);\n if (isErr(scored)) {\n return err(scored.error);\n }\n if (scored.data >= threshold) {\n edges.push({ a, b, score: scored.data });\n }\n }\n\n return ok({\n edges: edges.sort((left, right) => compareCandidateEdges(left, right)),\n warnings: [],\n });\n}\n","/**\n * Connected-components clustering over the candidate-edge graph (design §6.4\n * rule 2, T8).\n *\n * Two staged nodes are merged into the same cluster iff they are connected\n * (transitively) by a chain of candidate-merge edges. This is the SINGLE-LINK\n * rule: A~B and B~C cluster {A,B,C} even when A≁C directly, because each hop\n * cleared the similarity threshold. The frozen v1 default is single-link with NO\n * guard; the optional diameter guard (below) is the only deviation.\n *\n * Determinism:\n * - The component assignment is computed via union-find over the candidate\n * edge SET (a pure function of the edges, never their arrival order). We\n * additionally order edge consumption by `(a, b)` and union with a\n * min-id-as-root tie-break, so even the internal forest is identical across\n * shuffled inputs — not merely the resulting partition.\n * - Every cluster's `members` array is sorted by node id, and the cluster list\n * is sorted by each cluster's minimum member id. So the output is fully\n * canonical regardless of the order edges or seed node ids are supplied in.\n *\n * Diameter guard (optional, design §6.4 / T8):\n * When `clusterMaxDiameter` is set, a formed component must satisfy a single\n * bound: the maximum pairwise graph distance (in candidate-edge hops) between\n * any two members must not exceed the guard. A component that violates the\n * bound is split by the deterministic DROP-WEAKEST single-link rule: remove the\n * lowest-scoring candidate edge (ties broken by `(a, b)` id order) and\n * recompute components on the survivors, repeating until every sub-component\n * satisfies the bound. This is the frozen v1 behavior — no correlation\n * clustering in P0.\n */\n\nimport type { CandidateEdge } from \"./candidate-gen\";\nimport { compareMergeKeys, type MergeKey } from \"./node-key\";\nimport { compareCandidateEdges } from \"./scoring\";\nimport { UnionFind } from \"./union-find\";\n\n/**\n * The node IDENTITY the cluster graph is built over: the composite `(kind, id)`\n * {@link MergeKey}, NOT a bare node id. Two different-kind nodes that share an id\n * string are DISTINCT identities here, so single-link clustering never fuses them\n * into one component (the base guard would otherwise be silently bypassed).\n */\ntype AnyNodeId = MergeKey;\n\n/**\n * A resolved cluster of node identities that the merge collapses into one canonical\n * survivor. `members` is always sorted (by id, then kind) and never empty.\n */\nexport type ClusterResult = Readonly<{\n members: readonly AnyNodeId[];\n}>;\n\n/**\n * Builds connected components from a candidate-edge set plus an explicit seed\n * set of all node ids in scope. Seed ids with no incident edge become singleton\n * components, so the result partitions the ENTIRE node set, not just edge\n * endpoints.\n */\nfunction buildComponents(\n edges: readonly CandidateEdge[],\n nodeIds: readonly AnyNodeId[],\n edgesSorted = false,\n): ClusterResult[] {\n const forest = new UnionFind<AnyNodeId>(compareMergeKeys);\n const seed = new Set<AnyNodeId>(nodeIds);\n for (const id of nodeIds) {\n forest.add(id);\n }\n // Consume edges in canonical order so the forest is identical across shuffles.\n // An edge whose endpoint is NOT in the seed set is out of scope and skipped, so\n // the partition is a function of exactly the supplied node set — a candidate\n // edge can never inject a phantom member never passed in `nodeIds`.\n // `edgesSorted` lets a caller that already holds the edges in canonical order\n // (the drop-weakest loop) skip the redundant re-sort on every iteration.\n const orderedEdges =\n edgesSorted ? edges : (\n [...edges].sort((left, right) => compareCandidateEdges(left, right))\n );\n for (const edge of orderedEdges) {\n if (!seed.has(edge.a) || !seed.has(edge.b)) {\n continue;\n }\n forest.union(edge.a, edge.b);\n }\n\n const byRoot = new Map<AnyNodeId, AnyNodeId[]>();\n for (const id of forest.members()) {\n const root = forest.find(id);\n const bucket = byRoot.get(root);\n if (bucket === undefined) {\n byRoot.set(root, [id]);\n } else {\n bucket.push(id);\n }\n }\n\n const clusters: ClusterResult[] = [];\n for (const members of byRoot.values()) {\n clusters.push({\n members: [...members].sort((left, right) =>\n compareMergeKeys(left, right),\n ),\n });\n }\n // Order clusters by their (sorted) first member, which is the minimum id.\n clusters.sort((left, right) =>\n compareMergeKeys(left.members[0]!, right.members[0]!),\n );\n return clusters;\n}\n\n/**\n * Builds the undirected adjacency (member id → set of neighbor ids) for one\n * component's members, restricted to candidate edges whose BOTH endpoints are in\n * the component.\n */\nfunction adjacencyOf(\n members: readonly AnyNodeId[],\n edges: readonly CandidateEdge[],\n): Map<AnyNodeId, Set<AnyNodeId>> {\n const memberSet = new Set(members);\n const adjacency = new Map<AnyNodeId, Set<AnyNodeId>>();\n for (const id of members) {\n adjacency.set(id, new Set());\n }\n for (const edge of edges) {\n if (memberSet.has(edge.a) && memberSet.has(edge.b)) {\n adjacency.get(edge.a)!.add(edge.b);\n adjacency.get(edge.b)!.add(edge.a);\n }\n }\n return adjacency;\n}\n\n/**\n * Whether one component's pairwise graph diameter (in candidate-edge hops) EXCEEDS\n * `maxDiameter`. Runs a BFS from each member but EARLY-EXITS the moment it reaches\n * a node beyond `maxDiameter` (or finds the component disconnected), so a check\n * costs `O(members + edges-within-the-bound)` rather than the full all-pairs\n * `O(V·(V+E))` exact diameter — the guard only needs the threshold answer, never\n * the exact value. Equivalent to `componentDiameter(...) > maxDiameter`.\n */\nfunction exceedsDiameter(\n members: readonly AnyNodeId[],\n edges: readonly CandidateEdge[],\n maxDiameter: number,\n): boolean {\n if (members.length <= 1) {\n return false;\n }\n const adjacency = adjacencyOf(members, edges);\n for (const source of members) {\n const distance = new Map<AnyNodeId, number>([[source, 0]]);\n const queue: AnyNodeId[] = [source];\n let head = 0;\n while (head < queue.length) {\n const current = queue[head]!;\n head += 1;\n const currentDistance = distance.get(current)!;\n for (const neighbor of adjacency.get(current)!) {\n if (!distance.has(neighbor)) {\n const neighborDistance = currentDistance + 1;\n if (neighborDistance > maxDiameter) {\n return true; // a pair already exceeds the bound — stop early\n }\n distance.set(neighbor, neighborDistance);\n queue.push(neighbor);\n }\n }\n }\n if (distance.size < members.length) {\n return true; // disconnected from `source` → diameter is infinite\n }\n }\n return false;\n}\n\n/**\n * The candidate edges internal to a single component (both endpoints inside it),\n * in canonical `(a, b)` order.\n */\nfunction internalEdges(\n members: readonly AnyNodeId[],\n edges: readonly CandidateEdge[],\n): CandidateEdge[] {\n const memberSet = new Set(members);\n return edges\n .filter((edge) => memberSet.has(edge.a) && memberSet.has(edge.b))\n .sort((left, right) => compareCandidateEdges(left, right));\n}\n\n/**\n * The single weakest edge of a set: lowest score, ties broken by `(a, b)` id\n * order. The deterministic edge the drop-weakest splits remove first.\n */\nfunction weakestEdge(edges: readonly CandidateEdge[]): CandidateEdge {\n return edges.reduce((current, candidate) => {\n if (candidate.score !== current.score) {\n return candidate.score < current.score ? candidate : current;\n }\n return compareCandidateEdges(candidate, current) < 0 ? candidate : current;\n });\n}\n\n/**\n * The shared DROP-WEAKEST splitter (design §6.4 / §6.4-A). Repeatedly removes the\n * lowest-scoring internal candidate edge (ties broken by `(a, b)` id order) and\n * recomputes components until NO sub-component is still `isOffending`, then returns\n * the satisfying sub-components. `isOffending` receives the current surviving edge\n * set so a predicate like the diameter check can measure against it.\n *\n * The degenerate \"still offending but no internal edge left to drop\" case — only\n * reachable if a future caller passes a ≥2-member component with no internal edge —\n * degrades EVERY such offending component to singletons (keeping every satisfying\n * sibling intact), so the partition is never silently truncated. It first exhausts the\n * splittable offending components (those with an edge to drop), so an edgeless\n * offending sibling can never leave another offending component unsplit.\n */\nfunction splitUntil(\n members: readonly AnyNodeId[],\n edges: readonly CandidateEdge[],\n isOffending: (\n members: readonly AnyNodeId[],\n surviving: readonly CandidateEdge[],\n ) => boolean,\n): ClusterResult[] {\n // `surviving` starts in canonical `(a, b)` order and `.filter` preserves it, so\n // every iteration can pass it to `buildComponents` pre-sorted.\n let surviving = internalEdges(members, edges);\n\n for (;;) {\n const components = buildComponents(surviving, members, true);\n const offending = components.filter((component) =>\n isOffending(component.members, surviving),\n );\n if (offending.length === 0) {\n return components;\n }\n // Prefer to keep dropping the weakest edge of an offending component that still has\n // one; only when EVERY offending component is edgeless do we degrade them all.\n // Scan lazily — stop at the first offending component that still has an internal\n // edge instead of materializing internalEdges for every offending component.\n let splittable: CandidateEdge[] | undefined;\n for (const component of offending) {\n const componentEdges = internalEdges(component.members, surviving);\n if (componentEdges.length > 0) {\n splittable = componentEdges;\n break;\n }\n }\n if (splittable === undefined) {\n const offendingSet = new Set(offending);\n return components.flatMap((component) =>\n offendingSet.has(component) ?\n component.members.map((id) => ({ members: [id] }))\n : [component],\n );\n }\n const weakest = weakestEdge(splittable);\n surviving = surviving.filter((edge) => edge !== weakest);\n }\n}\n\n/**\n * Splits a single over-diameter component by the deterministic DROP-WEAKEST\n * single-link rule until every resulting sub-component satisfies `maxDiameter`.\n */\nfunction splitByDropWeakest(\n members: readonly AnyNodeId[],\n edges: readonly CandidateEdge[],\n maxDiameter: number,\n): ClusterResult[] {\n return splitUntil(members, edges, (componentMembers, surviving) =>\n exceedsDiameter(componentMembers, surviving, maxDiameter),\n );\n}\n\n/**\n * Computes the connected components of the candidate-edge graph over `nodeIds`,\n * applying the optional single-link diameter guard.\n *\n * @param candidateEdges Undirected candidate-merge edges (from T6). Order does\n * not affect the result.\n * @param nodeIds Every node id in scope. Ids with no incident candidate edge\n * become singleton clusters, so the output partitions the full set.\n * @returns Clusters with id-sorted members, sorted by minimum member id. Pure\n * over the input edge/node SETS.\n *\n * The diameter guard is deliberately NOT applied here: {@link enforceBaseGuard}\n * (§6.4-A) must run on these RAW components FIRST, and only then may a caller run\n * {@link enforceDiameter}. Folding the diameter split back in would let it sever a\n * base↔base bridge before base multiplicity is detected.\n */\nexport function connectedComponents(\n candidateEdges: readonly CandidateEdge[],\n nodeIds: readonly AnyNodeId[],\n): readonly ClusterResult[] {\n return buildComponents(candidateEdges, nodeIds);\n}\n\n/**\n * Applies the single-link DIAMETER guard to already-formed clusters: any cluster\n * whose pairwise diameter exceeds `clusterMaxDiameter` is split by the deterministic\n * drop-weakest rule. Separated from {@link connectedComponents} so the base guard\n * (§6.4-A) can run on the RAW pre-diameter components FIRST — a diameter split must\n * never sever a base↔base bridge before base-multiplicity is detected.\n */\nexport function enforceDiameter(\n clusters: readonly ClusterResult[],\n candidateEdges: readonly CandidateEdge[],\n clusterMaxDiameter: number,\n): readonly ClusterResult[] {\n const guarded: ClusterResult[] = [];\n for (const component of clusters) {\n if (\n exceedsDiameter(component.members, candidateEdges, clusterMaxDiameter)\n ) {\n guarded.push(\n ...splitByDropWeakest(\n component.members,\n candidateEdges,\n clusterMaxDiameter,\n ),\n );\n } else {\n guarded.push(component);\n }\n }\n guarded.sort((left, right) =>\n compareMergeKeys(left.members[0]!, right.members[0]!),\n );\n return guarded;\n}\n\n/** Count of a component's members that are committed BASE nodes. */\nfunction countBaseMembers(\n members: readonly AnyNodeId[],\n baseIds: ReadonlySet<AnyNodeId>,\n): number {\n let count = 0;\n for (const id of members) {\n if (baseIds.has(id)) {\n count += 1;\n }\n }\n return count;\n}\n\n/**\n * Splits a component holding ≥2 base members by the deterministic DROP-WEAKEST rule\n * until NO surviving sub-component holds two base members. This is CONTAINMENT, not\n * resolution: it removes the lowest-scoring BRIDGING edges (forced new↔base edges,\n * at max score, are dropped last), so the distinct committed entities land in\n * separate clusters and BOTH survive — it never \"picks\" which base wins (§6.4-A).\n */\nfunction splitByBaseMultiplicity(\n members: readonly AnyNodeId[],\n edges: readonly CandidateEdge[],\n baseIds: ReadonlySet<AnyNodeId>,\n): ClusterResult[] {\n return splitUntil(\n members,\n edges,\n (componentMembers) => countBaseMembers(componentMembers, baseIds) >= 2,\n );\n}\n\n/**\n * A connected component that spanned ≥2 distinct committed base entities — an\n * AMBIGUOUS match (§6.4-A). Reported regardless of how the component was split:\n * any component that EVER bridged two base identities is an ambiguity event.\n */\nexport type BaseMultiplicityEvent = Readonly<{\n baseIds: readonly AnyNodeId[];\n memberIds: readonly AnyNodeId[];\n}>;\n\n/**\n * Component-level BASE GUARD (§6.4-A). Single-link clustering is transitive, so two\n * committed entities fuse whenever ANY chain links them (`baseA ~ new ~ baseB`, or\n * through staged hops `baseA ~ new1 ~ new2 ~ baseB` where no single new node spans\n * both). A node-level guard misses the chain case; this guard is COMPONENT-level.\n *\n * MUST run on the RAW connected components, BEFORE any diameter split — otherwise a\n * diameter guard could sever a base↔base bridge into single-base pieces and the\n * ambiguity would go unreported (§6.4-A: reported regardless of how it split).\n *\n * Any component containing ≥2 distinct base members is an ambiguous match and is\n * reported as a {@link BaseMultiplicityEvent}. The committed entities are ALWAYS kept\n * SEPARATE — the base↔base collapse is REFUSED by splitting the component\n * (drop-weakest, containment only) until no sub-component holds two base members.\n * Splitting never downgrades the event from ambiguous, and never silently picks which\n * base wins. (A deliberate-collapse trust path is deferred until committed-entity\n * re-keying + edge repoint exist; §6.4-C.)\n *\n * A no-op fast path when there are no base members (the public snapshot path).\n *\n * @returns the guarded clusters (id-sorted members, sorted by min member id) and\n * one event per component that spanned ≥2 base entities.\n */\nexport function enforceBaseGuard(\n clusters: readonly ClusterResult[],\n candidateEdges: readonly CandidateEdge[],\n baseIds: ReadonlySet<AnyNodeId>,\n): Readonly<{\n clusters: readonly ClusterResult[];\n events: readonly BaseMultiplicityEvent[];\n}> {\n if (baseIds.size === 0) {\n return { clusters, events: [] };\n }\n\n const result: ClusterResult[] = [];\n const events: BaseMultiplicityEvent[] = [];\n for (const cluster of clusters) {\n const clusterBaseIds = cluster.members.filter((id) => baseIds.has(id));\n if (clusterBaseIds.length < 2) {\n result.push(cluster);\n continue;\n }\n events.push({\n baseIds: [...clusterBaseIds].sort((left, right) =>\n compareMergeKeys(left, right),\n ),\n memberIds: [...cluster.members].sort((left, right) =>\n compareMergeKeys(left, right),\n ),\n });\n // Always REFUSE the base↔base collapse: split for containment so both committed\n // entities survive separately (§6.4-A). A deliberate collapse is deferred (§6.4-C).\n result.push(\n ...splitByBaseMultiplicity(cluster.members, candidateEdges, baseIds),\n );\n }\n result.sort((left, right) =>\n compareMergeKeys(left.members[0]!, right.members[0]!),\n );\n return { clusters: result, events };\n}\n","/**\n * Node-level delete/modify conflict resolution (design §6.2, T8a).\n *\n * The §6.2 case the draft omitted: an INHERITED node that one fork DELETES while\n * another fork MODIFIES is neither a pure deletion nor a pure modification — it\n * is a delete/modify conflict whose outcome is governed by the\n * {@link DeleteModifyPolicy} (`\"deleteWins\"` | `\"modifyWins\"` | `\"flag\"`) and\n * surfaced in the {@link MergeReport}.\n *\n * This module is a PURE decision function over the staging set (T7) plus the\n * captured stable branch order (T8). It runs BEFORE clustering/canonicalize feed\n * the surviving modifications into the property union, and BEFORE edge repoint\n * (T9), to which it hands the authoritative FINAL LIVENESS of every inherited\n * endpoint:\n *\n * - a node finally deleted (`\"deleteWins\"`) → it is in {@link nodeDeletions};\n * T9 drops every edge touching it.\n * - a node kept/resurrected (`\"modifyWins\"` / `\"flag\"`, or never deleted) →\n * its modifications are in {@link survivingModifications}; T9 keeps its edges.\n *\n * DETERMINISM CONTRACT (inherited from the merge-wide invariant):\n * The keep-vs-delete decision is a function ONLY of the policy and the\n * (unordered) set of contributing branches — it NEVER consults wall-clock\n * arrival. The captured `branchRank` is used solely to TIE-BREAK which\n * modification survives under `\"modifyWins\"` / `\"flag\"` (and which branch ids\n * are recorded as `deletedBy` / `modifiedBy`), so two merges of the same branch\n * set in any order resolve every delete/modify conflict identically.\n */\n\nimport { canonicalValueKey } from \"./canonical-props\";\nimport type { ProvenanceWeights, ResolutionContext } from \"./conflict-policy\";\nimport {\n collectConflictingValues,\n resolvePropertyUnion,\n} from \"./conflict-policy\";\nimport { compareStrings, type MergeKey, mergeKey } from \"./node-key\";\nimport type {\n StagedModifiedEdge,\n StagedModifiedNode,\n StagingSet,\n} from \"./staging\";\nimport type { DeletedEdge, DeletedNode } from \"./state-diff\";\nimport type {\n EdgeId,\n GraphDef,\n JsonValue,\n NodeId,\n NodeType,\n} from \"./typegraph-internal\";\nimport type {\n BranchId,\n DeleteModifyConflict,\n DeleteModifyPolicy,\n DroppedItem,\n PropertyConflict,\n PropertyConflictPolicy,\n} from \"./types\";\n\n/** A node id in its untyped (`NodeType`-default) branded form. */\ntype AnyNodeId = NodeId<NodeType>;\ntype BranchTagged = Readonly<{ branchId: BranchId }>;\n\n/** Reason recorded on a {@link DroppedItem} for a finally-deleted node. */\nexport const DELETED_NODE_DROP_REASON = \"delete-modify:deleteWins\" as const;\n\n/**\n * The outcome of delete/modify resolution over the whole staging set.\n *\n * - `survivingModifications`: every staged inherited-node modification that the\n * merge will still apply — i.e. all modifications NOT overridden by a\n * `\"deleteWins\"` resolution. A node modified by several branches contributes\n * several entries here (one per branch), so T8's property union still sees the\n * full cross-branch disagreement.\n * - `nodeDeletions`: the AUTHORITATIVE set of inherited nodes that are finally\n * deleted — pure deletions (no branch modified them) plus delete/modify\n * conflicts resolved `\"deleteWins\"`. T9 reads this as the endpoint liveness.\n * - `conflicts`: one {@link DeleteModifyConflict} per inherited node that was\n * both deleted and modified.\n * - `dropped`: a `{ kind: \"node\" }` {@link DroppedItem} for every finally-deleted\n * node, so the report can enumerate exactly what left the merged graph.\n */\nexport type DeleteModifyResolution = Readonly<{\n survivingModifications: readonly StagedModifiedNode[];\n nodeDeletions: readonly DeletedNode[];\n conflicts: readonly DeleteModifyConflict[];\n dropped: readonly DroppedItem[];\n}>;\n\n/**\n * Picks the HIGHEST-PRIORITY branch from a set — the one with the lowest\n * `branchRank` (earliest in the captured stable order). Ties on rank fall back to\n * lexicographic branch-id order, so the choice is total and deterministic. Used\n * to record `deletedBy` / `modifiedBy` and to select which modification survives.\n */\nfunction pickHighestPriorityBranch(\n branchIds: readonly BranchId[],\n branchRank: ReadonlyMap<BranchId, number>,\n): BranchId {\n let chosen = branchIds[0]!;\n let chosenRank = branchRank.get(chosen) ?? Number.MAX_SAFE_INTEGER;\n for (const candidate of branchIds.slice(1)) {\n const candidateRank = branchRank.get(candidate) ?? Number.MAX_SAFE_INTEGER;\n if (\n candidateRank < chosenRank ||\n (candidateRank === chosenRank && compareStrings(candidate, chosen) < 0)\n ) {\n chosen = candidate;\n chosenRank = candidateRank;\n }\n }\n return chosen;\n}\n\nfunction effectiveDeleteModifyPolicy(\n policy: DeleteModifyPolicy,\n deletions: readonly BranchTagged[],\n modifications: readonly BranchTagged[],\n preferredBranchId: BranchId | undefined,\n): DeleteModifyPolicy {\n if (\n preferredBranchId !== undefined &&\n deletions.some((deletion) => deletion.branchId === preferredBranchId)\n ) {\n return \"deleteWins\";\n }\n if (\n policy === \"deleteWins\" &&\n preferredBranchId !== undefined &&\n modifications.some(\n (modification) => modification.branchId === preferredBranchId,\n )\n ) {\n return \"modifyWins\";\n }\n return policy;\n}\n\n/**\n * Groups staged items by the `(kind, id)` IDENTITY of the entity `entityOf` extracts\n * (a node or an edge), preserving the per-identity arrays so callers can inspect every\n * contributing branch. Keying on the composite identity (not bare id) keeps an\n * inherited `Patient` and an inherited `Encounter` that share an id string from being\n * reconciled/deleted as if they were one entity.\n */\nfunction groupByEntity<T>(\n items: readonly T[],\n entityOf: (item: T) => Readonly<{ id: string; kind: string }>,\n): ReadonlyMap<MergeKey, readonly T[]> {\n const grouped = new Map<MergeKey, T[]>();\n for (const item of items) {\n const entity = entityOf(item);\n const key = mergeKey(entity.kind, entity.id);\n const bucket = grouped.get(key);\n if (bucket === undefined) {\n grouped.set(key, [item]);\n } else {\n bucket.push(item);\n }\n }\n return grouped;\n}\n\n/**\n * The shared node/edge DELETE-MODIFY resolver — the single control flow behind\n * {@link resolveDeleteModify} (nodes) and {@link resolveEdgeDeleteModify} (edges).\n * `modifiedEntity`/`deletedEntity` extract each staged item's `(id, kind)` (its\n * `.node` or `.edge`), and `droppedKind` tags the {@link DroppedItem}; everything\n * else — conflict detection, policy application, pure-deletion/pure-modification\n * passthrough, and the canonical output sort — is identical for both.\n */\nfunction resolveDeleteModifyOver<\n ModifiedItem extends BranchTagged,\n DeletedItem extends BranchTagged,\n Id extends AnyNodeId | EdgeId,\n>(\n modified: readonly ModifiedItem[],\n deleted: readonly DeletedItem[],\n modifiedEntity: (item: ModifiedItem) => Readonly<{ id: Id; kind: string }>,\n deletedEntity: (item: DeletedItem) => Readonly<{ id: Id; kind: string }>,\n droppedKind: \"node\" | \"edge\",\n policy: DeleteModifyPolicy,\n branchRank: ReadonlyMap<BranchId, number>,\n preferredBranchId: BranchId | undefined,\n): Readonly<{\n survivingModifications: readonly ModifiedItem[];\n deletions: readonly Readonly<{ id: Id; kind: string }>[];\n conflicts: readonly DeleteModifyConflict[];\n dropped: readonly DroppedItem[];\n}> {\n const modifiedByKey = groupByEntity(modified, modifiedEntity);\n const deletedByKey = groupByEntity(deleted, deletedEntity);\n\n const survivingModifications: ModifiedItem[] = [];\n const deletions: Readonly<{ id: Id; kind: string }>[] = [];\n const conflicts: DeleteModifyConflict[] = [];\n const dropped: DroppedItem[] = [];\n\n const conflictedKeys = new Set<MergeKey>();\n for (const key of deletedByKey.keys()) {\n if (modifiedByKey.has(key)) {\n conflictedKeys.add(key);\n }\n }\n\n for (const [key, modifications] of modifiedByKey) {\n if (!conflictedKeys.has(key)) {\n for (const modification of modifications) {\n survivingModifications.push(modification);\n }\n continue;\n }\n\n const deletionsForKey = deletedByKey.get(key)!;\n const { id, kind } = modifiedEntity(modifications[0]!);\n const deletedBy = pickHighestPriorityBranch(\n deletionsForKey.map((deletion) => deletion.branchId),\n branchRank,\n );\n const modifiedBy = pickHighestPriorityBranch(\n modifications.map((modification) => modification.branchId),\n branchRank,\n );\n const effectivePolicy = effectiveDeleteModifyPolicy(\n policy,\n deletionsForKey,\n modifications,\n preferredBranchId,\n );\n\n conflicts.push({\n entityId: id,\n kind,\n deletedBy,\n modifiedBy,\n resolution: effectivePolicy,\n });\n\n if (effectivePolicy === \"deleteWins\") {\n deletions.push({ id, kind });\n dropped.push({ kind: droppedKind, id, reason: DELETED_NODE_DROP_REASON });\n continue;\n }\n\n // \"modifyWins\" and \"flag\" both KEEP the modification (resurrect the entity);\n // \"flag\" additionally leaves the recorded conflict unresolved for review.\n for (const modification of modifications) {\n survivingModifications.push(modification);\n }\n }\n\n for (const [key, deletionsForKey] of deletedByKey) {\n if (conflictedKeys.has(key)) {\n continue;\n }\n const { id, kind } = deletedEntity(deletionsForKey[0]!);\n deletions.push({ id, kind });\n }\n\n return {\n survivingModifications: [...survivingModifications].sort((left, right) => {\n const byId = compareStrings(\n modifiedEntity(left).id,\n modifiedEntity(right).id,\n );\n return byId === 0 ? compareStrings(left.branchId, right.branchId) : byId;\n }),\n deletions: [...deletions].sort((left, right) =>\n compareStrings(left.id, right.id),\n ),\n conflicts: [...conflicts].sort((left, right) =>\n compareStrings(left.entityId, right.entityId),\n ),\n dropped: [...dropped].sort((left, right) =>\n compareStrings(left.id, right.id),\n ),\n };\n}\n\n/**\n * The shared node/edge MODIFICATION reconciler — the single control flow behind\n * {@link reconcileModifications} (nodes) and {@link reconcileEdgeModifications}\n * (edges). Groups by `(kind, id)`, 3-way merges every multi-branch modification via\n * {@link threeWayMergeProps}, and rebuilds ONE surviving record per id via `rebuild`\n * (carrying the highest-priority contributor's branch + the merged props).\n */\nfunction reconcileOver<Item extends BranchTagged>(\n survivingModifications: readonly Item[],\n entityOf: (item: Item) => Readonly<{\n id: AnyNodeId | EdgeId;\n kind: string;\n baseProps: Readonly<Record<string, unknown>>;\n forkProps: Readonly<Record<string, unknown>>;\n }>,\n rebuild: (\n representative: Item,\n chosenBranch: BranchId,\n mergedProps: Record<string, JsonValue>,\n ) => Item,\n policy: PropertyConflictPolicy,\n branchRank: ReadonlyMap<BranchId, number>,\n weights: ProvenanceWeights | undefined,\n preferredBranchId: BranchId | undefined,\n): Readonly<{\n survivingModifications: readonly Item[];\n conflicts: readonly PropertyConflict[];\n}> {\n const context: ResolutionContext<GraphDef> = {\n policy,\n ...(weights === undefined ? {} : { weights }),\n };\n\n const grouped = groupByEntity(survivingModifications, entityOf);\n const out: Item[] = [];\n const conflicts: PropertyConflict[] = [];\n\n for (const modifications of grouped.values()) {\n if (modifications.length === 1) {\n out.push(modifications[0]!);\n continue;\n }\n const first = entityOf(modifications[0]!);\n const { props, conflicts: propertyConflicts } = threeWayMergeProps(\n first.id,\n first.kind,\n first.baseProps as Readonly<Record<string, JsonValue>>,\n modifications.map((modification) => ({\n branchId: modification.branchId,\n forkProps: entityOf(modification).forkProps as Readonly<\n Record<string, JsonValue>\n >,\n })),\n context,\n branchRank,\n preferredBranchId,\n );\n const chosenBranch = pickHighestPriorityBranch(\n modifications.map((modification) => modification.branchId),\n branchRank,\n );\n const representative =\n modifications.find(\n (modification) => modification.branchId === chosenBranch,\n ) ?? modifications[0]!;\n out.push(rebuild(representative, chosenBranch, props));\n for (const conflict of propertyConflicts) {\n conflicts.push(conflict);\n }\n }\n\n return {\n survivingModifications: [...out].sort((left, right) => {\n const byId = compareStrings(entityOf(left).id, entityOf(right).id);\n return byId === 0 ? compareStrings(left.branchId, right.branchId) : byId;\n }),\n conflicts: conflicts.sort((left, right) =>\n compareStrings(\n `${left.entityId}|${left.property}`,\n `${right.entityId}|${right.property}`,\n ),\n ),\n };\n}\n\n/**\n * Resolves every inherited node that is simultaneously DELETED by one or more\n * branches and MODIFIED by one or more (other) branches, per the\n * {@link DeleteModifyPolicy}:\n *\n * - `\"deleteWins\"` → the node is finally deleted (its modifications are\n * discarded). A {@link DeleteModifyConflict} with `resolution: \"deleteWins\"`\n * is recorded and a `{ kind: \"node\" }` {@link DroppedItem} is emitted.\n * - `\"modifyWins\"` → the node is RESURRECTED: its modifications survive (the\n * deletion is ignored). A conflict with `resolution: \"modifyWins\"` is\n * recorded; the node is NOT deleted.\n * - `\"flag\"` → the modifications survive (as with `\"modifyWins\"`) but the\n * conflict is recorded UNRESOLVED (`resolution: \"flag\"`) for human review.\n *\n * Pure deletions (no branch modified the node) pass straight through to\n * {@link nodeDeletions}; pure modifications (no branch deleted the node) pass\n * straight through to {@link survivingModifications}. Both unconflicted paths\n * carry NO {@link DeleteModifyConflict}.\n *\n * The result is order-independent: the keep-vs-delete decision depends only on\n * the policy and the contributing branch SET; `branchRank` is consulted solely to\n * tie-break which modification survives and which branch ids are recorded.\n *\n * @param staging The provenance-tagged union staging set (T7).\n * @param policy The delete/modify-conflict policy.\n * @param branchRank The captured stable branch rank (built once via\n * `buildBranchRank`, shared across phases). Used ONLY for deterministic\n * tie-breaking — never for the keep-vs-delete decision itself.\n */\nexport function resolveDeleteModify(\n staging: StagingSet,\n policy: DeleteModifyPolicy,\n branchRank: ReadonlyMap<BranchId, number>,\n preferredBranchId?: BranchId,\n): DeleteModifyResolution {\n const resolved = resolveDeleteModifyOver(\n staging.modifiedNodes,\n staging.deletedNodes,\n (item) => item.node,\n (item) => item.node,\n \"node\",\n policy,\n branchRank,\n preferredBranchId,\n );\n return {\n survivingModifications: resolved.survivingModifications,\n nodeDeletions: resolved.deletions,\n conflicts: resolved.conflicts,\n dropped: resolved.dropped,\n };\n}\n\n/**\n * The outcome of reconciling the surviving inherited modifications: ONE merged\n * record per node id (carrying the 3-way-merged props the commit applies) plus\n * every {@link PropertyConflict} that a multi-branch modification surfaced.\n */\nexport type ModificationReconciliation = Readonly<{\n survivingModifications: readonly StagedModifiedNode[];\n conflicts: readonly PropertyConflict[];\n}>;\n\n/** A single branch's full fork props for an inherited entity (node or edge). */\ntype ForkContribution = Readonly<{\n branchId: BranchId;\n forkProps: Readonly<Record<string, JsonValue>>;\n}>;\n\n/**\n * 3-WAY merges one inherited entity (node OR edge) modified by 2+ branches against\n * the SHARED base.\n *\n * Per property: a branch whose fork value equals base contributed no change; a\n * property exactly one branch changed takes that change; a property multiple\n * branches changed to DIFFERING values is a genuine conflict, resolved by the\n * captured policy on the stable `branchRank` and recorded as a\n * {@link PropertyConflict}. Property DELETIONS (a base key absent from a fork) are\n * treated conservatively as \"unchanged\" so an unrelated branch's edit is never\n * lost. `baseProps` is identical across the contributions (same base, same id).\n *\n * Shared by node modification reconciliation ({@link reconcileModifications}) and\n * edge modification reconciliation ({@link reconcileEdgeModifications}), so both\n * apply identical base-aware semantics — without this, disjoint edits to the same\n * entity by different branches would false-conflict and one edit could be lost.\n */\nfunction threeWayMergeProps(\n entityId: AnyNodeId | EdgeId,\n kind: string,\n baseProps: Readonly<Record<string, JsonValue>>,\n contributions: readonly ForkContribution[],\n context: ResolutionContext<GraphDef>,\n branchRank: ReadonlyMap<BranchId, number>,\n preferredBranchId?: BranchId,\n): Readonly<{\n props: Record<string, JsonValue>;\n conflicts: PropertyConflict[];\n}> {\n const merged: Record<string, JsonValue> = {};\n const conflicts: PropertyConflict[] = [];\n\n // Every property the base OR any fork carries. Base keys are included so a key\n // that EVERY fork dropped is still seen here (a fork's `forkProps` is its full\n // bag, so a missing base key is an intentional deletion, not an omission).\n const propertyNames = new Set<string>(Object.keys(baseProps));\n for (const contribution of contributions) {\n for (const name of Object.keys(contribution.forkProps)) {\n propertyNames.add(name);\n }\n }\n\n for (const property of [...propertyNames].sort(compareStrings)) {\n const baseHas = property in baseProps;\n const baseKey =\n baseHas ? canonicalValueKey(baseProps[property]!) : undefined;\n\n // Contributions from branches that actually CHANGED this property (present and\n // differing from base). Reuse the shared collector so the distinct-(branch,value)\n // dedupe + ordering match the node/edge property unions exactly — one definition\n // of conflict gathering, with the canonical NUL-separated dedupe key.\n const changed = contributions\n .filter((contribution) => {\n if (!(property in contribution.forkProps)) {\n return false; // absent — a deletion (handled below), never a change\n }\n const value = contribution.forkProps[property] as JsonValue;\n return !baseHas || canonicalValueKey(value) !== baseKey;\n })\n .map((contribution) => ({\n branchId: contribution.branchId,\n props: contribution.forkProps,\n }));\n const values = collectConflictingValues(property, changed);\n\n if (values.length === 0) {\n // No fork CHANGED the value. A fork's `forkProps` is its FULL bag, so a base\n // property a fork OMITS was DELETED by it; honor that deletion by leaving the\n // key out of `merged`. Otherwise every fork kept the base value, so it stands.\n const deletedByFork =\n baseHas &&\n contributions.some(\n (contribution) => !(property in contribution.forkProps),\n );\n if (baseHas && !deletedByFork) {\n merged[property] = baseProps[property]!;\n }\n continue;\n }\n\n const distinctValues = new Set(\n values.map((candidate) => canonicalValueKey(candidate.value)),\n );\n if (distinctValues.size === 1) {\n merged[property] = values[0]!.value; // a single, agreed-upon change\n continue;\n }\n\n const preferredValue = values.find(\n (value) => value.branchId === preferredBranchId,\n )?.value;\n const canonicalValue =\n preferredValue ?? (baseHas ? baseProps[property]! : values[0]!.value);\n const reportedValues =\n preferredBranchId === undefined ? values : (\n values.filter((value) => value.branchId !== preferredBranchId)\n );\n const { value, conflict } = resolvePropertyUnion(\n { entityId, kind, property, values, reportedValues, canonicalValue },\n context,\n branchRank,\n );\n merged[property] = value;\n if (conflict !== undefined) {\n conflicts.push(conflict);\n }\n }\n\n return { props: merged, conflicts };\n}\n\n/**\n * Reconciles the post-delete/modify surviving modifications into the records the\n * commit applies. An inherited node modified by a SINGLE branch passes through\n * unchanged; a node modified by TWO OR MORE branches is 3-way merged against the\n * base ({@link mergeModifiedProps}) into one record carrying the merged props,\n * surfacing any genuine cross-branch disagreement as a {@link PropertyConflict}.\n *\n * Without this, each per-branch modification was committed by id in turn, so the\n * lexicographically-largest branchId silently overwrote the others with NO\n * conflict recorded and the configured `onPropertyConflict` / `branchOrder`\n * bypassed (the §6.2 gap). The synthetic record's `branchId` is the highest\n * -priority contributor — cosmetic, since the commit reads only `node.id` / kind /\n * `forkProps`, and provenance for every contributing branch is recorded upstream.\n *\n * Order-independent: groups by id (the staging input is already `(id, branchId)`\n * sorted), merges per the stable `branchRank`, and sorts both outputs by stable\n * keys, so shuffling the branch set yields an identical result.\n *\n * @param survivingModifications The surviving modifications from\n * {@link resolveDeleteModify} (one entry per `(id, branch)`).\n * @param policy The property-conflict policy (shared with the cluster union, T8).\n * @param branchRank The captured stable branch rank.\n * @param weights Optional per-branch weights for `\"provenanceWeighted\"`.\n */\nexport function reconcileModifications(\n survivingModifications: readonly StagedModifiedNode[],\n policy: PropertyConflictPolicy,\n branchRank: ReadonlyMap<BranchId, number>,\n weights?: ProvenanceWeights,\n preferredBranchId?: BranchId,\n): ModificationReconciliation {\n return reconcileOver(\n survivingModifications,\n (item) => item.node,\n (representative, chosenBranch, mergedProps) => ({\n branchId: chosenBranch,\n node: { ...representative.node, forkProps: mergedProps },\n }),\n policy,\n branchRank,\n weights,\n preferredBranchId,\n );\n}\n\n// ============================================================\n// Inherited EDGE delete/modify resolution (the edge analogue of the node path\n// above). Edges carry fixed endpoints, so a \"modified\" edge only changes props;\n// the delete/modify and 3-way merge logic is otherwise identical to nodes, and\n// reuses the same {@link pickHighestPriorityBranch} + {@link threeWayMergeProps}\n// cores so node and edge behavior can never drift.\n// ============================================================\n\n/**\n * The outcome of delete/modify resolution over the staged inherited EDGES.\n * Mirrors {@link DeleteModifyResolution}: `edgeDeletions` is the authoritative set\n * of finally-deleted inherited edges (pure deletions plus `\"deleteWins\"` conflict\n * resolutions); `survivingModifications` is every modification the merge still\n * applies; `conflicts`/`dropped` mirror the node fields.\n */\nexport type EdgeDeleteModifyResolution = Readonly<{\n survivingModifications: readonly StagedModifiedEdge[];\n edgeDeletions: readonly DeletedEdge[];\n conflicts: readonly DeleteModifyConflict[];\n dropped: readonly DroppedItem[];\n}>;\n\n/**\n * Resolves every inherited EDGE simultaneously deleted by one+ branches and\n * modified by one+ (other) branches, per the {@link DeleteModifyPolicy} — the\n * edge analogue of {@link resolveDeleteModify}. Pure deletions flow to\n * `edgeDeletions`; pure modifications flow to `survivingModifications`. Without\n * this, inherited edge deletions were staged but never applied, so a branch's\n * edge deletion was silently dropped and the edge stayed live. Shares\n * {@link resolveDeleteModifyOver} with the node path so the two can never drift.\n */\nexport function resolveEdgeDeleteModify(\n staging: StagingSet,\n policy: DeleteModifyPolicy,\n branchRank: ReadonlyMap<BranchId, number>,\n preferredBranchId?: BranchId,\n): EdgeDeleteModifyResolution {\n const resolved = resolveDeleteModifyOver(\n staging.modifiedEdges,\n staging.deletedEdges,\n (item) => item.edge,\n (item) => item.edge,\n \"edge\",\n policy,\n branchRank,\n preferredBranchId,\n );\n return {\n survivingModifications: resolved.survivingModifications,\n edgeDeletions: resolved.deletions,\n conflicts: resolved.conflicts,\n dropped: resolved.dropped,\n };\n}\n\n/**\n * The edge analogue of {@link reconcileModifications}: ONE merged record per edge\n * id, carrying the 3-way-merged props the commit applies, plus every\n * {@link PropertyConflict} a multi-branch edge modification surfaced. Edge\n * endpoints are immutable, so only props are merged; the representative's\n * endpoints/kind are kept.\n */\nexport function reconcileEdgeModifications(\n survivingModifications: readonly StagedModifiedEdge[],\n policy: PropertyConflictPolicy,\n branchRank: ReadonlyMap<BranchId, number>,\n weights?: ProvenanceWeights,\n preferredBranchId?: BranchId,\n): Readonly<{\n survivingModifications: readonly StagedModifiedEdge[];\n conflicts: readonly PropertyConflict[];\n}> {\n return reconcileOver(\n survivingModifications,\n (item) => item.edge,\n (representative, chosenBranch, mergedProps) => ({\n branchId: chosenBranch,\n edge: { ...representative.edge, forkProps: mergedProps },\n }),\n policy,\n branchRank,\n weights,\n preferredBranchId,\n );\n}\n","/**\n * Edge repoint to canonical + set-dedupe cascade (design §6.3 / §6.4 rule 5, T9).\n *\n * After clustering (T8) collapses fork nodes into canonical survivors and\n * delete/modify resolution (T8a) fixes the FINAL LIVENESS of every endpoint, the\n * inherited and new edges of the merge must be:\n *\n * 1. REPOINTED — each endpoint mapped to its cluster's canonical id. An edge\n * `x → a` where `{a, b}` collapsed to canonical `c*` becomes `x → c*`.\n * 2. DROPPED — any edge whose (repointed) `from` or `to` is a finally-deleted\n * node (per T8a, NOT resurrected) is removed, recorded as a\n * {@link DroppedItem} with reason {@link ENDPOINT_DELETED_DROP_REASON}.\n * 3. DEDUPED — repointing can make two distinct edges identical. Edges are\n * collapsed as a pure SET operation keyed by\n * `(fromCanonical | type | toCanonical | propsKey)`, where `propsKey` is the\n * T2 canonical serializer over PARSED props. So `x → a` and `x → b` (both\n * repointed to `x → c*`) with equal props yield a SINGLE `x → c*`.\n * 4. RECONCILED — when two edges collapse to the same `(from, type, to)` but\n * carry DIFFERING props, the per-property disagreement is resolved by the\n * shared T8 conflict policy ({@link resolvePropertyUnion}) on the captured,\n * non-wall-clock branch order, recording an edge-level {@link PropertyConflict}\n * whose `entityId` is the surviving edge's id.\n *\n * Determinism: the dedupe is a pure function of the (unordered) staged-edge SET.\n * Within a collision group the surviving edge id is the lexicographically-minimal\n * member id, property resolution uses only the captured `branchRank`, and the\n * output is sorted by dedupe key — so shuffling the input edges yields an\n * identical result. Clusters are computed once upstream (T8) and passed in as\n * {@link canonicalOf}; this module never re-clusters.\n */\n\nimport { canonicalizeProps } from \"./canonical-props\";\nimport type { ClusterResult } from \"./clustering\";\nimport type { ProvenanceWeights, ResolutionContext } from \"./conflict-policy\";\nimport {\n collectConflictingValues,\n resolvePropertyUnion,\n} from \"./conflict-policy\";\nimport {\n compareStrings,\n idOf,\n kindOf,\n type MergeKey,\n mergeKey,\n} from \"./node-key\";\nimport type {\n EdgeId,\n GraphDef,\n JsonValue,\n NodeId,\n NodeType,\n} from \"./typegraph-internal\";\nimport type {\n BranchId,\n PropertyConflict,\n PropertyConflictPolicy,\n} from \"./types\";\n\n/** A node id in its untyped (`NodeType`-default) branded form. */\ntype AnyNodeId = NodeId<NodeType>;\n\n/** Reason recorded on a {@link DroppedItem} for an edge to a deleted endpoint. */\nexport const ENDPOINT_DELETED_DROP_REASON = \"edge:endpoint-deleted\" as const;\n\n/**\n * A `{ kind: \"edge\" }` dropped item. Mirrors the public {@link DroppedItem} but is\n * narrowed to edges so this module's output is precisely typed. Structurally\n * assignable to {@link DroppedItem}.\n */\ntype DroppedEdge = Readonly<{\n kind: \"edge\";\n id: EdgeId;\n reason: string;\n}>;\n\n/**\n * One staged edge fed into the repoint phase: a new fork edge or a surviving\n * inherited edge. Carries the parsed props (NOT a JSON string) so the dedupe key\n * and the conflict union both operate on the canonical structure, and the\n * {@link BranchId} that contributed it so edge-property conflicts resolve on the\n * same stable branch order as node-property conflicts.\n *\n * The orchestrator (T11) builds these from `StagedNewEdge` / surviving\n * `StagedModifiedEdge` items (T7); this module needs no knowledge of the diff\n * shape beyond these fields.\n */\nexport type StagedEdge = Readonly<{\n id: EdgeId;\n kind: string;\n fromId: AnyNodeId;\n toId: AnyNodeId;\n fromKind: string;\n toKind: string;\n props: Readonly<Record<string, JsonValue>>;\n branchId: BranchId;\n}>;\n\n/**\n * A surviving merged edge after repoint + dedupe. `id` is the canonical survivor\n * of its collision group (the lexicographically-minimal contributing edge id);\n * `mergedIds` is every staged edge id that collapsed into it (always includes\n * `id`), so the commit phase (T11) knows which inherited edges to fold away.\n */\nexport type MergedEdge = Readonly<{\n id: EdgeId;\n kind: string;\n fromId: AnyNodeId;\n toId: AnyNodeId;\n fromKind: string;\n toKind: string;\n props: Readonly<Record<string, JsonValue>>;\n mergedIds: readonly EdgeId[];\n}>;\n\n/**\n * The outcome of the repoint + dedupe cascade: the surviving merged edges, every\n * edge dropped for a deleted endpoint, and every edge-level property conflict the\n * dedupe surfaced.\n */\nexport type EdgeRepointResult<G extends GraphDef = GraphDef> = Readonly<{\n edges: readonly MergedEdge[];\n dropped: readonly DroppedEdge[];\n conflicts: readonly PropertyConflict<G>[];\n}>;\n\n/**\n * Builds the endpoint → canonical map from the resolved clusters. Every member of\n * a cluster maps to that cluster's canonical id; ids absent from the map (cluster\n * singletons / nodes never compared) are treated as their own canonical by the\n * `?? id` fallback at lookup time, so the map need only carry the rewrites.\n *\n * @param clusters Resolved clusters (T8). Each must be non-empty.\n * @param canonicalOf A `cluster → canonicalId` selector returning the cluster's\n * canonical survivor (as chosen by T8 `pickClusterSurvivor`), threaded so this\n * module reuses the merge-wide canonical choice rather than re-deriving it.\n */\nexport function buildCanonicalMap(\n clusters: readonly ClusterResult[],\n canonicalOf: (cluster: ClusterResult) => MergeKey,\n): ReadonlyMap<MergeKey, MergeKey> {\n const map = new Map<MergeKey, MergeKey>();\n for (const cluster of clusters) {\n const canonical = canonicalOf(cluster);\n for (const member of cluster.members) {\n map.set(member, canonical);\n }\n }\n return map;\n}\n\n/**\n * Resolves an endpoint IDENTITY (`(kind, id)` key) to its cluster canonical,\n * defaulting to itself. Keying on the composite identity is what stops an edge from\n * a `Patient` and an edge from an `Encounter` that share an endpoint id from being\n * repointed onto the same survivor.\n */\nfunction repoint(\n key: MergeKey,\n canonicalOf: ReadonlyMap<MergeKey, MergeKey>,\n): MergeKey {\n return canonicalOf.get(key) ?? key;\n}\n\n/**\n * The dedupe key for a repointed edge: a JSON-encoded `[from', type, to',\n * propsKey]` tuple. The `propsKey` is the T2 canonical serializer over the PARSED\n * props, so two edges that agree on endpoints, type, AND every property collapse to\n * one regardless of property key order. JSON-encoding the tuple (rather than\n * concatenating with a literal separator) keeps the key unambiguous even when an\n * edge `type` — a user-defined schema string — or a caller-supplied endpoint id\n * contains the separator character.\n */\nfunction dedupeKey(\n fromKey: MergeKey,\n type: string,\n toKey: MergeKey,\n props: Readonly<Record<string, JsonValue>>,\n): string {\n return JSON.stringify([fromKey, type, toKey, canonicalizeProps(props)]);\n}\n\n/**\n * The key identifying a collision GROUP — edges sharing `(from', type, to')`\n * regardless of props. Edges in the same group but with differing props are the\n * ones whose properties must be reconciled by the conflict policy. JSON-encoded\n * (see {@link dedupeKey}) so a `|`-bearing type/id can never fuse two distinct\n * groups.\n */\nfunction groupKey(fromKey: MergeKey, type: string, toKey: MergeKey): string {\n return JSON.stringify([fromKey, type, toKey]);\n}\n\n/**\n * A repointed staged edge plus both endpoints already mapped to their canonical\n * IDENTITY key (`(kind, id)`). The composite keys carry the canonical node's kind, so\n * the surviving edge's bare `fromId`/`toId` and `fromKind`/`toKind` are read off\n * `idOf`/`kindOf` of these keys — never the (possibly different-kind) staged endpoint.\n */\ntype RepointedEdge = Readonly<{\n staged: StagedEdge;\n fromKey: MergeKey;\n toKey: MergeKey;\n}>;\n\n/**\n * Picks the canonical survivor edge of a collision group: the member with the\n * lexicographically-minimal edge id. Mirrors the node min-id canonical rule (T8)\n * so the surviving id is independent of input edge order. (`generateId()` is\n * nanoid — random, not time-prefixed — so min-id never leaks creation order.)\n */\nfunction pickSurvivor(\n edges: readonly RepointedEdge[],\n preferredBranchId?: BranchId,\n): RepointedEdge {\n const preferred =\n preferredBranchId === undefined ?\n []\n : edges.filter((edge) => edge.staged.branchId === preferredBranchId);\n const candidates = preferred.length > 0 ? preferred : edges;\n let survivor = candidates[0]!;\n for (const candidate of candidates.slice(1)) {\n if (candidate.staged.id < survivor.staged.id) {\n survivor = candidate;\n }\n }\n return survivor;\n}\n\n/**\n * Unions the props of one collision group's edges, resolving any per-property\n * disagreement via the shared T8 conflict policy. Returns the surviving prop bag\n * plus an edge-level {@link PropertyConflict} for every property that genuinely\n * differed (its `entityId` is the surviving edge id).\n */\nfunction unionEdgeProps(\n survivorId: EdgeId,\n kind: string,\n survivor: RepointedEdge,\n edges: readonly RepointedEdge[],\n context: ResolutionContext<GraphDef>,\n branchRank: ReadonlyMap<BranchId, number>,\n preferredBranchId?: BranchId,\n): Readonly<{\n props: Record<string, JsonValue>;\n conflicts: PropertyConflict[];\n}> {\n const propertyNames = new Set<string>();\n for (const edge of edges) {\n for (const name of Object.keys(edge.staged.props)) {\n propertyNames.add(name);\n }\n }\n\n const props: Record<string, JsonValue> = {};\n const conflicts: PropertyConflict[] = [];\n\n // The staged record of each edge IS a `(branchId, props)` contribution, so the\n // shared node/edge collector consumes it directly.\n const contributions = edges.map((edge) => edge.staged);\n\n for (const property of [...propertyNames].sort((left, right) =>\n compareStrings(left, right),\n )) {\n const values = collectConflictingValues(property, contributions);\n if (values.length === 0) {\n continue;\n }\n const survivorValue =\n property in survivor.staged.props ?\n (survivor.staged.props[property] as JsonValue)\n : values[0]!.value;\n const canonicalValue: JsonValue =\n values.find((value) => value.branchId === preferredBranchId)?.value ??\n survivorValue;\n const reportedValues =\n preferredBranchId === undefined ? values : (\n values.filter((value) => value.branchId !== preferredBranchId)\n );\n\n const { value, conflict } = resolvePropertyUnion(\n {\n entityId: survivorId,\n kind,\n property,\n values,\n reportedValues,\n canonicalValue,\n },\n context,\n branchRank,\n );\n props[property] = value;\n if (conflict !== undefined) {\n conflicts.push(conflict);\n }\n }\n\n return { props, conflicts };\n}\n\n/**\n * Repoints every staged edge onto its cluster canonical, drops edges whose\n * (repointed) endpoints are finally deleted, and dedupes the survivors as a pure\n * set operation keyed by `(from' | type | to' | propsKey)`.\n *\n * Within a collision group sharing `(from', type, to')`:\n * - identical props collapse silently to one edge,\n * - DIFFERING props are reconciled by `policy` on the captured `branchRank`,\n * recording one edge-level {@link PropertyConflict} per disagreeing property.\n *\n * The surviving edge of every group is the lexicographically-minimal contributing\n * edge id; its `mergedIds` lists every collapsed edge id. Output is sorted by the\n * full dedupe key, so the result is a pure function of the unordered input set.\n *\n * @param stagedEdges The new + surviving-inherited edges to merge. Order does not\n * affect the result. Props MUST already be parsed objects.\n * @param canonicalOf The endpoint → canonical map (from {@link buildCanonicalMap}).\n * Endpoints absent from it map to themselves.\n * @param deletedNodeIds The AUTHORITATIVE finally-deleted node id set (T8a). Any\n * edge whose repointed `from`/`to` is in this set is dropped.\n * @param policy The property-conflict policy (shared with node union, T8).\n * @param branchRank The captured stable branch rank (built once via\n * `buildBranchRank`). Used only for deterministic conflict resolution — never\n * wall-clock.\n * @param weights Optional per-branch weights for the `\"provenanceWeighted\"` policy.\n */\nexport function repointEdges<G extends GraphDef = GraphDef>(\n stagedEdges: readonly StagedEdge[],\n canonicalOf: ReadonlyMap<MergeKey, MergeKey>,\n deletedNodeIds: ReadonlySet<MergeKey>,\n policy: PropertyConflictPolicy<G>,\n branchRank: ReadonlyMap<BranchId, number>,\n weights?: ProvenanceWeights,\n preferredBranchId?: BranchId,\n): EdgeRepointResult<G> {\n const dropped: DroppedEdge[] = [];\n const liveByDedupeKey = new Map<string, RepointedEdge[]>();\n // Per `(from', type, to')` group → the SET of distinct dedupe keys seen for it.\n // Insertion order is irrelevant: Phase 2 re-derives the survivor and sorts the\n // output explicitly, so the set carries membership only.\n const dedupeKeyByGroup = new Map<string, Set<string>>();\n\n // Phase 1: repoint endpoints (by their `(kind, id)` identity, so a cross-kind id\n // collision can never repoint two unrelated edges onto one survivor), drop edges to\n // deleted nodes, and bucket the survivors by their full dedupe key.\n for (const staged of stagedEdges) {\n const fromKey = repoint(\n mergeKey(staged.fromKind, staged.fromId),\n canonicalOf,\n );\n const toKey = repoint(mergeKey(staged.toKind, staged.toId), canonicalOf);\n\n if (deletedNodeIds.has(fromKey) || deletedNodeIds.has(toKey)) {\n dropped.push({\n kind: \"edge\",\n id: staged.id,\n reason: ENDPOINT_DELETED_DROP_REASON,\n });\n continue;\n }\n\n const repointed: RepointedEdge = { staged, fromKey, toKey };\n const key = dedupeKey(fromKey, staged.kind, toKey, staged.props);\n const bucket = liveByDedupeKey.get(key);\n if (bucket === undefined) {\n liveByDedupeKey.set(key, [repointed]);\n } else {\n bucket.push(repointed);\n }\n\n const group = groupKey(fromKey, staged.kind, toKey);\n const keysForGroup = dedupeKeyByGroup.get(group);\n if (keysForGroup === undefined) {\n dedupeKeyByGroup.set(group, new Set([key]));\n } else {\n keysForGroup.add(key);\n }\n }\n\n // Phase 2: per `(from', type, to')` group, fold the per-dedupe-key buckets into\n // one survivor. A group with a single dedupe key is an exact-equal collapse (no\n // conflict); a group with several dedupe keys means props differ, so the union\n // runs the conflict policy.\n const context: ResolutionContext<GraphDef> = {\n policy: policy as PropertyConflictPolicy<GraphDef>,\n ...(weights === undefined ? {} : { weights }),\n };\n\n const merged: MergedEdge[] = [];\n const conflicts: PropertyConflict<G>[] = [];\n\n const sortedGroups = [...dedupeKeyByGroup.keys()].sort((left, right) =>\n compareStrings(left, right),\n );\n\n for (const group of sortedGroups) {\n const dedupeKeys = [...dedupeKeyByGroup.get(group)!];\n const groupEdges: RepointedEdge[] = [];\n for (const key of dedupeKeys) {\n for (const edge of liveByDedupeKey.get(key)!) {\n groupEdges.push(edge);\n }\n }\n\n const survivor = pickSurvivor(groupEdges, preferredBranchId);\n const survivorId = survivor.staged.id;\n const mergedIds = [...groupEdges]\n .map((edge) => edge.staged.id)\n .sort((left, right) => compareStrings(left, right));\n\n // Endpoint ids AND kinds come from the canonical IDENTITY keys, so a repointed\n // edge always names the canonical node's own kind (the commit then applies any\n // retype cascade), never a staged endpoint that merely shared the id string.\n const fromId = idOf(survivor.fromKey);\n const fromKind = kindOf(survivor.fromKey);\n const toId = idOf(survivor.toKey);\n const toKind = kindOf(survivor.toKey);\n\n if (dedupeKeys.length === 1) {\n // Exact-equal collapse: every member shares identical props, so no\n // conflict is possible — keep the survivor's props verbatim.\n merged.push({\n id: survivorId,\n kind: survivor.staged.kind,\n fromId,\n toId,\n fromKind,\n toKind,\n props: survivor.staged.props,\n mergedIds,\n });\n continue;\n }\n\n const { props, conflicts: groupConflicts } = unionEdgeProps(\n survivorId,\n survivor.staged.kind,\n survivor,\n groupEdges,\n context,\n branchRank,\n preferredBranchId,\n );\n for (const conflict of groupConflicts) {\n conflicts.push(conflict as PropertyConflict<G>);\n }\n merged.push({\n id: survivorId,\n kind: survivor.staged.kind,\n fromId,\n toId,\n fromKind,\n toKind,\n props,\n mergedIds,\n });\n }\n\n // Sort on a PRECOMPUTED dedupe key per edge (Schwartzian) so `canonicalizeProps` +\n // serialization run once per edge, not twice on every comparison.\n const sortedEdges = merged\n .map((edge) => ({\n edge,\n sortKey: dedupeKey(\n mergeKey(edge.fromKind, edge.fromId),\n edge.kind,\n mergeKey(edge.toKind, edge.toId),\n edge.props,\n ),\n }))\n .sort((left, right) => compareStrings(left.sortKey, right.sortKey))\n .map(({ edge }) => edge);\n\n return {\n edges: sortedEdges,\n dropped: dropped.sort((left, right) => compareStrings(left.id, right.id)),\n conflicts: conflicts.sort((left, right) =>\n compareStrings(\n `${left.entityId}|${left.property}`,\n `${right.entityId}|${right.property}`,\n ),\n ),\n };\n}\n","/**\n * Validation + default-application for {@link MergeOptions}.\n *\n * The zod schema validates the scalar / enum surface (thresholds, ceilings,\n * enums) and applies the frozen P0 defaults. Function- and store-valued fields\n * (`canonical`, a function `onPropertyConflict`, `target`, per-kind `block` /\n * `custom.score`, `branchOrder`) are not meaningfully validatable by zod, so they\n * are threaded through unchanged after the scalar surface validates.\n *\n * `normalizeMergeOptions` is the single entry point: it returns a\n * {@link NormalizedMergeOptions} with every default resolved, so downstream\n * phases never branch on `undefined`.\n */\n\nimport { z } from \"zod\";\n\nimport type { GraphDef } from \"./typegraph-internal\";\nimport type {\n BranchId,\n ComparisonCeilingPolicy,\n DeleteModifyPolicy,\n Embedder,\n MergeOptions,\n PropertyConflictPolicy,\n ReconcileTypesMode,\n ResolveConfig,\n ResolvedCluster,\n ResolveMap,\n} from \"./types\";\n\n/**\n * Frozen P0 defaults. Exported so tests and downstream phases assert against the\n * same constants rather than re-typing literals.\n */\nexport const MERGE_OPTION_DEFAULTS = {\n reconcileTypes: \"off\",\n onPropertyConflict: \"flag\",\n onBasePropertyConflict: \"flag\",\n onDeleteModifyConflict: \"flag\",\n onComparisonCeiling: \"error\",\n provenance: true,\n persistProvenance: false,\n} as const satisfies Readonly<{\n reconcileTypes: ReconcileTypesMode;\n onPropertyConflict: \"flag\";\n onBasePropertyConflict: \"flag\";\n onDeleteModifyConflict: DeleteModifyPolicy;\n onComparisonCeiling: ComparisonCeilingPolicy;\n provenance: boolean;\n persistProvenance: boolean;\n}>;\n\n/**\n * zod schema for the STRING arm of `onPropertyConflict`. The field is a union of\n * this enum and a function; the function arm is not validatable by zod, but the\n * string arm is — and validating it here keeps `onPropertyConflict` consistent with\n * every other enum option, so a bad string fails with a clean option error rather\n * than an opaque `TypeError` deep inside conflict resolution.\n */\nconst propertyConflictPolicySchema = z.enum([\n \"flag\",\n \"lastWriteWins\",\n \"provenanceWeighted\",\n]);\n\n/** zod schema for a single resolve config's scalar surface (the threshold). */\nconst resolveConfigScalarSchema = z.object({\n threshold: z\n .number()\n .min(0, { message: \"threshold must be >= 0\" })\n .max(1, { message: \"threshold must be <= 1\" }),\n});\n\n/**\n * zod schema for the scalar / enum surface of {@link MergeOptions}. Function- and\n * store-valued fields are deliberately omitted (validated structurally by the\n * type system, not at runtime) and re-attached after parsing.\n */\nconst mergeOptionsScalarSchema = z.object({\n reconcileTypes: z\n .enum([\"ontology\", \"off\"])\n .default(MERGE_OPTION_DEFAULTS.reconcileTypes),\n onDeleteModifyConflict: z\n .enum([\"deleteWins\", \"modifyWins\", \"flag\"])\n .default(MERGE_OPTION_DEFAULTS.onDeleteModifyConflict),\n onComparisonCeiling: z\n .enum([\"error\", \"mergeByIdOnly\"])\n .default(MERGE_OPTION_DEFAULTS.onComparisonCeiling),\n provenance: z.boolean().default(MERGE_OPTION_DEFAULTS.provenance),\n persistProvenance: z\n .boolean()\n .default(MERGE_OPTION_DEFAULTS.persistProvenance),\n maxComparisonsPerKind: z\n .number()\n .int({ message: \"maxComparisonsPerKind must be an integer\" })\n .min(0, { message: \"maxComparisonsPerKind must be >= 0\" })\n .optional(),\n clusterMaxDiameter: z\n .number()\n .positive({ message: \"clusterMaxDiameter must be positive\" })\n .optional(),\n});\n\n/**\n * Fully-normalized merge options: every default resolved, the (validated)\n * pass-through fields attached. Downstream phases consume this, never the raw\n * {@link MergeOptions}.\n */\nexport type NormalizedMergeOptions<G extends GraphDef = GraphDef> = Readonly<{\n // Internal kind-agnostic view: the public {@link ResolveMap} is keyed per-kind,\n // but downstream phases index it by a runtime kind STRING, so the normalized\n // form widens to a plain record. Unknown keys were already validated away.\n resolve: Readonly<Record<string, ResolveConfig<G>>>;\n reconcileTypes: ReconcileTypesMode;\n onPropertyConflict: PropertyConflictPolicy<G>;\n onBasePropertyConflict: PropertyConflictPolicy<G>;\n onDeleteModifyConflict: DeleteModifyPolicy;\n onComparisonCeiling: ComparisonCeilingPolicy;\n provenance: boolean;\n persistProvenance: boolean;\n canonical?: (\n cluster: ResolvedCluster,\n ) => ReturnType<NonNullable<MergeOptions<G>[\"canonical\"]>>;\n embedder?: Embedder;\n target?: MergeOptions<G>[\"target\"];\n maxComparisonsPerKind?: number;\n clusterMaxDiameter?: number;\n branchOrder?: readonly BranchId[];\n provenanceWeights?: ReadonlyMap<BranchId, number>;\n}>;\n\n/**\n * Validates the STRING arm of a property-conflict policy (the function arm is not\n * validatable by zod), throwing a clean option error for an unknown enum value.\n * Shared by `onPropertyConflict` and the separate `onBasePropertyConflict`.\n */\nfunction validatePropertyConflictPolicy<G extends GraphDef>(\n policy: PropertyConflictPolicy<G>,\n label: string,\n): PropertyConflictPolicy<G> {\n if (\n typeof policy === \"string\" &&\n !propertyConflictPolicySchema.safeParse(policy).success\n ) {\n throw new Error(\n `Invalid ${label} \"${policy}\": expected \"flag\", \"lastWriteWins\", \"provenanceWeighted\", or a function.`,\n );\n }\n return policy;\n}\n\n/**\n * Validates each per-kind resolve config's threshold, leaving the strategy and\n * `block` function untouched. Returns the same map shape (resolve configs are\n * passed through; only their scalar surface is validated).\n */\nfunction validateResolveMap<G extends GraphDef>(\n resolve: ResolveMap<G> | undefined,\n): Readonly<Record<string, ResolveConfig<G>>> {\n if (resolve === undefined) {\n return {};\n }\n // The public ResolveMap binds each kind's config to that kind's NodeType;\n // validation only reads the kind-agnostic scalar surface, so widen to a plain\n // record (the per-kind block/similarity types are sound at every call site).\n const configs = resolve as unknown as Readonly<\n Record<string, ResolveConfig<G>>\n >;\n const validated: Record<string, ResolveConfig<G>> = {};\n for (const [kind, config] of Object.entries(configs)) {\n const parsed = resolveConfigScalarSchema.safeParse({\n threshold: config.threshold,\n });\n if (!parsed.success) {\n throw new Error(\n `Invalid resolve config for kind \"${kind}\": ${parsed.error.message}`,\n );\n }\n if (\n config.keyless !== undefined &&\n (!Number.isInteger(config.keyless.window) || config.keyless.window < 1)\n ) {\n throw new Error(\n `Invalid resolve config for kind \"${kind}\": keyless.window must be a positive integer, got ${config.keyless.window}.`,\n );\n }\n const strategy = config.similarity;\n if (strategy.kind === \"hybrid\") {\n for (const component of [\"vector\", \"fulltext\"] as const) {\n const weight = strategy.weights?.[component];\n if (weight !== undefined && (!Number.isFinite(weight) || weight < 0)) {\n throw new Error(\n `Invalid resolve config for kind \"${kind}\": similarity.weights.${component} must be a finite number >= 0, got ${String(weight)}.`,\n );\n }\n }\n }\n validated[kind] = config;\n }\n return validated;\n}\n\n/**\n * Validates the optional `\"provenanceWeighted\"` trust weights: every weight must\n * be a finite number `>= 0`, since a NaN / negative weight would corrupt the\n * highest-weight pick. Returns the same map.\n */\nfunction validateProvenanceWeights(\n weights: ReadonlyMap<BranchId, number>,\n): ReadonlyMap<BranchId, number> {\n for (const [branchId, weight] of weights) {\n if (!Number.isFinite(weight) || weight < 0) {\n throw new Error(\n `Invalid provenanceWeights for branch \"${branchId}\": weight must be a finite number >= 0, got ${String(weight)}.`,\n );\n }\n }\n return weights;\n}\n\n/**\n * Validates and normalizes {@link MergeOptions}, applying every P0 default.\n *\n * Throws (not a `Result`) on invalid scalar input — option validation is a\n * caller-boundary concern, surfaced as a thrown error per project conventions;\n * `merge()` converts it back to a typed `MergeError` at its own boundary.\n *\n * @throws if a threshold is outside `[0, 1]`, `maxComparisonsPerKind` is\n * negative/non-integer, or `clusterMaxDiameter` is non-positive.\n */\nexport function normalizeMergeOptions<G extends GraphDef>(\n options: MergeOptions<G> = {},\n): NormalizedMergeOptions<G> {\n const scalar = mergeOptionsScalarSchema.parse({\n reconcileTypes: options.reconcileTypes,\n onDeleteModifyConflict: options.onDeleteModifyConflict,\n onComparisonCeiling: options.onComparisonCeiling,\n provenance: options.provenance,\n persistProvenance: options.persistProvenance,\n ...(options.maxComparisonsPerKind === undefined ?\n {}\n : { maxComparisonsPerKind: options.maxComparisonsPerKind }),\n ...(options.clusterMaxDiameter === undefined ?\n {}\n : { clusterMaxDiameter: options.clusterMaxDiameter }),\n });\n\n const onPropertyConflict = validatePropertyConflictPolicy(\n options.onPropertyConflict ?? MERGE_OPTION_DEFAULTS.onPropertyConflict,\n \"onPropertyConflict\",\n );\n // DELIBERATELY does not fall back to `onPropertyConflict` — base↔branch conflicts\n // must not silently inherit a staged policy that could overwrite committed data.\n const onBasePropertyConflict = validatePropertyConflictPolicy(\n options.onBasePropertyConflict ??\n MERGE_OPTION_DEFAULTS.onBasePropertyConflict,\n \"onBasePropertyConflict\",\n );\n\n const provenanceWeights =\n options.provenanceWeights === undefined ?\n undefined\n : validateProvenanceWeights(options.provenanceWeights);\n\n // \"provenanceWeighted\" without weights would silently degrade to a\n // stable-branch-order (lastWriteWins) resolution and quietly commit a\n // different graph. Fail loudly instead so the misconfiguration is visible.\n const usesProvenanceWeighting =\n onPropertyConflict === \"provenanceWeighted\" ||\n onBasePropertyConflict === \"provenanceWeighted\";\n if (\n usesProvenanceWeighting &&\n (provenanceWeights === undefined || provenanceWeights.size === 0)\n ) {\n throw new Error(\n 'A \"provenanceWeighted\" property-conflict policy requires a non-empty provenanceWeights map.',\n );\n }\n\n return {\n resolve: validateResolveMap(options.resolve),\n reconcileTypes: scalar.reconcileTypes,\n onPropertyConflict,\n onBasePropertyConflict,\n onDeleteModifyConflict: scalar.onDeleteModifyConflict,\n onComparisonCeiling: scalar.onComparisonCeiling,\n provenance: scalar.provenance,\n persistProvenance: scalar.persistProvenance,\n ...(options.canonical === undefined ?\n {}\n : { canonical: options.canonical }),\n ...(options.embedder === undefined ? {} : { embedder: options.embedder }),\n ...(options.target === undefined ? {} : { target: options.target }),\n ...(scalar.maxComparisonsPerKind === undefined ?\n {}\n : { maxComparisonsPerKind: scalar.maxComparisonsPerKind }),\n ...(scalar.clusterMaxDiameter === undefined ?\n {}\n : { clusterMaxDiameter: scalar.clusterMaxDiameter }),\n ...(options.branchOrder === undefined ?\n {}\n : { branchOrder: options.branchOrder }),\n ...(provenanceWeights === undefined ? {} : { provenanceWeights }),\n };\n}\n","/**\n * Sidecar provenance graph — durable, queryable `{branch, sourceId}` → canonical\n * tagging for a merge (open-item #5: \"on-graph provenance persistence\").\n *\n * The merge's in-memory {@link import(\"./types\").ProvenanceIndex}\n * (`report.provenance.byBranch`) evaporates after the call. This module persists the\n * same contributions as TYPED nodes in a SIDECAR graph on the SAME backend as the\n * merge target — a separate graph (its own `graphId`-namespaced tables), so the\n * user's domain schema is untouched. It is a faithful prototype of a future\n * first-class TypeGraph `annotations` primitive (see `docs/design/annotations.md`).\n *\n * Persistence is POST-COMMIT and best-effort, by design: the merge's commit path is\n * unchanged and stays on the same public store/backend contracts. Provenance is derived and\n * re-runnable, and the node ids are DETERMINISTIC (a hash of `{targetGraphId, role,\n * canonicalKind, canonicalId, branchId, sourceId}`), so re-merging the same forks UPSERTS rather\n * than duplicating. Atomic-in-the-merge-transaction is a possible upgrade later\n * (TypeGraph's cross-store `withTransaction`), deliberately deferred for v1.\n */\n\nimport { z } from \"zod\";\n\nimport { compareStrings } from \"./node-key\";\nimport type { GraphBackend, Node, Store } from \"./typegraph-internal\";\nimport {\n createStoreWithSchema,\n defineGraph,\n defineNode,\n sha256Hex,\n} from \"./typegraph-internal\";\nimport type { BranchId, ProvenanceRecord } from \"./types\";\n\n/** The Provenance node: one row per `{branch, sourceId}` → canonical contribution. */\nconst Provenance = defineNode(\"Provenance\", {\n schema: z.object({\n targetGraphId: z.string(),\n role: z.enum([\"node\", \"edge\"]),\n canonicalId: z.string(),\n canonicalKind: z.string(),\n branchId: z.string(),\n sourceId: z.string(),\n }),\n});\n\n/**\n * Derives the sidecar graph id for a target graph. Suffixing the target's own id\n * keeps each target graph's provenance in its own `graphId`-namespaced tables on a\n * shared backend, while a single `Provenance` schema serves all of them.\n */\nexport function provenanceGraphId(targetGraphId: string): string {\n return `${targetGraphId}::merge-provenance`;\n}\n\n/** Builds the sidecar provenance graph definition for a target graph. */\nfunction buildProvenanceGraph(targetGraphId: string) {\n return defineGraph({\n id: provenanceGraphId(targetGraphId),\n nodes: { Provenance: { type: Provenance } },\n edges: {},\n });\n}\n\n/** The concrete sidecar provenance graph type. */\nexport type ProvenanceGraph = ReturnType<typeof buildProvenanceGraph>;\n\n/** A persisted provenance node (the queryable record). */\nexport type ProvenanceNode = Node<typeof Provenance>;\n\n/**\n * Opens — materializing the schema if needed — the provenance store for a target\n * graph on the given backend. Idempotent: safe to call before every persist/query,\n * and shares the backend with the target (so the caller must NOT close it\n * separately — closing the shared backend is the target owner's job).\n */\nexport async function openProvenanceStore(\n backend: GraphBackend,\n targetGraphId: string,\n): Promise<Store<ProvenanceGraph>> {\n const [store] = await createStoreWithSchema(\n buildProvenanceGraph(targetGraphId),\n backend,\n );\n return store;\n}\n\n/** Null byte — cannot occur in a normal id, so an unambiguous tuple separator. */\nconst ID_SEPARATOR = \"\\0\";\n\n/** Bytes of the SHA-256 digest kept (128 bits — collision-safe for provenance). */\nconst ID_DIGEST_BYTES = 16;\n\n/**\n * Deterministic provenance node id: a hash of the contribution tuple, so\n * re-persisting the same contribution UPSERTS the same row (idempotent re-runs).\n *\n * Uses the shared {@link sha256Hex} (Web Crypto) instead of `node:crypto` so the\n * `graph-merge` entry point stays importable on every runtime the library\n * targets (Cloudflare Workers, Deno, browsers) — `base-version.ts` already hashes\n * its content fingerprint the same way.\n */\nexport async function provenanceNodeId(\n targetGraphId: string,\n record: ProvenanceRecord,\n): Promise<string> {\n const tuple = [\n targetGraphId,\n record.role,\n // canonicalKind is part of node identity: two contributions to different-kind\n // canonicals that share a bare id (e.g. base Patient:x and Encounter:x) must NOT\n // hash to the same sidecar row and clobber each other (the (kind,id) identity model).\n record.canonicalKind,\n record.canonicalId,\n record.branchId,\n record.sourceId,\n ].join(ID_SEPARATOR);\n const digest = await sha256Hex(tuple, ID_DIGEST_BYTES);\n return `prov_${digest}`;\n}\n\n/**\n * Upserts one `Provenance` node per record into the sidecar store, keyed by the\n * deterministic id (re-running the same merge is a no-op upsert, never a\n * duplicate). Returns the row count written. The caller wraps this for best-effort\n * behavior — a failure here must not fail an already-committed merge.\n */\nexport async function persistProvenanceRecords(\n store: Store<ProvenanceGraph>,\n targetGraphId: string,\n records: readonly ProvenanceRecord[],\n): Promise<number> {\n if (records.length === 0) {\n return 0;\n }\n const items = await Promise.all(\n records.map(async (record) => ({\n id: await provenanceNodeId(targetGraphId, record),\n props: {\n targetGraphId,\n role: record.role,\n canonicalId: record.canonicalId,\n canonicalKind: record.canonicalKind,\n branchId: record.branchId,\n sourceId: record.sourceId,\n },\n })),\n );\n await store.nodes.Provenance.bulkUpsertById(items);\n return items.length;\n}\n\n/** Filter for {@link readProvenance}. Each field, when set, narrows the result. */\nexport type ProvenanceQuery = Readonly<{\n branchId?: BranchId | string;\n canonicalId?: string;\n role?: \"node\" | \"edge\";\n}>;\n\n/**\n * Reads persisted provenance back, filtered and stably ordered. The sidecar is a\n * normal typed graph, so this is a thin ergonomic wrapper over\n * `store.nodes.Provenance.find()` (filtered in memory — provenance volumes are\n * modest; a query-builder `where` is the scale path). Answers \"which canonical\n * entities did branch X contribute to?\" and \"who contributed canonical Y?\".\n */\nexport async function readProvenance(\n store: Store<ProvenanceGraph>,\n query: ProvenanceQuery = {},\n): Promise<readonly ProvenanceNode[]> {\n const all = await store.nodes.Provenance.find();\n return all\n .filter(\n (node) =>\n (query.branchId === undefined || node.branchId === query.branchId) &&\n (query.canonicalId === undefined ||\n node.canonicalId === query.canonicalId) &&\n (query.role === undefined || node.role === query.role),\n )\n .sort((left, right) => compareStrings(left.id, right.id));\n}\n","/**\n * Candidate SOURCES (design §4 / §6.1) — the RECALL layer of candidate generation.\n *\n * Candidate generation is three layers — sources → scoring → reconciler (§4). This\n * module is the FIRST layer: each source PROPOSES candidates and decides nothing\n * about a fuzzy match. A source emits three things:\n *\n * - `pairs` — unscored `(a, b)` node pairs handed to the shared scoring\n * stage (`scoring.ts`), which makes every fuzzy match decision.\n * - `forcedEdges` — DEFINITIONAL matches (a shared unique value) that bypass\n * scoring at {@link FORCED_MATCH_SCORE}.\n * - `baseMembers` — committed base nodes the source pulled into scope, so the\n * reconciler can seed + canonicalize a base endpoint without\n * re-querying the backend. EMPTY for staged-only sources.\n *\n * Two sources ship here — today's two blocking strategies (`blocking.ts`),\n * refactored behind the source interface:\n *\n * - {@link exactKeySource} (`exactKey`, §6.1) — the `block(node) => string`\n * bucket: same-bucket node pairs become fuzzy `pairs`. Staged-vs-staged.\n * - {@link uniqueSource} (`unique`, §6.1) — the unique-constraint signature\n * buckets: every same-signature pair is a FORCED edge (a shared unique value\n * is definitionally the same entity). Staged-vs-staged.\n *\n * Both read the SAME pre-computed `blockNodes` map off the scope (the UNION of the\n * `block()` key and the per-constraint signatures, `blocking.ts`), filtering it by\n * {@link isUniqueBucketKey}: `exactKey` owns the non-unique buckets, `unique` owns\n * the unique buckets. Sharing one blocked map (vs. re-blocking per source) keeps the\n * source split byte-identical to the old fused `generateCandidates` — a node with a\n * unique signature but no `block()` key lands ONLY in its unique bucket, never the\n * all-vs-all `unblocked` bucket.\n *\n * Determinism: the extraction visits buckets in sorted-key order over id-sorted\n * members and enumerates `i < j`, so proposals are emitted in a canonical order;\n * the scoring stage additionally dedups + sorts, so neither source's emission order\n * leaks into the merge result.\n */\n\nimport { isUniqueBucketKey, UNBLOCKED_BUCKET_KEY } from \"./blocking\";\nimport { MergeError } from \"./errors\";\nimport {\n compareMergeKeys,\n compareStrings,\n idOf,\n kindOf,\n type MergeKey,\n mergeKey,\n mergeKeyOf,\n} from \"./node-key\";\nimport type { CandidateEdge, CandidatePair } from \"./scoring\";\nimport { FORCED_MATCH_SCORE } from \"./scoring\";\nimport { fieldText } from \"./similarity\";\nimport type {\n GraphDef,\n JsonValue,\n Node,\n NodeId,\n NodeType,\n UniqueIntrospection,\n} from \"./typegraph-internal\";\nimport type { ResolveConfig } from \"./types\";\nimport { UnionFind } from \"./union-find\";\n\n/**\n * A committed BASE node a source pulled into the cluster universe (design §4\n * member contribution / §6.4-D). It carries the same `(id, kind, props)` a staged\n * member does, plus a reserved `\"base\"` origin so the reconciler can enforce\n * base-id-wins (§6.4-C) and tag provenance with the base sentinel (§6.4-D). EMPTY\n * for staged-only sources (`exactKey`, `unique`).\n */\nexport type BaseMember = Readonly<{\n id: NodeId<NodeType>;\n kind: string;\n props: Readonly<Record<string, JsonValue>>;\n origin: \"base\";\n}>;\n\n/**\n * What a candidate source emits for one kind: fuzzy `pairs` to score, FORCED\n * (definitional) edges to pass through unscored, and the committed `baseMembers`\n * it pulled into scope.\n */\ntype SourceResult = Readonly<{\n pairs: readonly CandidatePair[];\n forcedEdges: readonly CandidateEdge[];\n baseMembers: readonly BaseMember[];\n}>;\n\n/**\n * The minimal node-collection surface a base-querying source needs: the public\n * `bulkFindByConstraint` (typegraph 0.29.0). It computes each item's constraint key\n * from its props, returns the live committed match per item in INPUT ORDER\n * (`undefined` for misses, soft-deleted excluded), and is indexed by the `uniques`\n * table PK — so graph-merge never reconstructs constraint keys itself. A runtime,\n * kind-string-keyed view (like the commit's `TxNodes`) so a source can dispatch on\n * a kind string without threading the caller's concrete `Store<G>` generic.\n */\nexport type BaseNodeLookup = Readonly<{\n bulkFindByConstraint: (\n constraintName: string,\n items: readonly Readonly<{ props: Record<string, unknown> }>[],\n ) => Promise<readonly (Node<NodeType> | undefined)[]>;\n /**\n * The non-unique sibling (typegraph 0.30): for each item, the live committed nodes\n * sharing its declared-INDEX key (computed from props), returned per item in input\n * order, each inner array id-sorted, soft-deleted excluded. `limitPerInput` bounds\n * per-item fan-out (id-ordered, so the cap is deterministic). Candidate retrieval —\n * NOT a uniqueness/identity guarantee — so `baseKey` emits scored pairs, not forced\n * edges.\n */\n bulkFindByIndex: (\n indexName: string,\n items: readonly Readonly<{ props: Record<string, unknown> }>[],\n options?: Readonly<{ limitPerInput?: number }>,\n ) => Promise<readonly (readonly Node<NodeType>[])[]>;\n}>;\n\n/** Runtime, kind-string-keyed view of a store's node collections for base lookups. */\nexport type BaseLookupStore = Readonly<{\n nodes: Readonly<Record<string, BaseNodeLookup>>;\n}>;\n\n/**\n * The per-kind input a source generates over. `blocks` is the UNION `blockNodes`\n * result (`block()` key + per-constraint signatures) the staged sources read.\n *\n * The remaining fields are present only when a BASE-querying source (`baseUnique` /\n * `baseKey`, §6.2) is driven: the kind's materialized staged new `nodes` (the lookup\n * items), its `uniqueConstraints` (for `baseUnique`), the declared `blockIndex` name\n * (for `baseKey`, when the kind configured one), and the committed `store` to query\n * against. Staged-only sources (`exactKey`, `unique`) ignore them, so the public\n * `merge()` candidate path leaves them unset.\n */\nexport type SourceScope = Readonly<{\n kind: string;\n blocks: ReadonlyMap<string, readonly Node<NodeType>[]>;\n nodes?: readonly Node<NodeType>[];\n uniqueConstraints?: readonly UniqueIntrospection[];\n blockIndex?: string;\n /** When set, `exactKey` bounds the no-key (`\"unblocked\"`) bucket by sorted-\n * neighbourhood instead of all-vs-all (the `keyless` source, §6.2). */\n keyless?: KeylessConfig;\n store?: BaseLookupStore;\n}>;\n\n/**\n * A candidate source (design §4): proposes pairs (recall) + definitional forced\n * edges, and supplies the base members it pulled into scope. The `id` attributes\n * a source in reports and pins its determinism level (§7).\n */\nexport type CandidateSource = Readonly<{\n readonly id: string;\n generate(scope: SourceScope): Promise<SourceResult>;\n}>;\n\n/**\n * Orders a pair's two node IDENTITY keys (`(kind, id)`, not bare id) so the smaller\n * is `a`, with the matching node objects in `left`/`right`. Keying on the composite\n * identity is what keeps a `Patient` and an `Encounter` that share an id string from\n * being proposed as the same endpoint. Guarantees every proposal has a single\n * canonical `(a, b)` representation regardless of enumeration order.\n */\nfunction orderEndpoints<K extends NodeType>(\n left: Node<K>,\n right: Node<K>,\n): CandidatePair<K> {\n const leftKey = mergeKeyOf(left);\n const rightKey = mergeKeyOf(right);\n return compareMergeKeys(leftKey, rightKey) <= 0 ?\n { a: leftKey, b: rightKey, left, right }\n : { a: rightKey, b: leftKey, left: right, right: left };\n}\n\n/** Sorts a bucket's members by ascending node id (defensive — blocking already does). */\nfunction sortMembersById<K extends NodeType>(\n members: readonly Node<K>[],\n): readonly Node<K>[] {\n return [...members].sort((left, right) => compareStrings(left.id, right.id));\n}\n\n/** Visits the blocked buckets in sorted-key order. */\nfunction sortedBucketKeys(\n blocks: ReadonlyMap<string, readonly Node<NodeType>[]>,\n): readonly string[] {\n return [...blocks.keys()].sort((left, right) => compareStrings(left, right));\n}\n\n/** The system fields a {@link Node} carries alongside its schema props. */\nconst NODE_SYSTEM_FIELDS: ReadonlySet<string> = new Set([\"id\", \"kind\", \"meta\"]);\n\n/**\n * Extracts a node's schema PROPS from its spread runtime shape (`Node` spreads its\n * schema fields at the top level alongside `id` / `kind` / `meta`). Used to build a\n * base lookup's props from a staged node and a {@link BaseMember}'s props from the\n * returned committed node — without a second fetch or any knowledge of the schema.\n */\nfunction nodeProps(node: Node<NodeType>): Record<string, JsonValue> {\n const props: Record<string, JsonValue> = {};\n for (const [key, value] of Object.entries(\n node as unknown as Record<string, unknown>,\n )) {\n if (!NODE_SYSTEM_FIELDS.has(key)) {\n props[key] = value as JsonValue;\n }\n }\n return props;\n}\n\n/**\n * The bounded coarse source for the NO-KEY case (design §6.2, `keyless`): which\n * unblocked nodes to compare, and how far. `window` is the forward-neighbour count;\n * `sortFields` is the kind's similarity text fields, so the SORTED-NEIGHBOURHOOD sort\n * groups lexically-similar values adjacently (the same text the scorer reads).\n */\nexport type KeylessConfig = Readonly<{\n window: number;\n sortFields: readonly string[];\n}>;\n\n/**\n * Builds the {@link KeylessConfig} for a kind's resolve config (its `keyless.window`\n * plus the similarity text fields the sorted-neighbourhood pass sorts on), or\n * `undefined` when `keyless` is unset. The sort fields are the kind's similarity text\n * (so adjacency tracks the scorer's text); `custom` similarity exposes none → sort by\n * id only (bounded but semantically weak — a no-key custom kind wants `stagedVector`,\n * deferred §8).\n *\n * Shared by `merge()`'s source path AND the back-compat `generateCandidates()` helper,\n * so both honour `ResolveConfig.keyless` identically rather than the helper silently\n * ignoring it.\n */\nexport function keylessConfigFor<G extends GraphDef, K extends NodeType>(\n resolveConfig: ResolveConfig<G, K>,\n): KeylessConfig | undefined {\n if (resolveConfig.keyless === undefined) {\n return undefined;\n }\n const strategy = resolveConfig.similarity;\n const sortFields =\n strategy.kind === \"fulltext\" || strategy.kind === \"hybrid\" ? strategy.fields\n : strategy.kind === \"vector\" ? [strategy.field]\n : [];\n return { window: resolveConfig.keyless.window, sortFields };\n}\n\n/**\n * Single-pass SORTED-NEIGHBOURHOOD pairs over one bucket's members: sort by the\n * similarity-field text (tie-broken by id — a total order, so the output is a pure\n * function of the member SET), then propose each node only against its next `window`\n * neighbours. O(n·window) instead of O(n²); `window ≥ n-1` degenerates to all-vs-all.\n */\nfunction windowedPairs(\n members: readonly Node<NodeType>[],\n config: KeylessConfig,\n): readonly CandidatePair[] {\n const keyed = members.map((node) => ({\n node,\n key: fieldText(node, config.sortFields),\n }));\n keyed.sort((left, right) =>\n left.key === right.key ?\n compareStrings(left.node.id, right.node.id)\n : compareStrings(left.key, right.key),\n );\n const pairs: CandidatePair[] = [];\n for (let index = 0; index < keyed.length; index += 1) {\n const last = Math.min(index + config.window, keyed.length - 1);\n for (let index_ = index + 1; index_ <= last; index_ += 1) {\n pairs.push(orderEndpoints(keyed[index]!.node, keyed[index_]!.node));\n }\n }\n return pairs;\n}\n\n/**\n * Extracts the FUZZY candidate pairs from the NON-unique (block / unblocked)\n * buckets: every `i < j` pair of a bucket's id-sorted members, in sorted-key\n * order. Cross-bucket duplicates are left for the scoring stage to dedup.\n *\n * When `keyless` is set, the shared `\"unblocked\"` (no-key) bucket is bounded by\n * single-pass sorted-neighbourhood ({@link windowedPairs}) instead of all-vs-all —\n * closing the O(n²) cliff (design §6.2). Keyed `block()` buckets are unaffected\n * (they are already bounded by the key). Unset preserves all-vs-all for every bucket.\n */\nexport function pairsFromBlocks(\n blocks: ReadonlyMap<string, readonly Node<NodeType>[]>,\n keyless?: KeylessConfig,\n): readonly CandidatePair[] {\n const pairs: CandidatePair[] = [];\n for (const bucketKey of sortedBucketKeys(blocks)) {\n if (isUniqueBucketKey(bucketKey)) {\n continue;\n }\n const members = sortMembersById(blocks.get(bucketKey) ?? []);\n if (keyless !== undefined && bucketKey === UNBLOCKED_BUCKET_KEY) {\n pairs.push(...windowedPairs(members, keyless));\n continue;\n }\n for (let index = 0; index < members.length; index += 1) {\n for (let index_ = index + 1; index_ < members.length; index_ += 1) {\n pairs.push(orderEndpoints(members[index]!, members[index_]!));\n }\n }\n }\n return pairs;\n}\n\n/**\n * Extracts the FORCED (definitional) edges from the UNIQUE-constraint buckets:\n * every `i < j` pair of a bucket's id-sorted members, at {@link FORCED_MATCH_SCORE}.\n * Cross-bucket / cross-constraint duplicates are left for the scoring stage to dedup.\n */\nexport function forcedEdgesFromBlocks(\n blocks: ReadonlyMap<string, readonly Node<NodeType>[]>,\n): readonly CandidateEdge[] {\n const edges: CandidateEdge[] = [];\n for (const bucketKey of sortedBucketKeys(blocks)) {\n if (!isUniqueBucketKey(bucketKey)) {\n continue;\n }\n const members = sortMembersById(blocks.get(bucketKey) ?? []);\n for (let index = 0; index < members.length; index += 1) {\n for (let index_ = index + 1; index_ < members.length; index_ += 1) {\n const { a, b } = orderEndpoints(members[index]!, members[index_]!);\n edges.push({ a, b, score: FORCED_MATCH_SCORE });\n }\n }\n }\n return edges;\n}\n\n/**\n * Ontology RETYPE candidate edges (the cross-kind STAGED source, §6.4 / T10).\n *\n * Node identity is strictly `(kind, id)`, so a `Patient` and an `Encounter` that\n * share an id string are DISTINCT and never fuse. But under `reconcileTypes:\n * \"ontology\"`, two STAGED-NEW nodes that share a bare id AND carry subtype-compatible\n * kinds are \"the same entity at a refined type\" (one branch staged `Doctor:x`,\n * another `SpecialistDoctor:x`). This source forces those distinct identities into one\n * cluster so the reconciler can collapse it to the most-specific kind. The same-id\n * identities are PARTITIONED into maximal subtype-comparable groups first, so an\n * unrelated kind sharing the id (`Encounter:x` beside `Doctor:x` / `SpecialistDoctor:x`)\n * is split into its own group and does NOT suppress the valid retype; a group only\n * fuses when its kinds still collapse to a single most-specific kind.\n *\n * `isRetypeCompatible` MUST be the same most-specific-common-kind test the reconciler\n * uses ({@link import(\"./type-reconcile\").mostSpecificCommonKind}), so a kind set\n * fuses here iff the reconciler would later collapse it. The caller passes STAGED\n * identities only; committed-base members stay outside this staged retype source.\n *\n * Deterministic: ids are visited in sorted order, the identities at each id are sorted\n * + deduped, and a star of forced edges from the minimum identity makes the fusion\n * transitive (the scoring stage dedups the forced set).\n */\nexport function ontologyRetypeEdges(\n stagedIdentities: Iterable<MergeKey>,\n isRetypeCompatible: (kinds: readonly string[]) => boolean,\n): readonly CandidateEdge[] {\n const identitiesById = new Map<string, MergeKey[]>();\n for (const identity of stagedIdentities) {\n const id = idOf(identity);\n const bucket = identitiesById.get(id);\n if (bucket === undefined) {\n identitiesById.set(id, [identity]);\n } else {\n bucket.push(identity);\n }\n }\n\n const edges: CandidateEdge[] = [];\n for (const id of [...identitiesById.keys()].sort(compareStrings)) {\n const identities = [...new Set(identitiesById.get(id))].sort(\n compareMergeKeys,\n );\n if (identities.length < 2) {\n continue; // a single kind at this id — nothing cross-kind to reconcile.\n }\n // Partition the same-id identities into maximal subtype-comparable GROUPS, so an\n // UNRELATED kind sharing the id (e.g. an `Encounter:x` next to a `Doctor:x` /\n // `SpecialistDoctor:x` refinement) does not suppress the valid retype: two\n // identities join a group when their kinds are pairwise retype-compatible, and the\n // relation is unioned transitively.\n const group = unionByCompatibility(identities, isRetypeCompatible);\n for (const members of groupsOf(identities, group)) {\n // Only fuse a group that still collapses to ONE most-specific kind (a single\n // minimum). Incompatible siblings linked only through a shared subtype do not —\n // fusing them would force the reconciler to flag the cluster and pick a kind.\n if (\n members.length < 2 ||\n !isRetypeCompatible(members.map((identity) => kindOf(identity)))\n ) {\n continue;\n }\n for (let index = 1; index < members.length; index += 1) {\n edges.push({\n a: members[0]!,\n b: members[index]!,\n score: FORCED_MATCH_SCORE,\n });\n }\n }\n }\n return edges;\n}\n\n/**\n * Union-find over a same-id identity set: `identity → group representative`, where two\n * identities share a representative iff their kinds are (transitively) pairwise\n * {@link isRetypeCompatible}. Pure over the identity SET (the representative chosen is\n * irrelevant — only the partition matters, and callers re-sort each group).\n */\nfunction unionByCompatibility(\n identities: readonly MergeKey[],\n isRetypeCompatible: (kinds: readonly string[]) => boolean,\n): ReadonlyMap<MergeKey, MergeKey> {\n // Partition only — the representative chosen is irrelevant (callers re-sort each\n // group), so any total order works; `compareMergeKeys` keeps it deterministic.\n const forest = new UnionFind<MergeKey>(compareMergeKeys);\n for (const identity of identities) {\n forest.add(identity);\n }\n for (let index = 0; index < identities.length; index += 1) {\n for (let index_ = index + 1; index_ < identities.length; index_ += 1) {\n if (\n isRetypeCompatible([\n kindOf(identities[index]!),\n kindOf(identities[index_]!),\n ])\n ) {\n forest.union(identities[index]!, identities[index_]!);\n }\n }\n }\n return new Map(\n identities.map((identity) => [identity, forest.find(identity)]),\n );\n}\n\n/** Buckets identities by their union-find representative, each group id-sorted. */\nfunction groupsOf(\n identities: readonly MergeKey[],\n representativeOf: ReadonlyMap<MergeKey, MergeKey>,\n): readonly (readonly MergeKey[])[] {\n const byRoot = new Map<MergeKey, MergeKey[]>();\n for (const identity of identities) {\n const root = representativeOf.get(identity)!;\n const bucket = byRoot.get(root);\n if (bucket === undefined) {\n byRoot.set(root, [identity]);\n } else {\n bucket.push(identity);\n }\n }\n return [...byRoot.values()].map((group) => [...group].sort(compareMergeKeys));\n}\n\n/**\n * `exactKey` source (§6.1) — today's `block(node) => string` bucketing. Same-bucket\n * node pairs become fuzzy `pairs` for the scoring stage to decide. Staged-vs-staged,\n * fully deterministic, no base members.\n *\n * Also hosts the `keyless` source (§6.2): when `scope.keyless` is set, the no-key\n * (`\"unblocked\"`) bucket is bounded by sorted-neighbourhood rather than all-vs-all.\n * It rides `exactKey` rather than a parallel source because both operate on the same\n * staged blocked map and would otherwise double-emit the unblocked bucket.\n */\nexport const exactKeySource: CandidateSource = {\n id: \"exactKey\",\n generate(scope) {\n return Promise.resolve({\n pairs: pairsFromBlocks(scope.blocks, scope.keyless),\n forcedEdges: [],\n baseMembers: [],\n });\n },\n};\n\n/**\n * `unique` source (§6.1) — today's unique-constraint short-circuit. Every pair\n * sharing a unique signature is a FORCED edge: a shared unique value is\n * definitionally the same entity, so it merges regardless of similarity (differing\n * properties are reported as conflicts downstream, and the merged graph never\n * violates its own uniqueness). Staged-vs-staged, fully deterministic, no base\n * members.\n */\nexport const uniqueSource: CandidateSource = {\n id: \"unique\",\n generate(scope) {\n return Promise.resolve({\n pairs: [],\n forcedEdges: forcedEdgesFromBlocks(scope.blocks),\n baseMembers: [],\n });\n },\n};\n\n/**\n * `baseUnique` source (§6.2) — the first NEW-vs-BASE source. For each declared\n * unique constraint, it issues ONE batched `bulkFindByConstraint` over the staged\n * new nodes against the committed base store (TypeGraph's own constraint API,\n * indexed by the `uniques` PK; key computed from props, soft-deleted excluded). Each\n * hit is a DEFINITIONAL match — a staged node sharing a committed node's unique\n * value is the same entity — so it emits:\n *\n * - a FORCED edge between the staged node and the committed base node, and\n * - a {@link BaseMember} built from the returned committed node (no second fetch),\n * so the reconciler can seed + canonicalize the base endpoint (§4).\n *\n * Grouped by `(kind, constraint)` — one batched call per constraint — so each\n * constraint's own `fields` / `where` / `scope` / `collation` semantics are honoured\n * by construction; graph-merge never rebuilds keys. Deterministic: constraints are\n * visited in sorted name order, base members are deduped by id and id-sorted, and\n * the scoring stage dedups + sorts the forced edges.\n *\n * NOT part of {@link CANDIDATE_SOURCES}: the public `merge()` snapshot path stays\n * staged-vs-staged. This source is driven only by the synthetic new-vs-base scope\n * (later slice steps), which supplies the `nodes` / `uniqueConstraints` / `store`\n * the staged sources omit.\n */\nexport const baseUniqueSource: CandidateSource = {\n id: \"baseUnique\",\n async generate(scope) {\n const { kind, nodes, uniqueConstraints, store } = scope;\n if (\n nodes === undefined ||\n uniqueConstraints === undefined ||\n store === undefined\n ) {\n throw new MergeError(\n \"baseUniqueSource requires nodes, uniqueConstraints, and store in the source scope.\",\n { details: { kind, source: \"baseUnique\" } },\n );\n }\n\n const collection = store.nodes[kind];\n if (collection === undefined || nodes.length === 0) {\n return { pairs: [], forcedEdges: [], baseMembers: [] };\n }\n\n const forcedEdges: CandidateEdge[] = [];\n const baseMembers = new Map<string, BaseMember>();\n\n // The lookup items are the SAME for every constraint (one props bag per staged\n // node), so build them ONCE rather than per constraint, and fire the independent\n // per-constraint lookups concurrently. Results are consumed in sorted-constraint\n // order below, so the dedup-by-id keeps determinism despite the parallel I/O.\n const constraints = [...uniqueConstraints].sort((left, right) =>\n compareStrings(left.name, right.name),\n );\n const items = nodes.map((node) => ({ props: nodeProps(node) }));\n // `bulkFindByConstraint` re-validates each item's FULL props against the kind's\n // CREATE schema to compute the constraint key, so a non-idempotent create schema\n // (a transform/default/coercion) — or a staged node that otherwise fails the\n // schema — throws a typegraph error. Surface it as a typed MergeError carrying the\n // kind + constraint, rather than letting an opaque throw be masked as the generic\n // \"Merge failed while staging or committing\" wrapper downstream.\n const matchesByConstraint = await Promise.all(\n constraints.map(async (constraint) => {\n try {\n return await collection.bulkFindByConstraint(constraint.name, items);\n } catch (error) {\n throw new MergeError(\n `baseUniqueSource: new-vs-base lookup for constraint \"${constraint.name}\" on kind \"${kind}\" failed — a staged node's props could not be validated against the kind's schema for constraint-key computation.`,\n { details: { kind, constraint: constraint.name }, cause: error },\n );\n }\n }),\n );\n for (const matches of matchesByConstraint) {\n for (const [index, node] of nodes.entries()) {\n const base = matches[index];\n if (base === undefined) {\n continue;\n }\n const stagedNode = node;\n const stagedKey = mergeKey(stagedNode.kind, stagedNode.id);\n const baseKey = mergeKey(base.kind, base.id);\n // ALWAYS pull the committed node in as a base member, so the reconciler seeds +\n // canonicalizes it and enforces base-id-wins (§6.4-C) — including for a\n // same-(kind,id) re-discovery, where the committed value must still win over a\n // divergent staged prop. (Dropping the base member here is what made a same-id\n // re-add ERROR in the stale-overwrite guard instead of resolving onto the base.)\n if (!baseMembers.has(baseKey)) {\n baseMembers.set(baseKey, {\n origin: \"base\",\n id: base.id,\n kind: base.kind,\n props: nodeProps(base),\n });\n }\n // A same-(kind,id) re-discovery is already ONE identity (the base member lands\n // in the staged node's own cluster by key), so it needs no linking edge — a\n // self-loop would be a degenerate no-op. Skip ONLY the forced edge, not the\n // base member above.\n if (stagedKey === baseKey) {\n continue;\n }\n const { a, b } =\n compareMergeKeys(stagedKey, baseKey) <= 0 ?\n { a: stagedKey, b: baseKey }\n : { a: baseKey, b: stagedKey };\n forcedEdges.push({ a, b, score: FORCED_MATCH_SCORE });\n }\n }\n\n return {\n pairs: [],\n forcedEdges,\n baseMembers: [...baseMembers.values()].sort((left, right) =>\n compareStrings(left.id, right.id),\n ),\n };\n },\n};\n\n/**\n * `baseKey` source (§6.2, descriptor-backed block key) — the second NEW-vs-BASE\n * source. For the kind's declared block INDEX (named by `ResolveConfig.blockIndex`,\n * threaded onto the scope), it issues ONE batched `bulkFindByIndex` over the staged\n * new nodes against the committed base store (typegraph 0.30's non-unique index\n * lookup; key computed from props, soft-deleted excluded, fan-out bounded by\n * `limitPerInput`). Unlike {@link baseUniqueSource}, a shared block key is NOT\n * definitional — it is a candidate — so each new↔base hit emits:\n *\n * - a {@link CandidatePair} (staged ↔ base) handed to the shared scoring stage (it\n * becomes an edge only if it clears the kind's threshold), and\n * - a {@link BaseMember} built from the returned committed node (no second fetch).\n *\n * A same-(kind, id) hit needs no pair — the base member joins the staged node's own\n * cluster by key — so only its base member is emitted. graph-merge never reconstructs\n * the index key (typegraph owns `fields`/`scope`/`where`/collation), mirroring\n * `baseUnique`. Deterministic: typegraph returns matches per item in input order,\n * id-sorted; base members are deduped by id and id-sorted; the scoring stage dedups +\n * sorts the pairs. Field-set index keys only — a transform block key stays on the\n * staged-only opaque `block()` (§6.2).\n *\n * NOT part of {@link CANDIDATE_SOURCES}: the public `merge()` snapshot path stays\n * staged-vs-staged; this source runs only under the synthetic new-vs-base scope.\n */\nexport const baseKeySource: CandidateSource = {\n id: \"baseKey\",\n async generate(scope) {\n const { kind, nodes, blockIndex, store } = scope;\n // No declared block index for this kind → baseKey contributes nothing (a kind opts\n // into new-vs-base block-key recall by declaring an index + setting blockIndex).\n if (blockIndex === undefined) {\n return { pairs: [], forcedEdges: [], baseMembers: [] };\n }\n if (nodes === undefined || store === undefined) {\n throw new MergeError(\n \"baseKeySource requires nodes and store in the source scope.\",\n { details: { kind, source: \"baseKey\" } },\n );\n }\n\n const collection = store.nodes[kind];\n if (collection === undefined || nodes.length === 0) {\n return { pairs: [], forcedEdges: [], baseMembers: [] };\n }\n\n const items = nodes.map((node) => ({ props: nodeProps(node) }));\n // Like `bulkFindByConstraint`, an unknown index name / type-incompatible field\n // throws a typegraph error; surface it as a typed MergeError carrying the index +\n // kind rather than letting it be masked as the generic \"Merge failed\" wrapper.\n let matchesByNode: readonly (readonly Node<NodeType>[])[];\n try {\n matchesByNode = await collection.bulkFindByIndex(blockIndex, items);\n } catch (error) {\n throw new MergeError(\n `baseKeySource: new-vs-base lookup on index \"${blockIndex}\" for kind \"${kind}\" failed — the index is undeclared or a staged node's props are incompatible with its indexed fields.`,\n { details: { kind, index: blockIndex }, cause: error },\n );\n }\n\n const pairs: CandidatePair[] = [];\n const baseMembers = new Map<string, BaseMember>();\n for (const [index, node] of nodes.entries()) {\n const stagedNode = node;\n const stagedKey = mergeKey(stagedNode.kind, stagedNode.id);\n for (const base of matchesByNode[index] ?? []) {\n const baseKey = mergeKey(base.kind, base.id);\n if (!baseMembers.has(baseKey)) {\n baseMembers.set(baseKey, {\n origin: \"base\",\n id: base.id,\n kind: base.kind,\n props: nodeProps(base),\n });\n }\n // A same-(kind, id) re-discovery is already ONE identity; the base member lands\n // in the staged node's own cluster by key, so it needs no candidate pair.\n if (stagedKey === baseKey) {\n continue;\n }\n pairs.push(orderEndpoints(stagedNode, base));\n }\n }\n\n return {\n pairs,\n forcedEdges: [],\n baseMembers: [...baseMembers.values()].sort((left, right) =>\n compareStrings(left.id, right.id),\n ),\n };\n },\n};\n\n/**\n * The STAGED candidate sources the public `merge()` drives, in a fixed order (§6.1\n * \"phase: now\"). The scoring stage dedups + sorts the union, so this order does not\n * affect the merge result; it is fixed only for stable report attribution. The\n * new-vs-base {@link baseUniqueSource} / {@link baseKeySource} are deliberately NOT\n * here — they run only under the synthetic new-vs-base scope so the public snapshot\n * path stays staged-vs-staged.\n */\nexport const CANDIDATE_SOURCES: readonly CandidateSource[] = [\n exactKeySource,\n uniqueSource,\n];\n","/**\n * Staging (design §6.4 rule 1, T7): run the state-diff (T3) for EVERY branch,\n * tag each diff item with its origin {@link BranchId}, and assemble the UNION\n * of all branches' diffs into a single {@link StagingSet}.\n *\n * Why union (not incremental):\n * Downstream candidate-generation (T6) and clustering (T8) must be\n * order-independent — shuffling the branch order MUST yield an identical\n * merge. If staging folded branches one-at-a-time into a mutating cumulative\n * state, the result could depend on fold order. Instead we COLLECT every\n * branch's tagged items into flat arrays, then GROUP and SORT once at the end,\n * so the {@link StagingSet} is a pure function of the unordered branch SET.\n *\n * Provenance tagging:\n * Every staged item carries the {@link BranchId} of the branch whose diff\n * produced it. An inherited node modified differently by two branches appears\n * once per branch (each tagged), which is exactly what the conflict-detection\n * phases (T8 / T8a) need. A new node introduced by one branch appears once,\n * tagged by that branch.\n *\n * Determinism:\n * - New nodes/edges are grouped by kind; the per-kind arrays are sorted by\n * `(id, branchId)`.\n * - Flat collections (modified / deleted) are sorted by `(kind, id, branchId)`.\n * - Bucket maps iterate in lexicographic kind order.\n * The `(…, branchId)` tail breaks ties when the same id is contributed by more\n * than one branch, so the ordering is total and stable.\n */\n\nimport { compareStrings, type MergeKey } from \"./node-key\";\nimport type {\n ChangedEdge,\n ChangedNode,\n DeletedEdge,\n DeletedNode,\n ModifiedEdge,\n ModifiedNode,\n} from \"./state-diff\";\nimport { diffAgainstBase } from \"./state-diff\";\nimport type { GraphDef, Store } from \"./typegraph-internal\";\nimport type { BranchId, GraphBranch } from \"./types\";\n\n/** A new fork node tagged with the branch that introduced it. */\nexport type StagedNewNode = Readonly<{\n branchId: BranchId;\n node: ChangedNode;\n}>;\n\n/** A modified inherited node tagged with the branch that modified it. */\nexport type StagedModifiedNode = Readonly<{\n branchId: BranchId;\n node: ModifiedNode;\n}>;\n\n/** A deleted inherited node tagged with the branch that deleted it. */\ntype StagedDeletedNode = Readonly<{\n branchId: BranchId;\n node: DeletedNode;\n}>;\n\n/** A new fork edge tagged with the branch that introduced it. */\nexport type StagedNewEdge = Readonly<{\n branchId: BranchId;\n edge: ChangedEdge;\n}>;\n\n/** A modified inherited edge tagged with the branch that modified it. */\nexport type StagedModifiedEdge = Readonly<{\n branchId: BranchId;\n edge: ModifiedEdge;\n}>;\n\n/** A deleted inherited edge tagged with the branch that deleted it. */\ntype StagedDeletedEdge = Readonly<{\n branchId: BranchId;\n edge: DeletedEdge;\n}>;\n\n/**\n * The provenance-tagged union of every branch's state-diff against the base.\n *\n * New items are bucketed by kind so downstream blocking/candidate-gen (T5/T6)\n * can iterate one kind at a time. Modified and deleted items are kept as flat,\n * fully-sorted arrays — conflict detection (T8/T8a) groups them by id itself.\n */\nexport type StagingSet = Readonly<{\n /** New fork nodes, bucketed by kind. Map iterates in lexicographic kind order. */\n newNodesByKind: ReadonlyMap<string, readonly StagedNewNode[]>;\n /** Modified inherited nodes (one entry per (id, branch) modification). */\n modifiedNodes: readonly StagedModifiedNode[];\n /** Deleted inherited nodes (one entry per (id, branch) deletion). */\n deletedNodes: readonly StagedDeletedNode[];\n /** New fork edges, bucketed by kind. Map iterates in lexicographic kind order. */\n newEdgesByKind: ReadonlyMap<string, readonly StagedNewEdge[]>;\n /** Modified inherited edges (one entry per (id, branch) modification). */\n modifiedEdges: readonly StagedModifiedEdge[];\n /** Deleted inherited edges (one entry per (id, branch) deletion). */\n deletedEdges: readonly StagedDeletedEdge[];\n /**\n * `(kind, id) -> version` for the nodes of the branch named by\n * `stageBranches`' `captureTargetStateFor` argument, observed by that\n * branch's diff enumeration. Empty when no branch was requested. The\n * incremental merge captures the committed target branch here to use as the\n * plan-time baseline for its commit-time lost-update guard.\n */\n targetNodeVersions: ReadonlyMap<MergeKey, number>;\n /**\n * `(kind, id) -> edge content signature` for the edges of the same captured\n * branch. The edge-half analogue of {@link targetNodeVersions} (edges carry no\n * version, so the guard fingerprints their content). Empty when no branch was\n * requested.\n */\n targetEdgeSignatures: ReadonlyMap<MergeKey, string>;\n}>;\n\n/**\n * Total order over `(id, branchId)`. Used for the new-node/new-edge per-kind\n * buckets, where every member already shares a kind so kind need not be keyed.\n */\nfunction compareByIdThenBranch(\n left: Readonly<{ id: string; branchId: BranchId }>,\n right: Readonly<{ id: string; branchId: BranchId }>,\n): number {\n const byId = compareStrings(left.id, right.id);\n return byId === 0 ? compareStrings(left.branchId, right.branchId) : byId;\n}\n\n/**\n * Total order over `(kind, id, branchId)`. Used for the flat modified/deleted\n * collections, which mix kinds.\n */\nfunction compareByKindIdBranch(\n left: Readonly<{ kind: string; id: string; branchId: BranchId }>,\n right: Readonly<{ kind: string; id: string; branchId: BranchId }>,\n): number {\n const byKind = compareStrings(left.kind, right.kind);\n if (byKind !== 0) {\n return byKind;\n }\n const byId = compareStrings(left.id, right.id);\n return byId === 0 ? compareStrings(left.branchId, right.branchId) : byId;\n}\n\n/**\n * Groups items carrying a `kind` into a kind-keyed map whose iteration order is\n * lexicographic by kind and whose per-kind lists are sorted by `(id, branchId)`.\n */\nfunction groupByKind<\n T extends Readonly<{ kind: string; id: string; branchId: BranchId }>,\n>(items: readonly T[]): ReadonlyMap<string, readonly T[]> {\n const buckets = new Map<string, T[]>();\n for (const item of items) {\n const bucket = buckets.get(item.kind);\n if (bucket === undefined) {\n buckets.set(item.kind, [item]);\n } else {\n bucket.push(item);\n }\n }\n const ordered = new Map<string, readonly T[]>();\n for (const kind of [...buckets.keys()].sort((left, right) =>\n compareStrings(left, right),\n )) {\n ordered.set(\n kind,\n [...buckets.get(kind)!].sort((left, right) =>\n compareByIdThenBranch(left, right),\n ),\n );\n }\n return ordered;\n}\n\n/**\n * Stages the UNION of all branches' diffs against the base, provenance-tagged.\n *\n * Each branch is diffed against `baseStore` (the immutable reference — NEVER a\n * clone, per the Interchange `deletedAt` fidelity limitation), and every diff\n * item is tagged with that branch's id. All branches' tagged items are then\n * collected into flat arrays and grouped/sorted ONCE, so the result is a pure\n * function of the unordered branch set: passing the branches in any order yields\n * a structurally identical {@link StagingSet}.\n *\n * @param baseStore The immutable base store every branch is diffed against.\n * @param branches The branches to stage. Order does not affect the result.\n * @returns The provenance-tagged union staging set.\n */\nexport async function stageBranches<G extends GraphDef>(\n baseStore: Store<G>,\n branches: readonly GraphBranch<G>[],\n captureTargetStateFor?: BranchId,\n): Promise<StagingSet> {\n const newNodes: (StagedNewNode & { kind: string; id: string })[] = [];\n const modifiedNodes: (StagedModifiedNode & { kind: string; id: string })[] =\n [];\n const deletedNodes: (StagedDeletedNode & { kind: string; id: string })[] = [];\n const newEdges: (StagedNewEdge & { kind: string; id: string })[] = [];\n const modifiedEdges: (StagedModifiedEdge & { kind: string; id: string })[] =\n [];\n const deletedEdges: (StagedDeletedEdge & { kind: string; id: string })[] = [];\n\n let targetNodeVersions: ReadonlyMap<MergeKey, number> = new Map();\n let targetEdgeSignatures: ReadonlyMap<MergeKey, string> = new Map();\n for (const branch of branches) {\n const branchId = branch.id;\n const diff = await diffAgainstBase(\n baseStore,\n branch.store,\n branchId === captureTargetStateFor,\n );\n if (branchId === captureTargetStateFor) {\n targetNodeVersions = diff.forkNodeVersions;\n targetEdgeSignatures = diff.forkEdgeSignatures;\n }\n\n for (const node of diff.nodes.new) {\n newNodes.push({ branchId, node, kind: node.kind, id: node.id });\n }\n for (const node of diff.nodes.modified) {\n modifiedNodes.push({ branchId, node, kind: node.kind, id: node.id });\n }\n for (const node of diff.nodes.deleted) {\n deletedNodes.push({ branchId, node, kind: node.kind, id: node.id });\n }\n for (const edge of diff.edges.new) {\n newEdges.push({ branchId, edge, kind: edge.kind, id: edge.id });\n }\n for (const edge of diff.edges.modified) {\n modifiedEdges.push({ branchId, edge, kind: edge.kind, id: edge.id });\n }\n for (const edge of diff.edges.deleted) {\n deletedEdges.push({ branchId, edge, kind: edge.kind, id: edge.id });\n }\n }\n\n return {\n newNodesByKind: groupByKind(newNodes),\n modifiedNodes: [...modifiedNodes].sort((left, right) =>\n compareByKindIdBranch(left, right),\n ),\n deletedNodes: [...deletedNodes].sort((left, right) =>\n compareByKindIdBranch(left, right),\n ),\n newEdgesByKind: groupByKind(newEdges),\n modifiedEdges: [...modifiedEdges].sort((left, right) =>\n compareByKindIdBranch(left, right),\n ),\n deletedEdges: [...deletedEdges].sort((left, right) =>\n compareByKindIdBranch(left, right),\n ),\n targetNodeVersions,\n targetEdgeSignatures,\n };\n}\n","/**\n * Bounded retry for the merge commit transaction.\n *\n * The commit runs at `SERIALIZABLE` isolation (see `commitPlan` /\n * `commitIncrementalPlan`): under Postgres SSI a concurrent write that\n * invalidates the transaction's reads aborts one side with SQLSTATE 40001\n * (serialization failure); lock ordering between concurrent merges can also\n * surface 40P01 (deadlock). Both are TRANSIENT — the transaction did not\n * commit, and re-running it is the documented client protocol — so the commit\n * is retried a bounded number of times. The in-transaction `base@V`\n * re-validation runs on every attempt, so a retry that lands after a REAL\n * divergence fails deterministically with `BaseVersionMismatchError` instead\n * of committing a stale plan.\n *\n * SQLite and PGlite serialize writers (single connection), so retryable\n * conflicts cannot occur there and the wrapper is pass-through in practice.\n */\n\nimport { MergeError } from \"./errors\";\n\n/** SQLSTATEs that mean \"transaction aborted, safe to re-run verbatim\". */\nconst RETRYABLE_SQLSTATES: ReadonlySet<string> = new Set([\"40001\", \"40P01\"]);\n\n/**\n * Driver-message fallback for errors whose SQLSTATE was lost in wrapping.\n * Matches the fixed Postgres texts for serialization failure and deadlock.\n */\nconst RETRYABLE_MESSAGE_PATTERN =\n /could not serialize access|deadlock detected/i;\n\n/** Bounded number of commit attempts before giving up with a typed error. */\nexport const MAX_COMMIT_ATTEMPTS = 3;\n\n/**\n * Whether `error` (or anything in its cause chain) is a retryable transaction\n * conflict — a Postgres serialization failure (40001) or deadlock (40P01).\n * Walks the `cause` chain because drivers and wrappers (pg → Drizzle →\n * TypeGraph) re-wrap the original error; a visited set guards against cyclic\n * cause chains.\n */\nexport function isRetryableTxConflict(error: unknown): boolean {\n const seen = new Set<unknown>();\n let current: unknown = error;\n while (\n current !== undefined &&\n current !== null &&\n typeof current === \"object\" &&\n !seen.has(current)\n ) {\n seen.add(current);\n const candidate = current as Readonly<{\n code?: unknown;\n message?: unknown;\n cause?: unknown;\n }>;\n if (\n typeof candidate.code === \"string\" &&\n RETRYABLE_SQLSTATES.has(candidate.code)\n ) {\n return true;\n }\n if (\n typeof candidate.message === \"string\" &&\n RETRYABLE_MESSAGE_PATTERN.test(candidate.message)\n ) {\n return true;\n }\n current = candidate.cause;\n }\n return false;\n}\n\n/**\n * Runs `commit` (a function that opens and completes ONE transaction attempt),\n * retrying up to {@link MAX_COMMIT_ATTEMPTS} times on retryable conflicts.\n * Non-retryable errors propagate immediately; exhaustion raises a\n * {@link MergeError} carrying the final conflict as its cause.\n */\nexport async function withTxConflictRetry<T>(\n commit: () => Promise<T>,\n): Promise<T> {\n let lastConflict: unknown;\n for (let attempt = 1; attempt <= MAX_COMMIT_ATTEMPTS; attempt += 1) {\n try {\n return await commit();\n } catch (error) {\n if (!isRetryableTxConflict(error)) {\n throw error;\n }\n lastConflict = error;\n }\n }\n throw new MergeError(\n `Merge commit aborted by transaction conflicts (serialization failure or deadlock) on ${MAX_COMMIT_ATTEMPTS} consecutive attempts; giving up.`,\n {\n cause: lastConflict,\n details: { attempts: MAX_COMMIT_ATTEMPTS },\n suggestion:\n \"Reduce concurrent writes to the merge target, or serialize merges against it.\",\n },\n );\n}\n","/**\n * Opt-in ontology type reconciliation (design §6 / §7, T10).\n *\n * When entity resolution (T8) collapses fork nodes into one cluster, those nodes\n * may carry DIFFERING `node.kind` values across branches — e.g. one branch staged\n * a `Doctor` while another staged the more-specific `SpecialistDoctor` for what is\n * really the same person. With `reconcileTypes: \"ontology\"` enabled, this module\n * uses the PUBLIC-closure glue (T2a, `closures.ts`) to decide whether those kinds\n * are subClassOf-compatible and, if so, collapses the cluster to the\n * MOST-SPECIFIC common type, recording a {@link TypeReconciliation}. Genuinely\n * incompatible kinds (siblings, disjoint trees) are FLAGGED — never silently\n * collapsed — and surfaced as a {@link DroppedItem}.\n *\n * MOST-SPECIFIC = the unique minimum of the subclass partial order restricted to\n * the cluster's distinct kinds: the kind `T` such that every OTHER kind in the\n * cluster is a (transitive) ancestor of `T` (`isReachable(closure, T, other)`),\n * or is EQUIVALENT to `T` (mutual reachability, from folded `equivalentTo`\n * relations). If several mutually-equivalent kinds tie for the minimum, the\n * lexicographically-smallest representative is chosen so the outcome is\n * deterministic. If no single minimum exists, the kinds are incompatible.\n *\n * This module is a PURE decision function — no I/O, no store access. The\n * orchestrator (T11) builds the {@link ReconcileClusterInput}s from the resolved\n * clusters + the staged nodes' kinds, then applies the returned\n * {@link TypeReconcileResult.retypeMap} to the canonical node's `kind` and to the\n * repointed edges' `fromKind` / `toKind` annotations while keeping endpoint ids\n * stable (the cascade described in step 2). `mode: \"off\"` is a guaranteed no-op.\n */\n\nimport type { SubClassClosure } from \"./closures\";\nimport { isReachable } from \"./closures\";\nimport { compareStrings, idOf, type MergeKey } from \"./node-key\";\nimport type {\n DroppedItem,\n ReconcileTypesMode,\n TypeReconciliation,\n} from \"./types\";\n\n/**\n * Reason recorded on a {@link DroppedItem} when a cluster's mixed kinds are\n * neither subClassOf-comparable nor equivalent and therefore CANNOT be collapsed.\n * The cluster is left untouched (its members keep their original kinds); this\n * record only flags the incompatibility for the {@link MergeReport}.\n */\nexport const INCOMPATIBLE_TYPES_FLAG_REASON =\n \"type-reconcile:incompatible-kinds\" as const;\n\n/**\n * One resolved cluster fed into type reconciliation: the canonical survivor id\n * (from T8 `pickClusterSurvivor`) and the DISTINCT kinds present across the cluster's\n * members. Single-kind clusters (one distinct kind) are no-ops and may be omitted\n * by the caller, but are handled defensively here too.\n */\nexport type ReconcileClusterInput = Readonly<{\n /** The canonical survivor IDENTITY (`(kind, id)`), so the retype keys on the same\n * composite identity the commit looks it up by — never a bare id shared across\n * kinds. */\n canonicalId: MergeKey;\n /** The distinct member kinds in the cluster. Order does not affect the result. */\n memberKinds: readonly string[];\n}>;\n\n/**\n * The outcome of reconciling every cluster's kinds.\n *\n * - `reconciliations`: one {@link TypeReconciliation} per multi-kind cluster that\n * collapsed to a single most-specific type.\n * - `retypeMap`: `canonicalId → toType` for exactly those reconciled clusters, so\n * the commit (T11) can cascade the retype onto the canonical node and the\n * repointed edges' endpoint-kind annotations.\n * - `dropped`: one `{ kind: \"node\" }` {@link DroppedItem} per cluster whose kinds\n * were incompatible (flagged, NOT collapsed) — its `id` is the canonical id and\n * its `reason` is {@link INCOMPATIBLE_TYPES_FLAG_REASON}.\n */\nexport type TypeReconcileResult = Readonly<{\n reconciliations: readonly TypeReconciliation[];\n /** `canonical (kind, id) → toType` for each reconciled cluster, keyed by the\n * composite identity so the commit cascade resolves a retype unambiguously even\n * when an id is shared across kinds. */\n retypeMap: ReadonlyMap<MergeKey, string>;\n dropped: readonly DroppedItem[];\n}>;\n\n/** Distinct, lexicographically-sorted kinds — the canonical kind set. */\nfunction distinctKinds(kinds: readonly string[]): readonly string[] {\n return [...new Set(kinds)].sort((left, right) => compareStrings(left, right));\n}\n\n/**\n * Reports whether two kinds are EQUIVALENT under the closure — distinct names\n * that fold to the same `equivalentTo` class, hence mutually reachable. (A kind is\n * not equivalent to itself here; identical names are handled by the caller.)\n */\nfunction areEquivalent(\n closure: SubClassClosure,\n left: string,\n right: string,\n): boolean {\n return (\n left !== right &&\n isReachable(closure, left, right) &&\n isReachable(closure, right, left)\n );\n}\n\n/**\n * Reports whether `candidate` is \"at or below\" `other` in the subclass order:\n * either it is a (transitive) subclass of `other`, or the two are equivalent. This\n * is the predicate the most-specific kind must satisfy against every OTHER kind in\n * the cluster.\n */\nfunction isAtOrBelow(\n closure: SubClassClosure,\n candidate: string,\n other: string,\n): boolean {\n if (candidate === other) {\n return true;\n }\n return (\n isReachable(closure, candidate, other) ||\n areEquivalent(closure, candidate, other)\n );\n}\n\n/**\n * Finds the MOST-SPECIFIC common kind among `kinds`, or `undefined` if the kinds\n * are incompatible (no single minimum of the subclass order).\n *\n * A kind qualifies as the minimum when every OTHER kind is at-or-above it\n * ({@link isAtOrBelow}). Several mutually-equivalent kinds can all qualify; the\n * lexicographically-smallest qualifier is returned so the choice is deterministic.\n * Siblings (e.g. two leaves under a shared parent) and disjoint trees yield no\n * qualifier → `undefined` (incompatible).\n */\nexport function mostSpecificCommonKind(\n closure: SubClassClosure,\n kinds: readonly string[],\n): string | undefined {\n const qualifiers = kinds.filter((candidate) =>\n kinds.every((other) => isAtOrBelow(closure, candidate, other)),\n );\n if (qualifiers.length === 0) {\n return undefined;\n }\n return [...qualifiers].sort((left, right) => compareStrings(left, right))[0]!;\n}\n\n/**\n * Reconciles the differing kinds of each resolved cluster against the subClassOf\n * closure.\n *\n * For `mode: \"off\"` (the default) this is a guaranteed no-op: it returns zero\n * reconciliations, an empty retype map, and zero dropped items, regardless of the\n * clusters.\n *\n * For `mode: \"ontology\"`, each cluster with more than one distinct kind is\n * reconciled:\n *\n * - a single MOST-SPECIFIC common kind exists → the cluster collapses to it; a\n * {@link TypeReconciliation} is recorded (`fromTypes` = the distinct kinds,\n * `toType` = the chosen kind) and `canonicalId → toType` is added to\n * `retypeMap`. When the most-specific kind already equals the cluster's full\n * (single-element-after-collapse) intent — i.e. all kinds were equivalent and\n * fold to the same chosen representative — the reconciliation is still\n * recorded so the cascade can normalize the canonical node's kind.\n * - no single most-specific kind (siblings / disjoint trees) → the cluster is\n * FLAGGED incompatible: a `{ kind: \"node\" }` {@link DroppedItem} with reason\n * {@link INCOMPATIBLE_TYPES_FLAG_REASON} is recorded and the cluster is NOT\n * collapsed (no retype entry).\n *\n * Single-kind clusters never appear in the output. All output collections are\n * sorted by stable keys (`canonicalId`) so the result is a pure function of the\n * unordered cluster set.\n *\n * @param clusters The resolved clusters with their distinct member kinds.\n * @param closure The subClassOf closure from {@link buildSubClassClosure} (T2a).\n * @param mode `\"off\"` (no-op) or `\"ontology\"` (reconcile).\n */\nexport function reconcileTypes(\n clusters: readonly ReconcileClusterInput[],\n closure: SubClassClosure,\n mode: ReconcileTypesMode,\n): TypeReconcileResult {\n if (mode === \"off\") {\n return {\n reconciliations: [],\n retypeMap: new Map<MergeKey, string>(),\n dropped: [],\n };\n }\n\n const reconciliations: TypeReconciliation[] = [];\n const retypeMap = new Map<MergeKey, string>();\n const dropped: DroppedItem[] = [];\n\n for (const cluster of clusters) {\n const kinds = distinctKinds(cluster.memberKinds);\n if (kinds.length <= 1) {\n continue;\n }\n\n // The PUBLIC report fields (`entityId`, dropped `id`) carry the bare node id;\n // the internal retype keys on the full `(kind, id)` identity.\n const entityId = idOf(cluster.canonicalId);\n const toType = mostSpecificCommonKind(closure, kinds);\n if (toType === undefined) {\n dropped.push({\n kind: \"node\",\n id: entityId,\n reason: INCOMPATIBLE_TYPES_FLAG_REASON,\n });\n continue;\n }\n\n reconciliations.push({\n entityId,\n fromTypes: kinds,\n toType,\n });\n retypeMap.set(cluster.canonicalId, toType);\n }\n\n return {\n reconciliations: reconciliations.sort((left, right) =>\n compareStrings(left.entityId, right.entityId),\n ),\n retypeMap,\n dropped: dropped.sort((left, right) => compareStrings(left.id, right.id)),\n };\n}\n","/**\n * `merge()` orchestrator (design §7.2, T11).\n *\n * Composes every phase built in T3–T10 into one DB-agnostic primitive:\n *\n * 1. PRECONDITION — compute the target's `base@V` and reject any branch whose\n * `base` token does not match it (`BaseVersionMismatchError`). A branch\n * forked from a divergent schema or base revision cannot be merged\n * safely (design §5.2 / §13.6).\n * 2. STAGE — `stageBranches` (T7): the provenance-tagged UNION of every\n * branch's state-diff against the immutable base.\n * 3. CANDIDATE-GEN — per resolved kind: build node-shaped objects from the\n * staged NEW nodes, `blockNodes` (T5, folding in unique constraints from\n * `introspect()`), `generateCandidates` (T6, fulltext Dice + custom; vector/\n * hybrid guarded). Kinds NOT in `options.resolve` merge by id only.\n * 4. CLUSTER — `connectedComponents` (T8) over the accumulated candidate edges\n * and every staged new-node id, with the optional diameter guard.\n * 5. CANONICALIZE — `canonicalizeCluster` (T8): min-id survivor + commutative\n * property union under the stable, non-wall-clock conflict policy.\n * 6. DELETE/MODIFY — `resolveDeleteModify` (T8a): the authoritative final\n * liveness of every inherited node + the delete/modify conflicts.\n * 7. TYPE-RECONCILE — `reconcileTypes` (T10) over the public-closure glue when\n * `reconcileTypes: \"ontology\"`; otherwise a no-op.\n * 8. EDGE REPOINT — `repointEdges` (T9): repoint every staged edge onto its\n * cluster canonical, drop edges to finally-deleted endpoints, dedupe + union\n * edge props under the same conflict policy.\n * 9. COMMIT — apply everything to `target` (default = base store) in a single\n * `store.transaction` when the backend is transactional, else non-atomically\n * with a report warning (out of the P0 acceptance path — SQLite + Postgres\n * are both transactional).\n * 10. REPORT — assemble the {@link MergeReport} with merged counts, every\n * resolution / conflict / reconciliation / drop, and the in-memory\n * {@link ProvenanceIndex}. With `persistProvenance`, ALSO upsert the\n * `{branch, sourceId}` records to a sidecar provenance graph (post-commit,\n * best-effort — a failure surfaces as a report warning, never a failed merge).\n *\n * DETERMINISM: every phase is order-independent (pure functions over the\n * unordered branch / staged sets, with a branch order captured ONCE for\n * conflict resolution), so shuffling `branches` yields a deep-equal report and an\n * identical committed graph. T12 proves this with a fast-check shuffle property.\n */\n\nimport {\n computeBaseVersion,\n computeContentComponent,\n computeSchemaComponent,\n contentComponentOf,\n hasRevisionAnchor,\n revisionAnchorOf,\n revisionOriginOf,\n} from \"./base-version\";\nimport { blockNodes } from \"./blocking\";\nimport { canonicalizeProps, edgeStateSignature } from \"./canonical-props\";\nimport type { CanonicalEntity, ClusterMember } from \"./canonicalize\";\nimport { BASE_PROVENANCE_BRANCH, canonicalizeCluster } from \"./canonicalize\";\nimport { buildSubClassClosure } from \"./closures\";\nimport type { ClusterResult } from \"./clustering\";\nimport {\n connectedComponents,\n enforceBaseGuard,\n enforceDiameter,\n} from \"./clustering\";\nimport type { ProvenanceWeights } from \"./conflict-policy\";\nimport { buildBranchRank } from \"./conflict-policy\";\nimport {\n reconcileEdgeModifications,\n reconcileModifications,\n resolveDeleteModify,\n resolveEdgeDeleteModify,\n} from \"./delete-modify\";\nimport type { MergedEdge, StagedEdge } from \"./edge-repoint\";\nimport { buildCanonicalMap, repointEdges } from \"./edge-repoint\";\nimport { BaseVersionMismatchError, MergeError } from \"./errors\";\nimport {\n compareMergeKeys,\n compareStrings,\n idOf,\n kindOf,\n type MergeKey,\n mergeKey,\n mergeKeyOf,\n} from \"./node-key\";\nimport type { NormalizedMergeOptions } from \"./options\";\nimport { normalizeMergeOptions } from \"./options\";\nimport {\n openProvenanceStore,\n persistProvenanceRecords,\n provenanceGraphId,\n} from \"./provenance-store\";\nimport type { Result } from \"./result\";\nimport { err, isErr, ok } from \"./result\";\nimport type { CandidateEdge, CandidatePair } from \"./scoring\";\nimport { compareCandidateEdges, scoreCandidates } from \"./scoring\";\nimport type { SimilarityContext } from \"./similarity\";\nimport { embeddingFields, fieldText } from \"./similarity\";\nimport type { BaseLookupStore, BaseMember, SourceScope } from \"./sources\";\nimport {\n baseKeySource,\n baseUniqueSource,\n CANDIDATE_SOURCES,\n keylessConfigFor,\n ontologyRetypeEdges,\n} from \"./sources\";\nimport type {\n StagedModifiedEdge,\n StagedModifiedNode,\n StagedNewEdge,\n StagedNewNode,\n StagingSet,\n} from \"./staging\";\nimport { stageBranches } from \"./staging\";\nimport { withTxConflictRetry } from \"./tx-retry\";\nimport type { ReconcileClusterInput } from \"./type-reconcile\";\nimport { mostSpecificCommonKind, reconcileTypes } from \"./type-reconcile\";\nimport type {\n Edge,\n EdgeId,\n GraphDef,\n JsonValue,\n Node,\n NodeId,\n NodeType,\n Store,\n TransactionBackend,\n TransactionOptions,\n UniqueIntrospection,\n} from \"./typegraph-internal\";\nimport {\n lockRecordedGraphWrite,\n readRecordedClock,\n readRevisionOrigin,\n} from \"./typegraph-internal\";\nimport type {\n BaseAmbiguity,\n BaseVersion,\n BranchId,\n BranchProvenance,\n DeleteModifyConflict,\n DroppedItem,\n Embedder,\n EntityResolution,\n GraphBranch,\n MergeIncrementalArgs as MergeIncrementalArguments,\n MergeOptions,\n MergeReport,\n PropertyConflict,\n PropertyConflictPolicy,\n ProvenanceIndex,\n ProvenanceRecord,\n SimilarityStrategy,\n TypeReconciliation,\n} from \"./types\";\nimport { asBranchId } from \"./types\";\n\n/** A node id in its untyped (`NodeType`-default) branded form. */\ntype AnyNodeId = NodeId<NodeType>;\n\n/** Reserved synthetic branch id for the live target in `mergeIncremental()`. */\nconst COMMITTED_TARGET_BRANCH: BranchId = asBranchId(\"__committed_target__\");\n\n/**\n * Materializes a {@link Node}-shaped object from a staged new node's parsed\n * props. The blocking (T5) and similarity (T6) phases read schema fields directly\n * off the node (`node.name`), so the props must be spread at the top level with\n * `kind`/`id` alongside — exactly the runtime shape `Node<NodeType>` carries.\n */\nfunction asNode(staged: StagedNewNode): Node<NodeType> {\n return {\n kind: staged.node.kind,\n id: staged.node.id,\n ...staged.node.props,\n } as unknown as Node<NodeType>;\n}\n\n/**\n * Collects, per kind, every staged new node tagged by branch, in deterministic\n * `(id, branchId)` order. The staging set already buckets new nodes by kind in\n * lexicographic order; this re-sorts each bucket defensively so candidate-gen is\n * correct for any caller.\n */\nfunction newNodesByKind(\n staging: StagingSet,\n): ReadonlyMap<string, readonly StagedNewNode[]> {\n const ordered = new Map<string, readonly StagedNewNode[]>();\n for (const [kind, items] of staging.newNodesByKind) {\n ordered.set(\n kind,\n [...items].sort((left, right) => {\n const byId = compareStrings(left.node.id, right.node.id);\n return byId === 0 ?\n compareStrings(left.branchId, right.branchId)\n : byId;\n }),\n );\n }\n return ordered;\n}\n\n/**\n * Looks up a kind's declared unique constraints from the store introspection, so\n * blocking can short-circuit exact-match duplicates. Returns an empty array for a\n * kind with no constraints (or an unknown kind).\n */\nfunction uniqueConstraintsFor(\n introspectionKinds: ReadonlyMap<string, readonly UniqueIntrospection[]>,\n kind: string,\n): readonly UniqueIntrospection[] {\n return introspectionKinds.get(kind) ?? [];\n}\n\n/**\n * Precomputes the text→vector lookup the `vector`/`hybrid` scorers read.\n *\n * Runs the injected {@link Embedder} ONCE over the deduplicated, non-empty field\n * texts of every staged new node belonging to a `vector`/`hybrid` kind, in sorted\n * order. Embedding is per-text independent and the lookup is keyed by text, so the\n * map — and therefore every pairwise cosine — is a pure function of the staged node\n * SET, independent of branch/arrival order (the determinism contract). The text of\n * each node is taken via the SAME {@link fieldText} the scorer uses, so the\n * embedded key and the looked-up key always match.\n *\n * Returns an EMPTY map when no kind needs embeddings (or every text is empty). The\n * caller passes the map (vs. `undefined`) to {@link SimilarityContext} only when an\n * embedder was configured — that presence is what lets `scorePair` distinguish\n * \"embedder configured\" from \"vector/hybrid requested with no embedder\".\n *\n * This covers only STAGED node texts. COMMITTED base nodes pulled into staged↔base\n * candidate pairs by the base sources are not known until candidate generation\n * runs, so their texts are embedded there via {@link embedMissingPairTexts}.\n */\nasync function precomputeEmbeddings<G extends GraphDef>(\n byKind: ReadonlyMap<string, readonly StagedNewNode[]>,\n resolve: NormalizedMergeOptions<G>[\"resolve\"],\n embedder: Embedder,\n): Promise<ReadonlyMap<string, Float32Array>> {\n const texts = new Set<string>();\n for (const [kind, items] of byKind) {\n const config = resolve[kind];\n if (config === undefined) {\n continue;\n }\n const fields = embeddingFields(config.similarity);\n if (fields === undefined) {\n continue;\n }\n for (const staged of items) {\n const text = fieldText(asNode(staged), fields);\n if (text.length > 0) {\n texts.add(text);\n }\n }\n }\n\n const lookup = new Map<string, Float32Array>();\n if (texts.size === 0) {\n return lookup;\n }\n const orderedTexts = [...texts].sort((left, right) =>\n compareStrings(left, right),\n );\n const vectors = await embedder(orderedTexts);\n if (vectors.length !== orderedTexts.length) {\n throw new MergeError(\n `Embedder returned ${vectors.length} vectors for ${orderedTexts.length} texts; expected exactly one per text.`,\n {\n details: { texts: orderedTexts.length, vectors: vectors.length },\n suggestion:\n \"Ensure MergeOptions.embedder returns one vector per input text, in order.\",\n },\n );\n }\n for (const [index, text] of orderedTexts.entries()) {\n lookup.set(text, vectors[index]!);\n }\n return lookup;\n}\n\n/**\n * Ensures every text scored for a `vector`/`hybrid` kind is in the embeddings\n * lookup. {@link precomputeEmbeddings} embeds only STAGED node texts; the base\n * sources (`baseKeySource`/`baseUniqueSource`) pull COMMITTED nodes into\n * staged↔base candidate pairs whose texts were never embedded — without this they\n * would score MIN_SCORE and a staged node would commit as a DUPLICATE instead of\n * merging onto its committed entity. Embeds any pair-endpoint text missing from\n * `base` and returns the augmented map (the original when nothing is missing).\n * Keyed by text and embedded in sorted order, so the result stays a pure function\n * of the node set (the determinism contract). Non-embedding strategies\n * (`fulltext`/`custom`) return `base` unchanged.\n */\nasync function embedMissingPairTexts(\n base: ReadonlyMap<string, Float32Array> | undefined,\n pairs: readonly CandidatePair[],\n strategy: SimilarityStrategy,\n embedder: Embedder,\n): Promise<ReadonlyMap<string, Float32Array>> {\n const existing = base ?? new Map<string, Float32Array>();\n const fields = embeddingFields(strategy);\n if (fields === undefined) {\n return existing;\n }\n const missing = new Set<string>();\n for (const pair of pairs) {\n for (const node of [pair.left, pair.right]) {\n const text = fieldText(node, fields);\n if (text.length > 0 && !existing.has(text)) {\n missing.add(text);\n }\n }\n }\n if (missing.size === 0) {\n return existing;\n }\n const orderedTexts = [...missing].sort((left, right) =>\n compareStrings(left, right),\n );\n const vectors = await embedder(orderedTexts);\n if (vectors.length !== orderedTexts.length) {\n throw new MergeError(\n `Embedder returned ${vectors.length} vectors for ${orderedTexts.length} texts; expected exactly one per text.`,\n {\n details: { texts: orderedTexts.length, vectors: vectors.length },\n suggestion:\n \"Ensure MergeOptions.embedder returns one vector per input text, in order.\",\n },\n );\n }\n const augmented = new Map(existing);\n for (const [index, text] of orderedTexts.entries()) {\n augmented.set(text, vectors[index]!);\n }\n return augmented;\n}\n\n/**\n * Runs candidate generation for every kind that has a {@link ResolveConfig} by\n * driving the candidate SOURCES (`sources.ts`) over the shared SCORING stage\n * (`scoring.ts`, §4): per kind, each source proposes pairs + forced edges off the\n * scope, and the scoring stage turns them into the kind's candidate edges.\n * Accumulates edges + any base members across kinds and records comparison-ceiling\n * warnings. Kinds NOT in `resolve` (or with no staged new nodes) contribute no\n * candidate edges — they merge by id only.\n *\n * `useBaseSources` selects the resolution DIRECTION. The public snapshot `merge()`\n * passes `false` — only the staged sources (`exactKey`, `unique`) run, so no\n * committed node is pulled into scope (`baseMembers` is empty) and the path stays\n * staged-vs-staged. The synthetic new-vs-base scope passes `true`, adding\n * {@link baseUniqueSource} (which queries `target`) so a staged node re-discovering\n * a committed entity surfaces as a forced new↔base edge + a base member.\n *\n * Returns `err` when a kind's `onComparisonCeiling: \"error\"` ceiling trips or a\n * `vector`/`hybrid` strategy hits the no-embedder guard.\n */\nasync function generateAllCandidates<G extends GraphDef>(\n target: Store<G>,\n staging: StagingSet,\n options: NormalizedMergeOptions<G>,\n introspectionKinds: ReadonlyMap<string, readonly UniqueIntrospection[]>,\n ctx: SimilarityContext,\n useBaseSources: boolean,\n embedder: Embedder | undefined,\n): Promise<\n Result<\n Readonly<{\n edges: readonly CandidateEdge[];\n warnings: readonly string[];\n baseMembers: readonly BaseMember[];\n }>,\n MergeError\n >\n> {\n const allEdges: CandidateEdge[] = [];\n const warnings: string[] = [];\n const baseMembers: BaseMember[] = [];\n const byKind = newNodesByKind(staging);\n const sources =\n useBaseSources ?\n [...CANDIDATE_SOURCES, baseUniqueSource, baseKeySource]\n : CANDIDATE_SOURCES;\n // Base sources resolve staged nodes against the COMMITTED graph — the merge\n // TARGET, where prior runs' canonicals live — NOT the (possibly older) diff\n // reference. They coincide under the public snapshot path (target defaults to\n // store); they differ under the synthetic new-vs-base scope.\n const baseStore = target as unknown as BaseLookupStore;\n\n // Each kind's candidate generation is independent (results are concatenated, then\n // globally re-sorted below), so run them concurrently — under the base-source path\n // each kind's `bulkFindByConstraint` round-trip would otherwise serialise.\n const perKind = await Promise.all(\n [...byKind].map(\n async ([kind, items]): Promise<\n Result<\n Readonly<{\n edges: readonly CandidateEdge[];\n warnings: readonly string[];\n baseMembers: readonly BaseMember[];\n }>,\n MergeError\n >\n > => {\n const resolveConfig = options.resolve[kind];\n if (resolveConfig === undefined) {\n // No resolution config for this kind: merge by id only (no candidate\n // edges, so every new node stays a singleton cluster).\n return ok({ edges: [], warnings: [], baseMembers: [] });\n }\n\n const nodes = items.map((staged) => asNode(staged));\n const uniqueConstraints = uniqueConstraintsFor(\n introspectionKinds,\n kind,\n );\n const blocks = blockNodes(nodes, resolveConfig, uniqueConstraints);\n const keylessConfig = keylessConfigFor(resolveConfig);\n const scope: SourceScope = {\n kind,\n blocks,\n nodes,\n uniqueConstraints,\n store: baseStore,\n ...(resolveConfig.blockIndex === undefined ?\n {}\n : { blockIndex: resolveConfig.blockIndex }),\n ...(keylessConfig === undefined ? {} : { keyless: keylessConfig }),\n };\n\n const pairs: CandidatePair[] = [];\n const forcedEdges: CandidateEdge[] = [];\n const kindBaseMembers: BaseMember[] = [];\n for (const source of sources) {\n const produced = await source.generate(scope);\n pairs.push(...produced.pairs);\n forcedEdges.push(...produced.forcedEdges);\n kindBaseMembers.push(...produced.baseMembers);\n }\n\n // Base sources pull committed nodes into staged↔base pairs whose texts\n // were not in the staged-only precompute; embed them now so vector/hybrid\n // scoring can actually find them (otherwise the pair scores MIN_SCORE and\n // the staged node duplicates instead of merging onto the committed entity).\n const kindCtx =\n embedder === undefined ? ctx : (\n {\n ...ctx,\n embeddings: await embedMissingPairTexts(\n ctx.embeddings,\n pairs,\n resolveConfig.similarity,\n embedder,\n ),\n }\n );\n\n const scored = scoreCandidates(\n { pairs, forcedEdges },\n resolveConfig,\n kindCtx,\n options.onComparisonCeiling,\n options.maxComparisonsPerKind,\n );\n if (isErr(scored)) {\n return err(scored.error);\n }\n return ok({\n edges: scored.data.edges,\n warnings: scored.data.warnings.map(\n (warning) => `[${kind}] ${warning.message}`,\n ),\n baseMembers: kindBaseMembers,\n });\n },\n ),\n );\n\n for (const result of perKind) {\n if (isErr(result)) {\n return err(result.error);\n }\n allEdges.push(...result.data.edges);\n warnings.push(...result.data.warnings);\n baseMembers.push(...result.data.baseMembers);\n }\n\n return ok({\n // The ONE shared `(a, b)` edge comparator (id-first `(kind, id)` order), so this\n // stage emits edges in exactly the order clustering consumes them.\n edges: allEdges.sort((left, right) => compareCandidateEdges(left, right)),\n warnings,\n // Total order over the composite `(kind, id)` identity (two same-id/different-kind\n // base members would tie under a bare-id compare).\n baseMembers: baseMembers.sort((left, right) =>\n compareMergeKeys(mergeKeyOf(left), mergeKeyOf(right)),\n ),\n });\n}\n\n/**\n * Builds, per cluster, the {@link ClusterMember} contributions. A staged new node\n * contributes one member per branch that staged it (so a cross-branch property\n * disagreement surfaces as a conflict in the union, T8); a committed BASE node the\n * cluster pulled in contributes one `origin: \"base\"` member, carrying the reserved\n * {@link BASE_PROVENANCE_BRANCH} so it gap-fills the property union and survivor\n * selection can enforce base-id-wins (§6.4-C).\n */\nfunction clusterMembersFor(\n cluster: ClusterResult,\n newNodesById: ReadonlyMap<MergeKey, readonly StagedNewNode[]>,\n baseMembersById: ReadonlyMap<MergeKey, BaseMember>,\n): readonly ClusterMember[] {\n const members: ClusterMember[] = [];\n for (const key of cluster.members) {\n for (const staged of newNodesById.get(key) ?? []) {\n members.push({\n origin: \"staged\",\n id: staged.node.id,\n kind: staged.node.kind,\n branchId: staged.branchId,\n props: staged.node.props as Readonly<Record<string, JsonValue>>,\n });\n }\n const base = baseMembersById.get(key);\n if (base !== undefined) {\n members.push({\n origin: \"base\",\n id: base.id,\n kind: base.kind,\n branchId: BASE_PROVENANCE_BRANCH,\n props: base.props,\n });\n }\n }\n return members;\n}\n\n/**\n * Indexes the staged new nodes by id (preserving the per-id branch list), so\n * clustering / canonicalization can pull every branch's contribution for a node.\n */\nfunction indexNewNodesById(\n staging: StagingSet,\n): ReadonlyMap<MergeKey, readonly StagedNewNode[]> {\n const index = new Map<MergeKey, StagedNewNode[]>();\n for (const items of staging.newNodesByKind.values()) {\n for (const staged of items) {\n const key = mergeKeyOf(staged.node);\n const bucket = index.get(key);\n if (bucket === undefined) {\n index.set(key, [staged]);\n } else {\n bucket.push(staged);\n }\n }\n }\n return index;\n}\n\n/**\n * Flattens the staged NEW edges plus the surviving inherited MODIFIED edges into\n * the {@link StagedEdge} shape the repoint phase (T9) consumes (parsed props +\n * branch tag). Inherited edges that were not modified by any branch are unchanged\n * in the base and need no re-commit, so only modified inherited edges are folded\n * in here alongside the new edges.\n *\n * The modified inherited edges are the RECONCILED ones (one per id, 3-way merged\n * against base by {@link reconcileEdgeModifications}) — NOT the raw per-branch\n * `staging.modifiedEdges`. Staging each branch's full fork props separately would\n * make the repoint union treat unchanged-from-base fields as conflicts, dropping a\n * disjoint edit by another branch.\n */\nfunction buildStagedEdges(\n staging: StagingSet,\n modifiedEdges: readonly StagedModifiedEdge[],\n): readonly StagedEdge[] {\n const staged: StagedEdge[] = [];\n for (const items of staging.newEdgesByKind.values()) {\n for (const item of items) {\n staged.push(toStagedEdge(item.branchId, item));\n }\n }\n for (const item of modifiedEdges) {\n staged.push({\n id: item.edge.id,\n kind: item.edge.kind,\n fromId: item.edge.fromId,\n toId: item.edge.toId,\n fromKind: item.edge.fromKind,\n toKind: item.edge.toKind,\n props: item.edge.forkProps as Readonly<Record<string, JsonValue>>,\n branchId: item.branchId,\n });\n }\n return staged;\n}\n\n/** Projects a {@link StagedNewEdge} onto the repoint-phase {@link StagedEdge}. */\nfunction toStagedEdge(branchId: BranchId, item: StagedNewEdge): StagedEdge {\n return {\n id: item.edge.id,\n kind: item.edge.kind,\n fromId: item.edge.fromId,\n toId: item.edge.toId,\n fromKind: item.edge.fromKind,\n toKind: item.edge.toKind,\n props: item.edge.props as Readonly<Record<string, JsonValue>>,\n branchId,\n };\n}\n\n/**\n * Builds the report-only, in-memory provenance index from the full record list.\n * `byBranch(id)` answers which merged node / edge ids that branch contributed to:\n * a node id when the branch staged a new node that survived into a cluster's\n * canonical (or a surviving modification), an edge id when the branch staged an\n * edge that survived the repoint/dedupe. Collapses the records — which ALSO carry\n * each contribution's `sourceId` for the persisted sidecar — to deduped, sorted id\n * sets per branch (the unchanged report-only shape).\n */\nfunction buildProvenanceIndex(\n records: readonly ProvenanceRecord[],\n): ProvenanceIndex {\n const byBranch = new Map<\n BranchId,\n Readonly<{ nodeIds: Set<AnyNodeId>; edgeIds: Set<string> }>\n >();\n for (const record of records) {\n let entry = byBranch.get(record.branchId);\n if (entry === undefined) {\n entry = { nodeIds: new Set(), edgeIds: new Set() };\n byBranch.set(record.branchId, entry);\n }\n if (record.role === \"node\") {\n entry.nodeIds.add(record.canonicalId as AnyNodeId);\n } else {\n entry.edgeIds.add(record.canonicalId);\n }\n }\n\n const frozen = new Map<BranchId, BranchProvenance>();\n for (const [branchId, sets] of byBranch) {\n frozen.set(branchId, {\n nodeIds: [...sets.nodeIds].sort((left, right) =>\n compareStrings(left, right),\n ),\n edgeIds: [...sets.edgeIds]\n .sort((left, right) => compareStrings(left, right))\n .map((id) => id as Edge[\"id\"]),\n });\n }\n return {\n byBranch: (branchId: BranchId): BranchProvenance =>\n frozen.get(branchId) ?? { nodeIds: [], edgeIds: [] },\n };\n}\n\n/**\n * Appends a branch's contribution of a CANONICAL node id (`role: \"node\"`) or a\n * SURVIVING edge id (`role: \"edge\"`), keeping its source.\n */\nfunction pushProvenance(\n records: ProvenanceRecord[],\n role: ProvenanceRecord[\"role\"],\n branchId: BranchId,\n canonicalId: string,\n canonicalKind: string,\n sourceId: string,\n): void {\n records.push({ role, canonicalId, canonicalKind, branchId, sourceId });\n}\n\n/**\n * Empty per-branch trust weights — the fallback when the caller supplies no\n * {@link MergeOptions.provenanceWeights}. With empty weights the\n * `\"provenanceWeighted\"` policy degrades to the stable branch order (its\n * documented tie-break), i.e. `\"lastWriteWins\"` semantics.\n */\nconst EMPTY_WEIGHTS: ProvenanceWeights = new Map<BranchId, number>();\n\n/**\n * The fully-resolved (pre-commit) merge plan: everything the commit applies plus\n * everything the report records. Separated from the commit so the commit body is\n * a thin, mechanical application of an already-decided plan.\n *\n * Exported so the commit path can be unit-tested in isolation (e.g. proving that a\n * canonical entity whose id is an already-committed base node UPDATES that row and\n * repoints edges onto it, rather than inserting a duplicate — §6.2).\n */\nexport type MergePlan<G extends GraphDef> = Readonly<{\n canonicalEntities: readonly CanonicalEntity[];\n survivingModifications: readonly StagedModifiedNode[];\n nodeDeletions: ReadonlyMap<MergeKey, string>;\n edgeDeletions: ReadonlyMap<MergeKey, string>;\n mergedEdges: readonly MergedEdge[];\n // Base props of every inherited edge a fork MODIFIED, keyed by edge id. The\n // commit drops props a fork removed (a base key absent from the merged edge's\n // props) via {@link commitModificationProps} — edges, like nodes, are written\n // with PATCH semantics, so a removed key would otherwise survive. New edges\n // (never inherited) are absent from this map and need no deletion handling.\n inheritedEdgeBaseProps: ReadonlyMap<\n EdgeId,\n Readonly<Record<string, unknown>>\n >;\n retypeMap: ReadonlyMap<MergeKey, string>;\n resolutions: readonly EntityResolution[];\n propertyConflicts: readonly PropertyConflict<G>[];\n deleteModifyConflicts: readonly DeleteModifyConflict[];\n typeReconciliations: readonly TypeReconciliation[];\n dropped: readonly DroppedItem[];\n baseAmbiguities: readonly BaseAmbiguity[];\n provenanceRecords: readonly ProvenanceRecord[];\n warnings: readonly string[];\n}>;\n\n/**\n * Resolves the entire merge into a {@link MergePlan} WITHOUT touching the target.\n * Pure composition of the T3–T10 phases over the staged union; every step is\n * order-independent given the captured `branchRank`.\n */\nfunction planMerge<G extends GraphDef>(\n staging: StagingSet,\n candidateEdges: readonly CandidateEdge[],\n candidateWarnings: readonly string[],\n baseMembers: readonly BaseMember[],\n options: NormalizedMergeOptions<G>,\n branchRank: ReadonlyMap<BranchId, number>,\n subClassClosure: ReturnType<typeof buildSubClassClosure>,\n preferredBranchId?: BranchId,\n): MergePlan<G> {\n const provenanceRecords: ProvenanceRecord[] = [];\n // Per-branch trust weights for the `\"provenanceWeighted\"` policy, or empty when\n // the caller supplied none (then the policy falls back to the stable branch order).\n const weights = options.provenanceWeights ?? EMPTY_WEIGHTS;\n const recordProvenance = (\n role: ProvenanceRecord[\"role\"],\n branchId: BranchId,\n canonicalId: string,\n canonicalKind: string,\n sourceId: string,\n ): void => {\n if (branchId === preferredBranchId) {\n return;\n }\n pushProvenance(\n provenanceRecords,\n role,\n branchId,\n canonicalId,\n canonicalKind,\n sourceId,\n );\n };\n\n // (4) cluster over every staged new-node id + every base member id (so a forced\n // new↔base edge is not dropped as out-of-scope, clustering.ts:134) + the\n // candidate edges. Base members come only from base sources, so this set is\n // exactly the staged universe under the public snapshot path.\n const newNodesById = indexNewNodesById(staging);\n // A base member only belongs in the cluster universe if it actually PARTICIPATES:\n // it got an ACCEPTED candidate edge to a staged node (a forced `baseUnique` edge, or a\n // `baseKey`/fuzzy pair that cleared the threshold), or it shares a key with a staged\n // node (a same-(kind, id) rediscovery, which joins by key without an edge). A `baseKey`\n // hit whose fuzzy pair was REJECTED below threshold would otherwise be seeded as a\n // singleton cluster and re-committed — rewriting an unrelated committed row, inflating\n // `merged.nodes`, and recording spurious provenance under the base sentinel. Drop those\n // orphans here, now that scoring has decided which pairs survived.\n const acceptedEndpointKeys = new Set<MergeKey>();\n for (const edge of candidateEdges) {\n acceptedEndpointKeys.add(edge.a);\n acceptedEndpointKeys.add(edge.b);\n }\n const baseMembersById = new Map<MergeKey, BaseMember>();\n for (const member of baseMembers) {\n const key = mergeKeyOf(member);\n if (acceptedEndpointKeys.has(key) || newNodesById.has(key)) {\n baseMembersById.set(key, member);\n }\n }\n const newNodeIds = [...newNodesById.keys(), ...baseMembersById.keys()];\n\n // (3b) ONTOLOGY RETYPE edges (T10 input): identity stays strictly `(kind, id)`, but\n // under `reconcileTypes: \"ontology\"` two STAGED-new nodes sharing a bare id with\n // subtype-compatible kinds are the same entity at a refined type, so they are forced\n // into one cluster for the reconciler to collapse. Same most-specific-common-kind\n // test the reconciler uses (so a set fuses here iff it would collapse later);\n // staged-only (base members excluded — a committed-base retype is an inherited\n // mutation v1 refuses); `\"off\"` emits nothing, leaving identity strictly `(kind,id)`.\n const isOntology = options.reconcileTypes === \"ontology\";\n const preferKind =\n isOntology ?\n (kinds: readonly string[]): string | undefined =>\n mostSpecificCommonKind(subClassClosure, kinds)\n : undefined;\n const clusterEdges =\n isOntology ?\n [\n ...candidateEdges,\n ...ontologyRetypeEdges(\n newNodesById.keys(),\n (kinds) =>\n mostSpecificCommonKind(subClassClosure, kinds) !== undefined,\n ),\n ]\n : candidateEdges;\n\n // (4) component-level BASE GUARD (§6.4-A) runs on the RAW components, BEFORE the\n // diameter split — so a diameter guard can never sever a base↔base bridge into\n // single-base pieces and leave the ambiguity unreported. The committed entities are\n // always kept separate (the collapse is refused; a deliberate collapse is deferred,\n // §6.4-C), then the optional diameter guard splits the base-contained clusters.\n const baseIds = new Set<MergeKey>(baseMembersById.keys());\n const guard = enforceBaseGuard(\n connectedComponents(clusterEdges, newNodeIds),\n clusterEdges,\n baseIds,\n );\n const clusters =\n options.clusterMaxDiameter === undefined ?\n guard.clusters\n : enforceDiameter(guard.clusters, clusterEdges, options.clusterMaxDiameter);\n // The guard keys on composite `(kind, id)` identities; the public BaseAmbiguity\n // carries them in full, so a component spanning two same-id/different-kind committed\n // entities stays distinguishable in the report.\n const baseAmbiguities: BaseAmbiguity[] = guard.events.map((event) => ({\n baseIds: event.baseIds.map((key) => ({ kind: kindOf(key), id: idOf(key) })),\n memberIds: event.memberIds.map((key) => ({\n kind: kindOf(key),\n id: idOf(key),\n })),\n }));\n\n // (5) canonicalize each cluster: min-id survivor + commutative prop union.\n const canonicalEntities: CanonicalEntity[] = [];\n const resolutions: EntityResolution[] = [];\n const propertyConflicts: PropertyConflict<G>[] = [];\n // (7-input) the distinct member kinds per cluster, collected here so a committed\n // BASE member's kind is part of type reconciliation — a base↔staged kind divergence\n // (e.g. base `Doctor` vs staged `SpecialistDoctor`) must be reconciled/flagged, not\n // dropped because base members live outside `newNodesById`.\n const reconcileInputs: ReconcileClusterInput[] = [];\n for (const cluster of clusters) {\n const members = clusterMembersFor(cluster, newNodesById, baseMembersById);\n if (members.length === 0) {\n continue;\n }\n const entity = canonicalizeCluster(\n cluster,\n members,\n options.onPropertyConflict as PropertyConflictPolicy,\n branchRank,\n weights,\n options.canonical,\n options.onBasePropertyConflict as PropertyConflictPolicy,\n preferKind,\n preferredBranchId,\n );\n canonicalEntities.push(entity);\n reconcileInputs.push({\n canonicalId: mergeKey(entity.kind, entity.canonicalId),\n memberKinds: members.map((member) => member.kind),\n });\n // An EntityResolution records an actual MERGE — two or more distinct fork node\n // IDS collapsing into one canonical. Counted by distinct BARE id (not composite\n // identity): an ontology-retype cluster is several `(kind, id)` identities at ONE\n // id, which is a type reconciliation (recorded separately), not an id merge. A\n // singleton cluster records no resolution.\n const distinctMergedIds = new Set(\n cluster.members.map((member) => idOf(member)),\n );\n if (distinctMergedIds.size > 1) {\n resolutions.push(entity.resolution);\n }\n // Conflicts are recorded REGARDLESS of distinct-id count: two branches can\n // stage a new node under the SAME id with differing props, producing a genuine\n // cross-branch conflict inside a single-id cluster. `entity.conflicts` is\n // already gated by `resolved.conflicted`, so an agreeing single-member cluster\n // contributes none — but a real disagreement must not be silently auto-resolved\n // without a report entry.\n for (const conflict of entity.conflicts) {\n propertyConflicts.push(conflict as PropertyConflict<G>);\n }\n for (const member of members) {\n recordProvenance(\n \"node\",\n member.branchId,\n entity.canonicalId,\n entity.kind,\n member.id,\n );\n }\n }\n\n // (6) delete/modify resolution → authoritative final endpoint liveness.\n const deleteModify = resolveDeleteModify(\n staging,\n options.onDeleteModifyConflict,\n branchRank,\n preferredBranchId,\n );\n const nodeDeletions = new Map<MergeKey, string>();\n for (const deletion of deleteModify.nodeDeletions) {\n nodeDeletions.set(mergeKey(deletion.kind, deletion.id), deletion.kind);\n }\n for (const modification of deleteModify.survivingModifications) {\n recordProvenance(\n \"node\",\n modification.branchId,\n modification.node.id,\n modification.node.kind,\n modification.node.id,\n );\n }\n\n // Reconcile inherited nodes modified by 2+ branches into one merged record per\n // id (3-way against base), surfacing genuine disagreements as PropertyConflicts\n // instead of silently letting the last-committed branch win. Provenance above\n // already credited every contributing branch.\n const reconciledModifications = reconcileModifications(\n deleteModify.survivingModifications,\n options.onPropertyConflict as PropertyConflictPolicy,\n branchRank,\n weights,\n preferredBranchId,\n );\n for (const conflict of reconciledModifications.conflicts) {\n propertyConflicts.push(conflict as PropertyConflict<G>);\n }\n\n // (6-edge) the EDGE analogue of node delete/modify + reconcile. Inherited edge\n // deletions are applied (previously staged but never committed, so the edge\n // stayed live), and edges modified by 2+ branches are 3-way merged against base\n // so disjoint edits do not false-conflict (previously each branch's full fork\n // props were unioned, dropping a branch's independent edit). Provenance credits\n // every modifying branch (mirrors the node push), before reconcile collapses\n // them to one record per id.\n const edgeDeleteModify = resolveEdgeDeleteModify(\n staging,\n options.onDeleteModifyConflict,\n branchRank,\n preferredBranchId,\n );\n const edgeDeletions = new Map<MergeKey, string>();\n for (const deletion of edgeDeleteModify.edgeDeletions) {\n edgeDeletions.set(mergeKey(deletion.kind, deletion.id), deletion.kind);\n }\n for (const modification of edgeDeleteModify.survivingModifications) {\n recordProvenance(\n \"edge\",\n modification.branchId,\n modification.edge.id,\n modification.edge.kind,\n modification.edge.id,\n );\n }\n const reconciledEdgeModifications = reconcileEdgeModifications(\n edgeDeleteModify.survivingModifications,\n options.onPropertyConflict as PropertyConflictPolicy,\n branchRank,\n weights,\n preferredBranchId,\n );\n for (const conflict of reconciledEdgeModifications.conflicts) {\n propertyConflicts.push(conflict as PropertyConflict<G>);\n }\n\n // (7) opt-in ontology type reconciliation over the public-closure glue. Inputs\n // (incl. base member kinds) were collected per cluster in the canonicalize loop.\n const reconciliation = reconcileTypes(\n reconcileInputs,\n subClassClosure,\n options.reconcileTypes,\n );\n\n // (8) repoint every staged edge onto its cluster canonical + dedupe. Index the\n // canonical entities by their `(kind, id)` ONCE so the per-cluster survivor\n // lookup is O(1) — a linear scan per cluster would make the map build\n // O(clusters × entities), quadratic over the merged-node universe.\n const entityByIdentity = new Map<MergeKey, CanonicalEntity>();\n for (const entity of canonicalEntities) {\n entityByIdentity.set(mergeKey(entity.kind, entity.canonicalId), entity);\n }\n const canonicalOf = buildCanonicalMap(clusters, (cluster) =>\n pickClusterCanonical(cluster, entityByIdentity),\n );\n const stagedEdges = buildStagedEdges(\n staging,\n reconciledEdgeModifications.survivingModifications,\n );\n // An edge id can be staged by MORE THAN ONE branch (e.g. an inherited edge\n // modified by two branches), so map each id to the SET of contributing branches.\n // A plain last-write Map would credit only one branch's provenance.\n const stagedEdgeBranches = new Map<string, Set<BranchId>>();\n for (const staged of stagedEdges) {\n const branches = stagedEdgeBranches.get(staged.id);\n if (branches === undefined) {\n stagedEdgeBranches.set(staged.id, new Set([staged.branchId]));\n } else {\n branches.add(staged.branchId);\n }\n }\n const deletedNodeIdSet = new Set<MergeKey>(nodeDeletions.keys());\n const repoint = repointEdges<G>(\n stagedEdges,\n canonicalOf,\n deletedNodeIdSet,\n options.onPropertyConflict,\n branchRank,\n weights,\n preferredBranchId,\n );\n for (const merged of repoint.edges) {\n for (const sourceId of merged.mergedIds) {\n for (const branchId of stagedEdgeBranches.get(sourceId) ?? []) {\n recordProvenance(\"edge\", branchId, merged.id, merged.kind, sourceId);\n }\n }\n }\n\n const dropped: DroppedItem[] = [\n ...deleteModify.dropped,\n ...edgeDeleteModify.dropped,\n ...repoint.dropped,\n ...reconciliation.dropped,\n ].sort((left, right) =>\n compareStrings(`${left.kind}|${left.id}`, `${right.kind}|${right.id}`),\n );\n\n return {\n canonicalEntities,\n survivingModifications: reconciledModifications.survivingModifications,\n nodeDeletions,\n edgeDeletions,\n mergedEdges: repoint.edges,\n inheritedEdgeBaseProps: new Map(\n reconciledEdgeModifications.survivingModifications.map((modification) => [\n modification.edge.id,\n modification.edge.baseProps,\n ]),\n ),\n retypeMap: reconciliation.retypeMap,\n // Order report arrays by the composite (kind, id) identity — never a bare id\n // or a `|`-joined string. A bare id ties two different-kind entities that\n // share an id, and a `|` separator collides on caller-supplied ids/property\n // names that contain `|`; either makes the comparator non-total, so the\n // returned order would depend on stable-sort + insertion order and break the\n // order-independence the whole subsystem guarantees.\n resolutions: resolutions.sort((left, right) =>\n compareMergeKeys(\n mergeKey(left.kind, left.canonicalId),\n mergeKey(right.kind, right.canonicalId),\n ),\n ),\n propertyConflicts: [...propertyConflicts, ...repoint.conflicts].sort(\n (left, right) => {\n const byEntity = compareMergeKeys(\n mergeKey(left.kind, left.entityId),\n mergeKey(right.kind, right.entityId),\n );\n return byEntity === 0 ?\n compareStrings(left.property, right.property)\n : byEntity;\n },\n ),\n deleteModifyConflicts: [\n ...deleteModify.conflicts,\n ...edgeDeleteModify.conflicts,\n ].sort((left, right) =>\n compareMergeKeys(\n mergeKey(left.kind, left.entityId),\n mergeKey(right.kind, right.entityId),\n ),\n ),\n typeReconciliations: reconciliation.reconciliations,\n dropped,\n baseAmbiguities: baseAmbiguities.sort((left, right) =>\n compareMergeKeys(\n mergeKey(left.baseIds[0]!.kind, left.baseIds[0]!.id),\n mergeKey(right.baseIds[0]!.kind, right.baseIds[0]!.id),\n ),\n ),\n provenanceRecords,\n warnings: candidateWarnings,\n };\n}\n\n/**\n * The canonical survivor identity of a cluster, taken DIRECTLY from its already-resolved\n * {@link CanonicalEntity} so edge repoint reuses the exact survivor `canonicalizeCluster`\n * chose (base-id-wins, the `options.canonical` hook, and the most-specific-kind pick all\n * already applied there). This is the SINGLE survivor-selection point: re-deriving it\n * here by a second rule could split the canonical between the node write and the edge\n * repoint, so this never re-runs the hook.\n *\n * Every non-empty cluster yields exactly one canonical entity whose `(kind, id)` is one\n * of its members (the survivor is always a cluster member), so the lookup always hits;\n * a miss is an internal invariant violation, not a fallback.\n *\n * `entityByIdentity` maps each canonical entity's `(kind, id)` → entity, built once by\n * the caller, so finding a cluster's survivor is O(cluster.members) rather than a scan\n * of every canonical entity.\n */\nfunction pickClusterCanonical(\n cluster: ClusterResult,\n entityByIdentity: ReadonlyMap<MergeKey, CanonicalEntity>,\n): MergeKey {\n for (const member of cluster.members) {\n if (entityByIdentity.has(member)) {\n return member;\n }\n }\n throw new MergeError(\n \"Internal invariant: cluster has no canonical entity in pickClusterCanonical.\",\n { details: { members: cluster.members.map((member) => idOf(member)) } },\n );\n}\n\n/**\n * Builds the prop bag to COMMIT for an inherited modification, HONORING property\n * deletions. A fork's `forkProps` is its full intended state, so a base property\n * ABSENT from it was removed by that fork. The commit upsert shallow-merges the\n * written props onto the existing (base) row, so a removed key would otherwise\n * survive; writing it as `undefined` makes the row write drop it (the props column\n * is JSON-serialized, which omits `undefined`), so the fork's deletion is applied\n * instead of being silently reverted to the base value.\n */\nfunction commitModificationProps(\n baseProps: Readonly<Record<string, unknown>>,\n forkProps: Readonly<Record<string, unknown>>,\n): Record<string, unknown> {\n const props: Record<string, unknown> = { ...forkProps };\n for (const key of Object.keys(baseProps)) {\n if (!(key in forkProps)) {\n props[key] = undefined;\n }\n }\n return props;\n}\n\n/**\n * Applies a resolved {@link MergePlan} through a transaction's collection API.\n * Shared by `commitPlan()` and the guarded `mergeIncremental()` commit path so\n * both modes execute the same resolved semantics.\n */\nasync function applyMergePlan<G extends GraphDef>(\n plan: MergePlan<G>,\n nodesApi: TxNodes,\n edgesApi: TxEdges,\n): Promise<Readonly<{ nodes: number; edges: number }>> {\n // Counted by composite `(kind, id)` identity, so two different-kind nodes that\n // share an id string each count once (and never collide in the dedupe set).\n const committedNodeIds = new Set<MergeKey>();\n\n // Identities written as canonical cluster entities, and the fork props of every\n // surviving inherited modification keyed by identity. On the new-vs-base path a\n // committed node can be BOTH a base-member cluster survivor AND an inherited\n // modification; without coordinating the two writes the canonical upsert (built\n // from the cluster union, which carries the OLDER base props) would clobber the\n // modification's fork edit. We therefore fold the fork props into the canonical\n // write and skip the standalone modification write for that identity.\n const canonicalIdentities = new Set<MergeKey>();\n for (const entity of plan.canonicalEntities) {\n canonicalIdentities.add(mergeKey(entity.kind, entity.canonicalId));\n }\n const survivingModProps = new Map<\n MergeKey,\n Readonly<{\n baseProps: Readonly<Record<string, unknown>>;\n forkProps: Readonly<Record<string, unknown>>;\n }>\n >();\n for (const modification of plan.survivingModifications) {\n survivingModProps.set(mergeKeyOf(modification.node), {\n baseProps: modification.node.baseProps,\n forkProps: modification.node.forkProps,\n });\n }\n\n // Surviving inherited modifications, skipping any node finally deleted OR folded\n // into a canonical cluster write below. Property deletions the fork made are\n // honored via {@link commitModificationProps}.\n for (const modification of plan.survivingModifications) {\n const identity = mergeKeyOf(modification.node);\n if (plan.nodeDeletions.has(identity) || canonicalIdentities.has(identity)) {\n continue;\n }\n const collection = nodeCollection(nodesApi, modification.node.kind);\n await collection.upsertByIdFromRecord(\n modification.node.id,\n commitModificationProps(\n modification.node.baseProps,\n modification.node.forkProps,\n ),\n );\n committedNodeIds.add(identity);\n }\n\n // New canonical cluster nodes (survivors), with retype cascade. When the survivor\n // is also an inherited modification, merge the fork edit's props ON TOP of the\n // cluster union so the explicit fork edit is not lost to the (older) base props\n // the union carried.\n for (const entity of plan.canonicalEntities) {\n const identity = mergeKey(entity.kind, entity.canonicalId);\n if (plan.nodeDeletions.has(identity)) {\n continue;\n }\n const kind = plan.retypeMap.get(identity) ?? entity.kind;\n const modification = survivingModProps.get(identity);\n // Fold the fork edit ON TOP of the cluster union, honoring the fork's property\n // deletions (which surface as `undefined` and so override the union's value).\n const props =\n modification === undefined ?\n entity.props\n : {\n ...entity.props,\n ...commitModificationProps(\n modification.baseProps,\n modification.forkProps,\n ),\n };\n const collection = nodeCollection(nodesApi, kind);\n await collection.upsertByIdFromRecord(entity.canonicalId, props);\n committedNodeIds.add(mergeKey(kind, entity.canonicalId));\n }\n\n // Soft-delete every finally-deleted node (key encodes the kind; the value repeats\n // it for the collection lookup).\n for (const [identity, kind] of plan.nodeDeletions) {\n const collection = nodeCollection(nodesApi, kind);\n await collection.delete(idOf(identity));\n }\n\n // Soft-delete every finally-deleted inherited edge. These ids are disjoint from\n // the merged-edge upserts below (deleted edges are not staged), so order is\n // immaterial. Without this an inherited edge deleted in a branch stayed live.\n for (const [identity, kind] of plan.edgeDeletions) {\n await edgeCollection(edgesApi, kind).delete(idOf(identity));\n }\n\n // Repointed + deduped edges, grouped by kind so each kind is one batched\n // round-trip (upsert-by-id is order-independent). The retype cascade keys on\n // each endpoint's full `(kind, id)` identity.\n const edgesByKind = new Map<string, EdgeUpsert[]>();\n for (const edge of plan.mergedEdges) {\n const fromKind = plan.retypeMap.get(mergeKey(edge.fromKind, edge.fromId));\n const toKind = plan.retypeMap.get(mergeKey(edge.toKind, edge.toId));\n // Honor a fork's property deletion on an inherited edge: drop base keys absent\n // from the merged props (the edge upsert PATCH-merges, so a removed key would\n // otherwise survive). New edges have no base entry, so their props pass through.\n const edgeBaseProps = plan.inheritedEdgeBaseProps.get(edge.id);\n const props =\n edgeBaseProps === undefined ?\n edge.props\n : commitModificationProps(edgeBaseProps, edge.props);\n const item: EdgeUpsert = {\n id: edge.id,\n from: { kind: fromKind ?? edge.fromKind, id: edge.fromId },\n to: { kind: toKind ?? edge.toKind, id: edge.toId },\n props,\n };\n const existing = edgesByKind.get(edge.kind);\n if (existing === undefined) {\n edgesByKind.set(edge.kind, [item]);\n } else {\n existing.push(item);\n }\n }\n let committedEdges = 0;\n for (const [kind, items] of edgesByKind) {\n await edgeCollection(edgesApi, kind).bulkUpsertById(items);\n committedEdges += items.length;\n }\n\n return { nodes: committedNodeIds.size, edges: committedEdges };\n}\n\n/**\n * Applies a resolved {@link MergePlan} to the target via the typed transaction\n * collection API. Surviving inherited modifications are upserted by id, canonical\n * cluster nodes are upserted by id with their unioned + (optionally) retyped\n * props, finally-deleted nodes are soft-deleted, and repointed/deduped edges are\n * upserted by id. Returns the merged node / edge counts.\n *\n * UPDATE-NOT-INSERT (§6.2): every node write is an `upsertById`, so a canonical\n * entity whose id is an ALREADY-COMMITTED base node UPDATES that committed row in\n * place — the committed identity is stable and every edge repointed onto it (the\n * merged edges already carry the canonical endpoint) attaches to the surviving\n * row, never a duplicate insert. This is what lets a base member be the canonical\n * survivor once base sources land. Exported for isolated commit-path testing.\n *\n * COALESCE INTERACTION: when the target store was created with\n * `coalesceUnchangedUpserts`, a canonical/inherited upsert whose props already\n * equal the committed row is skipped (no write, no recorded row). This is sound\n * for merge and needs no bypass: the base@V guard runs BEFORE any upsert\n * (see {@link assertTargetUnchanged}), conflicts are resolved at plan time, and\n * an upsert-by-id never rewrites endpoints — so coalescing only elides writes\n * that would persist a byte-identical value, leaving the merged state\n * identical. It merely declines to re-stamp recorded time on rows the merge did\n * not actually change, which is exactly the option's intent.\n */\nexport async function commitPlan<G extends GraphDef>(\n target: Store<G>,\n plan: MergePlan<G>,\n expectedBaseVersion?: BaseVersion,\n): Promise<Readonly<{ nodes: number; edges: number }>> {\n if (!target.backend.capabilities.transactions) {\n throw new MergeError(\n \"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.)\",\n { details: { capability: \"transactions\" } },\n );\n }\n return withTxConflictRetry(() =>\n target.transaction(async (tx) => {\n // TOCTOU guard: the plan was resolved from reads taken OUTSIDE this\n // transaction, so the target may have been written between the base@V\n // precondition and this commit. Revision-anchored stores check their\n // durable clock under the graph write lock; legacy stores re-derive the\n // content fingerprint through this transaction's snapshot. Either proof\n // ensures the plan still describes the live target before committing.\n if (expectedBaseVersion !== undefined) {\n await assertTargetUnchanged(tx.backend, target, expectedBaseVersion);\n }\n return applyMergePlan(\n plan,\n tx.nodes as unknown as TxNodes,\n tx.edges as unknown as TxEdges,\n );\n }, mergeCommitTransactionOptions(target)),\n );\n}\n\n/**\n * Isolation for the merge commit transaction. SERIALIZABLE closes the window\n * between the in-transaction re-validation reads and COMMIT on multi-writer\n * Postgres (SSI aborts a racing writer with SQLSTATE 40001, which\n * {@link withTxConflictRetry} retries); SQLite and PGlite serialize writers by\n * construction, and the SQLite backend ignores the option.\n */\nconst MERGE_COMMIT_TX_OPTIONS = {\n isolationLevel: \"serializable\",\n} as const satisfies TransactionOptions;\n\nfunction mergeCommitTransactionOptions<G extends GraphDef>(\n target: Store<G>,\n): TransactionOptions | undefined {\n // Recorded-time capture only supports read-committed transactions because it\n // allocates its durable clock inside the write transaction. Revision-anchored\n // merges hold that same per-graph lock before checking the anchor, which\n // closes the TOCTOU gap without asking a history store for SERIALIZABLE.\n return target.historyEnabled ? undefined : MERGE_COMMIT_TX_OPTIONS;\n}\n\n/**\n * The in-transaction half of the base@V guard: revision-anchored targets read\n * their durable clock under the graph lock; legacy targets recompute their\n * content fingerprint through the transaction-scoped backend. The schema\n * component cannot drift because it is a pure function of the in-memory graph\n * definition.\n */\nasync function assertTargetUnchanged<G extends GraphDef>(\n txBackend: TransactionBackend,\n target: Store<G>,\n expectedBaseVersion: BaseVersion,\n): Promise<void> {\n if (hasRevisionAnchor(expectedBaseVersion)) {\n // All tracked writers acquire this lock before touching graph rows and\n // advance the same clock before committing. Holding it around the\n // read→apply sequence makes the O(1) anchor check a TOCTOU guard without\n // relying on the transaction's snapshot being the latest committed state.\n await lockRecordedGraphWrite(txBackend, target.graphId);\n const expectedOrigin = revisionOriginOf(expectedBaseVersion);\n const liveOrigin = await readRevisionOrigin(\n txBackend,\n target.revisionSchema,\n target.graphId,\n );\n if (liveOrigin !== expectedOrigin) {\n throw new BaseVersionMismatchError(\n \"The merge branch was forked from a different revision-tracked store; the resolved plan was not applied.\",\n {\n details: { expectedOrigin, liveOrigin },\n suggestion:\n \"Merge the branch back into its original base store, or fork a new branch from this target.\",\n },\n );\n }\n const liveRevision = await readRecordedClock(\n txBackend,\n target.revisionSchema,\n target.graphId,\n );\n const expectedRevision = revisionAnchorOf(expectedBaseVersion);\n if (liveRevision !== expectedRevision) {\n throw new BaseVersionMismatchError(\n \"The merge target was modified between the revision-anchor check and the commit transaction; the resolved plan was not applied.\",\n {\n details: { expectedRevision, liveRevision },\n suggestion:\n \"Re-run the merge (and re-branch if the divergence is real), or route all graph writes through the revision-tracked Store.\",\n },\n );\n }\n return;\n }\n const liveContent = await computeContentComponent(\n txBackend,\n target.graphId,\n target.graph,\n );\n const expectedContent = contentComponentOf(expectedBaseVersion);\n if (liveContent !== expectedContent) {\n throw new BaseVersionMismatchError(\n \"The merge target was modified between the base@V check and the commit transaction; the resolved plan no longer describes the live target and was not applied.\",\n {\n details: {\n expectedContentFingerprint: expectedContent,\n liveContentFingerprint: liveContent,\n },\n suggestion:\n \"Re-run the merge (and re-branch if the divergence is real), or serialize writers against merges on this target.\",\n },\n );\n }\n}\n\n/**\n * Runtime-keyed view of the transaction's node collections. The typed\n * `tx.nodes` is keyed by the graph's concrete kinds; the orchestrator dispatches\n * on kind STRINGS, so it indexes through this widened record. Each entry exposes\n * the subset of the collection API the commit uses.\n */\ntype TxNodes = Record<string, NodeCollectionLike>;\n\n/** Runtime-keyed view of the transaction's edge collections. See {@link TxNodes}. */\ntype TxEdges = Record<string, EdgeCollectionLike>;\n\n/** The node-collection surface the commit uses (runtime, kind-string keyed). */\ntype NodeCollectionLike = Readonly<{\n getById: (\n id: string,\n options?: Readonly<{ temporalMode?: \"includeTombstones\" }>,\n ) => Promise<Node | undefined>;\n getByIds: (\n ids: readonly string[],\n options?: Readonly<{ temporalMode?: \"includeTombstones\" }>,\n ) => Promise<readonly (Node | undefined)[]>;\n bulkCreate: (\n items: readonly Readonly<{\n id?: string;\n props: Record<string, unknown>;\n }>[],\n ) => Promise<unknown>;\n update: (id: string, props: Record<string, unknown>) => Promise<unknown>;\n upsertByIdFromRecord: (\n id: string,\n data: Record<string, unknown>,\n ) => Promise<unknown>;\n delete: (id: string) => Promise<void>;\n}>;\n\n/** The edge-collection surface the commit uses (runtime, kind-string keyed). */\ntype EdgeCollectionLike = Readonly<{\n getById: (\n id: string,\n options?: Readonly<{ temporalMode?: \"includeTombstones\" }>,\n ) => Promise<Edge | undefined>;\n getByIds: (\n ids: readonly string[],\n options?: Readonly<{ temporalMode?: \"includeTombstones\" }>,\n ) => Promise<readonly (Edge | undefined)[]>;\n bulkCreate: (\n items: readonly Readonly<{\n id?: string;\n from: Readonly<{ kind: string; id: string }>;\n to: Readonly<{ kind: string; id: string }>;\n props?: Record<string, unknown>;\n }>[],\n ) => Promise<unknown>;\n bulkUpsertById: (\n items: readonly Readonly<{\n id: string;\n from: Readonly<{ kind: string; id: string }>;\n to: Readonly<{ kind: string; id: string }>;\n props?: Record<string, unknown>;\n }>[],\n ) => Promise<unknown>;\n delete: (id: string) => Promise<void>;\n}>;\n\n/** A single edge upsert payload (the element of a {@link EdgeCollectionLike} batch). */\ntype EdgeUpsert = Parameters<EdgeCollectionLike[\"bulkUpsertById\"]>[0][number];\n\n/** Resolves a node collection by kind, failing loudly on an unknown kind. */\nfunction nodeCollection(nodes: TxNodes, kind: string): NodeCollectionLike {\n const collection = nodes[kind];\n if (collection === undefined) {\n throw new MergeError(`No node collection for kind \"${kind}\".`, {\n details: { kind },\n });\n }\n return collection;\n}\n\n/** Resolves an edge collection by kind, failing loudly on an unknown kind. */\nfunction edgeCollection(edges: TxEdges, kind: string): EdgeCollectionLike {\n const collection = edges[kind];\n if (collection === undefined) {\n throw new MergeError(`No edge collection for kind \"${kind}\".`, {\n details: { kind },\n });\n }\n return collection;\n}\n\n/**\n * Validates the `base@V` precondition: every branch's `base` token MUST equal the\n * target's current base version. A mismatch means the branch forked from a\n * divergent schema or base revision, which cannot be merged safely.\n */\nasync function validateBaseVersions<G extends GraphDef>(\n target: Store<G>,\n branches: readonly GraphBranch<G>[],\n): Promise<Result<BaseVersion, BaseVersionMismatchError>> {\n const targetVersion = await computeBaseVersion(target);\n for (const branch of branches) {\n if (branch.base !== targetVersion) {\n return err(\n new BaseVersionMismatchError(\n `Branch \"${branch.id}\" forked from base@V \"${branch.base}\", which does not match the merge target's current base@V \"${targetVersion}\".`,\n {\n details: {\n branchId: branch.id,\n branchBase: branch.base,\n targetBase: targetVersion,\n },\n },\n ),\n );\n }\n }\n return ok(targetVersion);\n}\n\n/** Normalizes options, converting an invalid-option throw into a typed result. */\nfunction tryNormalize<G extends GraphDef>(\n optionsInput: MergeOptions<G>,\n): Result<NormalizedMergeOptions<G>, MergeError> {\n try {\n return ok(normalizeMergeOptions(optionsInput));\n } catch (error) {\n return err(new MergeError(\"Invalid merge options.\", { cause: error }));\n }\n}\n\n/**\n * The shared resolve→commit→report pipeline behind both `merge()` (snapshot,\n * staged-vs-staged) and `mergeAgainstBase()` (synthetic new-vs-base). It stages the\n * union of branch diffs, generates candidates (with or without the base sources per\n * `useBaseSources`), resolves the plan, commits, and assembles the report. The\n * `base@V` precondition is the CALLER's responsibility — `merge()` enforces it,\n * the synthetic scope deliberately bypasses it (§6.4-B).\n */\nasync function resolveMerge<G extends GraphDef>(\n store: Store<G>,\n target: Store<G>,\n branches: readonly GraphBranch<G>[],\n options: NormalizedMergeOptions<G>,\n useBaseSources: boolean,\n incremental?: IncrementalConfig,\n expectedBaseVersion?: BaseVersion,\n): Promise<Result<MergeReport<G>, MergeError>> {\n // Reserved BranchIds are used for non-user contributions. Reject real branches\n // that try to mint them rather than silently corrupting conflict/provenance state.\n let targetBranchSeen = false;\n for (const branch of branches) {\n if (branch.id === BASE_PROVENANCE_BRANCH) {\n return err(\n new MergeError(\n `Branch id \"${BASE_PROVENANCE_BRANCH}\" is reserved for committed-base provenance and cannot be used as a branch id.`,\n { details: { branchId: branch.id } },\n ),\n );\n }\n if (branch.id === COMMITTED_TARGET_BRANCH) {\n if (\n incremental?.targetBranchId !== COMMITTED_TARGET_BRANCH ||\n targetBranchSeen\n ) {\n return err(\n new MergeError(\n `Branch id \"${COMMITTED_TARGET_BRANCH}\" is reserved for the committed incremental target and cannot be used as a branch id.`,\n { details: { branchId: branch.id } },\n ),\n );\n }\n targetBranchSeen = true;\n }\n }\n\n try {\n // (2) stage the provenance-tagged union of every branch's diff. For the\n // incremental path, capture the committed target branch's node versions from\n // its diff enumeration — the plan-time baseline for the commit-time\n // lost-update guard (assertInheritedTargetUnchanged).\n const preferredBranchId = incremental?.targetBranchId;\n const staging = await stageBranches(store, branches, preferredBranchId);\n\n // Capture the stable branch order ONCE (never wall-clock).\n const branchIds = branches.map((branch) => branch.id);\n const branchOrder =\n preferredBranchId === undefined ?\n (options.branchOrder ?? [])\n : [\n preferredBranchId,\n ...(options.branchOrder ?? []).filter(\n (branchId) => branchId !== preferredBranchId,\n ),\n ];\n const branchRank = buildBranchRank(branchOrder, branchIds);\n\n // Introspection snapshot: unique constraints for blocking + ontology closure.\n const introspection = store.introspect();\n const introspectionKinds = new Map<\n string,\n readonly UniqueIntrospection[]\n >();\n for (const kind of introspection.kinds) {\n introspectionKinds.set(kind.name, kind.unique);\n }\n const subClassClosure = buildSubClassClosure(introspection.ontology);\n\n // (3) candidate generation across every resolved kind. When an embedder is\n // configured, precompute the STAGED texts' vectors ONCE (a batched step) so\n // the per-pair `vector`/`hybrid` scoring is a pure in-memory cosine; base-node\n // texts pulled into staged↔base pairs are embedded inside generateAllCandidates\n // (they are not known until the base sources run). With no embedder,\n // `embeddings` stays absent and a vector/hybrid kind surfaces\n // SimilarityUnavailableError in candidate generation.\n const embeddings =\n options.embedder === undefined ?\n undefined\n : await precomputeEmbeddings(\n newNodesByKind(staging),\n options.resolve,\n options.embedder,\n );\n const ctx: SimilarityContext = {\n backend: store.backend,\n ...(embeddings === undefined ? {} : { embeddings }),\n };\n const candidates = await generateAllCandidates(\n target,\n staging,\n options,\n introspectionKinds,\n ctx,\n useBaseSources,\n options.embedder,\n );\n if (isErr(candidates)) {\n return err(candidates.error);\n }\n\n // (4–8) resolve the whole merge into a commit-ready plan.\n const plan = planMerge(\n staging,\n candidates.data.edges,\n candidates.data.warnings,\n candidates.data.baseMembers,\n options,\n branchRank,\n subClassClosure,\n preferredBranchId,\n );\n\n // (9) commit to the target. Incremental mode commits through the guarded path\n // (the existing-target-id write guard, §6.6); snapshot mode commits directly,\n // re-validating the captured base@V inside the transaction (TOCTOU guard).\n const merged =\n incremental === undefined ?\n await commitPlan(target, plan, expectedBaseVersion)\n : await commitIncrementalPlan(target, plan, {\n stagedNewByKind: newNodesByKind(staging),\n options,\n introspectionKinds,\n // The committed (kind, id) keys the base sources matched at PLAN time;\n // anything NEW the in-tx re-probe surfaces is a window write.\n plannedBaseMatchKeys: new Set(\n candidates.data.baseMembers.map((member) => mergeKeyOf(member)),\n ),\n targetNodeVersions: staging.targetNodeVersions,\n targetEdgeSignatures: staging.targetEdgeSignatures,\n });\n\n // (10) assemble the report. The full provenance records are always built in the\n // plan; the in-memory index is gated by `provenance`, and on-graph persistence\n // by `persistProvenance`.\n const provenance: ProvenanceIndex =\n options.provenance ?\n buildProvenanceIndex(plan.provenanceRecords)\n : { byBranch: () => ({ nodeIds: [], edgeIds: [] }) };\n\n const warnings = [...plan.warnings];\n let provenancePersisted: MergeReport<G>[\"provenancePersisted\"];\n if (options.persistProvenance) {\n // POST-COMMIT, best-effort: the graph is already committed, so a provenance\n // write failure must NOT fail the merge — it surfaces as a warning. The\n // sidecar node ids are deterministic, so this UPSERTS (idempotent re-runs).\n try {\n const provenanceStore = await openProvenanceStore(\n target.backend,\n target.graphId,\n );\n const count = await persistProvenanceRecords(\n provenanceStore,\n target.graphId,\n plan.provenanceRecords,\n );\n provenancePersisted = {\n graphId: provenanceGraphId(target.graphId),\n count,\n };\n } catch (error) {\n warnings.push(\n \"provenance persistence failed (graph committed; provenance not persisted): \" +\n (error instanceof Error ? error.message : String(error)),\n );\n }\n }\n\n const report: MergeReport<G> = {\n merged,\n resolutions: plan.resolutions,\n conflicts: plan.propertyConflicts,\n deleteModifyConflicts: plan.deleteModifyConflicts,\n typeReconciliations: plan.typeReconciliations,\n dropped: plan.dropped,\n baseAmbiguities: plan.baseAmbiguities,\n provenance,\n warnings,\n ...(provenancePersisted === undefined ? {} : { provenancePersisted }),\n };\n return ok(report);\n } catch (error) {\n // A typed MergeError thrown deeper (e.g. the incremental guard's stale-overwrite\n // refusal) carries its own precise message — surface it directly rather than\n // masking it behind the generic wrapper, which is reserved for opaque failures\n // (a backend error, a malformed row).\n if (error instanceof MergeError) {\n return err(error);\n }\n return err(\n new MergeError(\n `Merge failed while staging or committing: ${describeCause(error)}`,\n { cause: error },\n ),\n );\n }\n}\n\n/**\n * Merges a set of branches back into a target store (design §7.2).\n *\n * Validates that every branch forked from the target's current `base@V`, stages\n * the union of their diffs, resolves entities / conflicts / types through the\n * T3–T10 phases, and commits the merged result to `target` (default: the base\n * `store`) in a single transaction. Returns a {@link MergeReport} on success.\n *\n * This is the SNAPSHOT entry point: candidate generation runs the staged sources\n * only (`exactKey`, `unique`) — it never resolves a staged node against the\n * committed base. New-vs-base resolution is the separate {@link mergeAgainstBase}\n * scope, which has a weaker `base@V` contract.\n *\n * Errors are RETURNED (never thrown) as a typed {@link MergeError} subclass:\n * `BaseVersionMismatchError` for the precondition, `MergeError` for a\n * comparison-ceiling overrun / commit failure, `SimilarityUnavailableError` for a\n * `vector`/`hybrid` strategy with no configured vector strategy.\n *\n * @param store The base store the branches forked from. Used as the default merge\n * target and as the immutable diff reference.\n * @param branches The branches to merge. ORDER DOES NOT AFFECT THE RESULT — the\n * report and committed graph are identical across any permutation.\n * @param optionsInput Caller-facing {@link MergeOptions}; normalized internally.\n */\nexport async function merge<G extends GraphDef>(\n store: Store<G>,\n branches: readonly GraphBranch<G>[],\n optionsInput: MergeOptions<G> = {},\n): Promise<Result<MergeReport<G>, MergeError>> {\n const normalized = tryNormalize(optionsInput);\n if (isErr(normalized)) {\n return err(normalized.error);\n }\n const options = normalized.data;\n const target = options.target ?? store;\n\n // (1) base@V precondition — the snapshot contract. The validated token is\n // re-checked INSIDE the commit transaction (see `commitPlan`), so a target\n // write landing between this check and the commit fails typed instead of\n // committing a stale plan.\n const precondition = await validateBaseVersions(target, branches);\n if (isErr(precondition)) {\n return err(precondition.error);\n }\n\n return resolveMerge(\n store,\n target,\n branches,\n options,\n false,\n undefined,\n precondition.data,\n );\n}\n\n/**\n * SYNTHETIC new-vs-base merge scope (design §8 \"Slice 1\"). Runs the full\n * candidate-source + scoring + reconciler pipeline WITH the base sources active —\n * so a staged node re-discovering a committed entity resolves against it\n * (base-id-wins, update-not-insert) — while DELIBERATELY bypassing the `base@V`\n * snapshot precondition (§6.4-B) rather than fighting it.\n *\n * This is the lower-level scope the slice's mechanism is built and exercised behind\n * (the fixed-point + determinism gates drive it directly), and it is intentionally\n * NOT re-exported from the package barrel. The public incremental surface over it\n * is {@link mergeIncremental} (§6.6), which adds the fork-point precondition, the\n * keep-base pin, and the transaction-scoped existing-row guard. `merge()` and its\n * snapshot precondition are unchanged.\n */\nexport async function mergeAgainstBase<G extends GraphDef>(\n store: Store<G>,\n branches: readonly GraphBranch<G>[],\n optionsInput: MergeOptions<G> = {},\n): Promise<Result<MergeReport<G>, MergeError>> {\n const normalized = tryNormalize(optionsInput);\n if (isErr(normalized)) {\n return err(normalized.error);\n }\n const options = normalized.data;\n const target = options.target ?? store;\n\n // No branch-level base@V precondition here (the synthetic scope's contract),\n // but PLAN STABILITY still holds: the token captured before any planning\n // read is re-validated inside the commit transaction, so the target must not\n // move while THIS merge is in flight.\n const expectedBaseVersion = await computeBaseVersion(target);\n return resolveMerge(\n store,\n target,\n branches,\n options,\n true,\n undefined,\n expectedBaseVersion,\n );\n}\n\n// --- mergeIncremental: full fork-point-vs-live-target entry point (§6.6) -------\n\n/** Internal config carried into {@link resolveMerge} for incremental mode. */\ntype IncrementalConfig = Readonly<{\n targetBranchId: BranchId;\n}>;\n\n/**\n * Incremental precondition: every branch must have forked from THIS fork-point, so\n * the fork-point diff (fork-point → branch) is honest. The analogue of\n * {@link validateBaseVersions}, repointed from `target` to `forkPoint` (§6.6).\n */\nasync function validateForkPointVersions<G extends GraphDef>(\n forkPoint: Store<G>,\n branches: readonly GraphBranch<G>[],\n): Promise<Result<BaseVersion, BaseVersionMismatchError>> {\n const forkVersion = await computeBaseVersion(forkPoint);\n for (const branch of branches) {\n if (branch.base !== forkVersion) {\n return err(\n new BaseVersionMismatchError(\n `Branch \"${branch.id}\" forked from base@V \"${branch.base}\", which does not match the fork-point's base@V \"${forkVersion}\". mergeIncremental() requires every branch to have forked from the supplied forkPoint.`,\n {\n details: {\n branchId: branch.id,\n branchBase: branch.base,\n forkPointBase: forkVersion,\n },\n },\n ),\n );\n }\n }\n return ok(forkVersion);\n}\n\n/**\n * The minimal schema surface the write guards need: a kind's Zod schema, called the\n * SAME way the commit calls it (`safeParse`). Structural so the guard couples to the\n * parse behaviour, not a zod version.\n */\ntype PropsSchema = Readonly<{\n safeParse: (\n value: unknown,\n ) => { success: true; data: unknown } | { success: false };\n}>;\n\ntype RevalidatingWriteAnalysis =\n | Readonly<{\n status: \"valid\";\n /** Whether TypeGraph's re-validating write would change persisted bytes. */\n storageWouldChange: boolean;\n /** Whether declared schema fields would change, ignoring unknown stored keys. */\n schemaWouldChange: boolean;\n /** Whether the write would drop current props not preserved by the schema. */\n stripsCurrentProps: boolean;\n }>\n | Readonly<{ status: \"invalid\" }>;\n\n/** The declared schema for a node kind off the public `GraphDef` registry (or none). */\nfunction nodeSchemaFor<G extends GraphDef>(\n target: Store<G>,\n kind: string,\n): PropsSchema | undefined {\n const registry = target.graph.nodes as Record<\n string,\n Readonly<{ type?: Readonly<{ schema?: PropsSchema }> }> | undefined\n >;\n return registry[kind]?.type?.schema;\n}\n\n/** The declared schema for an edge kind off the public `GraphDef` registry (or none). */\nfunction edgeSchemaFor<G extends GraphDef>(\n target: Store<G>,\n kind: string,\n): PropsSchema | undefined {\n const registry = target.graph.edges as Record<\n string,\n Readonly<{ type?: Readonly<{ schema?: PropsSchema }> }> | undefined\n >;\n return registry[kind]?.type?.schema;\n}\n\n/**\n * Models TypeGraph's re-validating update semantics for one row:\n * `schema.safeParse({...current, ...planned})`, then storing the parsed result. This\n * is NOT used as a pre-transaction write guard anymore; `mergeIncremental()` calls it\n * inside the target transaction to decide between create/update/skip/error.\n */\nfunction analyzeRevalidatingWrite(\n schema: PropsSchema | undefined,\n current: Readonly<Record<string, unknown>>,\n planned: Readonly<Record<string, unknown>>,\n): RevalidatingWriteAnalysis {\n const merged = { ...current, ...planned };\n if (schema === undefined) {\n const storageWouldChange =\n canonicalizeProps(merged) !== canonicalizeProps(current);\n return {\n status: \"valid\",\n storageWouldChange,\n schemaWouldChange: storageWouldChange,\n stripsCurrentProps: false,\n };\n }\n\n const currentParsed = schema.safeParse(current);\n const mergedParsed = schema.safeParse(merged);\n if (!currentParsed.success || !mergedParsed.success) {\n return { status: \"invalid\" };\n }\n const normalizedCurrent = currentParsed.data as Record<string, unknown>;\n const normalizedMerged = mergedParsed.data as Record<string, unknown>;\n return {\n status: \"valid\",\n storageWouldChange:\n canonicalizeProps(normalizedMerged) !== canonicalizeProps(current),\n schemaWouldChange:\n canonicalizeProps(normalizedMerged) !==\n canonicalizeProps(normalizedCurrent),\n stripsCurrentProps:\n canonicalizeProps(normalizedCurrent) !== canonicalizeProps(current),\n };\n}\n\nexport function writeWouldChangeRow(\n schema: PropsSchema | undefined,\n committed: Readonly<Record<string, unknown>>,\n planned: Readonly<Record<string, unknown>>,\n): boolean {\n const analysis = analyzeRevalidatingWrite(schema, committed, planned);\n return analysis.status === \"valid\" ? analysis.storageWouldChange : false;\n}\n\n/**\n * Public node objects spread props at top-level. Strip TypeGraph structural keys so\n * write comparisons operate on the persisted props bag only.\n */\nfunction nodeProps(node: Node): Record<string, unknown> {\n const props: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(node)) {\n if (key === \"id\" || key === \"kind\" || key === \"meta\") continue;\n props[key] = value;\n }\n return props;\n}\n\n/**\n * Public edge objects spread props at top-level. Strip TypeGraph structural keys so\n * write comparisons operate on the persisted props bag only.\n */\nfunction edgeProps(edge: Edge): Record<string, unknown> {\n const props: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(edge)) {\n if (\n key === \"id\" ||\n key === \"kind\" ||\n key === \"fromKind\" ||\n key === \"fromId\" ||\n key === \"toKind\" ||\n key === \"toId\" ||\n key === \"meta\"\n ) {\n continue;\n }\n props[key] = value;\n }\n return props;\n}\n\nconst INCLUDE_TOMBSTONES = { temporalMode: \"includeTombstones\" as const };\n\nfunction finalEdgeFrom<G extends GraphDef>(\n edge: MergedEdge,\n plan: MergePlan<G>,\n) {\n return {\n kind:\n plan.retypeMap.get(mergeKey(edge.fromKind, edge.fromId)) ?? edge.fromKind,\n id: edge.fromId,\n };\n}\n\nfunction finalEdgeTo<G extends GraphDef>(edge: MergedEdge, plan: MergePlan<G>) {\n return {\n kind: plan.retypeMap.get(mergeKey(edge.toKind, edge.toId)) ?? edge.toKind,\n id: edge.toId,\n };\n}\n\nfunction assertValidRevalidatingWrite(\n analysis: RevalidatingWriteAnalysis,\n message: string,\n details: Record<string, unknown>,\n): asserts analysis is Extract<RevalidatingWriteAnalysis, { status: \"valid\" }> {\n if (analysis.status === \"invalid\") {\n throw new MergeError(message, { details });\n }\n}\n\nfunction describeCause(cause: unknown): string {\n return cause instanceof Error ? cause.message : String(cause);\n}\n\ntype PlannedNodeWrite = Readonly<{\n identity: MergeKey;\n kind: string;\n id: AnyNodeId;\n props: Readonly<Record<string, unknown>>;\n}>;\n\nfunction plannedNodeWrites<G extends GraphDef>(\n plan: MergePlan<G>,\n): readonly PlannedNodeWrite[] {\n const canonicalIdentities = new Set<MergeKey>();\n for (const entity of plan.canonicalEntities) {\n canonicalIdentities.add(mergeKey(entity.kind, entity.canonicalId));\n }\n const survivingModProps = new Map<\n MergeKey,\n Readonly<Record<string, unknown>>\n >();\n for (const modification of plan.survivingModifications) {\n survivingModProps.set(\n mergeKeyOf(modification.node),\n modification.node.forkProps,\n );\n }\n\n const writes: PlannedNodeWrite[] = [];\n for (const modification of plan.survivingModifications) {\n const identity = mergeKeyOf(modification.node);\n if (plan.nodeDeletions.has(identity) || canonicalIdentities.has(identity)) {\n continue;\n }\n writes.push({\n identity,\n kind: modification.node.kind,\n id: modification.node.id,\n props: modification.node.forkProps,\n });\n }\n for (const entity of plan.canonicalEntities) {\n const sourceIdentity = mergeKey(entity.kind, entity.canonicalId);\n if (plan.nodeDeletions.has(sourceIdentity)) {\n continue;\n }\n const kind = plan.retypeMap.get(sourceIdentity) ?? entity.kind;\n const forkProps = survivingModProps.get(sourceIdentity);\n writes.push({\n identity: mergeKey(kind, entity.canonicalId),\n kind,\n id: entity.canonicalId,\n props:\n forkProps === undefined ?\n entity.props\n : { ...entity.props, ...forkProps },\n });\n }\n return writes;\n}\n\nfunction edgeWriteSignature<G extends GraphDef>(\n edge: MergedEdge,\n plan: MergePlan<G>,\n): string {\n const from = finalEdgeFrom(edge, plan);\n const to = finalEdgeTo(edge, plan);\n return JSON.stringify([\n edge.kind,\n from.kind,\n from.id,\n to.kind,\n to.id,\n canonicalizeProps(edge.props),\n ]);\n}\n\nasync function validateIncrementalNodeWrites<G extends GraphDef>(\n target: Store<G>,\n nodesApi: TxNodes,\n plan: MergePlan<G>,\n): Promise<void> {\n const writes = plannedNodeWrites(plan);\n const nodeIdsByKind = new Map<string, AnyNodeId[]>();\n for (const write of writes) {\n const bucket = nodeIdsByKind.get(write.kind) ?? [];\n bucket.push(write.id);\n nodeIdsByKind.set(write.kind, bucket);\n }\n\n const currentByIdentity = new Map<MergeKey, Node | undefined>();\n for (const [kind, ids] of nodeIdsByKind) {\n const rows = await nodeCollection(nodesApi, kind).getByIds(\n ids,\n INCLUDE_TOMBSTONES,\n );\n for (const [index, id] of ids.entries()) {\n currentByIdentity.set(mergeKey(kind, id), rows[index]);\n }\n }\n\n for (const write of writes) {\n const current = currentByIdentity.get(write.identity);\n if (current === undefined) {\n continue;\n }\n if (current.meta.deletedAt !== undefined) {\n throw new MergeError(\n `mergeIncremental() would resurrect soft-deleted committed node \"${write.id}\" (kind \"${write.kind}\").`,\n { details: { id: write.id, kind: write.kind } },\n );\n }\n const analysis = analyzeRevalidatingWrite(\n nodeSchemaFor(target, write.kind),\n nodeProps(current),\n write.props,\n );\n assertValidRevalidatingWrite(\n analysis,\n `mergeIncremental() found an existing committed node \"${write.id}\" (kind \"${write.kind}\") whose current props do not validate against the active schema.`,\n { id: write.id, kind: write.kind },\n );\n if (analysis.stripsCurrentProps && analysis.schemaWouldChange) {\n throw new MergeError(\n `mergeIncremental() would update committed node \"${write.id}\" (kind \"${write.kind}\") but the write would strip existing props outside the active schema (lossy base update).`,\n { details: { id: write.id, kind: write.kind } },\n );\n }\n }\n}\n\nasync function validateIncrementalEdgeWrites<G extends GraphDef>(\n target: Store<G>,\n edgesApi: TxEdges,\n plan: MergePlan<G>,\n): Promise<void> {\n const signatureById = new Map<EdgeId, string>();\n for (const edge of plan.mergedEdges) {\n const signature = edgeWriteSignature(edge, plan);\n const existing = signatureById.get(edge.id);\n if (existing !== undefined && existing !== signature) {\n throw new MergeError(\n `mergeIncremental() would overwrite committed edge \"${edge.id}\" with multiple planned endpoint/prop shapes (edge.id collision).`,\n { details: { id: edge.id } },\n );\n }\n signatureById.set(edge.id, signature);\n }\n\n // Bucket the planned edges by their PLANNED kind and fetch each kind's ids in a\n // single round-trip. An edge belongs to exactly one kind, so this does O(edges)\n // lookups instead of scanning EVERY schema edge kind for every id (the old\n // O(edgeKinds × edges) fan-out that held the write lock far longer than needed).\n const plannedKindById = new Map<EdgeId, string>();\n const idsByKind = new Map<string, EdgeId[]>();\n for (const edge of plan.mergedEdges) {\n if (plannedKindById.has(edge.id)) {\n continue; // shape already deduped by the signature guard above\n }\n plannedKindById.set(edge.id, edge.kind);\n const bucket = idsByKind.get(edge.kind) ?? [];\n bucket.push(edge.id);\n idsByKind.set(edge.kind, bucket);\n }\n const existingById = new Map<string, Edge>();\n for (const [kind, ids] of idsByKind) {\n const rows = await edgeCollection(edgesApi, kind).getByIds(\n ids,\n INCLUDE_TOMBSTONES,\n );\n for (const [index, id] of ids.entries()) {\n const row = rows[index];\n if (row !== undefined) {\n existingById.set(id, row);\n }\n }\n }\n\n // Cross-kind collision guard: edge ids are GLOBALLY unique, so an id NOT found\n // under its planned kind may still be committed under a DIFFERENT kind — a silent\n // overwrite hazard. Scan the schema's edge kinds for ONLY those not-found ids,\n // through the transaction's collections (never `target.backend`, whose separate\n // connection would deadlock against the tx-held one). An update-only merge finds\n // every edge in the bucketed pass above, so this fallback is empty.\n const notFound = [...plannedKindById.keys()]\n .filter((id) => !existingById.has(id))\n .sort((left, right) => compareStrings(left, right));\n if (notFound.length > 0) {\n // Sequential: all queries share the same transaction client (a single\n // pg PoolClient). Concurrent client.query() calls on a PoolClient queue\n // with a deprecation warning in pg@8 and become an error in pg@9.\n const crossKindById = new Map<string, Edge>();\n for (const kind of Object.keys(target.graph.edges)) {\n const rows = await edgeCollection(edgesApi, kind).getByIds(\n notFound,\n INCLUDE_TOMBSTONES,\n );\n for (const [index, id] of notFound.entries()) {\n const row = rows[index];\n if (row !== undefined && !crossKindById.has(id)) {\n crossKindById.set(id, row);\n }\n }\n }\n for (const id of notFound) {\n const row = crossKindById.get(id);\n if (row === undefined) {\n continue;\n }\n if (row.meta.deletedAt !== undefined) {\n throw new MergeError(\n `mergeIncremental() would resurrect soft-deleted committed edge \"${id}\" (kind \"${row.kind}\").`,\n { details: { id, committedKind: row.kind } },\n );\n }\n throw new MergeError(\n `mergeIncremental() would overwrite committed edge \"${id}\" (kind \"${row.kind}\") with a different-kind edge \"${plannedKindById.get(id)!}\" of the same id.`,\n {\n details: {\n id,\n committedKind: row.kind,\n plannedKind: plannedKindById.get(id)!,\n },\n },\n );\n }\n }\n\n for (const edge of plan.mergedEdges) {\n const current = existingById.get(edge.id);\n if (current === undefined) {\n continue;\n }\n // `current` was fetched under `edge.kind`, so its kind matches by construction;\n // a different committed kind for this id is caught by the cross-kind guard above.\n if (current.meta.deletedAt !== undefined) {\n throw new MergeError(\n `mergeIncremental() would resurrect soft-deleted committed edge \"${edge.id}\" (kind \"${current.kind}\").`,\n { details: { id: edge.id, committedKind: current.kind } },\n );\n }\n\n const from = finalEdgeFrom(edge, plan);\n const to = finalEdgeTo(edge, plan);\n if (\n current.fromId !== from.id ||\n current.fromKind !== from.kind ||\n current.toId !== to.id ||\n current.toKind !== to.kind\n ) {\n throw new MergeError(\n `mergeIncremental() would overwrite committed edge \"${edge.id}\" (kind \"${edge.kind}\") with different endpoints.`,\n { details: { id: edge.id, kind: edge.kind } },\n );\n }\n\n const analysis = analyzeRevalidatingWrite(\n edgeSchemaFor(target, edge.kind),\n edgeProps(current),\n edge.props,\n );\n assertValidRevalidatingWrite(\n analysis,\n `mergeIncremental() found an existing committed edge \"${edge.id}\" (kind \"${edge.kind}\") whose current props do not validate against the active schema.`,\n { id: edge.id, kind: edge.kind },\n );\n if (analysis.stripsCurrentProps && analysis.schemaWouldChange) {\n throw new MergeError(\n `mergeIncremental() would update committed edge \"${edge.id}\" (kind \"${edge.kind}\") but the write would strip existing props outside the active schema.`,\n { details: { id: edge.id, kind: edge.kind } },\n );\n }\n }\n}\n\n/**\n * The reads `commitIncrementalPlan` needs to re-run the NEW-vs-BASE identity\n * resolution INSIDE the commit transaction — the inputs to {@link\n * collectBaseMatchKeys}, plus the set of committed `(kind, id)` keys those base\n * sources matched at PLAN time. Comparing the two closes the identity-resolution\n * TOCTOU window (see {@link assertBaseResolutionStable}).\n */\ntype IncrementalCommitGuard<G extends GraphDef> = Readonly<{\n stagedNewByKind: ReadonlyMap<string, readonly StagedNewNode[]>;\n options: NormalizedMergeOptions<G>;\n introspectionKinds: ReadonlyMap<string, readonly UniqueIntrospection[]>;\n plannedBaseMatchKeys: ReadonlySet<MergeKey>;\n /**\n * `(kind, id) -> version` for every committed target node observed while\n * planning (the target-branch diff enumeration). The commit-time guard\n * re-reads the rows the plan writes OR deletes and refuses if any inherited\n * row's version advanced in the plan→commit window — a concurrent write the\n * stale plan would otherwise overwrite (lost update).\n */\n targetNodeVersions: ReadonlyMap<MergeKey, number>;\n /**\n * `(kind, id) -> content signature` for every committed target edge observed\n * while planning. The edge-half analogue of {@link targetNodeVersions}: edges\n * have no version, so the guard fingerprints their mergeable content\n * (endpoints, liveness, canonical props) and refuses if the fingerprint of an\n * edge the plan upserts OR deletes drifted in the plan→commit window.\n */\n targetEdgeSignatures: ReadonlyMap<MergeKey, string>;\n}>;\n\n/**\n * Re-runs the NEW-vs-BASE identity probes — each kind's unique constraints\n * (`baseUnique`) and its declared block index (`baseKey`) — for the staged new\n * nodes against `lookupStore`, returning the set of committed `(kind, id)` keys\n * those probes surface. It computes the lookup keys from the SAME staged props\n * the planner used (typegraph owns key derivation), so the result over the\n * plan-time target reproduces `candidates.baseMembers`, and the result over the\n * tx-snapshot target reveals any committed row that became a match in between.\n *\n * Probes are issued STRICTLY SEQUENTIALLY (one awaited query at a time): inside\n * the commit transaction these run on the single tx-held client, where\n * concurrent `client.query()` calls queue with a pg deprecation warning that\n * becomes an error in pg@9.\n */\nasync function collectBaseMatchKeys<G extends GraphDef>(\n lookupStore: BaseLookupStore,\n guard: IncrementalCommitGuard<G>,\n): Promise<ReadonlySet<MergeKey>> {\n const matched = new Set<MergeKey>();\n for (const [kind, stagedNodes] of guard.stagedNewByKind) {\n const resolveConfig = guard.options.resolve[kind];\n // A kind with no resolve config has no base recall — it never pulls a\n // committed row into scope, so it carries no identity-resolution TOCTOU.\n if (resolveConfig === undefined) {\n continue;\n }\n const collection = lookupStore.nodes[kind];\n if (collection === undefined || stagedNodes.length === 0) {\n continue;\n }\n const items = stagedNodes.map((staged) => ({ props: staged.node.props }));\n\n for (const constraint of uniqueConstraintsFor(\n guard.introspectionKinds,\n kind,\n )) {\n const matches = await collection.bulkFindByConstraint(\n constraint.name,\n items,\n );\n for (const base of matches) {\n if (base !== undefined) {\n matched.add(mergeKeyOf(base));\n }\n }\n }\n\n if (resolveConfig.blockIndex !== undefined) {\n const matchesByItem = await collection.bulkFindByIndex(\n resolveConfig.blockIndex,\n items,\n );\n for (const perItem of matchesByItem) {\n for (const base of perItem) {\n matched.add(mergeKeyOf(base));\n }\n }\n }\n }\n return matched;\n}\n\n/**\n * The identity-resolution half of the incremental TOCTOU guard. The planner\n * resolves each branch addition against the target's committed rows from reads\n * taken OUTSIDE this transaction (`baseUnique`/`baseKey` in candidate\n * generation). A committed row sharing a branch addition's unique-constraint or\n * block-index key that LANDS in the plan→commit window is invisible to the\n * per-row write guards — they only re-fetch the plan's own write ids — so the\n * stale plan would commit the addition under its own id, leaving a duplicate the\n * base-source resolution would otherwise have collapsed. A unique-constraint\n * collision is still caught at write time by the uniques side-table, but only as\n * a late, opaque failure mid-apply; a non-unique BLOCK-INDEX collision has no\n * such backstop and commits the duplicate SILENTLY. This guard refuses both\n * early and typed, before any row is touched.\n *\n * Re-deriving the matched base keys through the TX-scoped store and comparing\n * them to the plan-time set proves no new identity match appeared. SERIALIZABLE\n * isolation makes the proof race-free on multi-writer Postgres: a concurrent\n * insert that this read would have to see aborts one side with a retryable\n * serialization failure; the retry re-runs this probe and fails typed.\n */\nasync function assertBaseResolutionStable<G extends GraphDef>(\n lookupStore: BaseLookupStore,\n guard: IncrementalCommitGuard<G>,\n): Promise<void> {\n const liveKeys = await collectBaseMatchKeys(lookupStore, guard);\n const appeared = [...liveKeys]\n .filter((key) => !guard.plannedBaseMatchKeys.has(key))\n .sort((left, right) => compareMergeKeys(left, right));\n if (appeared.length === 0) {\n return;\n }\n throw new BaseVersionMismatchError(\n `mergeIncremental() resolved its branch additions against the target as of planning, but ${appeared.length} committed row(s) matching a branch addition's identity key (a unique constraint or block index) were inserted before the commit transaction. Committing the plan would create duplicate entities the base-source resolution would otherwise have collapsed.`,\n {\n details: { appeared },\n suggestion:\n \"Re-run mergeIncremental(); the re-planned merge resolves the branch additions against the now-committed rows.\",\n },\n );\n}\n\n/** A `(kind, id)` the plan will mutate whose identity was an observed target row. */\ntype InheritedTargetRef = Readonly<{ kind: string; id: string }>;\n\n/** Anything keyed by {@link MergeKey} that can answer a membership check. */\ntype MergeKeyMembership = Readonly<{ has(key: MergeKey): boolean }>;\n\n/**\n * Buckets the plan's inherited-target mutations by kind, deduped by identity, for\n * a single batched re-read per kind. `identities` filters to the rows observed at\n * plan time (new rows the plan creates have no baseline and are skipped). Both a\n * write and a delete of the same identity collapse to one entry — either way the\n * row is re-checked once.\n */\nfunction bucketInheritedRefsByKind(\n refs: Iterable<InheritedTargetRef>,\n identities: MergeKeyMembership,\n): ReadonlyMap<string, readonly string[]> {\n const seen = new Set<MergeKey>();\n const idsByKind = new Map<string, string[]>();\n for (const ref of refs) {\n const identity = mergeKey(ref.kind, ref.id);\n if (!identities.has(identity) || seen.has(identity)) {\n continue;\n }\n seen.add(identity);\n const bucket = idsByKind.get(ref.kind) ?? [];\n bucket.push(ref.id);\n idsByKind.set(ref.kind, bucket);\n }\n return idsByKind;\n}\n\n/**\n * The version-check (nodes) and signature-check (edges) halves of the\n * incremental TOCTOU guard share one skeleton — bucket refs by kind, batch-fetch\n * the current rows, compare each against its plan-time baseline, and throw on\n * the first mismatch. `Row` is the fetched row shape and `Expected` the\n * comparable baseline value (a node version or an edge content signature).\n */\nasync function assertInheritedUnchanged<Row, Expected>(\n args: Readonly<{\n refs: readonly InheritedTargetRef[];\n expected: ReadonlyMap<MergeKey, Expected>;\n fetchRows: (\n kind: string,\n ids: readonly string[],\n ) => Promise<readonly (Row | undefined)[]>;\n deriveValue: (row: Row | undefined) => Expected | undefined;\n buildError: (\n id: string,\n kind: string,\n expected: Expected,\n current: Expected | undefined,\n ) => Error;\n }>,\n): Promise<void> {\n if (args.expected.size === 0) {\n return;\n }\n const idsByKind = bucketInheritedRefsByKind(args.refs, args.expected);\n for (const [kind, ids] of idsByKind) {\n const rows = await args.fetchRows(kind, ids);\n for (const [index, id] of ids.entries()) {\n const expected = args.expected.get(mergeKey(kind, id))!;\n const current = args.deriveValue(rows[index]);\n if (current === expected) {\n continue;\n }\n throw args.buildError(id, kind, expected, current);\n }\n }\n}\n\n/**\n * The inherited-target-row half of the incremental TOCTOU guard. The plan folds\n * the live target in as a preferred branch and resolves inherited modifications\n * against the target rows it enumerated OUTSIDE this transaction. If a committed\n * row the plan mutates was changed in the plan→commit window, applying the plan\n * would discard that write (a silent lost update) — the per-row write guards only\n * check resurrection / lossy strips, not that the row still holds the value the\n * plan merged from.\n *\n * Covers every path that mutates a committed target row: node writes and node\n * deletions (checked by `version`), and edge upserts and edge deletions (checked\n * by content signature, since edges carry no version). For each, it re-reads the\n * committed row through the tx snapshot and refuses if it drifted (or vanished).\n * SERIALIZABLE + retry then re-plans against the now-committed value, exactly as\n * the snapshot path's {@link assertTargetUnchanged} does for full-graph drift.\n */\nasync function assertInheritedTargetUnchanged<G extends GraphDef>(\n nodesApi: TxNodes,\n edgesApi: TxEdges,\n guard: IncrementalCommitGuard<G>,\n plan: MergePlan<G>,\n): Promise<void> {\n // Disjoint collections (nodes vs. edges) with no shared state — safe to run\n // concurrently.\n await Promise.all([\n assertInheritedNodesUnchanged(nodesApi, guard, plan),\n assertInheritedEdgesUnchanged(edgesApi, guard, plan),\n ]);\n}\n\n/** Version-checks every committed target node the plan writes or deletes. */\nasync function assertInheritedNodesUnchanged<G extends GraphDef>(\n nodesApi: TxNodes,\n guard: IncrementalCommitGuard<G>,\n plan: MergePlan<G>,\n): Promise<void> {\n const nodeRefs: InheritedTargetRef[] = plannedNodeWrites(plan).map(\n (write) => ({ kind: write.kind, id: write.id }),\n );\n for (const [identity, kind] of plan.nodeDeletions) {\n nodeRefs.push({ kind, id: idOf(identity) });\n }\n await assertInheritedUnchanged<Node, number>({\n refs: nodeRefs,\n expected: guard.targetNodeVersions,\n fetchRows: (kind, ids) =>\n nodeCollection(nodesApi, kind).getByIds(ids, INCLUDE_TOMBSTONES),\n deriveValue: (row) => row?.meta.version,\n buildError: (id, kind, expected, current) =>\n new BaseVersionMismatchError(\n `mergeIncremental() observed committed node \"${id}\" (kind \"${kind}\") at version ${expected} while planning, but it changed before the commit transaction; the resolved plan no longer describes the live target and was not applied.`,\n {\n details: {\n id,\n kind,\n expectedVersion: expected,\n currentVersion: current,\n },\n suggestion:\n \"Re-run mergeIncremental(); the re-planned merge resolves the inherited modifications against the now-committed rows.\",\n },\n ),\n });\n}\n\n/**\n * Signature-checks every committed target edge the plan upserts or deletes. Edges\n * carry no `version`, so the plan-time baseline is a content fingerprint\n * ({@link edgeStateSignature}) captured over the target's edge enumeration; a\n * changed fingerprint means the committed edge's endpoints, liveness, or props\n * drifted in the plan→commit window.\n */\nasync function assertInheritedEdgesUnchanged<G extends GraphDef>(\n edgesApi: TxEdges,\n guard: IncrementalCommitGuard<G>,\n plan: MergePlan<G>,\n): Promise<void> {\n const edgeRefs: InheritedTargetRef[] = plan.mergedEdges.map((edge) => ({\n kind: edge.kind,\n id: edge.id,\n }));\n for (const [identity, kind] of plan.edgeDeletions) {\n edgeRefs.push({ kind, id: idOf(identity) });\n }\n await assertInheritedUnchanged<Edge, string>({\n refs: edgeRefs,\n expected: guard.targetEdgeSignatures,\n fetchRows: (kind, ids) =>\n edgeCollection(edgesApi, kind).getByIds(ids, INCLUDE_TOMBSTONES),\n deriveValue: (row) =>\n row === undefined ? undefined : (\n edgeStateSignature({\n fromKind: row.fromKind,\n fromId: row.fromId,\n toKind: row.toKind,\n toId: row.toId,\n live: row.meta.deletedAt === undefined,\n props: edgeProps(row),\n })\n ),\n buildError: (id, kind) =>\n new BaseVersionMismatchError(\n `mergeIncremental() observed committed edge \"${id}\" (kind \"${kind}\") while planning, but its endpoints, liveness, or props changed before the commit transaction; the resolved plan no longer describes the live target and was not applied.`,\n {\n details: { id, kind },\n suggestion:\n \"Re-run mergeIncremental(); the re-planned merge resolves the inherited modifications against the now-committed rows.\",\n },\n ),\n });\n}\n\n/**\n * The full incremental commit path (§6.6). The planner has already folded the live\n * target in as a preferred synthetic branch, so this path preflights destructive\n * row hazards inside the target transaction and then applies the normal merge plan.\n */\nasync function commitIncrementalPlan<G extends GraphDef>(\n target: Store<G>,\n plan: MergePlan<G>,\n guard: IncrementalCommitGuard<G>,\n): Promise<Readonly<{ nodes: number; edges: number }>> {\n if (!target.backend.capabilities.transactions) {\n throw new MergeError(\n \"mergeIncremental() requires a transaction-capable target backend. Incremental writes must preflight existing rows and commit atomically; non-transactional fallback would allow partial graph writes.\",\n { details: { capability: \"transactions\" } },\n );\n }\n\n // Legacy targets use SERIALIZABLE + retry: the per-row guards read inside\n // this transaction, and SSI turns a conflicting concurrent write into a\n // retryable abort. Recorded-history targets cannot use SERIALIZABLE because\n // capture allocates its clock in read-committed mode; they instead acquire the\n // same graph write lock as every captured write before the guards run. In\n // PostgreSQL read committed each subsequent statement sees committed work that\n // landed before the lock was acquired, while the lock excludes later tracked\n // writes until this plan commits.\n return withTxConflictRetry(() =>\n target.transaction(async (tx) => {\n if (target.revisionTrackingEnabled) {\n await lockRecordedGraphWrite(tx.backend, target.graphId);\n }\n const nodesApi = tx.nodes as unknown as TxNodes;\n const edgesApi = tx.edges as unknown as TxEdges;\n // Identity-resolution TOCTOU guard: the base-source lookups ran OUTSIDE\n // this transaction, so re-derive them here (tx snapshot) and refuse the\n // plan if a matching committed row appeared in the window. `tx` exposes\n // the same `.nodes` collection record a `BaseLookupStore` needs.\n await assertBaseResolutionStable(tx as unknown as BaseLookupStore, guard);\n // Inherited-row TOCTOU guard: refuse if a committed node OR edge the plan\n // writes or deletes changed since it was observed at plan time (lost update).\n await assertInheritedTargetUnchanged(nodesApi, edgesApi, guard, plan);\n await validateIncrementalNodeWrites(target, nodesApi, plan);\n await validateIncrementalEdgeWrites(target, edgesApi, plan);\n return applyMergePlan(plan, nodesApi, edgesApi);\n }, mergeCommitTransactionOptions(target)),\n );\n}\n\n/**\n * Incremental merge — the public fork-point-vs-live-target entry point (design\n * §6.4-B / §6.6). It treats `forkPoint` as the immutable ancestor, folds the live\n * `target` in as a preferred committed branch, resolves branch additions against\n * committed rows, and propagates inherited node/edge modifications and deletions\n * through the same three-way merge planner.\n *\n * Object-form args so the two same-typed stores (`forkPoint`, `target`) cannot be\n * swapped. `options.target` is ignored — `target` is the explicit arg.\n *\n * Preconditions (typed errors): every branch forked from `forkPoint`\n * (`branch.base === computeBaseVersion(forkPoint)`); `forkPoint` and `target` share a\n * schema hash (schema drift is fatal; target CONTENT may have advanced); and\n * `onBasePropertyConflict` is `\"flag\"` (keep-base for committed-row conflicts).\n */\nexport async function mergeIncremental<G extends GraphDef>(\n args: MergeIncrementalArguments<G>,\n): Promise<Result<MergeReport<G>, MergeError>> {\n const { forkPoint, target, branches } = args;\n\n const normalized = tryNormalize(args.options ?? {});\n if (isErr(normalized)) {\n return err(normalized.error);\n }\n const options = normalized.data;\n\n // Keep-base pin: committed rows remain authoritative under unresolved base\n // conflicts. A non-keep-base policy would let a stale branch value overwrite a\n // newer committed value.\n if (options.onBasePropertyConflict !== \"flag\") {\n return err(\n new MergeError(\n 'mergeIncremental() requires onBasePropertyConflict: \"flag\" (keep-base); a non-keep-base policy could overwrite a newer committed base value with a stale branch value.',\n { details: {} },\n ),\n );\n }\n\n // Every branch must have forked from THIS fork-point (honest diff).\n const forkPrecondition = await validateForkPointVersions(forkPoint, branches);\n if (isErr(forkPrecondition)) {\n return err(forkPrecondition.error);\n }\n const forkVersion = forkPrecondition.data;\n\n // Schema half of base@V stays a hard precondition; target CONTENT may advance.\n const [forkSchema, targetSchema] = await Promise.all([\n computeSchemaComponent(forkPoint),\n computeSchemaComponent(target),\n ]);\n if (forkSchema !== targetSchema) {\n return err(\n new MergeError(\n \"mergeIncremental() requires target and forkPoint to share a schema; schema drift is not supported (the target content may differ — only the schema must match).\",\n { details: {} },\n ),\n );\n }\n\n const targetBranch: GraphBranch<G> = {\n id: COMMITTED_TARGET_BRANCH,\n base: forkVersion,\n store: target,\n };\n return resolveMerge(\n forkPoint,\n target,\n [targetBranch, ...branches],\n options,\n true,\n { targetBranchId: COMMITTED_TARGET_BRANCH },\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/graph-merge/canonical-props.ts","../../src/graph-merge/node-key.ts","../../src/graph-merge/state-diff.ts","../../src/graph-merge/types.ts","../../src/graph-merge/base-version.ts","../../src/graph-merge/errors.ts","../../src/graph-merge/working-copy.ts","../../src/graph-merge/branch.ts","../../src/graph-merge/blocking.ts","../../src/graph-merge/conflict-policy.ts","../../src/graph-merge/canonicalize.ts","../../src/graph-merge/union-find.ts","../../src/graph-merge/closures.ts","../../src/graph-merge/similarity.ts","../../src/graph-merge/scoring.ts","../../src/graph-merge/clustering.ts","../../src/graph-merge/delete-modify.ts","../../src/graph-merge/edge-repoint.ts","../../src/graph-merge/options.ts","../../src/graph-merge/provenance-store.ts","../../src/graph-merge/sources.ts","../../src/graph-merge/staging.ts","../../src/graph-merge/tx-retry.ts","../../src/graph-merge/type-reconcile.ts","../../src/graph-merge/merge.ts"],"names":["sortedReplacer","requireDefined","compareStrings","getNodeKinds","getEdgeKinds","storeBackend","computeSchemaHash","serializeSchema","sha256Hex","schemaComponent","TypeGraphError","createStoreWithSchema","importGraphStream","exportGraphStream","generateId","ok","err","computeUniqueKey","dedupeKey","value","computeTransitiveClosure","isReachable","isErr","byId","z","defineNode","defineGraph","branch","repoint","transactionBackend","lockRecordedGraphWrite","readRevisionOrigin","readRecordedClock","nodeProps"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * The single canonical property serializer for the merge primitive.\n *\n * Hoisted to T2 (rather than living next to the clustering code) because three\n * separate phases must agree byte-for-byte on the serialized form of a property\n * bag:\n *\n * - state-diff (T3) — to detect whether an inherited node's props changed,\n * - clustering / property union (T8) — to compare member values,\n * - edge repoint + dedupe (T9) — to key the `(from|type|to|propsKey)` tuple.\n *\n * {@link canonicalValueKey} is the SINGLE-VALUE sibling: the same recursive\n * key-sort over an arbitrary {@link JsonValue} (scalar / array / object), so the\n * conflict-resolution layer (T8 / `conflict-policy.ts`) decides value equality and\n * tie-breaks on the canonical form too — two branches that wrote a logically-equal\n * nested object with different key order must NOT register as a conflict.\n *\n * Determinism rules:\n * - Object keys are sorted lexicographically at every nesting level, so two\n * objects that differ only by key insertion order serialize identically.\n * - Arrays preserve order (order is semantically meaningful in a list).\n * - `undefined` keys are dropped (JSON has no `undefined`; an absent key and a\n * key set to `undefined` are treated as the same absence).\n * - All other JSON-representable values serialize via their natural form.\n *\n * IMPORTANT contract for callers: the input MUST be a PARSED plain object, never\n * a JSON string. Backend rows store `props` as a JSON string; callers MUST\n * `JSON.parse` first. Passing a string would serialize the string literal (with\n * its own incidental key order) rather than the canonical structure, so the\n * `propsKey` would NOT be stable across staged-vs-committed representations.\n */\n\nimport type { JsonValue } from \"./typegraph-internal\";\nimport { sortedReplacer } from \"./typegraph-internal\";\n\n/**\n * Produces a deterministic, recursively key-sorted JSON serialization of a\n * parsed property object.\n *\n * Delegates to the schema layer's {@link sortedReplacer} — the single canonical\n * JSON serializer in the codebase (also used by `computeSchemaHash` /\n * `computeSchemaDiff`) — so the merge primitive and the schema layer can never\n * drift on what \"canonical form\" means. The replacer sorts object keys at every\n * depth while preserving array order; `JSON.stringify` omits `undefined`-valued\n * keys, matching the \"an absent key and a key set to `undefined` are the same\n * absence\" rule in the module docs.\n *\n * @param props A PARSED plain object (NOT a JSON string). See module docs.\n * @returns A canonical JSON string suitable for equality comparison / dedupe\n * keying. Equivalent objects (key order aside) yield identical strings;\n * objects differing in any value yield differing strings.\n */\nexport function canonicalizeProps(\n props: Readonly<Record<string, unknown>>,\n): string {\n return JSON.stringify(props, sortedReplacer);\n}\n\n/**\n * Produces a deterministic, recursively key-sorted JSON serialization of a single\n * {@link JsonValue} — the per-value analogue of {@link canonicalizeProps}.\n *\n * Used by the conflict layer to compare candidate values, dedupe them, and\n * tie-break, so a nested object's incidental key order can never make two\n * logically-equal values look different (which would surface a spurious conflict).\n *\n * @param value Any parsed JSON value (scalar, array, or object). Not a JSON string.\n * @returns A canonical JSON string suitable for equality / dedupe / ordering.\n */\nexport function canonicalValueKey(value: JsonValue): string {\n return JSON.stringify(value, sortedReplacer);\n}\n\n/**\n * A stable fingerprint of a committed edge's mergeable state — its endpoints,\n * liveness, and canonical props. The incremental lost-update guard captures this\n * for every target edge at plan time and re-derives it inside the commit\n * transaction; a mismatch means the committed edge drifted in the plan→commit\n * window, so applying the plan (built from the plan-time value) would silently\n * overwrite that change. Edges carry no `version` column, so this content\n * fingerprint is the node-`version` analogue for the edge half of the guard.\n *\n * @param edge Endpoints, liveness, and PARSED props (never a JSON string).\n * @returns A canonical string; equal iff the two edge states are mergeably equal.\n */\nexport function edgeStateSignature(\n edge: Readonly<{\n fromKind: string;\n fromId: string;\n toKind: string;\n toId: string;\n live: boolean;\n props: Readonly<Record<string, unknown>>;\n }>,\n): string {\n return JSON.stringify([\n edge.fromKind,\n edge.fromId,\n edge.toKind,\n edge.toId,\n edge.live,\n canonicalizeProps(edge.props),\n ]);\n}\n\n/**\n * Normalizes a stored row's `props` — a JSON string on SQLite, an\n * already-parsed object on Postgres (jsonb rows arrive driver-parsed) — into\n * the plain object that {@link canonicalizeProps} requires. Malformed JSON, a\n * non-object, or an array all collapse to `{}` — a parse error never escapes.\n * Backend-written rows hold valid JSON, but an external / legacy / truncated\n * `props` value must not crash a state diff or a base-version fingerprint.\n * Centralized so the diff and the fingerprint can never disagree on what a\n * malformed row parses to.\n */\nexport function parseRowProps(\n props: string | Readonly<Record<string, unknown>>,\n): Readonly<Record<string, unknown>> {\n let parsed: unknown;\n if (typeof props === \"string\") {\n try {\n parsed = JSON.parse(props);\n } catch {\n return {};\n }\n } else {\n parsed = props;\n }\n if (parsed === null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n return {};\n }\n return parsed as Record<string, unknown>;\n}\n","/**\n * The composite MERGE IDENTITY key for a node: the pair `(kind, id)`.\n *\n * TypeGraph node identity is the PAIR `(kind, id)` — a bare id string is NOT unique\n * on its own (a `Patient` and an `Encounter` may both carry the id \"x\" as two\n * DISTINCT committed nodes; ids are caller-supplied). Every place the merge pipeline\n * groups, clusters, de-dupes, repoints, retypes, or deletes BY NODE IDENTITY must\n * key on this pair — never the bare id — or two different-kind nodes that happen to\n * share an id string silently fuse into one cluster (wrong merge, dropped node,\n * incoherent commit) and the §6.4-A base guard is bypassed.\n *\n * Represented as a NUL-joined string (a branded {@link MergeKey}) so it doubles as a\n * `Map`/`Set` key and a deterministic ordering key. `kind` is a schema identifier\n * (NUL-free), so the FIRST NUL unambiguously delimits kind from id even when a\n * caller-supplied id itself contains a NUL byte. This matches the `(kind, id)`\n * separator the commit-time write guard already uses.\n *\n * {@link compareMergeKeys} orders by the bare id FIRST (kind only breaks a same-id\n * tie), so the merge's \"minimum-id survivor\" / id-sorted-members semantics are\n * preserved unchanged for the common single-kind cluster — the composite key changes\n * WHICH nodes share an identity, never the ordering among genuinely distinct ids.\n */\n\nimport type { NodeId, NodeType } from \"./typegraph-internal\";\n\n/** The `(kind, id)` separator: a NUL byte (0x00), absent from schema kind names. */\nconst SEPARATOR = String.fromCharCode(0);\n\n/** A node id in its untyped (`NodeType`-default) branded form. */\ntype AnyNodeId = NodeId<NodeType>;\n\n/**\n * A composite `(kind, id)` node-identity key. Branded so it cannot be confused with\n * a bare {@link NodeId} at the type level — the whole point is that the two are NOT\n * interchangeable as identities.\n */\nexport type MergeKey = string & { readonly __mergeKey: unique symbol };\n\n/** Builds the composite identity key for a `(kind, id)` pair. */\nexport function mergeKey(kind: string, id: string): MergeKey {\n // `kindOf`/`idOf` split on the FIRST NUL, so a NUL in `kind` would alias distinct\n // identities (`mergeKey(\"a\\0b\",\"c\") === mergeKey(\"a\",\"b\\0c\")`), silently fusing\n // unrelated nodes into one cluster and bypassing the §6.4-A base guard this composite\n // key exists to protect. Kinds are NUL-free schema identifiers; fail loud if not.\n if (kind.includes(SEPARATOR)) {\n throw new Error(\n `Node kind ${JSON.stringify(kind)} contains a NUL byte, which collides the (kind, id) merge-identity separator.`,\n );\n }\n return `${kind}${SEPARATOR}${id}` as MergeKey;\n}\n\n/** Builds the composite identity key for any object carrying a `kind` and `id`. */\nexport function mergeKeyOf(\n node: Readonly<{ kind: string; id: string }>,\n): MergeKey {\n return mergeKey(node.kind, node.id);\n}\n\n/** The kind component of a {@link MergeKey}. */\nexport function kindOf(key: MergeKey): string {\n const separator = key.indexOf(SEPARATOR);\n return separator === -1 ? key : key.slice(0, separator);\n}\n\n/** The bare node id component of a {@link MergeKey}. */\nexport function idOf(key: MergeKey): AnyNodeId {\n const separator = key.indexOf(SEPARATOR);\n return (separator === -1 ? key : key.slice(separator + 1)) as AnyNodeId;\n}\n\n/**\n * Deterministic comparator over two merge keys, BARE ID first and kind only as a\n * same-id tie-break. This keeps the merge's minimum-id survivor selection and\n * id-sorted member order identical to the pre-composite behaviour for any pair of\n * genuinely distinct ids (the overwhelmingly common case), so the re-key changes\n * identity grouping without perturbing deterministic ordering.\n */\nexport function compareMergeKeys(left: MergeKey, right: MergeKey): number {\n const leftId = idOf(left);\n const rightId = idOf(right);\n if (leftId !== rightId) {\n return leftId < rightId ? -1 : 1;\n }\n const leftKind = kindOf(left);\n const rightKind = kindOf(right);\n return (\n leftKind < rightKind ? -1\n : leftKind > rightKind ? 1\n : 0\n );\n}\n\nexport { compareStrings } from \"../utils/compare\";\n","import { requireDefined } from \"../utils/presence\";\n/**\n * State-diff engine: compute the per-fork delta (new / modified / deleted nodes\n * and edges) of a working copy against the IMMUTABLE original base store.\n *\n * Why backend-level enumeration (not `Store.find()`): the collection API\n * silently hides soft-deleted rows, so a node deleted in a fork would be\n * invisible and the diff could never report a deletion. We therefore go through\n * the backend with `excludeDeleted: false` and read the raw `NodeRow`/`EdgeRow`.\n *\n * Row representation contract (verified against `NodeRow`/`EdgeRow`):\n * - `props` is a JSON string (SQLite) or a driver-parsed object (Postgres\n * jsonb) — every comparison routes it through `parseRowProps` before\n * `canonicalizeProps`, never feeding a raw string to the serializer (that\n * would key on incidental string-literal order, not canonical structure).\n * - `deleted_at` is a field, `undefined` for live rows. Liveness is\n * `row.deleted_at === undefined`.\n *\n * Enumeration ordering: both nodes AND edges use KEYSET pagination\n * (`orderBy: \"id\"` + `after` cursor) over the unique `id`, a TOTAL order, so\n * paging can neither skip nor duplicate a row even when many rows share a\n * `created_at`. (Edges previously had only offset paging over the non-unique\n * `created_at`, which could skip a boundary row under a reordering query plan.)\n *\n * Concurrency: P0 assumes quiesced (non-concurrent) forks per design §10.\n * Concurrent-write enumeration is a P1 concern.\n */\nimport {\n canonicalizeProps,\n edgeStateSignature,\n parseRowProps,\n} from \"./canonical-props\";\nimport { compareStrings, type MergeKey, mergeKey } from \"./node-key\";\nimport type {\n EdgeId,\n GraphBackend,\n GraphDef,\n NodeId,\n NodeType,\n Store,\n TransactionBackend,\n} from \"./typegraph-internal\";\nimport { getEdgeKinds, getNodeKinds } from \"./typegraph-internal\";\nimport { storeBackend } from \"./typegraph-internal\";\n\n/**\n * Local structural mirror of TypeGraph's internal `NodeRow`. 0.29.0 does NOT\n * re-export `NodeRow`/`EdgeRow` from any public entrypoint, but `GraphBackend`\n * (public) returns rows of exactly this shape from `findNodesByKind`, so the\n * runtime values are structurally assignable. Keep this local mirror until using\n * the backend row type directly buys enough clarity to justify the coupling.\n */\nexport type NodeRow = Readonly<{\n graph_id: string;\n kind: string;\n id: string;\n props: string | Readonly<Record<string, unknown>>;\n version: number;\n valid_from: string | undefined;\n valid_to: string | undefined;\n created_at: string;\n updated_at: string;\n deleted_at: string | undefined;\n}>;\n\n/** Local structural mirror of TypeGraph's internal `EdgeRow`. See {@link NodeRow}. */\nexport type EdgeRow = Readonly<{\n graph_id: string;\n id: string;\n kind: string;\n from_kind: string;\n from_id: string;\n to_kind: string;\n to_id: string;\n props: string | Readonly<Record<string, unknown>>;\n valid_from: string | undefined;\n valid_to: string | undefined;\n created_at: string;\n updated_at: string;\n deleted_at: string | undefined;\n}>;\n\n/**\n * Page size for keyset/offset enumeration. Large enough to keep round-trips low\n * on demo-scale graphs; the algorithm is correct for any positive value.\n */\nconst ENUMERATION_PAGE_SIZE = 1000;\n\n/**\n * A node that exists in both base and fork but whose canonicalized props differ.\n * Carries the parsed fork props so downstream phases (staging, conflict) avoid\n * re-parsing.\n */\nexport type ModifiedNode = Readonly<{\n id: NodeId<NodeType>;\n kind: string;\n baseProps: Readonly<Record<string, unknown>>;\n forkProps: Readonly<Record<string, unknown>>;\n row: NodeRow;\n}>;\n\n/** A node present and live only on one side of the diff. */\nexport type ChangedNode = Readonly<{\n id: NodeId<NodeType>;\n kind: string;\n props: Readonly<Record<string, unknown>>;\n row: NodeRow;\n}>;\n\n/** Identifier of a node that the fork removed (live in base, gone in fork). */\nexport type DeletedNode = Readonly<{\n id: NodeId<NodeType>;\n kind: string;\n}>;\n\n/** An edge present and live only on one side of the diff. */\nexport type ChangedEdge = Readonly<{\n id: EdgeId;\n kind: string;\n fromId: NodeId<NodeType>;\n toId: NodeId<NodeType>;\n fromKind: string;\n toKind: string;\n props: Readonly<Record<string, unknown>>;\n row: EdgeRow;\n}>;\n\n/** An edge present in both base and fork but whose canonicalized props differ. */\nexport type ModifiedEdge = Readonly<{\n id: EdgeId;\n kind: string;\n fromId: NodeId<NodeType>;\n toId: NodeId<NodeType>;\n fromKind: string;\n toKind: string;\n baseProps: Readonly<Record<string, unknown>>;\n forkProps: Readonly<Record<string, unknown>>;\n row: EdgeRow;\n}>;\n\n/** Identifier of an edge the fork removed (live in base, gone in fork). */\nexport type DeletedEdge = Readonly<{\n id: EdgeId;\n kind: string;\n}>;\n\n/**\n * The complete delta of a fork against the original base store.\n */\nexport type StateDiff = Readonly<{\n nodes: Readonly<{\n new: readonly ChangedNode[];\n modified: readonly ModifiedNode[];\n deleted: readonly DeletedNode[];\n }>;\n edges: Readonly<{\n new: readonly ChangedEdge[];\n modified: readonly ModifiedEdge[];\n deleted: readonly DeletedEdge[];\n }>;\n /**\n * `(kind, id) -> version` for every fork-store node observed during this diff\n * (live and soft-deleted). Captured from the same enumeration the diff reads,\n * so it is the fork's exact observed state — the incremental merge uses the\n * target branch's map as the plan-time baseline for its commit-time\n * lost-update guard (see assertInheritedTargetUnchanged in merge.ts).\n */\n forkNodeVersions: ReadonlyMap<MergeKey, number>;\n /**\n * `(kind, id) -> {@link edgeStateSignature}` for every fork-store edge observed\n * during this diff (live and soft-deleted). The edge-half analogue of\n * {@link forkNodeVersions}: edges carry no `version` column, so the guard\n * fingerprints their mergeable content (endpoints, liveness, canonical props)\n * instead. The incremental merge uses the target branch's map as the plan-time\n * baseline for the commit-time lost-update guard.\n */\n forkEdgeSignatures: ReadonlyMap<MergeKey, string>;\n}>;\n\n/**\n * Enumerates EVERY node of `kind` for `graphId` (live and soft-deleted) via\n * keyset pagination on `id`. Returns rows ascending in the BACKEND's own id\n * ordering — byte order on SQLite/PGlite, the database collation on server\n * Postgres. That order is deterministic and pagination-consistent (the cursor\n * comparison uses the same collation as ORDER BY), but it is NOT guaranteed to\n * equal JS code-unit order for mixed-case ids; consumers needing a canonical\n * cross-backend order sort in JS (as `stateDiff` and the base@V fingerprint\n * do).\n */\nexport async function enumerateAllNodes(\n backend: GraphBackend | TransactionBackend,\n graphId: string,\n kind: string,\n): Promise<readonly NodeRow[]> {\n const collected: NodeRow[] = [];\n let after: string | undefined;\n for (;;) {\n const page: readonly NodeRow[] = await backend.findNodesByKind({\n graphId,\n kind,\n excludeDeleted: false,\n orderBy: \"id\",\n limit: ENUMERATION_PAGE_SIZE,\n ...(after === undefined ? {} : { after }),\n });\n for (const row of page) {\n collected.push(row);\n }\n if (page.length < ENUMERATION_PAGE_SIZE) {\n break;\n }\n after = requireDefined(page.at(-1)).id;\n }\n return collected;\n}\n\n/**\n * Enumerates EVERY edge of `kind` for `graphId` (live and soft-deleted) via\n * keyset pagination on the unique `id` (a TOTAL order), so paging can neither\n * skip nor duplicate a row regardless of how many edges share a `created_at`.\n * Returns rows ascending in the backend's own id ordering (see\n * {@link enumerateAllNodes} for the collation caveat). Mirrors\n * {@link enumerateAllNodes}.\n */\nexport async function enumerateAllEdges(\n backend: GraphBackend | TransactionBackend,\n graphId: string,\n kind: string,\n): Promise<readonly EdgeRow[]> {\n const collected: EdgeRow[] = [];\n let after: string | undefined;\n for (;;) {\n const page: readonly EdgeRow[] = await backend.findEdgesByKind({\n graphId,\n kind,\n excludeDeleted: false,\n orderBy: \"id\",\n limit: ENUMERATION_PAGE_SIZE,\n ...(after === undefined ? {} : { after }),\n });\n for (const row of page) {\n collected.push(row);\n }\n if (page.length < ENUMERATION_PAGE_SIZE) {\n break;\n }\n after = requireDefined(page.at(-1)).id;\n }\n return collected;\n}\n\n/** True when the row is live (not soft-deleted). */\nfunction isLive(row: Readonly<{ deleted_at: string | undefined }>): boolean {\n return row.deleted_at === undefined;\n}\n\n/** Indexes rows by id for O(1) base-vs-fork lookup. */\nfunction indexById<T extends Readonly<{ id: string }>>(\n rows: readonly T[],\n): ReadonlyMap<string, T> {\n const index = new Map<string, T>();\n for (const row of rows) {\n index.set(row.id, row);\n }\n return index;\n}\n\n/**\n * Diffs the node sets of one kind. `new` = absent-in-base, live-in-fork;\n * `deleted` = live-in-base, absent-or-soft-deleted-in-fork; `modified` =\n * live in both with differing canonicalized props.\n */\nfunction diffNodeKind(\n kind: string,\n baseRows: readonly NodeRow[],\n forkRows: readonly NodeRow[],\n): Readonly<{\n new: ChangedNode[];\n modified: ModifiedNode[];\n deleted: DeletedNode[];\n}> {\n const baseIndex = indexById(baseRows);\n const forkIndex = indexById(forkRows);\n\n const created: ChangedNode[] = [];\n const modified: ModifiedNode[] = [];\n const deleted: DeletedNode[] = [];\n\n for (const forkRow of forkRows) {\n if (!isLive(forkRow)) {\n continue;\n }\n const baseRow = baseIndex.get(forkRow.id);\n const forkProps = parseRowProps(forkRow.props);\n if (baseRow === undefined || !isLive(baseRow)) {\n created.push({\n id: forkRow.id as NodeId<NodeType>,\n kind,\n props: forkProps,\n row: forkRow,\n });\n continue;\n }\n const baseProps = parseRowProps(baseRow.props);\n if (canonicalizeProps(baseProps) !== canonicalizeProps(forkProps)) {\n modified.push({\n id: forkRow.id as NodeId<NodeType>,\n kind,\n baseProps,\n forkProps,\n row: forkRow,\n });\n }\n }\n\n for (const baseRow of baseRows) {\n if (!isLive(baseRow)) {\n continue;\n }\n const forkRow = forkIndex.get(baseRow.id);\n if (forkRow === undefined || !isLive(forkRow)) {\n deleted.push({ id: baseRow.id as NodeId<NodeType>, kind });\n }\n }\n\n return { new: created, modified, deleted };\n}\n\n/**\n * Diffs the edge sets of one kind. Same liveness/modification rules as nodes,\n * carrying endpoint ids/kinds for the downstream repoint phase.\n */\nfunction diffEdgeKind(\n kind: string,\n baseRows: readonly EdgeRow[],\n forkRows: readonly EdgeRow[],\n): Readonly<{\n new: ChangedEdge[];\n modified: ModifiedEdge[];\n deleted: DeletedEdge[];\n}> {\n const baseIndex = indexById(baseRows);\n const forkIndex = indexById(forkRows);\n\n const created: ChangedEdge[] = [];\n const modified: ModifiedEdge[] = [];\n const deleted: DeletedEdge[] = [];\n\n for (const forkRow of forkRows) {\n if (!isLive(forkRow)) {\n continue;\n }\n const baseRow = baseIndex.get(forkRow.id);\n const forkProps = parseRowProps(forkRow.props);\n if (baseRow === undefined || !isLive(baseRow)) {\n created.push({\n id: forkRow.id as EdgeId,\n kind,\n fromId: forkRow.from_id as NodeId<NodeType>,\n toId: forkRow.to_id as NodeId<NodeType>,\n fromKind: forkRow.from_kind,\n toKind: forkRow.to_kind,\n props: forkProps,\n row: forkRow,\n });\n continue;\n }\n const baseProps = parseRowProps(baseRow.props);\n if (canonicalizeProps(baseProps) !== canonicalizeProps(forkProps)) {\n modified.push({\n id: forkRow.id as EdgeId,\n kind,\n fromId: forkRow.from_id as NodeId<NodeType>,\n toId: forkRow.to_id as NodeId<NodeType>,\n fromKind: forkRow.from_kind,\n toKind: forkRow.to_kind,\n baseProps,\n forkProps,\n row: forkRow,\n });\n }\n }\n\n for (const baseRow of baseRows) {\n if (!isLive(baseRow)) {\n continue;\n }\n const forkRow = forkIndex.get(baseRow.id);\n if (forkRow === undefined || !isLive(forkRow)) {\n deleted.push({ id: baseRow.id as EdgeId, kind });\n }\n }\n\n return { new: created, modified, deleted };\n}\n\n/** Stable id-ascending comparator over any `{ id: string }`. */\nfunction byId<T extends Readonly<{ id: string }>>(left: T, right: T): number {\n return compareStrings(left.id, right.id);\n}\n\n/**\n * Computes the full {@link StateDiff} of `forkStore` against `baseStore`.\n *\n * Both stores MUST share the same graph definition (the fork is a clone of the\n * base). The diff is keyed by id and sorted by `(kind, id)` so its shape is a\n * pure function of the stores' content, independent of enumeration order. No\n * branch tag is attached here — provenance tagging happens in T7 (staging).\n *\n * @param captureForkState Whether to populate {@link StateDiff.forkNodeVersions}\n * / {@link StateDiff.forkEdgeSignatures}. `stageBranches` only ever keeps these\n * maps for the one branch matching `captureTargetStateFor`, and computing the\n * edge signatures (canonicalizing props + stringifying every edge) is real\n * work — so callers that don't need them for this branch can skip it. Defaults\n * to `true` so direct callers (e.g. tests) get the full diff without having to\n * know this parameter exists.\n */\nexport async function diffAgainstBase<G extends GraphDef>(\n baseStore: Store<G>,\n forkStore: Store<G>,\n captureForkState = true,\n): Promise<StateDiff> {\n const graph = baseStore.graph;\n const nodeKinds = getNodeKinds(graph);\n const edgeKinds = getEdgeKinds(graph);\n\n const newNodes: ChangedNode[] = [];\n const modifiedNodes: ModifiedNode[] = [];\n const deletedNodes: DeletedNode[] = [];\n // Version snapshot of the fork store as observed by THIS diff's enumeration\n // (the same read the plan resolves against), keyed by merge identity.\n const forkNodeVersions = new Map<MergeKey, number>();\n\n for (const kind of nodeKinds) {\n const baseRows = await enumerateAllNodes(\n storeBackend(baseStore),\n baseStore.graphId,\n kind,\n );\n const forkRows = await enumerateAllNodes(\n storeBackend(forkStore),\n forkStore.graphId,\n kind,\n );\n if (captureForkState) {\n for (const row of forkRows) {\n forkNodeVersions.set(mergeKey(kind, row.id), row.version);\n }\n }\n const delta = diffNodeKind(kind, baseRows, forkRows);\n for (const entry of delta.new) {\n newNodes.push(entry);\n }\n for (const entry of delta.modified) {\n modifiedNodes.push(entry);\n }\n for (const entry of delta.deleted) {\n deletedNodes.push(entry);\n }\n }\n\n const newEdges: ChangedEdge[] = [];\n const modifiedEdges: ModifiedEdge[] = [];\n const deletedEdges: DeletedEdge[] = [];\n // Content fingerprint of the fork store's edges as observed by THIS diff's\n // enumeration — the edge-half baseline for the commit-time lost-update guard\n // (edges have no version, so we key on mergeable content instead).\n const forkEdgeSignatures = new Map<MergeKey, string>();\n\n for (const kind of edgeKinds) {\n const baseRows = await enumerateAllEdges(\n storeBackend(baseStore),\n baseStore.graphId,\n kind,\n );\n const forkRows = await enumerateAllEdges(\n storeBackend(forkStore),\n forkStore.graphId,\n kind,\n );\n if (captureForkState) {\n for (const row of forkRows) {\n forkEdgeSignatures.set(\n mergeKey(kind, row.id),\n edgeStateSignature({\n fromKind: row.from_kind,\n fromId: row.from_id,\n toKind: row.to_kind,\n toId: row.to_id,\n live: isLive(row),\n props: parseRowProps(row.props),\n }),\n );\n }\n }\n const delta = diffEdgeKind(kind, baseRows, forkRows);\n for (const entry of delta.new) {\n newEdges.push(entry);\n }\n for (const entry of delta.modified) {\n modifiedEdges.push(entry);\n }\n for (const entry of delta.deleted) {\n deletedEdges.push(entry);\n }\n }\n\n return {\n nodes: {\n new: newNodes.sort((left, right) => byId(left, right)),\n modified: modifiedNodes.sort((left, right) => byId(left, right)),\n deleted: deletedNodes.sort((left, right) => byId(left, right)),\n },\n edges: {\n new: newEdges.sort((left, right) => byId(left, right)),\n modified: modifiedEdges.sort((left, right) => byId(left, right)),\n deleted: deletedEdges.sort((left, right) => byId(left, right)),\n },\n forkNodeVersions,\n forkEdgeSignatures,\n };\n}\n","/**\n * Core type model for the graph-merge primitive.\n *\n * Finalized against TypeGraph's real generic machinery: the design's illustrative\n * `Node<G, K>` / `NodeId<NodeKinds<G>>` collapse onto TypeGraph's public\n * `Node` / `Edge` / `NodeId<NodeType>` / `EdgeId` (which are themselves branded\n * over `NodeType` / `EdgeType`). The merge surface is parameterized over\n * `G extends GraphDef` so `Store<G>` and `GraphBranch<G>` thread the caller's\n * concrete graph definition end-to-end.\n *\n * This module is pure type declarations plus the two branding helpers — no\n * runtime merge logic.\n */\n\nimport type {\n EdgeId,\n GetNodeType,\n GraphDef,\n JsonValue,\n Node,\n NodeId,\n NodeKinds,\n NodeType,\n Store,\n} from \"./typegraph-internal\";\n\n/**\n * Opaque identifier for a branch (working copy) of a base store. Branded so a\n * raw string cannot be passed where a deliberately-minted branch id is required.\n */\nexport type BranchId = string & Readonly<{ readonly __brand: \"BranchId\" }>;\n\n/**\n * Opaque token identifying the immutable `base@V` a branch was forked from.\n * Combines a schema hash with a staleness component. Branded so it cannot be\n * confused with an arbitrary string. The second component is a\n * durable revision anchor for stores with revision tracking enabled and a\n * compatibility content fingerprint otherwise.\n */\nexport type BaseVersion = string &\n Readonly<{ readonly __brand: \"BaseVersion\" }>;\n\n/**\n * Mints a {@link BranchId} from a raw string. Centralizes the brand cast so the\n * unsafe assertion lives in exactly one place.\n */\nexport function asBranchId(value: string): BranchId {\n return value as BranchId;\n}\n\n/**\n * Mints a {@link BaseVersion} from a raw string. Centralizes the brand cast so\n * the unsafe assertion lives in exactly one place.\n */\nexport function asBaseVersion(value: string): BaseVersion {\n return value as BaseVersion;\n}\n\n/**\n * A working-copy handle for one branch: its id, the `base@V` it forked from, and\n * a {@link Store} over the branch's own backend.\n */\nexport type GraphBranch<G extends GraphDef> = Readonly<{\n id: BranchId;\n base: BaseVersion;\n store: Store<G>;\n}>;\n\n/**\n * Options for {@link GraphBranch} creation. `id` is optional — when omitted a\n * fresh id is generated.\n */\nexport type BranchOptions = Readonly<{\n id?: BranchId;\n}>;\n\n/**\n * Turns text into an embedding vector. Injected via {@link MergeOptions.embedder}\n * and used by the `vector` / `hybrid` similarity strategies to score candidate\n * pairs by cosine IN MEMORY — the staged candidate nodes are unindexed in the\n * working copy, so a backend ANN index cannot score them pairwise (see\n * `scorePair`). Exact in-memory cosine over real model vectors is both the right\n * scale for bounded candidate dedup and deterministic, which the merge contract\n * requires.\n *\n * Batched and async: given N texts it returns N vectors in the SAME order, each a\n * fixed-dimension `Float32Array` (every vector a given embedder returns shares one\n * length — the model's embedding dimension). The function MUST be deterministic —\n * the same text always yields the same vector — because the whole merge is\n * order-independent and reproducible. Vectors need NOT be pre-normalized; cosine\n * scoring normalizes internally.\n *\n * The concrete local model lives in the CONSUMER (the harness ships an\n * all-MiniLM-L6-v2 embedder); this package depends only on the function shape, so\n * it stays model-agnostic and lean inside the TypeGraph core package.\n */\nexport type Embedder = (\n texts: readonly string[],\n) => Promise<readonly Float32Array[]>;\n\n/**\n * Pluggable per-kind similarity strategy (design §8).\n *\n * - `vector` / `hybrid` score candidate pairs by cosine over an injected\n * {@link Embedder} ({@link MergeOptions.embedder}), computed in memory; they\n * fail with `SimilarityUnavailableError` when no embedder is configured.\n * - `fulltext` and `custom` run with ZERO embeddings — the cross-DB-safe\n * default. `fulltext` uses an in-memory Sørensen–Dice trigram scorer (T6).\n *\n * The generic mirrors the design's `SimilarityStrategy<G, K>`: `K` constrains the\n * `custom` score function's node arguments to the resolved kind.\n */\nexport type SimilarityStrategy<\n G extends GraphDef = GraphDef,\n K extends NodeType = NodeType,\n> =\n | Readonly<{\n kind: \"hybrid\";\n fields: readonly string[];\n weights?: Readonly<{ vector?: number; fulltext?: number }>;\n // Phantom binding to the caller's graph, matching the design's\n // `SimilarityStrategy<G, K>` two-parameter shape. Never set at runtime.\n readonly __graph?: G;\n }>\n | Readonly<{ kind: \"vector\"; field: string; readonly __graph?: G }>\n | Readonly<{\n kind: \"fulltext\";\n fields: readonly string[];\n readonly __graph?: G;\n }>\n | Readonly<{\n kind: \"custom\";\n score: (a: Node<K>, b: Node<K>) => number;\n readonly __graph?: G;\n }>;\n\n/**\n * Per-kind entity-resolution configuration.\n */\nexport type ResolveConfig<\n G extends GraphDef = GraphDef,\n K extends NodeType = NodeType,\n> = Readonly<{\n /**\n * Cheap exact-equality blocking key, evaluated before similarity to bound the\n * O(n²) candidate comparisons. Returning `undefined` places the node in the\n * shared `\"unblocked\"` bucket (compared all-vs-all within its kind).\n *\n * STAGED-vs-staged only: it is an arbitrary JS function, so it cannot be queried\n * against the committed base. To recall committed entities by a block key\n * (new-vs-base, the `baseKey` source §6.2), declare the key as a TypeGraph node\n * index and name it via {@link ResolveConfig.blockIndex} instead.\n */\n block?: (node: Node<K>) => string | undefined;\n /**\n * Name of a declared TypeGraph node index (`defineNodeIndex`) whose key is this\n * kind's NEW-vs-BASE block key (design §6.2). When set and the new-vs-base scope is\n * driven, the `baseKey` source issues an indexed `bulkFindByIndex` lookup of\n * committed nodes sharing each staged node's index key and proposes them as scored\n * candidate pairs (a shared block key is a candidate, not a definitional match).\n *\n * The index keys on real fields (a field-set + scope + optional partial-`where`), so\n * only a FIELD-SET block key migrates here; a transform key (`slice`/`soundex`/…)\n * stays on the staged-only {@link block}. Unused on the public snapshot `merge()`\n * path. An undeclared name surfaces a typed error at lookup time.\n */\n blockIndex?: string;\n /**\n * Bounded coarse candidate generation for the NO-KEY case (design §6.2, the\n * `keyless` source). A node whose {@link block} returns `undefined` (and has no\n * unique signature) lands in the shared `\"unblocked\"` bucket, which is otherwise\n * compared ALL-vs-all — an O(n²) cliff that `maxComparisonsPerKind` then truncates\n * to id-only. Set `keyless` to bound that bucket by single-pass SORTED-NEIGHBOURHOOD\n * instead: the unblocked nodes are sorted by their similarity-field text (tie-broken\n * by id) and each is proposed only against its next `window` neighbours — O(n·window),\n * deterministic. Unset preserves today's all-vs-all behaviour. Only the `\"unblocked\"`\n * bucket is affected; keyed `block()` buckets are unchanged.\n */\n keyless?: Readonly<{\n /** Forward-neighbour window: each unblocked node is paired with its next `window`\n * neighbours in the sort. Must be a positive integer. Larger → more recall, more\n * comparisons (→ all-vs-all as `window` ≥ bucket size). */\n window: number;\n }>;\n /** Similarity strategy (design §8). */\n similarity: SimilarityStrategy<G, K>;\n /** Candidate-merge threshold in `[0, 1]`. */\n threshold: number;\n}>;\n\n/**\n * A resolved cluster of node ids that the merge collapses into one canonical\n * survivor.\n */\nexport type ResolvedCluster = Readonly<{\n members: readonly NodeId<NodeType>[];\n}>;\n\n/**\n * Policy for resolving conflicting property values across cluster members.\n *\n * - `\"flag\"` keeps the canonical's value and records a {@link PropertyConflict}\n * without auto-resolving.\n * - `\"lastWriteWins\"` picks by the stable branch/logical total order — NEVER\n * wall-clock arrival.\n * - `\"provenanceWeighted\"` picks by per-branch trust weight.\n * - A function delegates the decision, returning the surviving {@link JsonValue}.\n */\nexport type PropertyConflictPolicy<G extends GraphDef = GraphDef> =\n | \"flag\"\n | \"lastWriteWins\"\n | \"provenanceWeighted\"\n | ((conflict: PropertyConflict<G>) => JsonValue);\n\n/**\n * Policy for resolving an inherited node that is deleted by one branch and\n * modified by another (design §6.2).\n *\n * - `\"deleteWins\"` — the node is finally DELETED; the modification is discarded.\n * - `\"modifyWins\"` — the node is RESURRECTED; the modification survives.\n * - `\"flag\"` (default) — the **modification SURVIVES in the merged output** (as\n * with `\"modifyWins\"`) AND an **unresolved {@link DeleteModifyConflict} is\n * recorded** in `report.deleteModifyConflicts` for human review. `\"flag\"` is\n * therefore NOT neutral — it keeps data and surfaces the disagreement, on the\n * posture that a merge must never silently destroy the only branch still\n * carrying data. Choose `\"deleteWins\"` to honor the delete by default instead.\n */\nexport type DeleteModifyPolicy = \"deleteWins\" | \"modifyWins\" | \"flag\";\n\n/**\n * Behavior when `maxComparisonsPerKind` is exceeded for a kind.\n *\n * - `\"error\"` fails the merge with a typed error (default).\n * - `\"mergeByIdOnly\"` skips similarity for that kind, emits no candidate edges,\n * and records a report warning.\n */\nexport type ComparisonCeilingPolicy = \"error\" | \"mergeByIdOnly\";\n\n/**\n * Ontology type-reconciliation mode. `\"off\"` is a no-op (default); `\"ontology\"`\n * collapses compatible types to the most-specific via the public subClassOf\n * closure (T2a / T10).\n */\nexport type ReconcileTypesMode = \"ontology\" | \"off\";\n\n/**\n * Map of node kind name → its {@link ResolveConfig}. Keys are constrained to the\n * graph's node kinds (`keyof G[\"nodes\"]`), so a typo or a kind that does not\n * belong to the graph is a COMPILE error rather than a silently-ignored config\n * (which would let those nodes merge by id only without warning). Each kind's\n * config is bound to that kind's concrete `NodeType`, so `block(node)` and the\n * `custom` scorer see the right node shape. All keys are optional: kinds omitted\n * from this map merge by ID only (new fork nodes added as-is, no fuzzy\n * resolution). For the default unparameterized `GraphDef` the keys widen back to\n * `string`.\n */\nexport type ResolveMap<G extends GraphDef = GraphDef> = Readonly<\n Partial<{\n [K in NodeKinds<G>]: ResolveConfig<G, GetNodeType<G, K>>;\n }>\n>;\n\n/**\n * Caller-facing options for {@link merge}. All fields are optional with frozen\n * defaults applied by `normalizeMergeOptions` (see `options.ts`).\n */\nexport type MergeOptions<G extends GraphDef = GraphDef> = Readonly<{\n /** Per-kind entity resolution. Omitted kinds merge by ID only. */\n resolve?: ResolveMap<G>;\n /** Reconcile differing types across forks. Default `\"off\"`. */\n reconcileTypes?: ReconcileTypesMode;\n /** Property-conflict policy for staged-vs-staged disagreements. Default `\"flag\"`. */\n onPropertyConflict?: PropertyConflictPolicy<G>;\n /**\n * Property-conflict policy for BASE↔branch disagreements in a new-vs-base merge\n * (§6.4-C). DISTINCT from {@link onPropertyConflict} and DOES NOT inherit it:\n * `onPropertyConflict` can be `\"lastWriteWins\"` / `\"provenanceWeighted\"` / a\n * function, any of which would let a fuzzy branch match silently OVERWRITE\n * committed data. Default `\"flag\"` keeps the committed base value (and records the\n * conflict). Mirrors how `onDeleteModifyConflict` is kept separate. Only consulted\n * when a cluster contains a base member; the staged path never uses it.\n */\n onBasePropertyConflict?: PropertyConflictPolicy<G>;\n /** Delete/modify-conflict policy. Default `\"flag\"`. */\n onDeleteModifyConflict?: DeleteModifyPolicy;\n /** Comparison-ceiling behavior. Default `\"error\"`. */\n onComparisonCeiling?: ComparisonCeilingPolicy;\n /**\n * Deterministic survivor selection within a cluster. Default: the member with\n * the lexicographically-minimal node id.\n */\n canonical?: (cluster: ResolvedCluster) => NodeId<NodeType>;\n /** Populate the report-only provenance index. Default `true`. */\n provenance?: boolean;\n /**\n * Persist provenance ON-GRAPH: after the commit, upsert one `{branch, sourceId}`\n * row per contribution into a sidecar provenance graph on the target's backend\n * (queryable via `openProvenanceStore` / `readProvenance`). Default `false`\n * (report-only). Best-effort and post-commit — a persistence failure surfaces as\n * a {@link MergeReport.warnings} entry, never a failed merge.\n */\n persistProvenance?: boolean;\n /**\n * Local embedder for `vector` / `hybrid` similarity (in-memory cosine over the\n * staged candidate pairs). Required ONLY when a kind's resolve strategy is\n * `vector` or `hybrid`; `fulltext` / `custom` ignore it. A vector/hybrid\n * strategy with no embedder configured fails with a typed\n * {@link import(\"./errors\").SimilarityUnavailableError}.\n */\n embedder?: Embedder;\n /** Merge receiver. Default: the base `store`, written transactionally. */\n target?: Store<G>;\n /** Safety ceiling on candidate comparisons per kind. Default: unbounded. */\n maxComparisonsPerKind?: number;\n /**\n * Optional single-link diameter guard. When set, clusters whose pairwise\n * distance exceeds it are split by the deterministic drop-weakest rule (T8).\n */\n clusterMaxDiameter?: number;\n /**\n * Explicit stable branch order used by `lastWriteWins` / tie-breaking. When\n * omitted, branch ids sorted lexicographically are used. NEVER wall-clock.\n */\n branchOrder?: readonly BranchId[];\n /**\n * Per-branch trust weights consulted ONLY by the `\"provenanceWeighted\"`\n * property-conflict policy ({@link onPropertyConflict} /\n * {@link onBasePropertyConflict}): when branches disagree on a property value,\n * the value contributed by the highest-weight branch wins. Ties fall back to\n * {@link branchOrder} (then canonical value order); branches absent from the map\n * default to weight `0`. Ignored by every other policy. Keyed by\n * {@link BranchId}, like {@link branchOrder}. Without this map,\n * `\"provenanceWeighted\"` has no weights to consult and degrades to\n * `\"lastWriteWins\"` semantics.\n */\n provenanceWeights?: ReadonlyMap<BranchId, number>;\n}>;\n\n/**\n * Object-form arguments for {@link mergeIncremental} (§6.6). The two same-typed\n * stores are NAMED so `forkPoint` (the frozen ancestor the branches forked from, the\n * diff reference) and `target` (the live committed graph that base lookups and the\n * commit land on) cannot be swapped. `options.target` is ignored — `target` is the\n * explicit arg.\n */\nexport type MergeIncrementalArgs<G extends GraphDef = GraphDef> = Readonly<{\n forkPoint: Store<G>;\n target: Store<G>;\n branches: readonly GraphBranch<G>[];\n options?: MergeOptions<G>;\n}>;\n\n/**\n * Records that a set of fork node ids resolved to a single canonical survivor.\n */\nexport type EntityResolution = Readonly<{\n canonicalId: NodeId<NodeType>;\n memberIds: readonly NodeId<NodeType>[];\n kind: string;\n branchOrigins: readonly BranchId[];\n}>;\n\n/**\n * One candidate value contributing to a property conflict, tagged by its origin\n * branch.\n */\nexport type ConflictingValue = Readonly<{\n branchId: BranchId;\n value: JsonValue;\n}>;\n\n/**\n * A property whose value differed across cluster members (or across the two\n * collapsed edges for an edge conflict). `resolution` records the value the\n * policy selected.\n */\nexport type PropertyConflict<G extends GraphDef = GraphDef> = Readonly<{\n entityId: NodeId<NodeType> | EdgeId;\n kind: string;\n property: string;\n values: readonly ConflictingValue[];\n resolution: JsonValue;\n // `G` keeps the public conflict type parameterized by the caller's graph\n // (matching the design's `PropertyConflict<G>`); it carries no runtime field.\n readonly __graph?: G;\n}>;\n\n/**\n * An inherited node OR edge deleted by one branch and modified by another, with\n * the resolution the {@link DeleteModifyPolicy} produced. `entityId` is a\n * {@link NodeId} for a node conflict and an {@link EdgeId} for an edge conflict.\n */\nexport type DeleteModifyConflict = Readonly<{\n entityId: NodeId<NodeType> | EdgeId;\n kind: string;\n deletedBy: BranchId;\n modifiedBy: BranchId;\n resolution: DeleteModifyPolicy;\n}>;\n\n/**\n * Records that a cluster's mixed member kinds were collapsed to a single\n * canonical (most-specific) type via ontology reconciliation.\n */\nexport type TypeReconciliation = Readonly<{\n entityId: NodeId<NodeType>;\n fromTypes: readonly string[];\n toType: string;\n}>;\n\n/**\n * An item omitted from the merged result (e.g. an edge whose endpoint was\n * deleted, or an incompatible-typed cluster member).\n */\nexport type DroppedItem = Readonly<{\n kind: \"edge\" | \"node\";\n id: NodeId<NodeType> | EdgeId;\n reason: string;\n}>;\n\n/**\n * A `(kind, id)` node identity as surfaced in the merge report. Node identity is the\n * PAIR, never the bare id (a `Doctor` and a `SpecialistDoctor` can share an id string),\n * so report shapes that name nodes carry both halves.\n */\ntype ReportNodeIdentity = Readonly<{\n kind: string;\n id: NodeId<NodeType>;\n}>;\n\n/**\n * An AMBIGUOUS new-vs-base match (design §6.4-A): a connected component that\n * bridged ≥2 distinct committed base entities (directly, `baseA ~ new ~ baseB`, or\n * through staged hops, `baseA ~ new1 ~ new2 ~ baseB`). `baseIds` are the committed\n * entities the component spanned; `memberIds` are all of its members. Both are full\n * `(kind, id)` identities — the guard keys on the composite identity, so a component\n * spanning two SAME-id/different-kind bases stays distinguishable in the report. The\n * base↔base collapse is ALWAYS REFUSED — the component is split so the committed\n * entities stay separate. Reported regardless of how the component split. (A\n * deliberate-collapse trust path is deferred until committed-entity re-keying + edge\n * repoint exist; §6.4-C.)\n */\nexport type BaseAmbiguity = Readonly<{\n baseIds: readonly ReportNodeIdentity[];\n memberIds: readonly ReportNodeIdentity[];\n}>;\n\n/**\n * The contribution one branch made to the merged result. Returned by\n * {@link ProvenanceIndex.byBranch}. EXPLICITLY in-memory / report-only for P0 —\n * no on-graph prop tagging (deferred to the AgentFS phase).\n */\nexport type BranchProvenance = Readonly<{\n nodeIds: readonly NodeId<NodeType>[];\n edgeIds: readonly EdgeId[];\n}>;\n\n/**\n * Report-only, in-memory provenance index. `byBranch` answers \"which\n * nodes/edges did this branch contribute to the merged result?\".\n */\nexport type ProvenanceIndex = Readonly<{\n byBranch: (branchId: BranchId) => BranchProvenance;\n}>;\n\n/**\n * One `{branch, sourceId}` → canonical contribution — the unit of provenance.\n *\n * The in-memory {@link ProvenanceIndex} collapses these to `branch → {canonical\n * ids}`; the full record (which keeps the contributing `sourceId` and kind) is what\n * `persistProvenance` writes to the sidecar provenance graph. `sourceId` is the\n * fork-local id the contribution had in its branch BEFORE the merge collapsed it to\n * `canonicalId` (equal to `canonicalId` for an in-place modification).\n */\nexport type ProvenanceRecord = Readonly<{\n role: \"node\" | \"edge\";\n canonicalId: string;\n canonicalKind: string;\n branchId: BranchId;\n sourceId: string;\n}>;\n\n/**\n * The full result of a {@link merge}: counts, every resolution/conflict/\n * reconciliation/drop, and the report-only provenance index.\n */\nexport type MergeReport<G extends GraphDef = GraphDef> = Readonly<{\n merged: Readonly<{ nodes: number; edges: number }>;\n resolutions: readonly EntityResolution[];\n conflicts: readonly PropertyConflict<G>[];\n deleteModifyConflicts: readonly DeleteModifyConflict[];\n typeReconciliations: readonly TypeReconciliation[];\n dropped: readonly DroppedItem[];\n /**\n * Ambiguous new-vs-base matches (§6.4-A): components that bridged ≥2 committed\n * base entities. Empty on the staged-vs-staged snapshot path.\n */\n baseAmbiguities: readonly BaseAmbiguity[];\n provenance: ProvenanceIndex;\n /**\n * Non-fatal advisories from the merge — comparison-ceiling skips and, when\n * `persistProvenance` is set, a best-effort provenance-persistence failure (the\n * graph still committed). Empty on a clean merge.\n */\n warnings: readonly string[];\n /**\n * Present only when `persistProvenance` ran and SUCCEEDED: the sidecar provenance\n * graph id and how many `{branch, sourceId}` rows were upserted. Absent when\n * persistence was off or failed (a failure adds a {@link MergeReport.warnings}).\n */\n provenancePersisted?: Readonly<{ graphId: string; count: number }>;\n}>;\n","/**\n * `base@V` stamping.\n *\n * A {@link BaseVersion} is the immutable token a branch is forked from. It must\n * change whenever either the schema OR the live content of the base store\n * changes, so that `merge()`'s precondition check (T11) can reject a branch that\n * forked from a divergent base.\n *\n * The token is two stable components joined by a separator:\n *\n * 1. A **schema hash** — `computeSchemaHash(serializeSchema(graph, version))`.\n * This is content-addressed (the public `computeSchemaHash` deliberately\n * excludes the version number and `generatedAt`, so it is stable across\n * re-saves of the same schema).\n * 2. A **revision anchor** when the Store has `revisionTracking` (or\n * `history`) enabled — a durable random per-graph origin plus the\n * monotonic revision clock. This is O(1) to read and changes after every\n * successful Store write; the origin prevents independent stores with\n * coincident timestamps from sharing an anchor.\n * Stores without tracking retain the compatibility fallback: a\n * **content fingerprint**, a SHA-256 digest (truncated to a fixed-width\n * hex string) of every LIVE node and edge over the base store (`id`,\n * `updated_at`, the bitemporal `valid_from`/`valid_to`, and canonicalized\n * `props`; edges also carry their endpoint ids), sorted by id, so two stores\n * with identical live content fingerprint identically regardless of row\n * enumeration order or insertion order. Props AND validity are folded in so\n * the token changes on a content or validity edit even when `updated_at` ties\n * at millisecond granularity. Hashing keeps the token fixed-width instead of\n * growing linearly with store size.\n *\n * The token MUST be computed off the ORIGINAL base store, never off a clone:\n * `exportGraph`/`importGraph` regenerate `created_at`/`updated_at`, so a clone's\n * fingerprint would not match its source. (See the working-copy fidelity note in\n * T4.)\n *\n * `computeBaseVersion` is async because schema hashing, revision reads, and the\n * compatibility live-content enumeration go through async TypeGraph internals.\n * The design's synchronous illustrative signature does not survive contact with\n * the real store surface.\n */\n\nimport { canonicalizeProps, parseRowProps } from \"./canonical-props\";\nimport { compareStrings } from \"./node-key\";\nimport { enumerateAllEdges, enumerateAllNodes } from \"./state-diff\";\nimport type {\n GraphBackend,\n GraphDef,\n Store,\n TransactionBackend,\n} from \"./typegraph-internal\";\nimport { getEdgeKinds, getNodeKinds, sha256Hex } from \"./typegraph-internal\";\nimport { storeBackend } from \"./typegraph-internal\";\nimport { computeSchemaHash, serializeSchema } from \"./typegraph-internal\";\nimport type { BaseVersion } from \"./types\";\nimport { asBaseVersion } from \"./types\";\n\n/**\n * Separator between the schema-hash and revision-or-content token components.\n * The schema hash contains no NUL byte, so one NUL unambiguously delimits the\n * two components.\n */\nconst TOKEN_SEPARATOR = \"\\0\";\nconst REVISION_COMPONENT_PREFIX = \"revision:\";\nconst REVISION_COMPONENT_SEPARATOR = \":\";\nconst INITIAL_REVISION = \"initial\";\n\n/**\n * Falls back to schema version `1` when the backend has not recorded an active\n * schema version. `serializeSchema` only uses the version for the serialized\n * doc; the hash deliberately excludes it, so the exact value never affects the\n * resulting `BaseVersion`.\n */\nconst FALLBACK_SCHEMA_VERSION = 1;\n\n/**\n * Reads the active schema version from the backend, defaulting when absent. The\n * value is informational for `serializeSchema`; `computeSchemaHash` excludes the\n * version, so this never destabilizes the token.\n */\nasync function readActiveSchemaVersion(\n backend: GraphBackend,\n graphId: string,\n): Promise<number> {\n const active = await backend.getActiveSchema(graphId);\n return active?.version ?? FALLBACK_SCHEMA_VERSION;\n}\n\n/**\n * Computes the schema-hash component of the base version token — the SCHEMA half of\n * `base@V`, independent of live content. Exported so `mergeIncremental()` can assert\n * `forkPoint` and `target` share a schema (the hard half of its precondition) without\n * re-parsing the token separator or recomputing the content fingerprint (§6.6).\n */\nexport async function computeSchemaComponent<G extends GraphDef>(\n store: Store<G>,\n): Promise<string> {\n const version = await readActiveSchemaVersion(\n storeBackend(store),\n store.graphId,\n );\n return computeSchemaHash(serializeSchema(store.graph, version));\n}\n\n/**\n * Stable TOTAL comparator over `{ kind, id }` digest entries. Keyed on `(kind, id)`\n * because the node primary key is `(graph_id, kind, id)` — two nodes of different\n * kinds may legitimately share an `id` (e.g. `Person:x` and `Company:x`), so an\n * id-only comparator is non-total and would leave same-id/different-kind entries at\n * the mercy of sort stability. `(kind, id)` makes the digest order fully canonical.\n */\nfunction byDigestEntry(\n left: Readonly<{ kind: string; id: string }>,\n right: Readonly<{ kind: string; id: string }>,\n): number {\n const byKind = compareStrings(left.kind, right.kind);\n return byKind === 0 ? compareStrings(left.id, right.id) : byKind;\n}\n\n/**\n * Number of SHA-256 bytes retained for the content fingerprint. 16 bytes (128\n * bits) makes an accidental collision — which would let a divergent base pass\n * the merge precondition — negligible, while keeping the token fixed-width\n * regardless of store size.\n */\nconst CONTENT_FINGERPRINT_BYTES = 16;\n\n/**\n * Builds the deterministic content fingerprint over the base store's LIVE rows.\n *\n * Each live node contributes `(id, updatedAt, validFrom, validTo, props)` and\n * each live edge contributes `(id, updatedAt, validFrom, validTo, endpoints,\n * props)`; both lists are sorted by id before serialization so the fingerprint is\n * independent of enumeration order. Props are canonicalized so the token changes\n * whenever live content changes even when two writes land on the same millisecond\n * `updated_at` (timestamp granularity must never be the sole change signal). The\n * bitemporal `valid_from`/`valid_to` are folded in for the same reason — they are\n * user-mutable row content, so a validity-only edit that leaves `updated_at`\n * unchanged must still move the token. Soft-deleted rows are intentionally\n * excluded — the fingerprint describes the live base a branch forks from.\n *\n * Takes the backend rather than a `Store` so the SAME fingerprint can be\n * re-computed inside a commit transaction (via the tx-scoped backend) for the\n * in-transaction `base@V` re-validation — the reads then observe the\n * transaction's snapshot, not whatever a concurrent writer has since committed.\n */\nexport async function computeContentComponent<G extends GraphDef>(\n backend: GraphBackend | TransactionBackend,\n graphId: string,\n graph: G,\n): Promise<string> {\n const nodeKinds = getNodeKinds(graph);\n const edgeKinds = getEdgeKinds(graph);\n\n const nodeDigest: Readonly<{\n id: string;\n kind: string;\n updatedAt: string;\n validFrom: string | undefined;\n validTo: string | undefined;\n props: string;\n }>[] = [];\n for (const kind of nodeKinds) {\n const rows = await enumerateAllNodes(backend, graphId, kind);\n for (const row of rows) {\n if (row.deleted_at === undefined) {\n nodeDigest.push({\n id: row.id,\n kind: row.kind,\n updatedAt: row.updated_at,\n validFrom: row.valid_from,\n validTo: row.valid_to,\n props: canonicalizeProps(parseRowProps(row.props)),\n });\n }\n }\n }\n\n const edgeDigest: Readonly<{\n id: string;\n kind: string;\n fromId: string;\n toId: string;\n updatedAt: string;\n validFrom: string | undefined;\n validTo: string | undefined;\n props: string;\n }>[] = [];\n for (const kind of edgeKinds) {\n const rows = await enumerateAllEdges(backend, graphId, kind);\n for (const row of rows) {\n if (row.deleted_at === undefined) {\n edgeDigest.push({\n id: row.id,\n kind: row.kind,\n fromId: row.from_id,\n toId: row.to_id,\n updatedAt: row.updated_at,\n validFrom: row.valid_from,\n validTo: row.valid_to,\n props: canonicalizeProps(parseRowProps(row.props)),\n });\n }\n }\n }\n\n return sha256Hex(\n canonicalizeProps({\n nodes: nodeDigest.sort((left, right) => byDigestEntry(left, right)),\n edges: edgeDigest.sort((left, right) => byDigestEntry(left, right)),\n }),\n CONTENT_FINGERPRINT_BYTES,\n );\n}\n\n/**\n * Computes the immutable `base@V` token for a store. Combines the schema hash\n * with a durable revision anchor when tracking is enabled, otherwise with the\n * compatibility live-content fingerprint.\n *\n * MUST be called on the ORIGINAL base store, not a clone (clones regenerate\n * timestamps and would fingerprint differently when the compatibility path is\n * in use).\n */\nexport async function computeBaseVersion<G extends GraphDef>(\n store: Store<G>,\n): Promise<BaseVersion> {\n if (store.revisionTrackingEnabled) {\n const [schemaComponent, origin, revision] = await Promise.all([\n computeSchemaComponent(store),\n store.revisionOriginNow(),\n store.revisionNow(),\n ]);\n return asBaseVersion(\n `${schemaComponent}${TOKEN_SEPARATOR}${revisionComponent(origin, revision)}`,\n );\n }\n const [schemaComponent, contentComponent] = await Promise.all([\n computeSchemaComponent(store),\n computeContentComponent(storeBackend(store), store.graphId, store.graph),\n ]);\n return asBaseVersion(\n `${schemaComponent}${TOKEN_SEPARATOR}${contentComponent}`,\n );\n}\n\nfunction revisionComponent(\n origin: string,\n revision: string | undefined,\n): string {\n return `${REVISION_COMPONENT_PREFIX}${origin}${REVISION_COMPONENT_SEPARATOR}${revision ?? INITIAL_REVISION}`;\n}\n\n/** True when a base token uses the O(1) durable revision-anchor component. */\nexport function hasRevisionAnchor(version: BaseVersion): boolean {\n return contentComponentOf(version).startsWith(REVISION_COMPONENT_PREFIX);\n}\n\n/**\n * Extracts the durable revision from a revision-anchored base token. Undefined\n * represents the stable initial state before the first tracked write.\n */\nexport function revisionAnchorOf(version: BaseVersion): string | undefined {\n const revision = revisionPartsOf(version)?.revision;\n return revision === undefined || revision === INITIAL_REVISION ?\n undefined\n : revision;\n}\n\n/**\n * Extracts the durable store-specific namespace from a revision-anchored base\n * token. Undefined denotes a legacy timestamp-only anchor, which must never\n * be treated as equivalent to a current store's namespaced revision.\n */\nexport function revisionOriginOf(version: BaseVersion): string | undefined {\n return revisionPartsOf(version)?.origin;\n}\n\nfunction revisionPartsOf(\n version: BaseVersion,\n): Readonly<{ origin: string; revision: string }> | undefined {\n const component = contentComponentOf(version);\n if (!component.startsWith(REVISION_COMPONENT_PREFIX)) return undefined;\n const encoded = component.slice(REVISION_COMPONENT_PREFIX.length);\n const separator = encoded.indexOf(REVISION_COMPONENT_SEPARATOR);\n if (separator <= 0 || separator === encoded.length - 1) return undefined;\n return {\n origin: encoded.slice(0, separator),\n revision: encoded.slice(separator + 1),\n };\n}\n\n/**\n * Extracts the second component from a `base@V` token. The schema component\n * contains no NUL byte, so the substring after the separator is exactly the\n * durable revision or compatibility content fingerprint.\n *\n * Used by both revision-token parsing and legacy in-transaction content\n * re-validation. The schema component is a pure function of the in-memory\n * graph definition, so only the second component needs runtime checking.\n */\nexport function contentComponentOf(version: BaseVersion): string {\n const separatorIndex = (version as string).indexOf(TOKEN_SEPARATOR);\n return separatorIndex === -1 ? version : (\n (version as string).slice(separatorIndex + 1)\n );\n}\n","import type { TypeGraphErrorOptions } from \"./typegraph-internal\";\nimport { TypeGraphError } from \"./typegraph-internal\";\n\n/**\n * Error hierarchy for the graph-merge primitive.\n *\n * Every error extends the publicly-exported {@link TypeGraphError}, so consumers\n * can use the same `isTypeGraphError`/category machinery they already use for\n * TypeGraph itself. Each subclass carries a stable machine-readable `code`, a\n * fixed `ErrorCategory`, and a cause chain for debugging.\n */\n\n/**\n * Machine-readable error codes for the merge primitive. Stable identifiers so\n * callers can branch on `error.code` without string-matching messages.\n */\nexport const MERGE_ERROR_CODES = {\n merge: \"GRAPH_MERGE_ERROR\",\n branch: \"GRAPH_MERGE_BRANCH_ERROR\",\n similarityUnavailable: \"GRAPH_MERGE_SIMILARITY_UNAVAILABLE\",\n conflict: \"GRAPH_MERGE_CONFLICT\",\n baseVersionMismatch: \"GRAPH_MERGE_BASE_VERSION_MISMATCH\",\n} as const;\n\n/**\n * Options shared by every merge error. Mirrors the relevant subset of\n * TypeGraphError's options while making `cause`/`details`/`suggestion`\n * uniformly optional at the merge-error boundary.\n */\nexport type MergeErrorOptions = Readonly<{\n details?: Record<string, unknown>;\n suggestion?: string;\n cause?: unknown;\n}>;\n\n/**\n * Builds a {@link TypeGraphErrorOptions} for a fixed category, threading only\n * the optional fields that are actually present. Omitting undefined keys (rather\n * than assigning `undefined`) keeps the result valid under\n * `exactOptionalPropertyTypes`.\n */\nfunction toTypeGraphErrorOptions(\n category: TypeGraphErrorOptions[\"category\"],\n options: MergeErrorOptions,\n): TypeGraphErrorOptions {\n return {\n category,\n ...(options.details === undefined ? {} : { details: options.details }),\n ...(options.suggestion === undefined ?\n {}\n : { suggestion: options.suggestion }),\n ...(options.cause === undefined ? {} : { cause: options.cause }),\n };\n}\n\n/**\n * Generic failure raised while computing or committing a merge. The catch-all\n * for the orchestrator (comparison-ceiling overruns, commit failures, etc.).\n */\nexport class MergeError extends TypeGraphError {\n constructor(message: string, options: MergeErrorOptions = {}) {\n super(\n message,\n MERGE_ERROR_CODES.merge,\n toTypeGraphErrorOptions(\"system\", options),\n );\n this.name = \"MergeError\";\n }\n}\n\n/**\n * Failure raised while creating a working-copy branch of a base store\n * (clone/export/import failures, backend construction failures).\n */\nexport class BranchError extends TypeGraphError {\n constructor(message: string, options: MergeErrorOptions = {}) {\n super(\n message,\n MERGE_ERROR_CODES.branch,\n toTypeGraphErrorOptions(\"system\", options),\n );\n this.name = \"BranchError\";\n }\n}\n\n/**\n * Raised when a `vector`/`hybrid` similarity strategy is requested but no\n * {@link import(\"./types\").Embedder} was configured (`MergeOptions.embedder` is\n * absent). The `vector`/`hybrid` scorers compute cosine over real embeddings in\n * memory, so an embedder is mandatory for them; `fulltext`/`custom` need none.\n */\nexport class SimilarityUnavailableError extends MergeError {\n override readonly code = MERGE_ERROR_CODES.similarityUnavailable;\n\n constructor(message: string, options: MergeErrorOptions = {}) {\n super(message, {\n ...options,\n suggestion:\n options.suggestion ??\n \"Pass MergeOptions.embedder (a local model), or use a fulltext/custom similarity strategy.\",\n });\n this.name = \"SimilarityUnavailableError\";\n }\n}\n\n/**\n * Raised when a conflict cannot be resolved by the configured policy and the\n * caller has opted into hard-failing rather than flagging.\n */\nexport class MergeConflictError extends MergeError {\n override readonly code = MERGE_ERROR_CODES.conflict;\n\n constructor(message: string, options: MergeErrorOptions = {}) {\n super(message, options);\n this.name = \"MergeConflictError\";\n }\n}\n\n/**\n * Raised by the `merge()` precondition check when a branch's `base@V` token\n * does not match the merge target's current base version (the branch forked\n * from a divergent schema or content fingerprint).\n */\nexport class BaseVersionMismatchError extends MergeError {\n override readonly code = MERGE_ERROR_CODES.baseVersionMismatch;\n\n constructor(message: string, options: MergeErrorOptions = {}) {\n super(message, {\n ...options,\n suggestion:\n options.suggestion ??\n \"Re-branch from the current target so the branch base matches before merging.\",\n });\n this.name = \"BaseVersionMismatchError\";\n }\n}\n","/**\n * Pluggable working-copy strategy: how `branch()` produces an isolated,\n * independently-mutable copy of a base store.\n *\n * The P0 default is a faithful CLONE via streamed public interchange\n * ({@link cloneWorkingCopyStrategy}): `exportGraphStream` the base, then\n * `importGraphStream` into a fresh store on a caller-provided backend. IDs are\n * preserved by interchange, so the diff engine (T3) can key on stable ids across\n * base and fork. This leverages public entrypoints only, needs zero schema\n * changes, and behaves identically across SQLite and Postgres.\n *\n * INTERCHANGE FIDELITY LIMITATION (verified, design §13.x): the interchange\n * `meta` schema has no `deletedAt` field, so a base row that is already\n * soft-deleted would round-trip into the clone as LIVE (its tombstone lost). A\n * resurrected row would then read as a spurious `new` node in the fork's diff —\n * the base row is non-live, so `diffNodeKind` takes its `!isLive(base)` branch and\n * reports the (live, clone-resurrected) row as an addition — silently re-creating a\n * deleted node on commit. We therefore export with `includeDeleted: false`: the\n * clone carries only the base's LIVE state, exactly what `branch()` needs. The\n * merge state-diff is still computed against the ORIGINAL base store (live rows\n * only) as the immutable reference, never against the clone (clones regenerate\n * `created_at`/`updated_at`, which would otherwise destabilize `base@V`).\n *\n * `includeTemporal: true` carries `validFrom`/`validTo` through unchanged,\n * preserving the base's exact valid-time window on the clone: create-time\n * paths default an omitted `validFrom` to the row's own creation instant\n * (see #240), and export/import round-trip a still-open-left `valid_from`\n * (e.g. a row that predates the #240 fix) as an explicit `null` rather than\n * silently dropping it — see `InterchangeNodeSchema.validFrom`'s doc.\n * Without either half of this, the clone's re-import would re-stamp the\n * affected base rows to the CLONE's creation instant instead — narrowing\n * their validity window and making `asOf` reads on the fork diverge from\n * identical reads on the base for any instant between the row's real\n * creation and the clone.\n *\n * Logical-namespace (copy-on-write within one backend, no full data copy) is a\n * future strategy slot — see the `WorkingCopyStrategy` interface — deferred past\n * P0.\n */\n\nimport { BranchError } from \"./errors\";\nimport type { GraphBackend, GraphDef, Store } from \"./typegraph-internal\";\nimport { createStoreWithSchema } from \"./typegraph-internal\";\nimport { exportGraphStream, importGraphStream } from \"./typegraph-internal\";\n\n/**\n * Batch size for the clone's `importGraphStream` pass. Large enough to keep\n * round-trips low on demo-scale graphs; correctness is independent of the value.\n */\nconst CLONE_IMPORT_BATCH_SIZE = 1000;\n\n/**\n * How `branch()` materializes a working copy of a base store.\n *\n * `create` receives the live base store and returns a fresh, independently\n * mutable {@link Store} over the SAME graph definition, seeded with the base's\n * current state. Mutating the returned store MUST NOT affect the base.\n *\n * The single method is the only extension point: alternative strategies\n * (e.g. a future logical-namespace copy-on-write within one backend) implement\n * the same contract.\n */\nexport type WorkingCopyStrategy<G extends GraphDef> = Readonly<{\n create: (baseStore: Store<G>) => Promise<Store<G>>;\n}>;\n\n/**\n * Factory for a caller-provided backend. `branch()` stays backend-agnostic by\n * delegating backend construction to the caller: the clone strategy calls this\n * once per `create()` to obtain the fresh backend that backs the working copy.\n *\n * Returning a promise lets async backends (e.g. PGlite, which boots an\n * in-process Postgres engine) be constructed lazily at branch time.\n *\n * The returned backend MUST be EMPTY (no rows for the base graph): the clone\n * seeds it from the base via `importGraphStream` with `onConflict: \"error\"`, so a\n * pre-existing row is surfaced as a {@link BranchError} rather than silently\n * skipped (which would leave the working copy diverging from the base).\n * When the source store uses `revisionTracking`, the backend must also satisfy\n * that option's transactional revision-clock requirements because the clone\n * preserves the source's branchability contract.\n */\nexport type MakeBackend = () => Promise<GraphBackend>;\n\n/**\n * The P0 default working-copy strategy: faithful clone via streamed interchange.\n *\n * On each `create(baseStore)`:\n * 1. `exportGraphStream(baseStore, { includeMeta: true, includeTemporal: true,\n * includeDeleted: false })` — `includeMeta: true` carries\n * `created_at`/`updated_at`; `includeTemporal: true` carries\n * `validFrom`/`validTo` so the clone's valid-time window matches the base's\n * exactly (see the fidelity note above); `includeDeleted: false` keeps the\n * clone to LIVE rows only. Shipping soft-deleted rows is unsafe: the meta\n * schema has no `deletedAt`, so they would import as live and resurrect on\n * the fork's diff (see the fidelity note above). `branch()` only needs the\n * base's live state.\n * 2. Create a fresh store over the caller-provided backend with the SAME graph\n * definition via `createStoreWithSchema`.\n * 3. `importGraphStream(freshStore, data, { onConflict: \"error\", ... })` — ids are\n * preserved so the diff engine can key on them. `onConflict: \"error\"`\n * requires the backend to be EMPTY: a pre-existing row is a contract\n * violation that must surface loudly, never be silently skipped (a skipped\n * row would leave the clone diverging from the base, so the fork's diff would\n * report phantom modifications/deletions). `importGraphStream` RETURNS\n * `{ success, errors }` rather than throwing on a per-row rejection, so its\n * result is checked and any failure fails the branch.\n *\n * The backend `makeBackend()` returns is opened here, so any failure AFTER it is\n * created closes it before rethrowing — only the success path hands the backend\n * (via the returned store) to the caller, who then owns its lifecycle.\n *\n * @param makeBackend - Constructs the fresh, EMPTY backend the working copy is\n * built on.\n */\nexport function cloneWorkingCopyStrategy<G extends GraphDef>(\n makeBackend: MakeBackend,\n): WorkingCopyStrategy<G> {\n return {\n create: async (baseStore: Store<G>): Promise<Store<G>> => {\n const backend = await makeBackend();\n try {\n const [freshStore] = await createStoreWithSchema(\n baseStore.graph,\n backend,\n {\n // Keep descendants branchable with the same O(1) anchor contract,\n // but do not copy recorded-time history into the disposable fork.\n revisionTracking: baseStore.revisionTrackingEnabled,\n },\n );\n const result = await importGraphStream(\n freshStore,\n exportGraphStream(baseStore, {\n includeMeta: true,\n includeTemporal: true,\n includeDeleted: false,\n batchSize: CLONE_IMPORT_BATCH_SIZE,\n }),\n {\n onConflict: \"error\",\n onUnknownProperty: \"error\",\n validateReferences: true,\n batchSize: CLONE_IMPORT_BATCH_SIZE,\n },\n );\n if (!result.success) {\n throw new BranchError(\n \"Clone import failed: the working copy could not be seeded from the base store. The backend returned by makeBackend() must be empty.\",\n { details: { errors: result.errors } },\n );\n }\n return freshStore;\n } catch (error) {\n // The backend was opened above; close it on any failure so its\n // connection / file handle / in-process engine cannot leak. A close\n // failure must not mask the original error.\n try {\n await backend.close();\n } catch {\n // Intentionally ignored — surface the original branch failure.\n }\n throw error;\n }\n },\n };\n}\n","/**\n * `branch()` — fork an isolated, independently-mutable working copy of a base\n * store (design §7.1).\n *\n * A branch is a {@link GraphBranch}: a fresh {@link BranchId}, the immutable\n * `base@V` token the copy forked from (computed off the ORIGINAL base store via\n * {@link computeBaseVersion}, never off the clone), and a {@link Store} over the\n * branch's own backend seeded with the base's live state.\n *\n * The copy mechanism is pluggable behind {@link WorkingCopyStrategy}. The P0\n * default is the faithful streamed-interchange clone\n * ({@link cloneWorkingCopyStrategy}),\n * which keeps this primitive backend-agnostic: the caller supplies a\n * `makeBackend` factory, and `branch()` never names a concrete backend.\n */\n\nimport { computeBaseVersion } from \"./base-version\";\nimport { BranchError } from \"./errors\";\nimport type { Result } from \"./result\";\nimport { err, ok } from \"./result\";\nimport type { GraphDef } from \"./typegraph-internal\";\nimport { generateId } from \"./typegraph-internal\";\nimport type { BranchOptions, GraphBranch } from \"./types\";\nimport { asBranchId } from \"./types\";\nimport type { MakeBackend, WorkingCopyStrategy } from \"./working-copy\";\nimport { cloneWorkingCopyStrategy } from \"./working-copy\";\n\n/**\n * Creates an isolated working-copy branch of `baseStore`.\n *\n * Stamps the `base@V` token off the original base store, mints (or accepts) a\n * {@link BranchId}, and materializes the working copy via the resolved strategy.\n * The default strategy is a faithful clone over a fresh backend produced by\n * `makeBackend`; pass an explicit `strategy` to override (e.g. a future\n * logical-namespace copy-on-write).\n *\n * Returns a {@link Result}: success yields the {@link GraphBranch}; any failure\n * (base-version stamping, backend construction, streamed interchange) is wrapped in a\n * {@link BranchError} with the underlying cause attached. Errors are returned,\n * never thrown — this is internal-logic surface (the caller converts to a thrown\n * error at the framework boundary).\n *\n * @param baseStore - The store to fork. Remains untouched.\n * @param makeBackend - Factory for the working copy's backend (keeps the\n * primitive backend-agnostic). Used only by the default clone strategy; ignored\n * when an explicit `strategy` is supplied.\n * @param options - Optional `{ id }` to set an explicit branch id.\n * @param strategy - Optional working-copy strategy override.\n */\nexport async function branch<G extends GraphDef>(\n baseStore: GraphBranch<G>[\"store\"],\n makeBackend: MakeBackend,\n options?: BranchOptions,\n strategy?: WorkingCopyStrategy<G>,\n): Promise<Result<GraphBranch<G>, BranchError>> {\n try {\n const base = await computeBaseVersion(baseStore);\n const id = options?.id ?? asBranchId(generateId());\n const workingCopyStrategy =\n strategy ?? cloneWorkingCopyStrategy<G>(makeBackend);\n const store = await workingCopyStrategy.create(baseStore);\n return ok({ id, base, store });\n } catch (error) {\n return err(\n new BranchError(\"Failed to create working-copy branch of base store\", {\n cause: error,\n }),\n );\n }\n}\n","import { requireDefined } from \"../utils/presence\";\n/**\n * Per-kind blocking (design §9 phase 2): bucket a kind's NEW nodes by a cheap\n * exact-equality key so candidate-gen (T6) only compares pairs that could\n * plausibly be the same entity, bounding the otherwise-O(n²) work.\n *\n * A node is placed into a bucket for EACH key it produces, so it can belong to\n * MULTIPLE buckets — two key sources combined as a UNION (not a composite key):\n *\n * 1. The caller's `ResolveConfig.block(node)` — an application-defined cheap\n * pre-filter (e.g. a Patient's `birthDate`) → its ONE block bucket.\n * 2. The kind's declared `unique` constraints, read from the PUBLIC\n * `store.introspect().kinds[k].unique` → ONE bucket per constraint the node\n * fully satisfies. A unique constraint is an exact-match short-circuit: two\n * nodes sharing all of a constraint's field values are definitionally the\n * same entity, so they co-bucket THERE regardless of their block keys or any\n * OTHER constraint.\n *\n * Composing the two sources into a single key (the old behavior) was a bug: a\n * differing `block()` key — or a differing EARLIER constraint — split two nodes\n * that share a unique value into separate buckets, so candidate-gen never compared\n * them and a real duplicate survived the merge. The UNION fixes this: a shared\n * unique value always co-buckets, independent of `block()`.\n *\n * candidate-gen compares pairs within each bucket and DEDUPS pairs across buckets,\n * so a node in several buckets is compared against the UNION of its bucket-mates,\n * each pair scored exactly once.\n *\n * Determinism is load-bearing — candidate-gen order must never leak into merge\n * results — so bucket keys are emitted sorted lexicographically, each bucket's\n * member list is sorted by `node.id`, and each unique signature is built in the\n * constraint's declared field order.\n *\n * A node that produces NO key (no `block()`, no satisfied constraint) lands in the\n * shared {@link UNBLOCKED_BUCKET_KEY} bucket, compared all-vs-all within its kind.\n * This is the safe (no false-negative) fallback: blocking only ever prunes pairs\n * that are guaranteed non-matches.\n *\n * This module is a PURE function over its inputs (the introspection snapshot is\n * read synchronously by the caller and passed in); it performs no I/O.\n */\nimport { compareStrings } from \"./node-key\";\nimport type { Node, NodeType, UniqueIntrospection } from \"./typegraph-internal\";\nimport { computeUniqueKey } from \"./typegraph-internal\";\nimport type { ResolveConfig } from \"./types\";\n\n/**\n * Bucket key for nodes that produced no blocking key from either `block()` or a\n * unique constraint. Members of this bucket are compared all-vs-all within their\n * kind by candidate-gen.\n */\nexport const UNBLOCKED_BUCKET_KEY = \"unblocked\";\n\n/**\n * Separator joining the parts of a bucket key (its prefix, and a unique\n * signature's constraint name + field values). Chosen as a control character so it\n * cannot collide with ordinary stringified property values.\n */\nconst KEY_PART_SEPARATOR = \"\\0\";\n\n/**\n * Prefix marking a `block()`-key bucket, so a `block()` value can never be confused\n * with a unique-constraint value that happens to stringify the same.\n */\nconst BLOCK_KEY_PREFIX = \"b\";\n\n/** Prefix marking a unique-constraint bucket. See {@link BLOCK_KEY_PREFIX}. */\nconst UNIQUE_KEY_PREFIX = \"u\";\n\n/**\n * True when a bucket key denotes a UNIQUE-constraint bucket (vs. a `block()` or the\n * unblocked bucket). candidate-gen FORCE-MERGES every pair in such a bucket: a\n * shared unique value is definitionally the same entity (the exact-match\n * short-circuit), so the pair is a GUARANTEED merge candidate regardless of the\n * similarity threshold — differing properties are then reported as conflicts\n * normally. This also keeps the merged graph from violating its own uniqueness:\n * two unmerged same-unique rows could never commit.\n */\nexport function isUniqueBucketKey(key: string): boolean {\n return key.startsWith(`${UNIQUE_KEY_PREFIX}${KEY_PART_SEPARATOR}`);\n}\n\n/**\n * Builds the exact-match signature for one unique constraint from a node's\n * field values, or `undefined` when ANY of the constraint's fields is `null` /\n * `undefined` (a partial key cannot establish exact-match equality, and — since\n * the introspection snapshot does not expose a constraint's `where` predicate —\n * skipping absent values keeps a partial unique constraint from silently\n * over-merging two distinct rows that the database would treat as a non-match;\n * a genuine non-partial null collision still surfaces loudly at commit).\n *\n * The signature delegates to {@link computeUniqueKey} — the SAME key the store\n * enforces uniqueness with — so a blocking bucket co-buckets EXACTLY the values\n * the commit-time uniqueness check treats as equal. Hand-rolling a separate\n * canonical encoding here drifted from enforcement: it distinguished the number\n * `1` from the string `\"1\"` (which `computeUniqueKey` collapses, so the merge\n * aborted with a `UniquenessError`) and key-sorted object values (which\n * `computeUniqueKey` does not, so distinct rows were silently over-merged).\n */\nfunction constraintSignature(\n node: Node<NodeType>,\n constraint: UniqueIntrospection,\n): string | undefined {\n const props = node as unknown as Record<string, unknown>;\n for (const field of constraint.fields) {\n const value = props[field];\n if (value === undefined || value === null) {\n return undefined;\n }\n }\n return `${constraint.name}${KEY_PART_SEPARATOR}${computeUniqueKey(\n props,\n constraint.fields,\n constraint.collation,\n )}`;\n}\n\n/**\n * Computes the SET of bucket keys a node belongs to: its `block()` key bucket (if\n * `block()` returned a key) PLUS one bucket per unique constraint the node fully\n * satisfies. Because a shared unique value gets its OWN bucket — never intersected\n * with the block key or other constraints — two nodes sharing it always co-bucket.\n * Returns `[UNBLOCKED_BUCKET_KEY]` when the node produces no key at all.\n *\n * Each unique signature already embeds its constraint name, so distinct constraints\n * yield distinct keys; the `b`/`u` prefixes keep block and unique keyspaces\n * disjoint. No constraint ordering is needed — each is an independent bucket.\n */\nfunction bucketKeysFor(\n node: Node<NodeType>,\n block: ResolveConfig[\"block\"],\n constraints: readonly UniqueIntrospection[],\n): readonly string[] {\n const keys: string[] = [];\n\n const blockKey = block?.(node);\n if (blockKey !== undefined) {\n keys.push(`${BLOCK_KEY_PREFIX}${KEY_PART_SEPARATOR}${blockKey}`);\n }\n\n for (const constraint of constraints) {\n const signature = constraintSignature(node, constraint);\n if (signature !== undefined) {\n keys.push(`${UNIQUE_KEY_PREFIX}${KEY_PART_SEPARATOR}${signature}`);\n }\n }\n\n return keys.length === 0 ? [UNBLOCKED_BUCKET_KEY] : keys;\n}\n\n/**\n * Buckets a kind's NEW nodes by their blocking key(s). A node may land in MORE\n * THAN ONE bucket — its `block()` bucket plus a bucket for each unique constraint\n * it satisfies — so two nodes sharing any blocking key co-bucket and are compared.\n *\n * @param newNodes The kind's new (fork-introduced) nodes. All nodes SHOULD be of\n * one kind; the caller invokes `blockNodes` once per resolved kind.\n * @param resolveConfig The kind's resolution config; its optional `block`\n * function supplies the application blocking key.\n * @param uniqueConstraints The kind's `unique` constraints from\n * `store.introspect().kinds[k].unique`. Pass an empty array when blocking\n * should rely on `block()` alone.\n * @returns A map from bucket key → that bucket's nodes. Iteration order of the\n * returned map is the lexicographic order of bucket keys, and each bucket's\n * node list is sorted by `node.id`, so the result is a pure, order-independent\n * function of the input node SET. A node may appear in several buckets;\n * candidate-gen dedups pairs so each is scored once.\n */\nexport function blockNodes<K extends NodeType>(\n newNodes: readonly Node<K>[],\n resolveConfig: Pick<ResolveConfig, \"block\">,\n uniqueConstraints: readonly UniqueIntrospection[] = [],\n): Map<string, Node<K>[]> {\n const buckets = new Map<string, Node<K>[]>();\n\n for (const node of newNodes) {\n for (const key of bucketKeysFor(\n node,\n resolveConfig.block,\n uniqueConstraints,\n )) {\n const bucket = buckets.get(key);\n if (bucket === undefined) {\n buckets.set(key, [node]);\n } else {\n bucket.push(node);\n }\n }\n }\n\n const sortedKeys = [...buckets.keys()].sort((left, right) =>\n compareStrings(left, right),\n );\n const ordered = new Map<string, Node<K>[]>();\n for (const key of sortedKeys) {\n const members = [...requireDefined(buckets.get(key))].sort((left, right) =>\n compareStrings(left.id, right.id),\n );\n ordered.set(key, members);\n }\n return ordered;\n}\n","import { requireDefined } from \"../utils/presence\";\n/**\n * The centralized property-conflict resolution rule (design §6.4 rule 4 / §7.3,\n * T8). Shared by canonical node-property union (T8 / `canonicalize.ts`) and edge\n * property-collision resolution (T9), so the determinism contract lives in\n * exactly one place.\n *\n * DETERMINISM CONTRACT — the single most important invariant of the merge:\n * Conflict resolution NEVER consults wall-clock arrival time. When a value\n * must be chosen among differing per-branch candidates, the choice is made on\n * a STABLE branch total order — either the caller-supplied\n * `MergeOptions.branchOrder`, or branch ids sorted lexicographically — captured\n * ONCE before any resolution runs. Two merges of the same branch set in any\n * order therefore resolve every conflict identically.\n */\nimport { canonicalValueKey } from \"./canonical-props\";\nimport { compareStrings } from \"./node-key\";\nimport type {\n EdgeId,\n GraphDef,\n JsonValue,\n NodeId,\n NodeType,\n} from \"./typegraph-internal\";\nimport type {\n BranchId,\n ConflictingValue,\n PropertyConflict,\n PropertyConflictPolicy,\n} from \"./types\";\n\n/**\n * The candidate values for one conflicted property, each tagged with the branch\n * that contributed it. Built by the union phases (node/edge) before delegating\n * to {@link resolveConflictValue}.\n */\ntype ConflictInput = Readonly<{\n /** The property name in conflict. */\n property: string;\n /** Every distinct contributing `(branchId, value)`, one per source. */\n values: readonly ConflictingValue[];\n /** The canonical survivor's own value — kept under the `\"flag\"` policy. */\n canonicalValue: JsonValue;\n}>;\n\n/**\n * Per-branch trust weights for the `\"provenanceWeighted\"` policy. Branches absent\n * from the map default to weight `0`. Ties are broken by the stable branch order.\n */\nexport type ProvenanceWeights = ReadonlyMap<BranchId, number>;\n\n/**\n * The captured, immutable resolution context. The stable branch order is passed\n * separately as a precomputed `branchRank` (built once via {@link buildBranchRank}\n * and shared across every conflict), so this context carries only the policy and\n * the optional `\"provenanceWeighted\"` weights.\n *\n * BRANCH ORDER IS A PRIORITY ORDER: the branch appearing EARLIER in\n * `MergeOptions.branchOrder` (lower rank) has higher precedence. `\"lastWriteWins\"`\n * therefore picks the value of the HIGHEST-PRIORITY branch (lowest rank / first\n * in the order) — the \"winning write\" is defined by the stable order, NOT by\n * wall-clock arrival. There is no wall-clock anywhere in this module.\n */\nexport type ResolutionContext<G extends GraphDef = GraphDef> = Readonly<{\n policy: PropertyConflictPolicy<G>;\n weights?: ProvenanceWeights;\n}>;\n\n/**\n * The outcome of resolving one property conflict: the surviving value and\n * whether the values actually differed (so callers know whether to record a\n * {@link PropertyConflict}).\n */\ntype ConflictResolution = Readonly<{\n value: JsonValue;\n conflicted: boolean;\n}>;\n\n/**\n * Builds the rank lookup for a stable branch order. Branch ids not present in\n * the supplied order are appended in lexicographic order after the explicit\n * ones, so an incomplete `branchOrder` is still total and deterministic.\n */\nexport function buildBranchRank(\n branchOrder: readonly BranchId[],\n allBranchIds: readonly BranchId[],\n): ReadonlyMap<BranchId, number> {\n const rank = new Map<BranchId, number>();\n let next = 0;\n for (const branchId of branchOrder) {\n if (!rank.has(branchId)) {\n rank.set(branchId, next);\n next += 1;\n }\n }\n const remaining = allBranchIds\n .filter((branchId) => !rank.has(branchId))\n .sort((left, right) => compareStrings(left, right));\n for (const branchId of remaining) {\n if (!rank.has(branchId)) {\n rank.set(branchId, next);\n next += 1;\n }\n }\n return rank;\n}\n\n/**\n * Returns the value contributed by the HIGHEST-PRIORITY branch — the one with\n * the lowest rank (earliest in the stable branch order). Ties (two contributions\n * sharing a rank, e.g. when the same branch staged two values) are broken by the\n * canonical serialization of the value, so the choice is fully deterministic.\n */\nfunction pickByPriority(\n values: readonly ConflictingValue[],\n branchRank: ReadonlyMap<BranchId, number>,\n): JsonValue {\n let chosen = requireDefined(values[0]);\n let chosenRank = branchRank.get(chosen.branchId) ?? Number.MAX_SAFE_INTEGER;\n for (const candidate of values.slice(1)) {\n const candidateRank =\n branchRank.get(candidate.branchId) ?? Number.MAX_SAFE_INTEGER;\n if (candidateRank < chosenRank) {\n chosen = candidate;\n chosenRank = candidateRank;\n } else if (\n candidateRank === chosenRank &&\n canonicalValueKey(candidate.value) < canonicalValueKey(chosen.value)\n ) {\n chosen = candidate;\n }\n }\n return chosen.value;\n}\n\n/**\n * Picks the value contributed by the highest-weight branch under\n * `\"provenanceWeighted\"`. Ties on weight fall back to the stable branch order\n * (highest-priority / lowest rank wins), then to canonical value order — never\n * wall-clock.\n */\nfunction pickByWeight(\n values: readonly ConflictingValue[],\n weights: ProvenanceWeights,\n branchRank: ReadonlyMap<BranchId, number>,\n): JsonValue {\n let chosen = requireDefined(values[0]);\n let chosenWeight = weights.get(chosen.branchId) ?? 0;\n let chosenRank = branchRank.get(chosen.branchId) ?? Number.MAX_SAFE_INTEGER;\n for (const candidate of values.slice(1)) {\n const candidateWeight = weights.get(candidate.branchId) ?? 0;\n const candidateRank =\n branchRank.get(candidate.branchId) ?? Number.MAX_SAFE_INTEGER;\n if (candidateWeight > chosenWeight) {\n chosen = candidate;\n chosenWeight = candidateWeight;\n chosenRank = candidateRank;\n continue;\n }\n if (candidateWeight === chosenWeight) {\n if (candidateRank < chosenRank) {\n chosen = candidate;\n chosenRank = candidateRank;\n } else if (\n candidateRank === chosenRank &&\n canonicalValueKey(candidate.value) < canonicalValueKey(chosen.value)\n ) {\n chosen = candidate;\n }\n }\n }\n return chosen.value;\n}\n\n/**\n * Returns whether every contributing value is deeply equal (so there is no real\n * conflict). Compares the {@link canonicalValueKey} (recursively key-sorted) form\n * so two branches that wrote a logically-equal object with different key order do\n * NOT register as a conflict.\n */\nfunction allValuesEqual(values: readonly ConflictingValue[]): boolean {\n if (values.length <= 1) {\n return true;\n }\n const first = canonicalValueKey(requireDefined(values[0]).value);\n return values.every(\n (candidate) => canonicalValueKey(candidate.value) === first,\n );\n}\n\n/**\n * A single `(branchId, props)` contribution to a property union — a cluster\n * member (node) or a collision-group member (edge's staged record). The union\n * phases differ in their surrounding base/survivor logic but agree on HOW to\n * gather a property's candidate values, so they share {@link collectConflictingValues}.\n */\ntype Contribution = Readonly<{\n branchId: BranchId;\n props: Readonly<Record<string, JsonValue>>;\n}>;\n\n/**\n * Collects the distinct `(branchId, value)` contributions for one property across\n * a set of contributions, in stable `(branchId, canonical-value)` order. Distinct\n * on `(branchId, value)`: two contributions from the same branch carrying the same\n * value collapse to one entry, but the same branch contributing two different\n * values is preserved (so an intra-branch contradiction stays visible).\n *\n * Shared by the node property union (T8) and the edge property union (T9) so the\n * determinism-critical dedupe + sort is defined exactly once and node/edge conflict\n * records are shaped identically.\n */\nexport function collectConflictingValues(\n property: string,\n contributions: readonly Contribution[],\n): readonly ConflictingValue[] {\n const seen = new Set<string>();\n const values: ConflictingValue[] = [];\n for (const { branchId, props } of contributions) {\n if (!(property in props)) {\n continue;\n }\n const value = props[property] as JsonValue;\n const dedupeKey = `${branchId}\\0${canonicalValueKey(value)}`;\n if (seen.has(dedupeKey)) {\n continue;\n }\n seen.add(dedupeKey);\n values.push({ branchId, value });\n }\n return [...values].sort((left, right) => {\n const byBranch = compareStrings(left.branchId, right.branchId);\n return byBranch === 0 ?\n compareStrings(\n canonicalValueKey(left.value),\n canonicalValueKey(right.value),\n )\n : byBranch;\n });\n}\n\n/**\n * Resolves one property conflict under the captured {@link ResolutionContext}.\n *\n * - If all contributing values are equal → that value, `conflicted: false`.\n * - `\"flag\"` → keep the canonical's value, `conflicted: true` (caller records a\n * {@link PropertyConflict}; no auto-resolution).\n * - `\"lastWriteWins\"` → the value of the HIGHEST-PRIORITY branch (earliest in the\n * stable order / lowest rank). NEVER wall-clock.\n * - `\"provenanceWeighted\"` → the value of the highest-weight branch (ties →\n * highest-priority branch → canonical value order).\n * - function policy → the value returned by the delegate.\n *\n * @param input The conflicted property, its tagged candidate values, and the\n * canonical survivor's own value.\n * @param context The captured policy + stable branch order + optional weights.\n * @param makeConflict Builds the {@link PropertyConflict}-shaped record passed to\n * a function policy. Kept as a callback so this module needs no knowledge of\n * the node-vs-edge entity shape.\n * @returns The surviving value and whether the values genuinely differed.\n */\nfunction resolveConflictValue<G extends GraphDef = GraphDef>(\n input: ConflictInput,\n context: ResolutionContext<G>,\n branchRank: ReadonlyMap<BranchId, number>,\n makeConflict: (\n resolution: JsonValue,\n ) => Parameters<\n Extract<PropertyConflictPolicy<G>, (...args: never[]) => unknown>\n >[0],\n): ConflictResolution {\n if (allValuesEqual(input.values)) {\n return {\n value: input.values[0]?.value ?? input.canonicalValue,\n conflicted: false,\n };\n }\n\n const { policy } = context;\n\n if (policy === \"flag\") {\n return { value: input.canonicalValue, conflicted: true };\n }\n if (policy === \"lastWriteWins\") {\n return {\n value: pickByPriority(input.values, branchRank),\n conflicted: true,\n };\n }\n if (policy === \"provenanceWeighted\") {\n const weights = context.weights ?? new Map<BranchId, number>();\n return {\n value: pickByWeight(input.values, weights, branchRank),\n conflicted: true,\n };\n }\n // Function policy: delegate, but first resolve a stable provisional value so\n // the conflict record handed to the delegate is itself deterministic.\n const provisional = pickByPriority(input.values, branchRank);\n const resolved = policy(makeConflict(provisional));\n return { value: resolved, conflicted: true };\n}\n\n/**\n * The resolve-and-record tail every property union shares (node cluster union T8,\n * edge collision union T9, inherited 3-way merge T8a): resolve the conflict, then —\n * if the values genuinely differed — build the public {@link PropertyConflict}. The\n * SINGLE place the conflict record is shaped, so the value the function policy sees\n * and the value recorded can never drift.\n *\n * `values` is the FULL contributing set the policy resolves over; `reportedValues`\n * is the PUBLIC subset (synthetic sentinels excluded) recorded on the conflict.\n */\nexport function resolvePropertyUnion<G extends GraphDef = GraphDef>(\n input: Readonly<{\n entityId: NodeId<NodeType> | EdgeId;\n kind: string;\n property: string;\n values: readonly ConflictingValue[];\n reportedValues: readonly ConflictingValue[];\n canonicalValue: JsonValue;\n }>,\n context: ResolutionContext<G>,\n branchRank: ReadonlyMap<BranchId, number>,\n): Readonly<{ value: JsonValue; conflict: PropertyConflict<G> | undefined }> {\n const makeRecord = (resolution: JsonValue): PropertyConflict<G> => ({\n entityId: input.entityId,\n kind: input.kind,\n property: input.property,\n values: input.reportedValues,\n resolution,\n });\n const resolved = resolveConflictValue(\n {\n property: input.property,\n values: input.values,\n canonicalValue: input.canonicalValue,\n },\n context,\n branchRank,\n (resolution) => makeRecord(resolution),\n );\n return {\n value: resolved.value,\n conflict: resolved.conflicted ? makeRecord(resolved.value) : undefined,\n };\n}\n","import { requireDefined } from \"../utils/presence\";\n/**\n * Canonical survivor selection + commutative property union (design §6.4 rule 3\n * & rule 4 / §7.3, T8).\n *\n * Given a {@link ClusterResult} (member ids) and the per-member, per-branch\n * property contributions, this module:\n *\n * 1. Picks the CANONICAL survivor — by default the member with the\n * lexicographically-minimal node id (`MergeOptions.canonical` overrides).\n * Because `generateId()` is nanoid (random, NOT time-prefixed), min-id is\n * independent of creation order — the canonical choice cannot leak the\n * order nodes were created or branches were merged in.\n * 2. UNIONS properties across all members: per property, collect every\n * `(branchId, value)`; if all agree → that value; if they differ → defer to\n * the conflict policy on a STABLE non-wall-clock branch order (T8 /\n * `conflict-policy.ts`), recording a {@link PropertyConflict}.\n *\n * The result is a pure function of the (unordered) member set + the captured\n * branch order, so shuffling members or branches yields an identical resolution.\n */\nimport type { ClusterResult } from \"./clustering\";\nimport type { ProvenanceWeights, ResolutionContext } from \"./conflict-policy\";\nimport {\n collectConflictingValues,\n resolvePropertyUnion,\n} from \"./conflict-policy\";\nimport { compareMergeKeys, compareStrings, idOf, mergeKeyOf } from \"./node-key\";\nimport type {\n GraphDef,\n JsonValue,\n NodeId,\n NodeType,\n} from \"./typegraph-internal\";\nimport type {\n BranchId,\n ConflictingValue,\n EntityResolution,\n PropertyConflict,\n PropertyConflictPolicy,\n ResolvedCluster,\n} from \"./types\";\nimport { asBranchId } from \"./types\";\n\n/**\n * Reserved provenance \"branch\" for a BASE contribution (§6.4-D). A committed base\n * member has no real branch; this BranchId-shaped sentinel is the key its\n * contributions carry through the value union and the provenance records, so those\n * paths tolerate a base member without a separate code path. It is NOT a real branch\n * id — it is EXCLUDED from the public {@link EntityResolution.branchOrigins} (which\n * lists only real contributing branches), and callers must never mint a branch with\n * this reserved value (rejected at the merge boundary; kept NUL-free so it round-trips\n * through `persistProvenance` on every backend).\n */\nexport const BASE_PROVENANCE_BRANCH: BranchId =\n asBranchId(\"__committed_base__\");\n\n/** A node id in its untyped (`NodeType`-default) branded form. */\ntype AnyNodeId = NodeId<NodeType>;\n\n/**\n * Where a {@link ClusterMember}'s contribution originated: a branch's STAGED diff,\n * or a committed BASE node a base source pulled into the cluster (design §6.4-C).\n * The mandatory `branchId` cannot represent a base member, so this discriminator is\n * what lets the reconciler tell the two apart — it enforces base-id-wins (§6.4-C: a\n * base member is the canonical survivor, see {@link pickClusterSurvivor}) and tags\n * base provenance with {@link BASE_PROVENANCE_BRANCH} (§6.4-D). The new-vs-base\n * sources (`baseUnique`) emit `\"base\"` members; the public snapshot `merge()` path\n * stays staged-only, so every member there is `\"staged\"`.\n */\ntype MemberOrigin = \"staged\" | \"base\";\n\n/**\n * One member of a cluster, with the parsed props the contributing branch staged\n * for it. A node that appears in several branches contributes several\n * {@link ClusterMember} entries (one per branch), so property differences across\n * branches surface as conflicts.\n */\nexport type ClusterMember = Readonly<{\n origin: MemberOrigin;\n id: AnyNodeId;\n kind: string;\n branchId: BranchId;\n props: Readonly<Record<string, JsonValue>>;\n}>;\n\n/**\n * The fully-resolved canonical entity for one cluster: the survivor id, the\n * unioned property bag, the {@link EntityResolution} record, and any\n * {@link PropertyConflict}s the union surfaced.\n */\nexport type CanonicalEntity = Readonly<{\n canonicalId: AnyNodeId;\n kind: string;\n props: Readonly<Record<string, JsonValue>>;\n resolution: EntityResolution;\n conflicts: readonly PropertyConflict[];\n}>;\n\n/**\n * Bare-id reference selector over a PUBLIC {@link ResolvedCluster}: the member with\n * the lexicographically-minimal node id, or the caller's override. It is NOT the\n * live survivor selector — the merge path selects survivors via\n * {@link pickClusterSurvivor}, which is cross-kind-aware (composite `(kind, id)`\n * keys), enforces base-id-wins, and is where the {@link MergeOptions.canonical} hook\n * is actually consulted. Kept as the documented bare-id default a `canonical` hook\n * mirrors; do not wire new phases onto this helper.\n */\nexport function pickCanonical(\n cluster: ResolvedCluster,\n override?: (cluster: ResolvedCluster) => AnyNodeId,\n): AnyNodeId {\n if (override !== undefined) {\n return override(cluster);\n }\n return requireDefined(\n [...cluster.members].sort((left, right) => compareStrings(left, right))[0],\n );\n}\n\n/**\n * Selects a cluster's canonical survivor MEMBER, enforcing BASE-ID-WINS (§6.4-C)\n * UPSTREAM of the `MergeOptions.canonical` hook. Returning the member (not just its\n * id) carries the survivor's KIND alongside its id, so the canonical entity's kind is\n * the survivor's own kind — never a different-kind member that merely shares the id\n * string (the cross-kind identity hazard).\n *\n * - if the cluster contains a BASE member, the committed base identity is the\n * survivor and the hook is BYPASSED — the committed identity (and everything\n * pointing at it) must stay stable, so this is a commit-correctness invariant,\n * not a survivor preference. By §6.4-A a merged cluster holds ≤1 base member; the\n * min base `(id, kind)` is taken defensively so selection is deterministic even\n * before that guard lands.\n * - otherwise the cluster is pure staged-vs-staged and the hook (mapped over the\n * bare-id view of the cluster) or the min-`(id, kind)` default applies.\n */\nfunction pickClusterSurvivor(\n members: readonly ClusterMember[],\n cluster: ClusterResult,\n canonicalOverride?: (cluster: ResolvedCluster) => AnyNodeId,\n preferKind?: (kinds: readonly string[]) => string | undefined,\n): ClusterMember {\n const byKey = (left: ClusterMember, right: ClusterMember): number =>\n compareMergeKeys(mergeKeyOf(left), mergeKeyOf(right));\n\n // base-id-wins (§6.4-C): the committed identity is the survivor outright. By the\n // staged-only ontology-retype rule, a base member never shares an id with a\n // different-kind member, so no cross-kind kind choice arises here.\n const baseMembers = members\n .filter((member) => member.origin === \"base\")\n .sort(byKey);\n if (baseMembers.length > 0) {\n return requireDefined(baseMembers[0]);\n }\n\n // The survivor's bare id: the override's pick (mapped over the bare-id view of the\n // cluster) when it names a real member, else the minimum identity's id.\n let canonicalId: AnyNodeId | undefined;\n if (canonicalOverride !== undefined) {\n const chosen = canonicalOverride({ members: cluster.members.map(idOf) });\n if (members.some((member) => member.id === chosen)) {\n canonicalId = chosen;\n }\n }\n if (canonicalId === undefined) {\n const minIdentity = [...cluster.members].sort((left, right) =>\n compareMergeKeys(left, right),\n )[0];\n canonicalId =\n minIdentity === undefined ?\n requireDefined(members[0]).id\n : idOf(minIdentity);\n }\n\n // Among the members AT that id, choose the KIND. An ontology-retype cluster carries\n // several subtype-compatible kinds under one id; `preferKind` selects the\n // MOST-SPECIFIC one, BYPASSING the bare-id hook (which cannot tell `Doctor:x` from\n // `SpecialistDoctor:x`). Otherwise the id has a single kind and the min `(id, kind)`\n // member is taken.\n const membersAtId = members.filter((member) => member.id === canonicalId);\n if (membersAtId.length === 0) {\n return requireDefined([...members].sort(byKey)[0]);\n }\n const kinds = [...new Set(membersAtId.map((member) => member.kind))];\n const chosenKind =\n preferKind !== undefined && kinds.length > 1 ?\n preferKind(kinds)\n : undefined;\n return (\n (chosenKind === undefined ? undefined : (\n membersAtId.find((member) => member.kind === chosenKind)\n )) ?? requireDefined([...membersAtId].sort(byKey)[0])\n );\n}\n\nfunction findPreferredMember(\n members: readonly ClusterMember[],\n property: string,\n preferredBranchId: BranchId | undefined,\n): ClusterMember | undefined {\n if (preferredBranchId === undefined) {\n return undefined;\n }\n return members.find(\n (member) =>\n member.branchId === preferredBranchId && property in member.props,\n );\n}\n\nfunction memberPropertyValue(\n member: ClusterMember,\n property: string,\n): JsonValue | undefined {\n if (!(property in member.props)) {\n return undefined;\n }\n return member.props[property];\n}\n\nfunction pickCanonicalPropertyValue(\n canonicalMember: ClusterMember,\n members: readonly ClusterMember[],\n property: string,\n values: readonly ConflictingValue[],\n preferredBranchId: BranchId | undefined,\n): JsonValue {\n const preferredMember = findPreferredMember(\n members,\n property,\n preferredBranchId,\n );\n const preferredValue =\n preferredMember === undefined ? undefined : (\n memberPropertyValue(preferredMember, property)\n );\n if (preferredValue !== undefined) {\n return preferredValue;\n }\n\n const canonicalValue = memberPropertyValue(canonicalMember, property);\n return canonicalValue === undefined ?\n requireDefined(values[0]).value\n : canonicalValue;\n}\n\n/**\n * Unions the properties of a cluster's members into a single canonical property\n * bag, resolving any per-property disagreement via the conflict policy on a\n * stable branch order. Returns the merged props plus a {@link PropertyConflict}\n * for every property that genuinely differed.\n *\n * @param canonicalId The survivor id (from {@link pickClusterSurvivor}); the entity id\n * on every recorded conflict.\n * @param kind The canonical entity's kind, recorded on each conflict.\n * @param members Every `(branchId, props)` contribution for this cluster.\n * @param context The captured policy + stable branch order + optional weights.\n * @param branchRank The branch rank lookup (built once, shared across clusters).\n */\nfunction unionProperties(\n canonicalMember: ClusterMember,\n members: readonly ClusterMember[],\n context: ResolutionContext<GraphDef>,\n baseContext: ResolutionContext<GraphDef>,\n branchRank: ReadonlyMap<BranchId, number>,\n preferredBranchId?: BranchId,\n): Readonly<{\n props: Record<string, JsonValue>;\n conflicts: PropertyConflict[];\n}> {\n const canonicalId = canonicalMember.id;\n const kind = canonicalMember.kind;\n const hasBaseMember = members.some((member) => member.origin === \"base\");\n\n const propertyNames = new Set<string>();\n for (const member of members) {\n for (const name of Object.keys(member.props)) {\n propertyNames.add(name);\n }\n }\n\n const props: Record<string, JsonValue> = {};\n const conflicts: PropertyConflict[] = [];\n\n for (const property of [...propertyNames].sort((left, right) =>\n compareStrings(left, right),\n )) {\n const values = collectConflictingValues(property, members);\n if (values.length === 0) {\n continue;\n }\n const canonicalValue = pickCanonicalPropertyValue(\n canonicalMember,\n members,\n property,\n values,\n preferredBranchId,\n );\n\n // A disagreement that involves a committed BASE value is governed by the\n // SEPARATE onBasePropertyConflict policy (§6.4-C) — it must not inherit the\n // staged policy, which could let a branch overwrite committed data. Because\n // base-id-wins makes the base member canonical, `canonicalValue` is already the\n // committed value, so `\"flag\"` keeps it. A property the base lacks is a pure\n // gap-fill / staged-vs-staged conflict and uses the staged policy.\n const baseInvolved =\n hasBaseMember &&\n members.some(\n (member) => member.origin === \"base\" && property in member.props,\n );\n\n // Resolution math sees the FULL contributions (including the base value, so the\n // disagreement is detected and base-id-wins resolves it). But the reserved\n // {@link BASE_PROVENANCE_BRANCH} sentinel is NOT a real branch, so it is excluded\n // from the PUBLIC conflict's `values` — exactly as it is from `branchOrigins`. The\n // committed value the base contributed still surfaces as the conflict `resolution`.\n const reportedValues = values.filter(\n (value) =>\n value.branchId !== BASE_PROVENANCE_BRANCH &&\n value.branchId !== preferredBranchId,\n );\n const { value, conflict } = resolvePropertyUnion(\n {\n entityId: canonicalId,\n kind,\n property,\n values,\n reportedValues,\n canonicalValue,\n },\n baseInvolved ? baseContext : context,\n branchRank,\n );\n props[property] = value;\n if (conflict !== undefined) {\n conflicts.push(conflict);\n }\n }\n\n return { props, conflicts };\n}\n\n/**\n * Resolves a single cluster into its {@link CanonicalEntity}: picks the survivor,\n * unions properties under the conflict policy, and assembles the\n * {@link EntityResolution} record.\n *\n * @param cluster The cluster's member ids (id-sorted from T8 clustering).\n * @param members The per-branch property contributions for those member ids.\n * @param policy The staged-vs-staged property-conflict policy.\n * @param branchRank The captured stable branch rank (built once).\n * @param weights Optional per-branch trust weights for `\"provenanceWeighted\"`.\n * @param canonicalOverride Optional `MergeOptions.canonical` survivor selector.\n * @param basePolicy The SEPARATE base↔branch policy (§6.4-C, `onBasePropertyConflict`)\n * governing conflicts that involve a committed base value. Defaults to `\"flag\"`\n * (keep committed value) — it never inherits `policy`.\n */\nexport function canonicalizeCluster(\n cluster: ClusterResult,\n members: readonly ClusterMember[],\n policy: PropertyConflictPolicy,\n branchRank: ReadonlyMap<BranchId, number>,\n weights?: ProvenanceWeights,\n canonicalOverride?: (cluster: ResolvedCluster) => AnyNodeId,\n basePolicy: PropertyConflictPolicy = \"flag\",\n preferKind?: (kinds: readonly string[]) => string | undefined,\n preferredBranchId?: BranchId,\n): CanonicalEntity {\n const survivor = pickClusterSurvivor(\n members,\n cluster,\n canonicalOverride,\n preferKind,\n );\n const canonicalId = survivor.id;\n const kind = survivor.kind;\n\n const context: ResolutionContext<GraphDef> = {\n policy,\n ...(weights === undefined ? {} : { weights }),\n };\n const baseContext: ResolutionContext<GraphDef> = {\n policy: basePolicy,\n ...(weights === undefined ? {} : { weights }),\n };\n\n const { props, conflicts } = unionProperties(\n survivor,\n members,\n context,\n baseContext,\n branchRank,\n preferredBranchId,\n );\n\n // The public resolution reports the DISTINCT bare member ids; the cluster carries\n // composite `(kind, id)` keys, so project each to its id and dedup (an ontology\n // retype puts several kinds under one id, which collapses to a single member id).\n const memberIds = [\n ...new Set(cluster.members.map((member) => idOf(member))),\n ].sort((left, right) => compareStrings(left, right));\n // `branchOrigins` lists the REAL contributing branches; the reserved\n // {@link BASE_PROVENANCE_BRANCH} sentinel a base member carries is NOT a branch, so\n // it is excluded from this public field (it still flows through the value union and\n // the provenance records, which is where a base contribution is tracked).\n const branchOrigins = [\n ...new Set(\n members\n .map((member) => member.branchId)\n .filter(\n (branchId) =>\n branchId !== BASE_PROVENANCE_BRANCH &&\n branchId !== preferredBranchId,\n ),\n ),\n ].sort((left, right) => compareStrings(left, right));\n\n const resolution: EntityResolution = {\n canonicalId,\n memberIds,\n kind,\n branchOrigins,\n };\n\n return { canonicalId, kind, props, resolution, conflicts };\n}\n","import { requireDefined } from \"../utils/presence\";\n/**\n * A deterministic disjoint-set forest (union-find), shared by every merge phase\n * that folds a set of items into equivalence classes — ontology equivalence\n * (`closures.ts`), candidate clustering (`clustering.ts`), and cross-kind identity\n * grouping (`sources.ts`).\n *\n * Determinism is the load-bearing property: path compression keeps `find` flat,\n * and the union rule makes the chosen representative a pure function of the union\n * SET, not the union order — the item that compares LEAST (by the `compare`\n * supplied at construction) always becomes the root. Two runs that union the same\n * pairs in any order therefore produce identical roots, which is what lets the\n * merge's partitions be order-independent. Callers that only need the partition\n * (and re-sort each group) may pass any total order; callers that expose the\n * representative (e.g. an equivalence-class canonical) pass the comparator whose\n * minimum they want as the representative.\n */\nexport class UnionFind<T> {\n private readonly parent = new Map<T, T>();\n\n constructor(private readonly compare: (left: T, right: T) => number) {}\n\n /** Adds `value` as its own singleton set if it is not already present. */\n add(value: T): void {\n if (!this.parent.has(value)) {\n this.parent.set(value, value);\n }\n }\n\n /** Returns the representative of `value`'s set, compressing the path to it. */\n find(value: T): T {\n this.add(value);\n let root = value;\n while (this.parent.get(root) !== root) {\n root = requireDefined(this.parent.get(root));\n }\n // Path compression: point every node on the walk straight at the root.\n let cursor = value;\n while (cursor !== root) {\n const next = requireDefined(this.parent.get(cursor));\n this.parent.set(cursor, root);\n cursor = next;\n }\n return root;\n }\n\n /** Merges the sets of `left` and `right`; the `compare`-minimal root wins. */\n union(left: T, right: T): void {\n const leftRoot = this.find(left);\n const rightRoot = this.find(right);\n if (leftRoot === rightRoot) {\n return;\n }\n if (this.compare(leftRoot, rightRoot) <= 0) {\n this.parent.set(rightRoot, leftRoot);\n } else {\n this.parent.set(leftRoot, rightRoot);\n }\n }\n\n /** Every value seen by {@link add}/{@link find}/{@link union}, insertion order. */\n members(): readonly T[] {\n return [...this.parent.keys()];\n }\n}\n","/**\n * Ontology subclass-closure glue over TypeGraph's PUBLIC closure utilities.\n *\n * TypeGraph 0.29.0 exports `computeTransitiveClosure` / `invertClosure` /\n * `isReachable` from the package root, and `store.introspect().ontology` exposes\n * the declared meta-edges as `{ metaEdge, from, to, origin }` records. This\n * module is therefore THIN GLUE: it projects the introspected ontology onto the\n * `[child, parent]` relation pairs the public closure builder expects, folds in\n * `equivalentTo` equivalence classes, and exposes the {@link isReachable}\n * accessor reconcileTypes (T10) consumes. There is deliberately NO local Warshall\n * reimplementation — the transitive work is done entirely by the public\n * `computeTransitiveClosure`.\n *\n * Direction convention (verified against `store.introspect()` at runtime):\n * `subClassOf(Child, Parent)` introspects as `{ metaEdge: \"subClassOf\",\n * from: \"Child\", to: \"Parent\" }`. So `from` is the more-specific (child) type\n * and `to` is the more-general (parent) type, matching the `[child, parent]`\n * relation pairs `computeTransitiveClosure` consumes, where `isReachable(closure,\n * child, ancestor)` answers \"is `child` a (transitive) subclass of `ancestor`?\".\n */\nimport { compareStrings } from \"./node-key\";\nimport type { OntologyIntrospection } from \"./typegraph-internal\";\nimport {\n computeTransitiveClosure,\n isReachable as isReachablePublic,\n} from \"./typegraph-internal\";\nimport { UnionFind } from \"./union-find\";\n\n/**\n * The meta-edge name identifying a subclass relation in `introspect().ontology`.\n */\nexport const SUB_CLASS_OF_META_EDGE = \"subClassOf\";\n\n/**\n * The meta-edge name identifying an equivalence relation in\n * `introspect().ontology`. `equivalentTo` edges are folded into symmetric\n * equivalence classes so that equivalent types share each other's ancestors and\n * descendants.\n */\nconst EQUIVALENT_TO_META_EDGE = \"equivalentTo\";\n\n/**\n * An immutable subclass closure plus the equivalence-class canonicalization used\n * to fold `equivalentTo` relations.\n *\n * - `closure` maps each (canonicalized) child type to the set of all its\n * (canonicalized) transitive ancestors, as produced by the public\n * `computeTransitiveClosure`.\n * - `canonicalOf` maps every type seen in the ontology to its equivalence-class\n * representative (the lexicographically-smallest member). Types not involved\n * in any `equivalentTo` relation map to themselves.\n */\nexport type SubClassClosure = Readonly<{\n closure: ReadonlyMap<string, ReadonlySet<string>>;\n canonicalOf: ReadonlyMap<string, string>;\n}>;\n\n/**\n * Builds the subclass closure from an introspected ontology.\n *\n * Steps:\n * 1. Fold every `equivalentTo` relation into a union-find so equivalent types\n * collapse to a single deterministic representative.\n * 2. Project every `subClassOf` relation onto a `[childRep, parentRep]` pair\n * (each endpoint canonicalized to its equivalence representative). Self\n * loops introduced by equivalence are dropped — a type is never its own\n * strict subclass.\n * 3. Hand the relation pairs to the PUBLIC `computeTransitiveClosure`. No local\n * transitive-closure logic exists here.\n *\n * @param ontology The `store.introspect().ontology` array.\n * @returns A `SubClassClosure` queryable via `isReachable` (which canonicalizes\n * its inputs through the equivalence map).\n */\nexport function buildSubClassClosure(\n ontology: readonly OntologyIntrospection[],\n): SubClassClosure {\n // Union by lexicographically-smaller representative, so each equivalence class's\n // canonical is its lex-min member, independent of relation insertion order.\n const unionFind = new UnionFind<string>(compareStrings);\n\n for (const relation of ontology) {\n unionFind.add(relation.from);\n unionFind.add(relation.to);\n if (relation.metaEdge === EQUIVALENT_TO_META_EDGE) {\n unionFind.union(relation.from, relation.to);\n }\n }\n\n const canonicalOf = new Map<string, string>();\n for (const value of unionFind.members()) {\n canonicalOf.set(value, unionFind.find(value));\n }\n\n const relationKeys = new Set<string>();\n const relations: (readonly [string, string])[] = [];\n for (const relation of ontology) {\n if (relation.metaEdge !== SUB_CLASS_OF_META_EDGE) {\n continue;\n }\n const child = canonicalOf.get(relation.from) ?? relation.from;\n const parent = canonicalOf.get(relation.to) ?? relation.to;\n if (child === parent) {\n continue;\n }\n const key = `${child}\\0${parent}`;\n if (relationKeys.has(key)) {\n continue;\n }\n relationKeys.add(key);\n relations.push([child, parent]);\n }\n\n return {\n closure: computeTransitiveClosure(relations),\n canonicalOf,\n };\n}\n\n/**\n * Resolves a type name to its equivalence-class representative, falling back to\n * the name itself when the type was never seen in the ontology.\n */\nfunction canonicalType(closure: SubClassClosure, type: string): string {\n return closure.canonicalOf.get(type) ?? type;\n}\n\n/**\n * Reports whether `from` is a (transitive) subclass of `to`.\n *\n * Both arguments are canonicalized through the equivalence map first, then the\n * PUBLIC `isReachable` is consulted. Equivalent-but-distinct types (e.g.\n * `equivalentTo(Physician, Doctor)`) are treated as mutually reachable. A type\n * is NOT considered a subclass of itself (the relation is strict / irreflexive),\n * matching the public closure's non-reflexive semantics.\n *\n * @param closure The closure produced by `buildSubClassClosure`.\n * @param from The candidate descendant (more-specific) type.\n * @param to The candidate ancestor (more-general) type.\n */\nexport function isReachable(\n closure: SubClassClosure,\n from: string,\n to: string,\n): boolean {\n const fromRep = canonicalType(closure, from);\n const toRep = canonicalType(closure, to);\n if (fromRep === toRep) {\n // Distinct names that fold to the same equivalence class are mutually\n // reachable; identical names are NOT (strict subclass relation).\n return from !== to;\n }\n return isReachablePublic(closure.closure, fromRep, toRep);\n}\n","import { requireDefined } from \"../utils/presence\";\n/**\n * Pluggable, symmetric candidate-pair similarity scoring (design §8, T6).\n *\n * Four strategy kinds, two of which are the ZERO-EMBEDDING P0 default:\n *\n * - `custom` — the caller's own `score(a, b)` function, clamped to `[0, 1]`.\n * - `fulltext` — an IN-MEMORY Sørensen–Dice trigram coefficient over the\n * configured `fields` of the two staged nodes. No embeddings,\n * no DB round-trips, identical across every backend. This is\n * the portable scorer the FHIR demo runs on.\n * - `vector` / `hybrid` — REAL embeddings scored IN MEMORY. An injected\n * {@link import(\"./types\").Embedder} (precomputed by `merge()`\n * into `ctx.embeddings`, a text→vector lookup) turns each node's\n * configured field text into a vector; the pair is scored by\n * cosine. `vector` is pure cosine over one field; `hybrid` blends\n * cosine with the Dice trigram by `weights` (default 0.5 / 0.5).\n * Staged candidate rows are unindexed, so a backend ANN index\n * cannot score them pairwise — exact in-memory cosine is the right\n * tool at candidate-dedup scale AND is deterministic (the merge\n * contract). With NO embedder configured (`ctx.embeddings`\n * absent), scoring fails with a typed\n * {@link SimilarityUnavailableError}.\n *\n * IMPORTANT: this module never touches `store.search.fulltext`. Staged candidate\n * nodes are unindexed in the working copy, so the DB fulltext index cannot score\n * them; the in-memory Dice scorer is the only correct option for staged\n * candidate generation. `store.search.fulltext` is reserved for the T11 parity\n * probe.\n *\n * Symmetry is a load-bearing invariant: clustering treats candidate edges as\n * undirected, so `scorePair(a, b)` MUST equal `scorePair(b, a)`. The Dice\n * coefficient is symmetric by construction; the `custom` branch documents the\n * requirement and the caller is responsible for honoring it.\n */\nimport { canonicalValueKey } from \"./canonical-props\";\nimport { SimilarityUnavailableError } from \"./errors\";\nimport type { MergeKey } from \"./node-key\";\nimport type { Result } from \"./result\";\nimport { err, ok } from \"./result\";\nimport type {\n GraphBackend,\n JsonValue,\n Node,\n NodeType,\n} from \"./typegraph-internal\";\nimport type { SimilarityStrategy } from \"./types\";\n\n/**\n * Ambient context a scorer needs beyond the two nodes.\n *\n * - `backend` is carried for diagnostics (the dialect in error details).\n * - `embeddings` is the precomputed text→vector lookup `merge()` builds by running\n * the injected {@link import(\"./types\").Embedder} over every staged field text of\n * the `vector`/`hybrid` kinds. Its PRESENCE means an embedder was configured;\n * its ABSENCE makes a `vector`/`hybrid` strategy fail with\n * {@link SimilarityUnavailableError}. `fulltext`/`custom` never read it.\n */\nexport type SimilarityContext = Readonly<{\n backend: GraphBackend;\n embeddings?: ReadonlyMap<string, Float32Array>;\n}>;\n\n/** Lower bound of the similarity codomain. */\nconst MIN_SCORE = 0;\n\n/** Upper bound of the similarity codomain. */\nconst MAX_SCORE = 1;\n\n/**\n * Sub-threshold sentinel returned by {@link scorePrepared} for a pair with NO\n * comparable text (one side has no value in the scoring field). It is BELOW\n * {@link MIN_SCORE}, and the kind's `threshold` is validated to `[0, 1]`, so a\n * textless pair can never clear ANY threshold — including `threshold: 0`, where\n * a `MIN_SCORE` (0) return would otherwise pass `score >= threshold` and merge two\n * distinct entities that share no evidence. The standalone {@link scorePair}\n * surfaces this as `MIN_SCORE` to keep its `[0, 1]` contract; only candidate-gen\n * (via {@link createPairScorer} + the threshold gate) treats it as \"never a match\".\n */\nconst NO_EVIDENCE_SCORE = -1;\n\n/** Trigram window length for the Sørensen–Dice coefficient. */\nconst TRIGRAM_LENGTH = 3;\n\n/**\n * Padding character framing a normalized string before trigram extraction, so\n * leading/trailing characters are weighted like interior ones and very short\n * strings still produce trigrams. A space is conventional and cannot appear in a\n * trigram alongside itself for non-trivial inputs.\n */\nconst TRIGRAM_PAD = \" \";\n\n/**\n * Clamps an arbitrary number into the `[0, 1]` similarity codomain. `NaN`\n * collapses to {@link MIN_SCORE} so a misbehaving custom scorer can never inject\n * a non-comparable score into clustering.\n */\nfunction clampScore(value: number): number {\n if (Number.isNaN(value)) {\n return MIN_SCORE;\n }\n if (value < MIN_SCORE) {\n return MIN_SCORE;\n }\n if (value > MAX_SCORE) {\n return MAX_SCORE;\n }\n return value;\n}\n\n/**\n * Reads a single schema field off a node. `Node<N>` spreads its schema\n * properties at the top level (e.g. `node.name`, not `node.props.name`), so a\n * field is indexed directly on the node.\n */\nfunction readField(node: Node<NodeType>, field: string): unknown {\n return (node as unknown as Record<string, unknown>)[field];\n}\n\n/**\n * Concatenates a node's configured `fields` into a single lowercase comparison\n * string. Non-string field values are coerced via `String(...)`; absent /\n * `undefined` fields contribute nothing. Fields are joined with a space so two\n * adjacent fields cannot fuse into a spurious cross-field trigram.\n *\n * Exported so `merge()`'s embedding precompute keys the text→vector lookup by the\n * EXACT same text `scorePair` looks up — there is a single source of truth for \"the\n * text of a node under a strategy's fields\", so the precompute and the scorer can\n * never disagree on what to embed.\n */\nexport function fieldText(\n node: Node<NodeType>,\n fields: readonly string[],\n): string {\n const parts: string[] = [];\n for (const field of fields) {\n const value = readField(node, field);\n if (value === undefined || value === null) {\n continue;\n }\n parts.push(stringifyFieldValue(value));\n }\n return parts.join(TRIGRAM_PAD).toLowerCase();\n}\n\nfunction stringifyFieldValue(value: unknown): string {\n if (typeof value === \"string\") {\n return value;\n }\n if (\n typeof value === \"number\" ||\n typeof value === \"boolean\" ||\n typeof value === \"bigint\"\n ) {\n return String(value);\n }\n // Objects/arrays: canonical (recursively key-sorted) JSON so two\n // logically-equal values written with different key order yield the same\n // comparison text — matching canonicalValueKey used everywhere else.\n return canonicalValueKey(value as JsonValue);\n}\n\n/**\n * Extracts the trigram MULTISET of a normalized string as a count map. A\n * multiset (not a set) is required so repeated trigrams contribute their full\n * multiplicity to the Dice intersection, matching the standard Sørensen–Dice\n * formulation `2·|A∩B| / (|A|+|B|)` over bags.\n */\nfunction trigramMultiset(text: string): Map<string, number> {\n const counts = new Map<string, number>();\n if (text.length === 0) {\n return counts;\n }\n const padded = `${TRIGRAM_PAD}${text}${TRIGRAM_PAD}`;\n for (let index = 0; index + TRIGRAM_LENGTH <= padded.length; index += 1) {\n const gram = padded.slice(index, index + TRIGRAM_LENGTH);\n counts.set(gram, (counts.get(gram) ?? 0) + 1);\n }\n return counts;\n}\n\n/** Total cardinality (with multiplicity) of a trigram multiset. */\nfunction multisetSize(counts: Map<string, number>): number {\n let total = 0;\n for (const count of counts.values()) {\n total += count;\n }\n return total;\n}\n\n/**\n * Multiset intersection cardinality: for every shared trigram, the lesser of\n * the two multiplicities.\n */\nfunction multisetIntersectionSize(\n left: Map<string, number>,\n right: Map<string, number>,\n): number {\n let shared = 0;\n for (const [gram, leftCount] of left) {\n const rightCount = right.get(gram);\n if (rightCount !== undefined) {\n shared += Math.min(leftCount, rightCount);\n }\n }\n return shared;\n}\n\n/**\n * Computes the symmetric Sørensen–Dice trigram coefficient of two raw strings:\n * lowercase, pad, extract trigram multisets, then `2·|A∩B| / (|A|+|B|)`.\n *\n * Edge cases:\n * - Two empty strings score {@link MAX_SCORE} (vacuously identical).\n * - One empty and one non-empty score {@link MIN_SCORE}.\n *\n * Exported so the determinism / acceptance tests can assert the metric directly.\n */\n/**\n * Sørensen–Dice coefficient over two PRECOMPUTED trigram multisets — the metric\n * core, with the same empty-input rules as {@link diceTrigramSimilarity}. The\n * candidate scorer prepares each node's multiset ONCE and calls this directly, so\n * a node's trigrams are built once rather than rebuilt for every pair it joins.\n */\nfunction diceFromMultisets(\n left: Map<string, number>,\n right: Map<string, number>,\n): number {\n const leftSize = multisetSize(left);\n const rightSize = multisetSize(right);\n if (leftSize === 0 && rightSize === 0) {\n return MAX_SCORE;\n }\n if (leftSize === 0 || rightSize === 0) {\n return MIN_SCORE;\n }\n const shared = multisetIntersectionSize(left, right);\n return (2 * shared) / (leftSize + rightSize);\n}\n\nexport function diceTrigramSimilarity(left: string, right: string): number {\n return diceFromMultisets(\n trigramMultiset(left.toLowerCase()),\n trigramMultiset(right.toLowerCase()),\n );\n}\n\n/**\n * The field(s) whose text a `vector`/`hybrid` strategy embeds, or `undefined` for\n * the zero-embedding strategies (`fulltext`/`custom`). `merge()`'s precompute uses\n * this to decide which staged texts to embed; `scorePair` uses the SAME selection\n * implicitly via {@link fieldText}, so the embedded text and the looked-up text\n * match exactly.\n */\nexport function embeddingFields(\n strategy: SimilarityStrategy,\n): readonly string[] | undefined {\n switch (strategy.kind) {\n case \"vector\": {\n return [strategy.field];\n }\n case \"hybrid\": {\n return strategy.fields;\n }\n case \"fulltext\":\n case \"custom\": {\n return undefined;\n }\n default: {\n const exhaustive: never = strategy;\n throw new Error(\n `Unhandled similarity strategy: ${JSON.stringify(exhaustive)}`,\n );\n }\n }\n}\n\n/**\n * Cosine similarity of two equal-length vectors, in `[-1, 1]`. Computed in a fixed\n * index order so it is deterministic. Returns {@link MIN_SCORE} for a dimension\n * mismatch or a zero-magnitude vector (no comparable direction → no evidence),\n * never `NaN`. `scorePair` clamps the result into the `[0, 1]` similarity codomain.\n *\n */\nfunction cosineSimilarity(left: Float32Array, right: Float32Array): number {\n if (left.length !== right.length || left.length === 0) {\n return MIN_SCORE;\n }\n let dot = 0;\n let leftMagnitude = 0;\n let rightMagnitude = 0;\n for (let index = 0; index < left.length; index += 1) {\n const leftComponent = requireDefined(left[index]);\n const rightComponent = requireDefined(right[index]);\n dot += leftComponent * rightComponent;\n leftMagnitude += leftComponent * leftComponent;\n rightMagnitude += rightComponent * rightComponent;\n }\n if (leftMagnitude === 0 || rightMagnitude === 0) {\n return MIN_SCORE;\n }\n return dot / (Math.sqrt(leftMagnitude) * Math.sqrt(rightMagnitude));\n}\n\n/**\n * Cosine of the two field texts' precomputed vectors. A text whose vector is\n * absent from the lookup (only possible if the precompute and scorer disagreed —\n * they cannot, since both go through {@link fieldText}) scores {@link MIN_SCORE}\n * defensively rather than throwing.\n */\nfunction cosineFromLookup(\n embeddings: ReadonlyMap<string, Float32Array>,\n leftText: string,\n rightText: string,\n): number {\n const leftVector = embeddings.get(leftText);\n const rightVector = embeddings.get(rightText);\n if (leftVector === undefined || rightVector === undefined) {\n return MIN_SCORE;\n }\n return cosineSimilarity(leftVector, rightVector);\n}\n\n/** Default hybrid blend: equal weight to the vector and fulltext components. */\nconst DEFAULT_HYBRID_WEIGHT = 0.5;\n\n/**\n * Coerces a raw weight into the non-negative finite domain. A non-finite value\n * (`NaN`/`±Infinity`) contributes `0` rather than poisoning the whole blend —\n * `Math.max(0, NaN)` is `NaN`, which would survive the `total === 0` guard and\n * collapse every hybrid score to 0. Valid weights are rejected earlier at the\n * options boundary (`normalizeMergeOptions`); this is the defensive backstop.\n */\nfunction nonNegativeFinite(value: number): number {\n return Number.isFinite(value) ? Math.max(0, value) : 0;\n}\n\n/**\n * Normalizes a hybrid strategy's `weights` so the vector and fulltext components\n * sum to 1, defaulting either omitted side to {@link DEFAULT_HYBRID_WEIGHT}. A\n * degenerate `{0, 0}` (or negative / non-finite) total falls back to an even\n * 0.5/0.5 split so the blend can never divide by zero, invert, or produce `NaN`.\n */\nfunction normalizeHybridWeights(\n weights: Readonly<{ vector?: number; fulltext?: number }> | undefined,\n): Readonly<{ vector: number; fulltext: number }> {\n const vector = nonNegativeFinite(weights?.vector ?? DEFAULT_HYBRID_WEIGHT);\n const fulltext = nonNegativeFinite(\n weights?.fulltext ?? DEFAULT_HYBRID_WEIGHT,\n );\n const total = vector + fulltext;\n if (total === 0) {\n return { vector: DEFAULT_HYBRID_WEIGHT, fulltext: DEFAULT_HYBRID_WEIGHT };\n }\n return { vector: vector / total, fulltext: fulltext / total };\n}\n\n/**\n * Builds the {@link SimilarityUnavailableError} for a `vector`/`hybrid` strategy\n * requested with no configured embedder.\n */\nfunction embedderUnavailable(\n kind: \"vector\" | \"hybrid\",\n ctx: SimilarityContext,\n): SimilarityUnavailableError {\n return new SimilarityUnavailableError(\n `Similarity strategy \"${kind}\" requires a configured embedder (MergeOptions.embedder); none was provided.`,\n { details: { strategy: kind, dialect: ctx.backend.dialect } },\n );\n}\n\n/**\n * The field(s) a strategy reads off a node to form its comparison text: the\n * embedded field(s) for `vector`/`hybrid`, the configured `fields` for `fulltext`,\n * and none for `custom` (which scores the node objects directly).\n */\nfunction scoringFields(strategy: SimilarityStrategy): readonly string[] {\n switch (strategy.kind) {\n case \"fulltext\":\n case \"hybrid\": {\n return strategy.fields;\n }\n case \"vector\": {\n return [strategy.field];\n }\n case \"custom\": {\n return [];\n }\n default: {\n const exhaustive: never = strategy;\n throw new Error(\n `Unhandled similarity strategy: ${JSON.stringify(exhaustive)}`,\n );\n }\n }\n}\n\n/**\n * A node's per-strategy comparison inputs, computed ONCE and reused across every\n * pair the node joins: its lowercase {@link fieldText} (looked up in the embedding\n * map for `vector`/`hybrid`) and, for the trigram strategies, its trigram multiset.\n * The original `node` is retained for the `custom` strategy, which scores nodes\n * directly. {@link createPairScorer} memoizes one of these per node.\n */\ntype PreparedNode<K extends NodeType = NodeType> = Readonly<{\n node: Node<K>;\n text: string;\n grams: Map<string, number>;\n}>;\n\n/** Empty trigram multiset shared by strategies that never consult grams. */\nconst NO_GRAMS: Map<string, number> = new Map<string, number>();\n\n/** Computes a node's {@link PreparedNode} for a strategy (trigrams only when used). */\nfunction prepareNode<K extends NodeType>(\n node: Node<K>,\n strategy: SimilarityStrategy,\n): PreparedNode<K> {\n const text = fieldText(node, scoringFields(strategy));\n const grams =\n strategy.kind === \"fulltext\" || strategy.kind === \"hybrid\" ?\n trigramMultiset(text)\n : NO_GRAMS;\n return { node, text, grams };\n}\n\n/**\n * Scores a candidate pair from its two {@link PreparedNode}s under a\n * {@link SimilarityStrategy}, returning a value in `[0, 1]` (guaranteed symmetric\n * for the built-in strategies). This is the single match-decision switch;\n * {@link scorePair} and {@link createPairScorer} both feed it prepared nodes.\n *\n * @returns `ok(score)` on success, or `err(SimilarityUnavailableError)` when a\n * `vector`/`hybrid` strategy is requested with no configured embedder.\n */\nfunction scorePrepared<K extends NodeType>(\n left: PreparedNode<K>,\n right: PreparedNode<K>,\n strategy: SimilarityStrategy,\n ctx: SimilarityContext,\n): Result<number, SimilarityUnavailableError> {\n switch (strategy.kind) {\n case \"custom\": {\n // The caller owns symmetry here; we only clamp into the codomain so a\n // stray out-of-range or NaN score cannot corrupt clustering.\n const raw = strategy.score(left.node, right.node);\n return ok(clampScore(raw));\n }\n case \"fulltext\": {\n // A node with NO text in the configured fields offers no evidence of a\n // match. Comparing two such nodes must NOT collapse two distinct entities,\n // NOT even at threshold 0 — so it returns the sub-threshold\n // {@link NO_EVIDENCE_SCORE}, never the vacuous diceTrigramSimilarity(\"\",\"\")\n // === 1. The metric itself keeps empty==empty==1 for direct callers / the\n // acceptance tests; this guard is candidate-gen's policy.\n if (left.text.length === 0 || right.text.length === 0) {\n return ok(NO_EVIDENCE_SCORE);\n }\n return ok(clampScore(diceFromMultisets(left.grams, right.grams)));\n }\n case \"vector\": {\n // Presence of `ctx.embeddings` == an embedder was configured. Absent → the\n // caller asked for vector similarity without supplying MergeOptions.embedder.\n if (ctx.embeddings === undefined) {\n return err(embedderUnavailable(\"vector\", ctx));\n }\n // A node with no text in the field offers no evidence of a match —\n // NO_EVIDENCE_SCORE, not the cosine of two zero/absent vectors (mirrors the\n // fulltext guard, and excludes the pair even at threshold 0).\n if (left.text.length === 0 || right.text.length === 0) {\n return ok(NO_EVIDENCE_SCORE);\n }\n const cosine = cosineFromLookup(ctx.embeddings, left.text, right.text);\n return ok(clampScore(cosine));\n }\n case \"hybrid\": {\n if (ctx.embeddings === undefined) {\n return err(embedderUnavailable(\"hybrid\", ctx));\n }\n if (left.text.length === 0 || right.text.length === 0) {\n return ok(NO_EVIDENCE_SCORE);\n }\n // Blend exact in-memory cosine (semantic/spelling proximity) with the Dice\n // trigram (literal character overlap) by the normalized weights. Both\n // components are symmetric, so the blend is too.\n const vectorScore = clampScore(\n cosineFromLookup(ctx.embeddings, left.text, right.text),\n );\n const fulltextScore = diceFromMultisets(left.grams, right.grams);\n const weights = normalizeHybridWeights(strategy.weights);\n return ok(\n clampScore(\n weights.vector * vectorScore + weights.fulltext * fulltextScore,\n ),\n );\n }\n default: {\n // Exhaustiveness guard: a new strategy kind must add a branch above, or\n // this assignment fails to compile.\n const exhaustive: never = strategy;\n throw new Error(\n `Unhandled similarity strategy: ${JSON.stringify(exhaustive)}`,\n );\n }\n }\n}\n\n/**\n * Scores a candidate pair under a {@link SimilarityStrategy}, returning a value\n * in `[0, 1]` (guaranteed symmetric for the built-in strategies). A single-pair\n * convenience over {@link scorePrepared}; the candidate loop uses\n * {@link createPairScorer} instead so per-node work is not repeated across pairs.\n *\n * @param a First staged node.\n * @param b Second staged node.\n * @param strategy The per-kind similarity strategy from the kind's `ResolveConfig`.\n * @param ctx Ambient context (the backend, for vector-capability gating).\n * @returns `ok(score)` on success, or `err(SimilarityUnavailableError)` when a\n * `vector`/`hybrid` strategy is requested with no configured embedder.\n */\nexport function scorePair<K extends NodeType>(\n a: Node<K>,\n b: Node<K>,\n strategy: SimilarityStrategy,\n ctx: SimilarityContext,\n): Result<number, SimilarityUnavailableError> {\n const result = scorePrepared(\n prepareNode(a, strategy),\n prepareNode(b, strategy),\n strategy,\n ctx,\n );\n // The standalone scorer's contract is a [0, 1] score; the internal\n // NO_EVIDENCE_SCORE sentinel (a textless pair) surfaces here as MIN_SCORE. Only\n // candidate-gen needs the sub-threshold value to exclude the pair at threshold 0.\n if (result.success && result.data === NO_EVIDENCE_SCORE) {\n return ok(MIN_SCORE);\n }\n return result;\n}\n\n/**\n * Builds a memoized pair scorer for one kind. Each node's {@link PreparedNode} is\n * computed once, keyed by its `(kind, id)` {@link MergeKey}, so a node appearing in\n * m candidate pairs has its text + trigram multiset built once, not m times — the\n * per-bucket cost drops from O(pairs · text) trigram builds to O(nodes · text).\n * Pair-for-pair equivalent to {@link scorePair}.\n */\nexport function createPairScorer<K extends NodeType>(\n strategy: SimilarityStrategy,\n ctx: SimilarityContext,\n): (\n a: MergeKey,\n left: Node<K>,\n b: MergeKey,\n right: Node<K>,\n) => Result<number, SimilarityUnavailableError> {\n const prepared = new Map<MergeKey, PreparedNode<K>>();\n const prepare = (key: MergeKey, node: Node<K>): PreparedNode<K> => {\n const cached = prepared.get(key);\n if (cached !== undefined) {\n return cached;\n }\n const fresh = prepareNode(node, strategy);\n prepared.set(key, fresh);\n return fresh;\n };\n return (a, left, b, right) =>\n scorePrepared(prepare(a, left), prepare(b, right), strategy, ctx);\n}\n","/**\n * The shared SCORING stage (design §4, the single match-decision point).\n *\n * Candidate generation is three layers — sources → scoring → reconciler (§4).\n * This module is the MIDDLE layer: it turns the candidate PROPOSALS every source\n * emits into the {@link CandidateEdge} set the reconciler consumes, applying the\n * EXACT same scorer + threshold regardless of which source proposed a pair. A\n * source proposes (recall); scoring disposes (the match decision).\n *\n * Two proposal kinds enter:\n *\n * - {@link CandidatePair}s — unscored `(a, b)` node pairs from any source. They\n * are deduped by canonical `(a, b)` and each scored EXACTLY ONCE by\n * {@link scorePair}; only pairs clearing the kind's threshold become edges.\n * - FORCED {@link CandidateEdge}s — DEFINITIONAL matches (a shared unique value)\n * that BYPASS scoring entirely, emitted at {@link FORCED_MATCH_SCORE}. A forced\n * pair is never also fuzzy-scored: forced `(a, b)` keys are reserved first, so\n * a fuzzy pair proposing the same endpoints is dropped before scoring.\n *\n * This was previously fused into `candidate-gen.ts`'s `generateCandidates` (which\n * scored AND thresholded inline); naming scoring as its own stage is what makes\n * \"the scorer — not a source — decides matches\" concrete (§4). `generateCandidates`\n * now composes the bucket sources over this stage.\n *\n * Determinism: the emitted edge set is a pure function of the proposal SETS — pairs\n * are deduped by canonical `(a, b)`, scored by the symmetric {@link scorePair}, and\n * the final list is sorted by `(a, b)`, so neither the order proposals arrive in\n * nor the directionality of a pair affects the result.\n *\n * The {@link ComparisonCeilingPolicy} bounds only the FUZZY scoring work (the\n * embedder step for vector/hybrid); FORCED edges are definitional, not\n * similarity-based, so they are emitted regardless of the ceiling:\n *\n * - `\"error\"` — exceeding the ceiling fails with a typed {@link MergeError}.\n * - `\"mergeByIdOnly\"` — fuzzy similarity is SKIPPED for the kind (no\n * threshold-scored edges), FORCED edges are still emitted,\n * and a {@link CandidateWarning} is recorded.\n */\n\nimport { MergeError } from \"./errors\";\nimport { compareMergeKeys, type MergeKey } from \"./node-key\";\nimport type { Result } from \"./result\";\nimport { err, isErr, ok } from \"./result\";\nimport type { SimilarityContext } from \"./similarity\";\nimport { createPairScorer } from \"./similarity\";\nimport type { Node, NodeType } from \"./typegraph-internal\";\nimport type { ComparisonCeilingPolicy, ResolveConfig } from \"./types\";\n\n/**\n * An undirected candidate-merge edge between two nodes that should merge.\n * Endpoints are stored in ascending id order (`a < b`) so the edge has a single\n * canonical representation. Fuzzy edges carry their similarity score; FORCED\n * (definitional) edges carry {@link FORCED_MATCH_SCORE}.\n */\nexport type CandidateEdge = Readonly<{\n a: MergeKey;\n b: MergeKey;\n score: number;\n}>;\n\n/**\n * A non-fatal advisory raised during scoring — currently only the\n * `\"mergeByIdOnly\"` comparison-ceiling skip. Surfaced in the merge report.\n */\ntype CandidateWarning = Readonly<{\n kind: \"comparisonCeiling\";\n comparisons: number;\n limit: number;\n message: string;\n}>;\n\n/**\n * The scoring result for one kind: the emitted edges plus any advisories.\n * Returned inside a {@link Result} so the `vector`/`hybrid` guard and the\n * `\"error\"` ceiling path can fail without throwing.\n */\nexport type CandidateGenResult = Readonly<{\n edges: readonly CandidateEdge[];\n warnings: readonly CandidateWarning[];\n}>;\n\n/**\n * An unscored candidate pair a source proposes for scoring: the canonical\n * endpoint ids `(a, b)` (`a < b`) plus the two node objects the scorer reads\n * fields off of. `left`/`right` carry the nodes whose ids are `a`/`b`\n * respectively, but {@link scorePair} is symmetric so their roles are\n * interchangeable for scoring.\n */\nexport type CandidatePair<K extends NodeType = NodeType> = Readonly<{\n a: MergeKey;\n b: MergeKey;\n left: Node<K>;\n right: Node<K>;\n}>;\n\n/**\n * The proposals the scoring stage consumes for one kind: the fuzzy pairs to score\n * and the forced (definitional) edges to pass through unscored.\n */\nexport type ScoringInput<K extends NodeType = NodeType> = Readonly<{\n pairs: readonly CandidatePair<K>[];\n forcedEdges: readonly CandidateEdge[];\n}>;\n\n/**\n * Score for a FORCED (definitional, unique-match) edge — the maximum, so the pair\n * always clears any threshold and is never the weakest edge a diameter guard would\n * drop. Sources that emit forced edges stamp this score; scoring passes it through.\n */\nexport const FORCED_MATCH_SCORE = 1;\n\n/**\n * Stable `(a, b)` ascending comparator over {@link CandidateEdge}. Endpoints are\n * `(kind, id)` MergeKeys, so ordering uses the SAME id-first {@link compareMergeKeys}\n * the clustering stage uses — never raw kind-first string order. The SINGLE shared\n * definition: clustering and `merge()`'s candidate generation import this instead of\n * re-deriving it, so every stage orders the edge set identically by construction.\n */\nexport function compareCandidateEdges(\n left: CandidateEdge,\n right: CandidateEdge,\n): number {\n const byA = compareMergeKeys(left.a, right.a);\n return byA === 0 ? compareMergeKeys(left.b, right.b) : byA;\n}\n\n/** The canonical dedup key for a pair / edge's ordered endpoints. */\nfunction endpointKey(a: MergeKey, b: MergeKey): string {\n return JSON.stringify([a, b]);\n}\n\n/**\n * Scores the proposed candidates for a single kind into a {@link CandidateEdge}\n * set, applying the kind's threshold and the comparison-ceiling policy.\n *\n * FORCED endpoint keys are reserved FIRST, so a fuzzy pair proposing the same\n * `(a, b)` is dropped before scoring — a forced (definitional) match is never also\n * fuzzy-scored. The remaining fuzzy pairs are deduped by canonical `(a, b)` and\n * scored exactly once; only those clearing `threshold` become edges. The combined\n * forced + passing-fuzzy edge list is sorted by `(a, b)`.\n *\n * @param input The fuzzy pairs + forced edges every source proposed for the kind.\n * @param resolveConfig The kind's resolution config (similarity strategy + threshold).\n * @param ctx Ambient context (the backend, for vector-capability gating).\n * @param ceilingPolicy Behavior when `maxComparisonsPerKind` is exceeded.\n * @param maxComparisonsPerKind Optional per-kind FUZZY-comparison ceiling.\n * `undefined` means unbounded. Forced edges are never bounded by it.\n * @returns `ok({ edges, warnings })`, or `err(...)` when the `\"error\"` ceiling\n * fires or a `vector`/`hybrid` guard trips.\n */\nexport function scoreCandidates<K extends NodeType>(\n input: ScoringInput<K>,\n resolveConfig: ResolveConfig,\n ctx: SimilarityContext,\n ceilingPolicy: ComparisonCeilingPolicy,\n maxComparisonsPerKind?: number,\n): Result<CandidateGenResult, MergeError> {\n const { similarity, threshold } = resolveConfig;\n\n // Reserve forced endpoint keys FIRST so a fuzzy pair proposing the same pair is\n // dropped — a definitional match is never also fuzzy-scored (the old Phase-1\n // before Phase-2 dedup, now source-agnostic).\n const seen = new Set<string>();\n const forced: CandidateEdge[] = [];\n for (const edge of input.forcedEdges) {\n const key = endpointKey(edge.a, edge.b);\n if (!seen.has(key)) {\n seen.add(key);\n forced.push(edge);\n }\n }\n\n const fuzzy: CandidatePair<K>[] = [];\n for (const pair of input.pairs) {\n const key = endpointKey(pair.a, pair.b);\n if (!seen.has(key)) {\n seen.add(key);\n fuzzy.push(pair);\n }\n }\n\n if (\n maxComparisonsPerKind !== undefined &&\n fuzzy.length > maxComparisonsPerKind\n ) {\n if (ceilingPolicy === \"error\") {\n return err(\n new MergeError(\n `Comparison ceiling exceeded: ${fuzzy.length} candidate pairs > maxComparisonsPerKind ${maxComparisonsPerKind}.`,\n {\n details: {\n comparisons: fuzzy.length,\n limit: maxComparisonsPerKind,\n },\n suggestion:\n 'Tighten the kind\\'s block() to shrink buckets, or set onComparisonCeiling: \"mergeByIdOnly\".',\n },\n ),\n );\n }\n // \"mergeByIdOnly\": skip FUZZY similarity for this kind, but KEEP the forced\n // edges — those are definitional, not similarity-based.\n return ok({\n edges: [...forced].sort((left, right) =>\n compareCandidateEdges(left, right),\n ),\n warnings: [\n {\n kind: \"comparisonCeiling\",\n comparisons: fuzzy.length,\n limit: maxComparisonsPerKind,\n message: `Skipped similarity for this kind: ${fuzzy.length} candidate pairs exceeded maxComparisonsPerKind ${maxComparisonsPerKind}; nodes will merge by id and exact unique match only.`,\n },\n ],\n });\n }\n\n // One memoized scorer per kind so each node's text + trigram multiset is built\n // once, not once per pair it joins (the within-bucket pair count is ~O(n²)).\n const scorer = createPairScorer<K>(similarity, ctx);\n const edges: CandidateEdge[] = [...forced];\n for (const { left, right, a, b } of fuzzy) {\n const scored = scorer(a, left, b, right);\n if (isErr(scored)) {\n return err(scored.error);\n }\n if (scored.data >= threshold) {\n edges.push({ a, b, score: scored.data });\n }\n }\n\n return ok({\n edges: edges.sort((left, right) => compareCandidateEdges(left, right)),\n warnings: [],\n });\n}\n","import { requireDefined } from \"../utils/presence\";\n/**\n * Connected-components clustering over the candidate-edge graph (design §6.4\n * rule 2, T8).\n *\n * Two staged nodes are merged into the same cluster iff they are connected\n * (transitively) by a chain of candidate-merge edges. This is the SINGLE-LINK\n * rule: A~B and B~C cluster {A,B,C} even when A≁C directly, because each hop\n * cleared the similarity threshold. The frozen v1 default is single-link with NO\n * guard; the optional diameter guard (below) is the only deviation.\n *\n * Determinism:\n * - The component assignment is computed via union-find over the candidate\n * edge SET (a pure function of the edges, never their arrival order). We\n * additionally order edge consumption by `(a, b)` and union with a\n * min-id-as-root tie-break, so even the internal forest is identical across\n * shuffled inputs — not merely the resulting partition.\n * - Every cluster's `members` array is sorted by node id, and the cluster list\n * is sorted by each cluster's minimum member id. So the output is fully\n * canonical regardless of the order edges or seed node ids are supplied in.\n *\n * Diameter guard (optional, design §6.4 / T8):\n * When `clusterMaxDiameter` is set, a formed component must satisfy a single\n * bound: the maximum pairwise graph distance (in candidate-edge hops) between\n * any two members must not exceed the guard. A component that violates the\n * bound is split by the deterministic DROP-WEAKEST single-link rule: remove the\n * lowest-scoring candidate edge (ties broken by `(a, b)` id order) and\n * recompute components on the survivors, repeating until every sub-component\n * satisfies the bound. This is the frozen v1 behavior — no correlation\n * clustering in P0.\n */\nimport type { CandidateEdge } from \"./candidate-gen\";\nimport { compareMergeKeys, type MergeKey } from \"./node-key\";\nimport { compareCandidateEdges } from \"./scoring\";\nimport { UnionFind } from \"./union-find\";\n\n/**\n * The node IDENTITY the cluster graph is built over: the composite `(kind, id)`\n * {@link MergeKey}, NOT a bare node id. Two different-kind nodes that share an id\n * string are DISTINCT identities here, so single-link clustering never fuses them\n * into one component (the base guard would otherwise be silently bypassed).\n */\ntype AnyNodeId = MergeKey;\n\n/**\n * A resolved cluster of node identities that the merge collapses into one canonical\n * survivor. `members` is always sorted (by id, then kind) and never empty.\n */\nexport type ClusterResult = Readonly<{\n members: readonly AnyNodeId[];\n}>;\n\n/**\n * Builds connected components from a candidate-edge set plus an explicit seed\n * set of all node ids in scope. Seed ids with no incident edge become singleton\n * components, so the result partitions the ENTIRE node set, not just edge\n * endpoints.\n */\nfunction buildComponents(\n edges: readonly CandidateEdge[],\n nodeIds: readonly AnyNodeId[],\n edgesSorted = false,\n): ClusterResult[] {\n const forest = new UnionFind<AnyNodeId>(compareMergeKeys);\n const seed = new Set<AnyNodeId>(nodeIds);\n for (const id of nodeIds) {\n forest.add(id);\n }\n // Consume edges in canonical order so the forest is identical across shuffles.\n // An edge whose endpoint is NOT in the seed set is out of scope and skipped, so\n // the partition is a function of exactly the supplied node set — a candidate\n // edge can never inject a phantom member never passed in `nodeIds`.\n // `edgesSorted` lets a caller that already holds the edges in canonical order\n // (the drop-weakest loop) skip the redundant re-sort on every iteration.\n const orderedEdges =\n edgesSorted ? edges : (\n [...edges].sort((left, right) => compareCandidateEdges(left, right))\n );\n for (const edge of orderedEdges) {\n if (!seed.has(edge.a) || !seed.has(edge.b)) {\n continue;\n }\n forest.union(edge.a, edge.b);\n }\n\n const byRoot = new Map<AnyNodeId, AnyNodeId[]>();\n for (const id of forest.members()) {\n const root = forest.find(id);\n const bucket = byRoot.get(root);\n if (bucket === undefined) {\n byRoot.set(root, [id]);\n } else {\n bucket.push(id);\n }\n }\n\n const clusters: ClusterResult[] = [];\n for (const members of byRoot.values()) {\n clusters.push({\n members: [...members].sort((left, right) =>\n compareMergeKeys(left, right),\n ),\n });\n }\n // Order clusters by their (sorted) first member, which is the minimum id.\n clusters.sort((left, right) =>\n compareMergeKeys(\n requireDefined(left.members[0]),\n requireDefined(right.members[0]),\n ),\n );\n return clusters;\n}\n\n/**\n * Builds the undirected adjacency (member id → set of neighbor ids) for one\n * component's members, restricted to candidate edges whose BOTH endpoints are in\n * the component.\n */\nfunction adjacencyOf(\n members: readonly AnyNodeId[],\n edges: readonly CandidateEdge[],\n): Map<AnyNodeId, Set<AnyNodeId>> {\n const memberSet = new Set(members);\n const adjacency = new Map<AnyNodeId, Set<AnyNodeId>>();\n for (const id of members) {\n adjacency.set(id, new Set());\n }\n for (const edge of edges) {\n if (memberSet.has(edge.a) && memberSet.has(edge.b)) {\n requireDefined(adjacency.get(edge.a)).add(edge.b);\n requireDefined(adjacency.get(edge.b)).add(edge.a);\n }\n }\n return adjacency;\n}\n\n/**\n * Whether one component's pairwise graph diameter (in candidate-edge hops) EXCEEDS\n * `maxDiameter`. Runs a BFS from each member but EARLY-EXITS the moment it reaches\n * a node beyond `maxDiameter` (or finds the component disconnected), so a check\n * costs `O(members + edges-within-the-bound)` rather than the full all-pairs\n * `O(V·(V+E))` exact diameter — the guard only needs the threshold answer, never\n * the exact value. Equivalent to `componentDiameter(...) > maxDiameter`.\n */\nfunction exceedsDiameter(\n members: readonly AnyNodeId[],\n edges: readonly CandidateEdge[],\n maxDiameter: number,\n): boolean {\n if (members.length <= 1) {\n return false;\n }\n const adjacency = adjacencyOf(members, edges);\n for (const source of members) {\n const distance = new Map<AnyNodeId, number>([[source, 0]]);\n const queue: AnyNodeId[] = [source];\n let head = 0;\n while (head < queue.length) {\n const current = requireDefined(queue[head]);\n head += 1;\n const currentDistance = requireDefined(distance.get(current));\n for (const neighbor of requireDefined(adjacency.get(current))) {\n if (!distance.has(neighbor)) {\n const neighborDistance = currentDistance + 1;\n if (neighborDistance > maxDiameter) {\n return true; // a pair already exceeds the bound — stop early\n }\n distance.set(neighbor, neighborDistance);\n queue.push(neighbor);\n }\n }\n }\n if (distance.size < members.length) {\n return true; // disconnected from `source` → diameter is infinite\n }\n }\n return false;\n}\n\n/**\n * The candidate edges internal to a single component (both endpoints inside it),\n * in canonical `(a, b)` order.\n */\nfunction internalEdges(\n members: readonly AnyNodeId[],\n edges: readonly CandidateEdge[],\n): CandidateEdge[] {\n const memberSet = new Set(members);\n return edges\n .filter((edge) => memberSet.has(edge.a) && memberSet.has(edge.b))\n .sort((left, right) => compareCandidateEdges(left, right));\n}\n\n/**\n * The single weakest edge of a set: lowest score, ties broken by `(a, b)` id\n * order. The deterministic edge the drop-weakest splits remove first.\n */\nfunction weakestEdge(edges: readonly CandidateEdge[]): CandidateEdge {\n return edges.reduce((current, candidate) => {\n if (candidate.score !== current.score) {\n return candidate.score < current.score ? candidate : current;\n }\n return compareCandidateEdges(candidate, current) < 0 ? candidate : current;\n });\n}\n\n/**\n * The shared DROP-WEAKEST splitter (design §6.4 / §6.4-A). Repeatedly removes the\n * lowest-scoring internal candidate edge (ties broken by `(a, b)` id order) and\n * recomputes components until NO sub-component is still `isOffending`, then returns\n * the satisfying sub-components. `isOffending` receives the current surviving edge\n * set so a predicate like the diameter check can measure against it.\n *\n * The degenerate \"still offending but no internal edge left to drop\" case — only\n * reachable if a future caller passes a ≥2-member component with no internal edge —\n * degrades EVERY such offending component to singletons (keeping every satisfying\n * sibling intact), so the partition is never silently truncated. It first exhausts the\n * splittable offending components (those with an edge to drop), so an edgeless\n * offending sibling can never leave another offending component unsplit.\n */\nfunction splitUntil(\n members: readonly AnyNodeId[],\n edges: readonly CandidateEdge[],\n isOffending: (\n members: readonly AnyNodeId[],\n surviving: readonly CandidateEdge[],\n ) => boolean,\n): ClusterResult[] {\n // `surviving` starts in canonical `(a, b)` order and `.filter` preserves it, so\n // every iteration can pass it to `buildComponents` pre-sorted.\n let surviving = internalEdges(members, edges);\n\n for (;;) {\n const components = buildComponents(surviving, members, true);\n const offending = components.filter((component) =>\n isOffending(component.members, surviving),\n );\n if (offending.length === 0) {\n return components;\n }\n // Prefer to keep dropping the weakest edge of an offending component that still has\n // one; only when EVERY offending component is edgeless do we degrade them all.\n // Scan lazily — stop at the first offending component that still has an internal\n // edge instead of materializing internalEdges for every offending component.\n let splittable: CandidateEdge[] | undefined;\n for (const component of offending) {\n const componentEdges = internalEdges(component.members, surviving);\n if (componentEdges.length > 0) {\n splittable = componentEdges;\n break;\n }\n }\n if (splittable === undefined) {\n const offendingSet = new Set(offending);\n return components.flatMap((component) =>\n offendingSet.has(component) ?\n component.members.map((id) => ({ members: [id] }))\n : [component],\n );\n }\n const weakest = weakestEdge(splittable);\n surviving = surviving.filter((edge) => edge !== weakest);\n }\n}\n\n/**\n * Splits a single over-diameter component by the deterministic DROP-WEAKEST\n * single-link rule until every resulting sub-component satisfies `maxDiameter`.\n */\nfunction splitByDropWeakest(\n members: readonly AnyNodeId[],\n edges: readonly CandidateEdge[],\n maxDiameter: number,\n): ClusterResult[] {\n return splitUntil(members, edges, (componentMembers, surviving) =>\n exceedsDiameter(componentMembers, surviving, maxDiameter),\n );\n}\n\n/**\n * Computes the connected components of the candidate-edge graph over `nodeIds`,\n * applying the optional single-link diameter guard.\n *\n * @param candidateEdges Undirected candidate-merge edges (from T6). Order does\n * not affect the result.\n * @param nodeIds Every node id in scope. Ids with no incident candidate edge\n * become singleton clusters, so the output partitions the full set.\n * @returns Clusters with id-sorted members, sorted by minimum member id. Pure\n * over the input edge/node SETS.\n *\n * The diameter guard is deliberately NOT applied here: {@link enforceBaseGuard}\n * (§6.4-A) must run on these RAW components FIRST, and only then may a caller run\n * {@link enforceDiameter}. Folding the diameter split back in would let it sever a\n * base↔base bridge before base multiplicity is detected.\n */\nexport function connectedComponents(\n candidateEdges: readonly CandidateEdge[],\n nodeIds: readonly AnyNodeId[],\n): readonly ClusterResult[] {\n return buildComponents(candidateEdges, nodeIds);\n}\n\n/**\n * Applies the single-link DIAMETER guard to already-formed clusters: any cluster\n * whose pairwise diameter exceeds `clusterMaxDiameter` is split by the deterministic\n * drop-weakest rule. Separated from {@link connectedComponents} so the base guard\n * (§6.4-A) can run on the RAW pre-diameter components FIRST — a diameter split must\n * never sever a base↔base bridge before base-multiplicity is detected.\n */\nexport function enforceDiameter(\n clusters: readonly ClusterResult[],\n candidateEdges: readonly CandidateEdge[],\n clusterMaxDiameter: number,\n): readonly ClusterResult[] {\n const guarded: ClusterResult[] = [];\n for (const component of clusters) {\n if (\n exceedsDiameter(component.members, candidateEdges, clusterMaxDiameter)\n ) {\n guarded.push(\n ...splitByDropWeakest(\n component.members,\n candidateEdges,\n clusterMaxDiameter,\n ),\n );\n } else {\n guarded.push(component);\n }\n }\n guarded.sort((left, right) =>\n compareMergeKeys(\n requireDefined(left.members[0]),\n requireDefined(right.members[0]),\n ),\n );\n return guarded;\n}\n\n/** Count of a component's members that are committed BASE nodes. */\nfunction countBaseMembers(\n members: readonly AnyNodeId[],\n baseIds: ReadonlySet<AnyNodeId>,\n): number {\n let count = 0;\n for (const id of members) {\n if (baseIds.has(id)) {\n count += 1;\n }\n }\n return count;\n}\n\n/**\n * Splits a component holding ≥2 base members by the deterministic DROP-WEAKEST rule\n * until NO surviving sub-component holds two base members. This is CONTAINMENT, not\n * resolution: it removes the lowest-scoring BRIDGING edges (forced new↔base edges,\n * at max score, are dropped last), so the distinct committed entities land in\n * separate clusters and BOTH survive — it never \"picks\" which base wins (§6.4-A).\n */\nfunction splitByBaseMultiplicity(\n members: readonly AnyNodeId[],\n edges: readonly CandidateEdge[],\n baseIds: ReadonlySet<AnyNodeId>,\n): ClusterResult[] {\n return splitUntil(\n members,\n edges,\n (componentMembers) => countBaseMembers(componentMembers, baseIds) >= 2,\n );\n}\n\n/**\n * A connected component that spanned ≥2 distinct committed base entities — an\n * AMBIGUOUS match (§6.4-A). Reported regardless of how the component was split:\n * any component that EVER bridged two base identities is an ambiguity event.\n */\nexport type BaseMultiplicityEvent = Readonly<{\n baseIds: readonly AnyNodeId[];\n memberIds: readonly AnyNodeId[];\n}>;\n\n/**\n * Component-level BASE GUARD (§6.4-A). Single-link clustering is transitive, so two\n * committed entities fuse whenever ANY chain links them (`baseA ~ new ~ baseB`, or\n * through staged hops `baseA ~ new1 ~ new2 ~ baseB` where no single new node spans\n * both). A node-level guard misses the chain case; this guard is COMPONENT-level.\n *\n * MUST run on the RAW connected components, BEFORE any diameter split — otherwise a\n * diameter guard could sever a base↔base bridge into single-base pieces and the\n * ambiguity would go unreported (§6.4-A: reported regardless of how it split).\n *\n * Any component containing ≥2 distinct base members is an ambiguous match and is\n * reported as a {@link BaseMultiplicityEvent}. The committed entities are ALWAYS kept\n * SEPARATE — the base↔base collapse is REFUSED by splitting the component\n * (drop-weakest, containment only) until no sub-component holds two base members.\n * Splitting never downgrades the event from ambiguous, and never silently picks which\n * base wins. (A deliberate-collapse trust path is deferred until committed-entity\n * re-keying + edge repoint exist; §6.4-C.)\n *\n * A no-op fast path when there are no base members (the public snapshot path).\n *\n * @returns the guarded clusters (id-sorted members, sorted by min member id) and\n * one event per component that spanned ≥2 base entities.\n */\nexport function enforceBaseGuard(\n clusters: readonly ClusterResult[],\n candidateEdges: readonly CandidateEdge[],\n baseIds: ReadonlySet<AnyNodeId>,\n): Readonly<{\n clusters: readonly ClusterResult[];\n events: readonly BaseMultiplicityEvent[];\n}> {\n if (baseIds.size === 0) {\n return { clusters, events: [] };\n }\n\n const result: ClusterResult[] = [];\n const events: BaseMultiplicityEvent[] = [];\n for (const cluster of clusters) {\n const clusterBaseIds = cluster.members.filter((id) => baseIds.has(id));\n if (clusterBaseIds.length < 2) {\n result.push(cluster);\n continue;\n }\n events.push({\n baseIds: [...clusterBaseIds].sort((left, right) =>\n compareMergeKeys(left, right),\n ),\n memberIds: [...cluster.members].sort((left, right) =>\n compareMergeKeys(left, right),\n ),\n });\n // Always REFUSE the base↔base collapse: split for containment so both committed\n // entities survive separately (§6.4-A). A deliberate collapse is deferred (§6.4-C).\n result.push(\n ...splitByBaseMultiplicity(cluster.members, candidateEdges, baseIds),\n );\n }\n result.sort((left, right) =>\n compareMergeKeys(\n requireDefined(left.members[0]),\n requireDefined(right.members[0]),\n ),\n );\n return { clusters: result, events };\n}\n","import { requireDefined } from \"../utils/presence\";\n/**\n * Node-level delete/modify conflict resolution (design §6.2, T8a).\n *\n * The §6.2 case the draft omitted: an INHERITED node that one fork DELETES while\n * another fork MODIFIES is neither a pure deletion nor a pure modification — it\n * is a delete/modify conflict whose outcome is governed by the\n * {@link DeleteModifyPolicy} (`\"deleteWins\"` | `\"modifyWins\"` | `\"flag\"`) and\n * surfaced in the {@link MergeReport}.\n *\n * This module is a PURE decision function over the staging set (T7) plus the\n * captured stable branch order (T8). It runs BEFORE clustering/canonicalize feed\n * the surviving modifications into the property union, and BEFORE edge repoint\n * (T9), to which it hands the authoritative FINAL LIVENESS of every inherited\n * endpoint:\n *\n * - a node finally deleted (`\"deleteWins\"`) → it is in {@link nodeDeletions};\n * T9 drops every edge touching it.\n * - a node kept/resurrected (`\"modifyWins\"` / `\"flag\"`, or never deleted) →\n * its modifications are in {@link survivingModifications}; T9 keeps its edges.\n *\n * DETERMINISM CONTRACT (inherited from the merge-wide invariant):\n * The keep-vs-delete decision is a function ONLY of the policy and the\n * (unordered) set of contributing branches — it NEVER consults wall-clock\n * arrival. The captured `branchRank` is used solely to TIE-BREAK which\n * modification survives under `\"modifyWins\"` / `\"flag\"` (and which branch ids\n * are recorded as `deletedBy` / `modifiedBy`), so two merges of the same branch\n * set in any order resolve every delete/modify conflict identically.\n */\nimport { canonicalValueKey } from \"./canonical-props\";\nimport type { ProvenanceWeights, ResolutionContext } from \"./conflict-policy\";\nimport {\n collectConflictingValues,\n resolvePropertyUnion,\n} from \"./conflict-policy\";\nimport { compareStrings, type MergeKey, mergeKey } from \"./node-key\";\nimport type {\n StagedModifiedEdge,\n StagedModifiedNode,\n StagingSet,\n} from \"./staging\";\nimport type { DeletedEdge, DeletedNode } from \"./state-diff\";\nimport type {\n EdgeId,\n GraphDef,\n JsonValue,\n NodeId,\n NodeType,\n} from \"./typegraph-internal\";\nimport type {\n BranchId,\n DeleteModifyConflict,\n DeleteModifyPolicy,\n DroppedItem,\n PropertyConflict,\n PropertyConflictPolicy,\n} from \"./types\";\n\n/** A node id in its untyped (`NodeType`-default) branded form. */\ntype AnyNodeId = NodeId<NodeType>;\ntype BranchTagged = Readonly<{ branchId: BranchId }>;\n\n/** Reason recorded on a {@link DroppedItem} for a finally-deleted node. */\nexport const DELETED_NODE_DROP_REASON = \"delete-modify:deleteWins\" as const;\n\n/**\n * The outcome of delete/modify resolution over the whole staging set.\n *\n * - `survivingModifications`: every staged inherited-node modification that the\n * merge will still apply — i.e. all modifications NOT overridden by a\n * `\"deleteWins\"` resolution. A node modified by several branches contributes\n * several entries here (one per branch), so T8's property union still sees the\n * full cross-branch disagreement.\n * - `nodeDeletions`: the AUTHORITATIVE set of inherited nodes that are finally\n * deleted — pure deletions (no branch modified them) plus delete/modify\n * conflicts resolved `\"deleteWins\"`. T9 reads this as the endpoint liveness.\n * - `conflicts`: one {@link DeleteModifyConflict} per inherited node that was\n * both deleted and modified.\n * - `dropped`: a `{ kind: \"node\" }` {@link DroppedItem} for every finally-deleted\n * node, so the report can enumerate exactly what left the merged graph.\n */\nexport type DeleteModifyResolution = Readonly<{\n survivingModifications: readonly StagedModifiedNode[];\n nodeDeletions: readonly DeletedNode[];\n conflicts: readonly DeleteModifyConflict[];\n dropped: readonly DroppedItem[];\n}>;\n\n/**\n * Picks the HIGHEST-PRIORITY branch from a set — the one with the lowest\n * `branchRank` (earliest in the captured stable order). Ties on rank fall back to\n * lexicographic branch-id order, so the choice is total and deterministic. Used\n * to record `deletedBy` / `modifiedBy` and to select which modification survives.\n */\nfunction pickHighestPriorityBranch(\n branchIds: readonly BranchId[],\n branchRank: ReadonlyMap<BranchId, number>,\n): BranchId {\n let chosen = requireDefined(branchIds[0]);\n let chosenRank = branchRank.get(chosen) ?? Number.MAX_SAFE_INTEGER;\n for (const candidate of branchIds.slice(1)) {\n const candidateRank = branchRank.get(candidate) ?? Number.MAX_SAFE_INTEGER;\n if (\n candidateRank < chosenRank ||\n (candidateRank === chosenRank && compareStrings(candidate, chosen) < 0)\n ) {\n chosen = candidate;\n chosenRank = candidateRank;\n }\n }\n return chosen;\n}\n\nfunction effectiveDeleteModifyPolicy(\n policy: DeleteModifyPolicy,\n deletions: readonly BranchTagged[],\n modifications: readonly BranchTagged[],\n preferredBranchId: BranchId | undefined,\n): DeleteModifyPolicy {\n if (\n preferredBranchId !== undefined &&\n deletions.some((deletion) => deletion.branchId === preferredBranchId)\n ) {\n return \"deleteWins\";\n }\n if (\n policy === \"deleteWins\" &&\n preferredBranchId !== undefined &&\n modifications.some(\n (modification) => modification.branchId === preferredBranchId,\n )\n ) {\n return \"modifyWins\";\n }\n return policy;\n}\n\n/**\n * Groups staged items by the `(kind, id)` IDENTITY of the entity `entityOf` extracts\n * (a node or an edge), preserving the per-identity arrays so callers can inspect every\n * contributing branch. Keying on the composite identity (not bare id) keeps an\n * inherited `Patient` and an inherited `Encounter` that share an id string from being\n * reconciled/deleted as if they were one entity.\n */\nfunction groupByEntity<T>(\n items: readonly T[],\n entityOf: (item: T) => Readonly<{ id: string; kind: string }>,\n): ReadonlyMap<MergeKey, readonly T[]> {\n const grouped = new Map<MergeKey, T[]>();\n for (const item of items) {\n const entity = entityOf(item);\n const key = mergeKey(entity.kind, entity.id);\n const bucket = grouped.get(key);\n if (bucket === undefined) {\n grouped.set(key, [item]);\n } else {\n bucket.push(item);\n }\n }\n return grouped;\n}\n\n/**\n * The shared node/edge DELETE-MODIFY resolver — the single control flow behind\n * {@link resolveDeleteModify} (nodes) and {@link resolveEdgeDeleteModify} (edges).\n * `modifiedEntity`/`deletedEntity` extract each staged item's `(id, kind)` (its\n * `.node` or `.edge`), and `droppedKind` tags the {@link DroppedItem}; everything\n * else — conflict detection, policy application, pure-deletion/pure-modification\n * passthrough, and the canonical output sort — is identical for both.\n */\nfunction resolveDeleteModifyOver<\n ModifiedItem extends BranchTagged,\n DeletedItem extends BranchTagged,\n Id extends AnyNodeId | EdgeId,\n>(\n modified: readonly ModifiedItem[],\n deleted: readonly DeletedItem[],\n modifiedEntity: (item: ModifiedItem) => Readonly<{ id: Id; kind: string }>,\n deletedEntity: (item: DeletedItem) => Readonly<{ id: Id; kind: string }>,\n droppedKind: \"node\" | \"edge\",\n policy: DeleteModifyPolicy,\n branchRank: ReadonlyMap<BranchId, number>,\n preferredBranchId: BranchId | undefined,\n): Readonly<{\n survivingModifications: readonly ModifiedItem[];\n deletions: readonly Readonly<{ id: Id; kind: string }>[];\n conflicts: readonly DeleteModifyConflict[];\n dropped: readonly DroppedItem[];\n}> {\n const modifiedByKey = groupByEntity(modified, modifiedEntity);\n const deletedByKey = groupByEntity(deleted, deletedEntity);\n\n const survivingModifications: ModifiedItem[] = [];\n const deletions: Readonly<{ id: Id; kind: string }>[] = [];\n const conflicts: DeleteModifyConflict[] = [];\n const dropped: DroppedItem[] = [];\n\n const conflictedKeys = new Set<MergeKey>();\n for (const key of deletedByKey.keys()) {\n if (modifiedByKey.has(key)) {\n conflictedKeys.add(key);\n }\n }\n\n for (const [key, modifications] of modifiedByKey) {\n if (!conflictedKeys.has(key)) {\n for (const modification of modifications) {\n survivingModifications.push(modification);\n }\n continue;\n }\n\n const deletionsForKey = requireDefined(deletedByKey.get(key));\n const { id, kind } = modifiedEntity(requireDefined(modifications[0]));\n const deletedBy = pickHighestPriorityBranch(\n deletionsForKey.map((deletion) => deletion.branchId),\n branchRank,\n );\n const modifiedBy = pickHighestPriorityBranch(\n modifications.map((modification) => modification.branchId),\n branchRank,\n );\n const effectivePolicy = effectiveDeleteModifyPolicy(\n policy,\n deletionsForKey,\n modifications,\n preferredBranchId,\n );\n\n conflicts.push({\n entityId: id,\n kind,\n deletedBy,\n modifiedBy,\n resolution: effectivePolicy,\n });\n\n if (effectivePolicy === \"deleteWins\") {\n deletions.push({ id, kind });\n dropped.push({ kind: droppedKind, id, reason: DELETED_NODE_DROP_REASON });\n continue;\n }\n\n // \"modifyWins\" and \"flag\" both KEEP the modification (resurrect the entity);\n // \"flag\" additionally leaves the recorded conflict unresolved for review.\n for (const modification of modifications) {\n survivingModifications.push(modification);\n }\n }\n\n for (const [key, deletionsForKey] of deletedByKey) {\n if (conflictedKeys.has(key)) {\n continue;\n }\n const { id, kind } = deletedEntity(requireDefined(deletionsForKey[0]));\n deletions.push({ id, kind });\n }\n\n return {\n survivingModifications: [...survivingModifications].sort((left, right) => {\n const byId = compareStrings(\n modifiedEntity(left).id,\n modifiedEntity(right).id,\n );\n return byId === 0 ? compareStrings(left.branchId, right.branchId) : byId;\n }),\n deletions: [...deletions].sort((left, right) =>\n compareStrings(left.id, right.id),\n ),\n conflicts: [...conflicts].sort((left, right) =>\n compareStrings(left.entityId, right.entityId),\n ),\n dropped: [...dropped].sort((left, right) =>\n compareStrings(left.id, right.id),\n ),\n };\n}\n\n/**\n * The shared node/edge MODIFICATION reconciler — the single control flow behind\n * {@link reconcileModifications} (nodes) and {@link reconcileEdgeModifications}\n * (edges). Groups by `(kind, id)`, 3-way merges every multi-branch modification via\n * {@link threeWayMergeProps}, and rebuilds ONE surviving record per id via `rebuild`\n * (carrying the highest-priority contributor's branch + the merged props).\n */\nfunction reconcileOver<Item extends BranchTagged>(\n survivingModifications: readonly Item[],\n entityOf: (item: Item) => Readonly<{\n id: AnyNodeId | EdgeId;\n kind: string;\n baseProps: Readonly<Record<string, unknown>>;\n forkProps: Readonly<Record<string, unknown>>;\n }>,\n rebuild: (\n representative: Item,\n chosenBranch: BranchId,\n mergedProps: Record<string, JsonValue>,\n ) => Item,\n policy: PropertyConflictPolicy,\n branchRank: ReadonlyMap<BranchId, number>,\n weights: ProvenanceWeights | undefined,\n preferredBranchId: BranchId | undefined,\n): Readonly<{\n survivingModifications: readonly Item[];\n conflicts: readonly PropertyConflict[];\n}> {\n const context: ResolutionContext<GraphDef> = {\n policy,\n ...(weights === undefined ? {} : { weights }),\n };\n\n const grouped = groupByEntity(survivingModifications, entityOf);\n const out: Item[] = [];\n const conflicts: PropertyConflict[] = [];\n\n for (const modifications of grouped.values()) {\n if (modifications.length === 1) {\n out.push(requireDefined(modifications[0]));\n continue;\n }\n const first = entityOf(requireDefined(modifications[0]));\n const { props, conflicts: propertyConflicts } = threeWayMergeProps(\n first.id,\n first.kind,\n first.baseProps as Readonly<Record<string, JsonValue>>,\n modifications.map((modification) => ({\n branchId: modification.branchId,\n forkProps: entityOf(modification).forkProps as Readonly<\n Record<string, JsonValue>\n >,\n })),\n context,\n branchRank,\n preferredBranchId,\n );\n const chosenBranch = pickHighestPriorityBranch(\n modifications.map((modification) => modification.branchId),\n branchRank,\n );\n const representative =\n modifications.find(\n (modification) => modification.branchId === chosenBranch,\n ) ?? requireDefined(modifications[0]);\n out.push(rebuild(representative, chosenBranch, props));\n for (const conflict of propertyConflicts) {\n conflicts.push(conflict);\n }\n }\n\n return {\n survivingModifications: [...out].sort((left, right) => {\n const byId = compareStrings(entityOf(left).id, entityOf(right).id);\n return byId === 0 ? compareStrings(left.branchId, right.branchId) : byId;\n }),\n conflicts: conflicts.sort((left, right) =>\n compareStrings(\n `${left.entityId}|${left.property}`,\n `${right.entityId}|${right.property}`,\n ),\n ),\n };\n}\n\n/**\n * Resolves every inherited node that is simultaneously DELETED by one or more\n * branches and MODIFIED by one or more (other) branches, per the\n * {@link DeleteModifyPolicy}:\n *\n * - `\"deleteWins\"` → the node is finally deleted (its modifications are\n * discarded). A {@link DeleteModifyConflict} with `resolution: \"deleteWins\"`\n * is recorded and a `{ kind: \"node\" }` {@link DroppedItem} is emitted.\n * - `\"modifyWins\"` → the node is RESURRECTED: its modifications survive (the\n * deletion is ignored). A conflict with `resolution: \"modifyWins\"` is\n * recorded; the node is NOT deleted.\n * - `\"flag\"` → the modifications survive (as with `\"modifyWins\"`) but the\n * conflict is recorded UNRESOLVED (`resolution: \"flag\"`) for human review.\n *\n * Pure deletions (no branch modified the node) pass straight through to\n * {@link nodeDeletions}; pure modifications (no branch deleted the node) pass\n * straight through to {@link survivingModifications}. Both unconflicted paths\n * carry NO {@link DeleteModifyConflict}.\n *\n * The result is order-independent: the keep-vs-delete decision depends only on\n * the policy and the contributing branch SET; `branchRank` is consulted solely to\n * tie-break which modification survives and which branch ids are recorded.\n *\n * @param staging The provenance-tagged union staging set (T7).\n * @param policy The delete/modify-conflict policy.\n * @param branchRank The captured stable branch rank (built once via\n * `buildBranchRank`, shared across phases). Used ONLY for deterministic\n * tie-breaking — never for the keep-vs-delete decision itself.\n */\nexport function resolveDeleteModify(\n staging: StagingSet,\n policy: DeleteModifyPolicy,\n branchRank: ReadonlyMap<BranchId, number>,\n preferredBranchId?: BranchId,\n): DeleteModifyResolution {\n const resolved = resolveDeleteModifyOver(\n staging.modifiedNodes,\n staging.deletedNodes,\n (item) => item.node,\n (item) => item.node,\n \"node\",\n policy,\n branchRank,\n preferredBranchId,\n );\n return {\n survivingModifications: resolved.survivingModifications,\n nodeDeletions: resolved.deletions,\n conflicts: resolved.conflicts,\n dropped: resolved.dropped,\n };\n}\n\n/**\n * The outcome of reconciling the surviving inherited modifications: ONE merged\n * record per node id (carrying the 3-way-merged props the commit applies) plus\n * every {@link PropertyConflict} that a multi-branch modification surfaced.\n */\nexport type ModificationReconciliation = Readonly<{\n survivingModifications: readonly StagedModifiedNode[];\n conflicts: readonly PropertyConflict[];\n}>;\n\n/** A single branch's full fork props for an inherited entity (node or edge). */\ntype ForkContribution = Readonly<{\n branchId: BranchId;\n forkProps: Readonly<Record<string, JsonValue>>;\n}>;\n\n/**\n * 3-WAY merges one inherited entity (node OR edge) modified by 2+ branches against\n * the SHARED base.\n *\n * Per property: a branch whose fork value equals base contributed no change; a\n * property exactly one branch changed takes that change; a property multiple\n * branches changed to DIFFERING values is a genuine conflict, resolved by the\n * captured policy on the stable `branchRank` and recorded as a\n * {@link PropertyConflict}. Property DELETIONS (a base key absent from a fork) are\n * treated conservatively as \"unchanged\" so an unrelated branch's edit is never\n * lost. `baseProps` is identical across the contributions (same base, same id).\n *\n * Shared by node modification reconciliation ({@link reconcileModifications}) and\n * edge modification reconciliation ({@link reconcileEdgeModifications}), so both\n * apply identical base-aware semantics — without this, disjoint edits to the same\n * entity by different branches would false-conflict and one edit could be lost.\n */\nfunction threeWayMergeProps(\n entityId: AnyNodeId | EdgeId,\n kind: string,\n baseProps: Readonly<Record<string, JsonValue>>,\n contributions: readonly ForkContribution[],\n context: ResolutionContext<GraphDef>,\n branchRank: ReadonlyMap<BranchId, number>,\n preferredBranchId?: BranchId,\n): Readonly<{\n props: Record<string, JsonValue>;\n conflicts: PropertyConflict[];\n}> {\n const merged: Record<string, JsonValue> = {};\n const conflicts: PropertyConflict[] = [];\n\n // Every property the base OR any fork carries. Base keys are included so a key\n // that EVERY fork dropped is still seen here (a fork's `forkProps` is its full\n // bag, so a missing base key is an intentional deletion, not an omission).\n const propertyNames = new Set<string>(Object.keys(baseProps));\n for (const contribution of contributions) {\n for (const name of Object.keys(contribution.forkProps)) {\n propertyNames.add(name);\n }\n }\n\n for (const property of [...propertyNames].sort(compareStrings)) {\n const baseHas = property in baseProps;\n const baseKey =\n baseHas ?\n canonicalValueKey(requireDefined(baseProps[property]))\n : undefined;\n\n // Contributions from branches that actually CHANGED this property (present and\n // differing from base). Reuse the shared collector so the distinct-(branch,value)\n // dedupe + ordering match the node/edge property unions exactly — one definition\n // of conflict gathering, with the canonical NUL-separated dedupe key.\n const changed = contributions\n .filter((contribution) => {\n if (!(property in contribution.forkProps)) {\n return false; // absent — a deletion (handled below), never a change\n }\n const value = contribution.forkProps[property] as JsonValue;\n return !baseHas || canonicalValueKey(value) !== baseKey;\n })\n .map((contribution) => ({\n branchId: contribution.branchId,\n props: contribution.forkProps,\n }));\n const values = collectConflictingValues(property, changed);\n\n if (values.length === 0) {\n // No fork CHANGED the value. A fork's `forkProps` is its FULL bag, so a base\n // property a fork OMITS was DELETED by it; honor that deletion by leaving the\n // key out of `merged`. Otherwise every fork kept the base value, so it stands.\n const deletedByFork =\n baseHas &&\n contributions.some(\n (contribution) => !(property in contribution.forkProps),\n );\n if (baseHas && !deletedByFork) {\n merged[property] = requireDefined(baseProps[property]);\n }\n continue;\n }\n\n const distinctValues = new Set(\n values.map((candidate) => canonicalValueKey(candidate.value)),\n );\n if (distinctValues.size === 1) {\n merged[property] = requireDefined(values[0]).value; // a single, agreed-upon change\n continue;\n }\n\n const preferredValue = values.find(\n (value) => value.branchId === preferredBranchId,\n )?.value;\n const canonicalValue =\n preferredValue ??\n (baseHas ?\n requireDefined(baseProps[property])\n : requireDefined(values[0]).value);\n const reportedValues =\n preferredBranchId === undefined ? values : (\n values.filter((value) => value.branchId !== preferredBranchId)\n );\n const { value, conflict } = resolvePropertyUnion(\n { entityId, kind, property, values, reportedValues, canonicalValue },\n context,\n branchRank,\n );\n merged[property] = value;\n if (conflict !== undefined) {\n conflicts.push(conflict);\n }\n }\n\n return { props: merged, conflicts };\n}\n\n/**\n * Reconciles the post-delete/modify surviving modifications into the records the\n * commit applies. An inherited node modified by a SINGLE branch passes through\n * unchanged; a node modified by TWO OR MORE branches is 3-way merged against the\n * base ({@link mergeModifiedProps}) into one record carrying the merged props,\n * surfacing any genuine cross-branch disagreement as a {@link PropertyConflict}.\n *\n * Without this, each per-branch modification was committed by id in turn, so the\n * lexicographically-largest branchId silently overwrote the others with NO\n * conflict recorded and the configured `onPropertyConflict` / `branchOrder`\n * bypassed (the §6.2 gap). The synthetic record's `branchId` is the highest\n * -priority contributor — cosmetic, since the commit reads only `node.id` / kind /\n * `forkProps`, and provenance for every contributing branch is recorded upstream.\n *\n * Order-independent: groups by id (the staging input is already `(id, branchId)`\n * sorted), merges per the stable `branchRank`, and sorts both outputs by stable\n * keys, so shuffling the branch set yields an identical result.\n *\n * @param survivingModifications The surviving modifications from\n * {@link resolveDeleteModify} (one entry per `(id, branch)`).\n * @param policy The property-conflict policy (shared with the cluster union, T8).\n * @param branchRank The captured stable branch rank.\n * @param weights Optional per-branch weights for `\"provenanceWeighted\"`.\n */\nexport function reconcileModifications(\n survivingModifications: readonly StagedModifiedNode[],\n policy: PropertyConflictPolicy,\n branchRank: ReadonlyMap<BranchId, number>,\n weights?: ProvenanceWeights,\n preferredBranchId?: BranchId,\n): ModificationReconciliation {\n return reconcileOver(\n survivingModifications,\n (item) => item.node,\n (representative, chosenBranch, mergedProps) => ({\n branchId: chosenBranch,\n node: { ...representative.node, forkProps: mergedProps },\n }),\n policy,\n branchRank,\n weights,\n preferredBranchId,\n );\n}\n\n// ============================================================\n// Inherited EDGE delete/modify resolution (the edge analogue of the node path\n// above). Edges carry fixed endpoints, so a \"modified\" edge only changes props;\n// the delete/modify and 3-way merge logic is otherwise identical to nodes, and\n// reuses the same {@link pickHighestPriorityBranch} + {@link threeWayMergeProps}\n// cores so node and edge behavior can never drift.\n// ============================================================\n\n/**\n * The outcome of delete/modify resolution over the staged inherited EDGES.\n * Mirrors {@link DeleteModifyResolution}: `edgeDeletions` is the authoritative set\n * of finally-deleted inherited edges (pure deletions plus `\"deleteWins\"` conflict\n * resolutions); `survivingModifications` is every modification the merge still\n * applies; `conflicts`/`dropped` mirror the node fields.\n */\nexport type EdgeDeleteModifyResolution = Readonly<{\n survivingModifications: readonly StagedModifiedEdge[];\n edgeDeletions: readonly DeletedEdge[];\n conflicts: readonly DeleteModifyConflict[];\n dropped: readonly DroppedItem[];\n}>;\n\n/**\n * Resolves every inherited EDGE simultaneously deleted by one+ branches and\n * modified by one+ (other) branches, per the {@link DeleteModifyPolicy} — the\n * edge analogue of {@link resolveDeleteModify}. Pure deletions flow to\n * `edgeDeletions`; pure modifications flow to `survivingModifications`. Without\n * this, inherited edge deletions were staged but never applied, so a branch's\n * edge deletion was silently dropped and the edge stayed live. Shares\n * {@link resolveDeleteModifyOver} with the node path so the two can never drift.\n */\nexport function resolveEdgeDeleteModify(\n staging: StagingSet,\n policy: DeleteModifyPolicy,\n branchRank: ReadonlyMap<BranchId, number>,\n preferredBranchId?: BranchId,\n): EdgeDeleteModifyResolution {\n const resolved = resolveDeleteModifyOver(\n staging.modifiedEdges,\n staging.deletedEdges,\n (item) => item.edge,\n (item) => item.edge,\n \"edge\",\n policy,\n branchRank,\n preferredBranchId,\n );\n return {\n survivingModifications: resolved.survivingModifications,\n edgeDeletions: resolved.deletions,\n conflicts: resolved.conflicts,\n dropped: resolved.dropped,\n };\n}\n\n/**\n * The edge analogue of {@link reconcileModifications}: ONE merged record per edge\n * id, carrying the 3-way-merged props the commit applies, plus every\n * {@link PropertyConflict} a multi-branch edge modification surfaced. Edge\n * endpoints are immutable, so only props are merged; the representative's\n * endpoints/kind are kept.\n */\nexport function reconcileEdgeModifications(\n survivingModifications: readonly StagedModifiedEdge[],\n policy: PropertyConflictPolicy,\n branchRank: ReadonlyMap<BranchId, number>,\n weights?: ProvenanceWeights,\n preferredBranchId?: BranchId,\n): Readonly<{\n survivingModifications: readonly StagedModifiedEdge[];\n conflicts: readonly PropertyConflict[];\n}> {\n return reconcileOver(\n survivingModifications,\n (item) => item.edge,\n (representative, chosenBranch, mergedProps) => ({\n branchId: chosenBranch,\n edge: { ...representative.edge, forkProps: mergedProps },\n }),\n policy,\n branchRank,\n weights,\n preferredBranchId,\n );\n}\n","import { requireDefined } from \"../utils/presence\";\n/**\n * Edge repoint to canonical + set-dedupe cascade (design §6.3 / §6.4 rule 5, T9).\n *\n * After clustering (T8) collapses fork nodes into canonical survivors and\n * delete/modify resolution (T8a) fixes the FINAL LIVENESS of every endpoint, the\n * inherited and new edges of the merge must be:\n *\n * 1. REPOINTED — each endpoint mapped to its cluster's canonical id. An edge\n * `x → a` where `{a, b}` collapsed to canonical `c*` becomes `x → c*`.\n * 2. DROPPED — any edge whose (repointed) `from` or `to` is a finally-deleted\n * node (per T8a, NOT resurrected) is removed, recorded as a\n * {@link DroppedItem} with reason {@link ENDPOINT_DELETED_DROP_REASON}.\n * 3. DEDUPED — repointing can make two distinct edges identical. Edges are\n * collapsed as a pure SET operation keyed by\n * `(fromCanonical | type | toCanonical | propsKey)`, where `propsKey` is the\n * T2 canonical serializer over PARSED props. So `x → a` and `x → b` (both\n * repointed to `x → c*`) with equal props yield a SINGLE `x → c*`.\n * 4. RECONCILED — when two edges collapse to the same `(from, type, to)` but\n * carry DIFFERING props, the per-property disagreement is resolved by the\n * shared T8 conflict policy ({@link resolvePropertyUnion}) on the captured,\n * non-wall-clock branch order, recording an edge-level {@link PropertyConflict}\n * whose `entityId` is the surviving edge's id.\n *\n * Determinism: the dedupe is a pure function of the (unordered) staged-edge SET.\n * Within a collision group the surviving edge id is the lexicographically-minimal\n * member id, property resolution uses only the captured `branchRank`, and the\n * output is sorted by dedupe key — so shuffling the input edges yields an\n * identical result. Clusters are computed once upstream (T8) and passed in as\n * {@link canonicalOf}; this module never re-clusters.\n */\nimport { canonicalizeProps } from \"./canonical-props\";\nimport type { ClusterResult } from \"./clustering\";\nimport type { ProvenanceWeights, ResolutionContext } from \"./conflict-policy\";\nimport {\n collectConflictingValues,\n resolvePropertyUnion,\n} from \"./conflict-policy\";\nimport {\n compareStrings,\n idOf,\n kindOf,\n type MergeKey,\n mergeKey,\n} from \"./node-key\";\nimport type {\n EdgeId,\n GraphDef,\n JsonValue,\n NodeId,\n NodeType,\n} from \"./typegraph-internal\";\nimport type {\n BranchId,\n PropertyConflict,\n PropertyConflictPolicy,\n} from \"./types\";\n\n/** A node id in its untyped (`NodeType`-default) branded form. */\ntype AnyNodeId = NodeId<NodeType>;\n\n/** Reason recorded on a {@link DroppedItem} for an edge to a deleted endpoint. */\nexport const ENDPOINT_DELETED_DROP_REASON = \"edge:endpoint-deleted\" as const;\n\n/**\n * A `{ kind: \"edge\" }` dropped item. Mirrors the public {@link DroppedItem} but is\n * narrowed to edges so this module's output is precisely typed. Structurally\n * assignable to {@link DroppedItem}.\n */\ntype DroppedEdge = Readonly<{\n kind: \"edge\";\n id: EdgeId;\n reason: string;\n}>;\n\n/**\n * One staged edge fed into the repoint phase: a new fork edge or a surviving\n * inherited edge. Carries the parsed props (NOT a JSON string) so the dedupe key\n * and the conflict union both operate on the canonical structure, and the\n * {@link BranchId} that contributed it so edge-property conflicts resolve on the\n * same stable branch order as node-property conflicts.\n *\n * The orchestrator (T11) builds these from `StagedNewEdge` / surviving\n * `StagedModifiedEdge` items (T7); this module needs no knowledge of the diff\n * shape beyond these fields.\n */\nexport type StagedEdge = Readonly<{\n id: EdgeId;\n kind: string;\n fromId: AnyNodeId;\n toId: AnyNodeId;\n fromKind: string;\n toKind: string;\n props: Readonly<Record<string, JsonValue>>;\n branchId: BranchId;\n}>;\n\n/**\n * A surviving merged edge after repoint + dedupe. `id` is the canonical survivor\n * of its collision group (the lexicographically-minimal contributing edge id);\n * `mergedIds` is every staged edge id that collapsed into it (always includes\n * `id`), so the commit phase (T11) knows which inherited edges to fold away.\n */\nexport type MergedEdge = Readonly<{\n id: EdgeId;\n kind: string;\n fromId: AnyNodeId;\n toId: AnyNodeId;\n fromKind: string;\n toKind: string;\n props: Readonly<Record<string, JsonValue>>;\n mergedIds: readonly EdgeId[];\n}>;\n\n/**\n * The outcome of the repoint + dedupe cascade: the surviving merged edges, every\n * edge dropped for a deleted endpoint, and every edge-level property conflict the\n * dedupe surfaced.\n */\nexport type EdgeRepointResult<G extends GraphDef = GraphDef> = Readonly<{\n edges: readonly MergedEdge[];\n dropped: readonly DroppedEdge[];\n conflicts: readonly PropertyConflict<G>[];\n}>;\n\n/**\n * Builds the endpoint → canonical map from the resolved clusters. Every member of\n * a cluster maps to that cluster's canonical id; ids absent from the map (cluster\n * singletons / nodes never compared) are treated as their own canonical by the\n * `?? id` fallback at lookup time, so the map need only carry the rewrites.\n *\n * @param clusters Resolved clusters (T8). Each must be non-empty.\n * @param canonicalOf A `cluster → canonicalId` selector returning the cluster's\n * canonical survivor (as chosen by T8 `pickClusterSurvivor`), threaded so this\n * module reuses the merge-wide canonical choice rather than re-deriving it.\n */\nexport function buildCanonicalMap(\n clusters: readonly ClusterResult[],\n canonicalOf: (cluster: ClusterResult) => MergeKey,\n): ReadonlyMap<MergeKey, MergeKey> {\n const map = new Map<MergeKey, MergeKey>();\n for (const cluster of clusters) {\n const canonical = canonicalOf(cluster);\n for (const member of cluster.members) {\n map.set(member, canonical);\n }\n }\n return map;\n}\n\n/**\n * Resolves an endpoint IDENTITY (`(kind, id)` key) to its cluster canonical,\n * defaulting to itself. Keying on the composite identity is what stops an edge from\n * a `Patient` and an edge from an `Encounter` that share an endpoint id from being\n * repointed onto the same survivor.\n */\nfunction repoint(\n key: MergeKey,\n canonicalOf: ReadonlyMap<MergeKey, MergeKey>,\n): MergeKey {\n return canonicalOf.get(key) ?? key;\n}\n\n/**\n * The dedupe key for a repointed edge: a JSON-encoded `[from', type, to',\n * propsKey]` tuple. The `propsKey` is the T2 canonical serializer over the PARSED\n * props, so two edges that agree on endpoints, type, AND every property collapse to\n * one regardless of property key order. JSON-encoding the tuple (rather than\n * concatenating with a literal separator) keeps the key unambiguous even when an\n * edge `type` — a user-defined schema string — or a caller-supplied endpoint id\n * contains the separator character.\n */\nfunction dedupeKey(\n fromKey: MergeKey,\n type: string,\n toKey: MergeKey,\n props: Readonly<Record<string, JsonValue>>,\n): string {\n return JSON.stringify([fromKey, type, toKey, canonicalizeProps(props)]);\n}\n\n/**\n * The key identifying a collision GROUP — edges sharing `(from', type, to')`\n * regardless of props. Edges in the same group but with differing props are the\n * ones whose properties must be reconciled by the conflict policy. JSON-encoded\n * (see {@link dedupeKey}) so a `|`-bearing type/id can never fuse two distinct\n * groups.\n */\nfunction groupKey(fromKey: MergeKey, type: string, toKey: MergeKey): string {\n return JSON.stringify([fromKey, type, toKey]);\n}\n\n/**\n * A repointed staged edge plus both endpoints already mapped to their canonical\n * IDENTITY key (`(kind, id)`). The composite keys carry the canonical node's kind, so\n * the surviving edge's bare `fromId`/`toId` and `fromKind`/`toKind` are read off\n * `idOf`/`kindOf` of these keys — never the (possibly different-kind) staged endpoint.\n */\ntype RepointedEdge = Readonly<{\n staged: StagedEdge;\n fromKey: MergeKey;\n toKey: MergeKey;\n}>;\n\n/**\n * Picks the canonical survivor edge of a collision group: the member with the\n * lexicographically-minimal edge id. Mirrors the node min-id canonical rule (T8)\n * so the surviving id is independent of input edge order. (`generateId()` is\n * nanoid — random, not time-prefixed — so min-id never leaks creation order.)\n */\nfunction pickSurvivor(\n edges: readonly RepointedEdge[],\n preferredBranchId?: BranchId,\n): RepointedEdge {\n const preferred =\n preferredBranchId === undefined ?\n []\n : edges.filter((edge) => edge.staged.branchId === preferredBranchId);\n const candidates = preferred.length > 0 ? preferred : edges;\n let survivor = requireDefined(candidates[0]);\n for (const candidate of candidates.slice(1)) {\n if (candidate.staged.id < survivor.staged.id) {\n survivor = candidate;\n }\n }\n return survivor;\n}\n\n/**\n * Unions the props of one collision group's edges, resolving any per-property\n * disagreement via the shared T8 conflict policy. Returns the surviving prop bag\n * plus an edge-level {@link PropertyConflict} for every property that genuinely\n * differed (its `entityId` is the surviving edge id).\n */\nfunction unionEdgeProps(\n survivorId: EdgeId,\n kind: string,\n survivor: RepointedEdge,\n edges: readonly RepointedEdge[],\n context: ResolutionContext<GraphDef>,\n branchRank: ReadonlyMap<BranchId, number>,\n preferredBranchId?: BranchId,\n): Readonly<{\n props: Record<string, JsonValue>;\n conflicts: PropertyConflict[];\n}> {\n const propertyNames = new Set<string>();\n for (const edge of edges) {\n for (const name of Object.keys(edge.staged.props)) {\n propertyNames.add(name);\n }\n }\n\n const props: Record<string, JsonValue> = {};\n const conflicts: PropertyConflict[] = [];\n\n // The staged record of each edge IS a `(branchId, props)` contribution, so the\n // shared node/edge collector consumes it directly.\n const contributions = edges.map((edge) => edge.staged);\n\n for (const property of [...propertyNames].sort((left, right) =>\n compareStrings(left, right),\n )) {\n const values = collectConflictingValues(property, contributions);\n if (values.length === 0) {\n continue;\n }\n const survivorValue =\n property in survivor.staged.props ?\n (survivor.staged.props[property] as JsonValue)\n : requireDefined(values[0]).value;\n const canonicalValue: JsonValue =\n values.find((value) => value.branchId === preferredBranchId)?.value ??\n survivorValue;\n const reportedValues =\n preferredBranchId === undefined ? values : (\n values.filter((value) => value.branchId !== preferredBranchId)\n );\n\n const { value, conflict } = resolvePropertyUnion(\n {\n entityId: survivorId,\n kind,\n property,\n values,\n reportedValues,\n canonicalValue,\n },\n context,\n branchRank,\n );\n props[property] = value;\n if (conflict !== undefined) {\n conflicts.push(conflict);\n }\n }\n\n return { props, conflicts };\n}\n\n/**\n * Repoints every staged edge onto its cluster canonical, drops edges whose\n * (repointed) endpoints are finally deleted, and dedupes the survivors as a pure\n * set operation keyed by `(from' | type | to' | propsKey)`.\n *\n * Within a collision group sharing `(from', type, to')`:\n * - identical props collapse silently to one edge,\n * - DIFFERING props are reconciled by `policy` on the captured `branchRank`,\n * recording one edge-level {@link PropertyConflict} per disagreeing property.\n *\n * The surviving edge of every group is the lexicographically-minimal contributing\n * edge id; its `mergedIds` lists every collapsed edge id. Output is sorted by the\n * full dedupe key, so the result is a pure function of the unordered input set.\n *\n * @param stagedEdges The new + surviving-inherited edges to merge. Order does not\n * affect the result. Props MUST already be parsed objects.\n * @param canonicalOf The endpoint → canonical map (from {@link buildCanonicalMap}).\n * Endpoints absent from it map to themselves.\n * @param deletedNodeIds The AUTHORITATIVE finally-deleted node id set (T8a). Any\n * edge whose repointed `from`/`to` is in this set is dropped.\n * @param policy The property-conflict policy (shared with node union, T8).\n * @param branchRank The captured stable branch rank (built once via\n * `buildBranchRank`). Used only for deterministic conflict resolution — never\n * wall-clock.\n * @param weights Optional per-branch weights for the `\"provenanceWeighted\"` policy.\n */\nexport function repointEdges<G extends GraphDef = GraphDef>(\n stagedEdges: readonly StagedEdge[],\n canonicalOf: ReadonlyMap<MergeKey, MergeKey>,\n deletedNodeIds: ReadonlySet<MergeKey>,\n policy: PropertyConflictPolicy<G>,\n branchRank: ReadonlyMap<BranchId, number>,\n weights?: ProvenanceWeights,\n preferredBranchId?: BranchId,\n): EdgeRepointResult<G> {\n const dropped: DroppedEdge[] = [];\n const liveByDedupeKey = new Map<string, RepointedEdge[]>();\n // Per `(from', type, to')` group → the SET of distinct dedupe keys seen for it.\n // Insertion order is irrelevant: Phase 2 re-derives the survivor and sorts the\n // output explicitly, so the set carries membership only.\n const dedupeKeyByGroup = new Map<string, Set<string>>();\n\n // Phase 1: repoint endpoints (by their `(kind, id)` identity, so a cross-kind id\n // collision can never repoint two unrelated edges onto one survivor), drop edges to\n // deleted nodes, and bucket the survivors by their full dedupe key.\n for (const staged of stagedEdges) {\n const fromKey = repoint(\n mergeKey(staged.fromKind, staged.fromId),\n canonicalOf,\n );\n const toKey = repoint(mergeKey(staged.toKind, staged.toId), canonicalOf);\n\n if (deletedNodeIds.has(fromKey) || deletedNodeIds.has(toKey)) {\n dropped.push({\n kind: \"edge\",\n id: staged.id,\n reason: ENDPOINT_DELETED_DROP_REASON,\n });\n continue;\n }\n\n const repointed: RepointedEdge = { staged, fromKey, toKey };\n const key = dedupeKey(fromKey, staged.kind, toKey, staged.props);\n const bucket = liveByDedupeKey.get(key);\n if (bucket === undefined) {\n liveByDedupeKey.set(key, [repointed]);\n } else {\n bucket.push(repointed);\n }\n\n const group = groupKey(fromKey, staged.kind, toKey);\n const keysForGroup = dedupeKeyByGroup.get(group);\n if (keysForGroup === undefined) {\n dedupeKeyByGroup.set(group, new Set([key]));\n } else {\n keysForGroup.add(key);\n }\n }\n\n // Phase 2: per `(from', type, to')` group, fold the per-dedupe-key buckets into\n // one survivor. A group with a single dedupe key is an exact-equal collapse (no\n // conflict); a group with several dedupe keys means props differ, so the union\n // runs the conflict policy.\n const context: ResolutionContext<GraphDef> = {\n policy: policy as PropertyConflictPolicy<GraphDef>,\n ...(weights === undefined ? {} : { weights }),\n };\n\n const merged: MergedEdge[] = [];\n const conflicts: PropertyConflict<G>[] = [];\n\n const sortedGroups = [...dedupeKeyByGroup.keys()].sort((left, right) =>\n compareStrings(left, right),\n );\n\n for (const group of sortedGroups) {\n const dedupeKeys = [...requireDefined(dedupeKeyByGroup.get(group))];\n const groupEdges: RepointedEdge[] = [];\n for (const key of dedupeKeys) {\n for (const edge of requireDefined(liveByDedupeKey.get(key))) {\n groupEdges.push(edge);\n }\n }\n\n const survivor = pickSurvivor(groupEdges, preferredBranchId);\n const survivorId = survivor.staged.id;\n const mergedIds = [...groupEdges]\n .map((edge) => edge.staged.id)\n .sort((left, right) => compareStrings(left, right));\n\n // Endpoint ids AND kinds come from the canonical IDENTITY keys, so a repointed\n // edge always names the canonical node's own kind (the commit then applies any\n // retype cascade), never a staged endpoint that merely shared the id string.\n const fromId = idOf(survivor.fromKey);\n const fromKind = kindOf(survivor.fromKey);\n const toId = idOf(survivor.toKey);\n const toKind = kindOf(survivor.toKey);\n\n if (dedupeKeys.length === 1) {\n // Exact-equal collapse: every member shares identical props, so no\n // conflict is possible — keep the survivor's props verbatim.\n merged.push({\n id: survivorId,\n kind: survivor.staged.kind,\n fromId,\n toId,\n fromKind,\n toKind,\n props: survivor.staged.props,\n mergedIds,\n });\n continue;\n }\n\n const { props, conflicts: groupConflicts } = unionEdgeProps(\n survivorId,\n survivor.staged.kind,\n survivor,\n groupEdges,\n context,\n branchRank,\n preferredBranchId,\n );\n for (const conflict of groupConflicts) {\n conflicts.push(conflict as PropertyConflict<G>);\n }\n merged.push({\n id: survivorId,\n kind: survivor.staged.kind,\n fromId,\n toId,\n fromKind,\n toKind,\n props,\n mergedIds,\n });\n }\n\n // Sort on a PRECOMPUTED dedupe key per edge (Schwartzian) so `canonicalizeProps` +\n // serialization run once per edge, not twice on every comparison.\n const sortedEdges = merged\n .map((edge) => ({\n edge,\n sortKey: dedupeKey(\n mergeKey(edge.fromKind, edge.fromId),\n edge.kind,\n mergeKey(edge.toKind, edge.toId),\n edge.props,\n ),\n }))\n .sort((left, right) => compareStrings(left.sortKey, right.sortKey))\n .map(({ edge }) => edge);\n\n return {\n edges: sortedEdges,\n dropped: dropped.sort((left, right) => compareStrings(left.id, right.id)),\n conflicts: conflicts.sort((left, right) =>\n compareStrings(\n `${left.entityId}|${left.property}`,\n `${right.entityId}|${right.property}`,\n ),\n ),\n };\n}\n","/**\n * Validation + default-application for {@link MergeOptions}.\n *\n * The zod schema validates the scalar / enum surface (thresholds, ceilings,\n * enums) and applies the frozen P0 defaults. Function- and store-valued fields\n * (`canonical`, a function `onPropertyConflict`, `target`, per-kind `block` /\n * `custom.score`, `branchOrder`) are not meaningfully validatable by zod, so they\n * are threaded through unchanged after the scalar surface validates.\n *\n * `normalizeMergeOptions` is the single entry point: it returns a\n * {@link NormalizedMergeOptions} with every default resolved, so downstream\n * phases never branch on `undefined`.\n */\n\nimport { z } from \"zod\";\n\nimport type { GraphDef } from \"./typegraph-internal\";\nimport type {\n BranchId,\n ComparisonCeilingPolicy,\n DeleteModifyPolicy,\n Embedder,\n MergeOptions,\n PropertyConflictPolicy,\n ReconcileTypesMode,\n ResolveConfig,\n ResolvedCluster,\n ResolveMap,\n} from \"./types\";\n\n/**\n * Frozen P0 defaults. Exported so tests and downstream phases assert against the\n * same constants rather than re-typing literals.\n */\nexport const MERGE_OPTION_DEFAULTS = {\n reconcileTypes: \"off\",\n onPropertyConflict: \"flag\",\n onBasePropertyConflict: \"flag\",\n onDeleteModifyConflict: \"flag\",\n onComparisonCeiling: \"error\",\n provenance: true,\n persistProvenance: false,\n} as const satisfies Readonly<{\n reconcileTypes: ReconcileTypesMode;\n onPropertyConflict: \"flag\";\n onBasePropertyConflict: \"flag\";\n onDeleteModifyConflict: DeleteModifyPolicy;\n onComparisonCeiling: ComparisonCeilingPolicy;\n provenance: boolean;\n persistProvenance: boolean;\n}>;\n\n/**\n * zod schema for the STRING arm of `onPropertyConflict`. The field is a union of\n * this enum and a function; the function arm is not validatable by zod, but the\n * string arm is — and validating it here keeps `onPropertyConflict` consistent with\n * every other enum option, so a bad string fails with a clean option error rather\n * than an opaque `TypeError` deep inside conflict resolution.\n */\nconst propertyConflictPolicySchema = z.enum([\n \"flag\",\n \"lastWriteWins\",\n \"provenanceWeighted\",\n]);\n\n/** zod schema for a single resolve config's scalar surface (the threshold). */\nconst resolveConfigScalarSchema = z.object({\n threshold: z\n .number()\n .min(0, { message: \"threshold must be >= 0\" })\n .max(1, { message: \"threshold must be <= 1\" }),\n});\n\n/**\n * zod schema for the scalar / enum surface of {@link MergeOptions}. Function- and\n * store-valued fields are deliberately omitted (validated structurally by the\n * type system, not at runtime) and re-attached after parsing.\n */\nconst mergeOptionsScalarSchema = z.object({\n reconcileTypes: z\n .enum([\"ontology\", \"off\"])\n .default(MERGE_OPTION_DEFAULTS.reconcileTypes),\n onDeleteModifyConflict: z\n .enum([\"deleteWins\", \"modifyWins\", \"flag\"])\n .default(MERGE_OPTION_DEFAULTS.onDeleteModifyConflict),\n onComparisonCeiling: z\n .enum([\"error\", \"mergeByIdOnly\"])\n .default(MERGE_OPTION_DEFAULTS.onComparisonCeiling),\n provenance: z.boolean().default(MERGE_OPTION_DEFAULTS.provenance),\n persistProvenance: z\n .boolean()\n .default(MERGE_OPTION_DEFAULTS.persistProvenance),\n maxComparisonsPerKind: z\n .number()\n .int({ message: \"maxComparisonsPerKind must be an integer\" })\n .min(0, { message: \"maxComparisonsPerKind must be >= 0\" })\n .optional(),\n clusterMaxDiameter: z\n .number()\n .positive({ message: \"clusterMaxDiameter must be positive\" })\n .optional(),\n});\n\n/**\n * Fully-normalized merge options: every default resolved, the (validated)\n * pass-through fields attached. Downstream phases consume this, never the raw\n * {@link MergeOptions}.\n */\nexport type NormalizedMergeOptions<G extends GraphDef = GraphDef> = Readonly<{\n // Internal kind-agnostic view: the public {@link ResolveMap} is keyed per-kind,\n // but downstream phases index it by a runtime kind STRING, so the normalized\n // form widens to a plain record. Unknown keys were already validated away.\n resolve: Readonly<Record<string, ResolveConfig<G>>>;\n reconcileTypes: ReconcileTypesMode;\n onPropertyConflict: PropertyConflictPolicy<G>;\n onBasePropertyConflict: PropertyConflictPolicy<G>;\n onDeleteModifyConflict: DeleteModifyPolicy;\n onComparisonCeiling: ComparisonCeilingPolicy;\n provenance: boolean;\n persistProvenance: boolean;\n canonical?: (\n cluster: ResolvedCluster,\n ) => ReturnType<NonNullable<MergeOptions<G>[\"canonical\"]>>;\n embedder?: Embedder;\n target?: MergeOptions<G>[\"target\"];\n maxComparisonsPerKind?: number;\n clusterMaxDiameter?: number;\n branchOrder?: readonly BranchId[];\n provenanceWeights?: ReadonlyMap<BranchId, number>;\n}>;\n\n/**\n * Validates the STRING arm of a property-conflict policy (the function arm is not\n * validatable by zod), throwing a clean option error for an unknown enum value.\n * Shared by `onPropertyConflict` and the separate `onBasePropertyConflict`.\n */\nfunction validatePropertyConflictPolicy<G extends GraphDef>(\n policy: PropertyConflictPolicy<G>,\n label: string,\n): PropertyConflictPolicy<G> {\n if (\n typeof policy === \"string\" &&\n !propertyConflictPolicySchema.safeParse(policy).success\n ) {\n throw new Error(\n `Invalid ${label} \"${policy}\": expected \"flag\", \"lastWriteWins\", \"provenanceWeighted\", or a function.`,\n );\n }\n return policy;\n}\n\n/**\n * Validates each per-kind resolve config's threshold, leaving the strategy and\n * `block` function untouched. Returns the same map shape (resolve configs are\n * passed through; only their scalar surface is validated).\n */\nfunction validateResolveMap<G extends GraphDef>(\n resolve: ResolveMap<G> | undefined,\n): Readonly<Record<string, ResolveConfig<G>>> {\n if (resolve === undefined) {\n return {};\n }\n // The public ResolveMap binds each kind's config to that kind's NodeType;\n // validation only reads the kind-agnostic scalar surface, so widen to a plain\n // record (the per-kind block/similarity types are sound at every call site).\n const configs = resolve as unknown as Readonly<\n Record<string, ResolveConfig<G>>\n >;\n const validated: Record<string, ResolveConfig<G>> = {};\n for (const [kind, config] of Object.entries(configs)) {\n const parsed = resolveConfigScalarSchema.safeParse({\n threshold: config.threshold,\n });\n if (!parsed.success) {\n throw new Error(\n `Invalid resolve config for kind \"${kind}\": ${parsed.error.message}`,\n );\n }\n if (\n config.keyless !== undefined &&\n (!Number.isInteger(config.keyless.window) || config.keyless.window < 1)\n ) {\n throw new Error(\n `Invalid resolve config for kind \"${kind}\": keyless.window must be a positive integer, got ${config.keyless.window}.`,\n );\n }\n const strategy = config.similarity;\n if (strategy.kind === \"hybrid\") {\n for (const component of [\"vector\", \"fulltext\"] as const) {\n const weight = strategy.weights?.[component];\n if (weight !== undefined && (!Number.isFinite(weight) || weight < 0)) {\n throw new Error(\n `Invalid resolve config for kind \"${kind}\": similarity.weights.${component} must be a finite number >= 0, got ${String(weight)}.`,\n );\n }\n }\n }\n validated[kind] = config;\n }\n return validated;\n}\n\n/**\n * Validates the optional `\"provenanceWeighted\"` trust weights: every weight must\n * be a finite number `>= 0`, since a NaN / negative weight would corrupt the\n * highest-weight pick. Returns the same map.\n */\nfunction validateProvenanceWeights(\n weights: ReadonlyMap<BranchId, number>,\n): ReadonlyMap<BranchId, number> {\n for (const [branchId, weight] of weights) {\n if (!Number.isFinite(weight) || weight < 0) {\n throw new Error(\n `Invalid provenanceWeights for branch \"${branchId}\": weight must be a finite number >= 0, got ${String(weight)}.`,\n );\n }\n }\n return weights;\n}\n\n/**\n * Validates and normalizes {@link MergeOptions}, applying every P0 default.\n *\n * Throws (not a `Result`) on invalid scalar input — option validation is a\n * caller-boundary concern, surfaced as a thrown error per project conventions;\n * `merge()` converts it back to a typed `MergeError` at its own boundary.\n *\n * @throws if a threshold is outside `[0, 1]`, `maxComparisonsPerKind` is\n * negative/non-integer, or `clusterMaxDiameter` is non-positive.\n */\nexport function normalizeMergeOptions<G extends GraphDef>(\n options: MergeOptions<G> = {},\n): NormalizedMergeOptions<G> {\n const scalar = mergeOptionsScalarSchema.parse({\n reconcileTypes: options.reconcileTypes,\n onDeleteModifyConflict: options.onDeleteModifyConflict,\n onComparisonCeiling: options.onComparisonCeiling,\n provenance: options.provenance,\n persistProvenance: options.persistProvenance,\n ...(options.maxComparisonsPerKind === undefined ?\n {}\n : { maxComparisonsPerKind: options.maxComparisonsPerKind }),\n ...(options.clusterMaxDiameter === undefined ?\n {}\n : { clusterMaxDiameter: options.clusterMaxDiameter }),\n });\n\n const onPropertyConflict = validatePropertyConflictPolicy(\n options.onPropertyConflict ?? MERGE_OPTION_DEFAULTS.onPropertyConflict,\n \"onPropertyConflict\",\n );\n // DELIBERATELY does not fall back to `onPropertyConflict` — base↔branch conflicts\n // must not silently inherit a staged policy that could overwrite committed data.\n const onBasePropertyConflict = validatePropertyConflictPolicy(\n options.onBasePropertyConflict ??\n MERGE_OPTION_DEFAULTS.onBasePropertyConflict,\n \"onBasePropertyConflict\",\n );\n\n const provenanceWeights =\n options.provenanceWeights === undefined ?\n undefined\n : validateProvenanceWeights(options.provenanceWeights);\n\n // \"provenanceWeighted\" without weights would silently degrade to a\n // stable-branch-order (lastWriteWins) resolution and quietly commit a\n // different graph. Fail loudly instead so the misconfiguration is visible.\n const usesProvenanceWeighting =\n onPropertyConflict === \"provenanceWeighted\" ||\n onBasePropertyConflict === \"provenanceWeighted\";\n if (\n usesProvenanceWeighting &&\n (provenanceWeights === undefined || provenanceWeights.size === 0)\n ) {\n throw new Error(\n 'A \"provenanceWeighted\" property-conflict policy requires a non-empty provenanceWeights map.',\n );\n }\n\n return {\n resolve: validateResolveMap(options.resolve),\n reconcileTypes: scalar.reconcileTypes,\n onPropertyConflict,\n onBasePropertyConflict,\n onDeleteModifyConflict: scalar.onDeleteModifyConflict,\n onComparisonCeiling: scalar.onComparisonCeiling,\n provenance: scalar.provenance,\n persistProvenance: scalar.persistProvenance,\n ...(options.canonical === undefined ?\n {}\n : { canonical: options.canonical }),\n ...(options.embedder === undefined ? {} : { embedder: options.embedder }),\n ...(options.target === undefined ? {} : { target: options.target }),\n ...(scalar.maxComparisonsPerKind === undefined ?\n {}\n : { maxComparisonsPerKind: scalar.maxComparisonsPerKind }),\n ...(scalar.clusterMaxDiameter === undefined ?\n {}\n : { clusterMaxDiameter: scalar.clusterMaxDiameter }),\n ...(options.branchOrder === undefined ?\n {}\n : { branchOrder: options.branchOrder }),\n ...(provenanceWeights === undefined ? {} : { provenanceWeights }),\n };\n}\n","/**\n * Sidecar provenance graph — durable, queryable `{branch, sourceId}` → canonical\n * tagging for a merge (open-item #5: \"on-graph provenance persistence\").\n *\n * The merge's in-memory {@link import(\"./types\").ProvenanceIndex}\n * (`report.provenance.byBranch`) evaporates after the call. This module persists the\n * same contributions as TYPED nodes in a SIDECAR graph on the SAME backend as the\n * merge target — a separate graph (its own `graphId`-namespaced tables), so the\n * user's domain schema is untouched. It is a faithful prototype of a future\n * first-class TypeGraph `annotations` primitive (see `docs/design/annotations.md`).\n *\n * Persistence is POST-COMMIT and best-effort, by design: the merge's commit path is\n * unchanged and stays on the same public store/backend contracts. Provenance is derived and\n * re-runnable, and the node ids are DETERMINISTIC (a hash of `{targetGraphId, role,\n * canonicalKind, canonicalId, branchId, sourceId}`), so re-merging the same forks UPSERTS rather\n * than duplicating. Atomic-in-the-merge-transaction is a possible upgrade later\n * (TypeGraph's cross-store `withTransaction`), deliberately deferred for v1.\n */\n\nimport { z } from \"zod\";\n\nimport { compareStrings } from \"./node-key\";\nimport type { GraphBackend, Node, Store } from \"./typegraph-internal\";\nimport {\n createStoreWithSchema,\n defineGraph,\n defineNode,\n sha256Hex,\n} from \"./typegraph-internal\";\nimport type { BranchId, ProvenanceRecord } from \"./types\";\n\n/** The Provenance node: one row per `{branch, sourceId}` → canonical contribution. */\nconst Provenance = defineNode(\"Provenance\", {\n schema: z.object({\n targetGraphId: z.string(),\n role: z.enum([\"node\", \"edge\"]),\n canonicalId: z.string(),\n canonicalKind: z.string(),\n branchId: z.string(),\n sourceId: z.string(),\n }),\n});\n\n/**\n * Derives the sidecar graph id for a target graph. Suffixing the target's own id\n * keeps each target graph's provenance in its own `graphId`-namespaced tables on a\n * shared backend, while a single `Provenance` schema serves all of them.\n */\nexport function provenanceGraphId(targetGraphId: string): string {\n return `${targetGraphId}::merge-provenance`;\n}\n\n/** Builds the sidecar provenance graph definition for a target graph. */\nfunction buildProvenanceGraph(targetGraphId: string) {\n return defineGraph({\n id: provenanceGraphId(targetGraphId),\n nodes: { Provenance: { type: Provenance } },\n edges: {},\n });\n}\n\n/** The concrete sidecar provenance graph type. */\nexport type ProvenanceGraph = ReturnType<typeof buildProvenanceGraph>;\n\n/** A persisted provenance node (the queryable record). */\nexport type ProvenanceNode = Node<typeof Provenance>;\n\n/**\n * Opens — materializing the schema if needed — the provenance store for a target\n * graph on the given backend. Idempotent: safe to call before every persist/query,\n * and shares the backend with the target (so the caller must NOT close it\n * separately — closing the shared backend is the target owner's job).\n */\nexport async function openProvenanceStore(\n backend: GraphBackend,\n targetGraphId: string,\n): Promise<Store<ProvenanceGraph>> {\n const [store] = await createStoreWithSchema(\n buildProvenanceGraph(targetGraphId),\n backend,\n );\n return store;\n}\n\n/** Null byte — cannot occur in a normal id, so an unambiguous tuple separator. */\nconst ID_SEPARATOR = \"\\0\";\n\n/** Bytes of the SHA-256 digest kept (128 bits — collision-safe for provenance). */\nconst ID_DIGEST_BYTES = 16;\n\n/**\n * Deterministic provenance node id: a hash of the contribution tuple, so\n * re-persisting the same contribution UPSERTS the same row (idempotent re-runs).\n *\n * Uses the shared {@link sha256Hex} (Web Crypto) instead of `node:crypto` so the\n * `graph-merge` entry point stays importable on every runtime the library\n * targets (Cloudflare Workers, Deno, browsers) — `base-version.ts` already hashes\n * its content fingerprint the same way.\n */\nexport async function provenanceNodeId(\n targetGraphId: string,\n record: ProvenanceRecord,\n): Promise<string> {\n const tuple = [\n targetGraphId,\n record.role,\n // canonicalKind is part of node identity: two contributions to different-kind\n // canonicals that share a bare id (e.g. base Patient:x and Encounter:x) must NOT\n // hash to the same sidecar row and clobber each other (the (kind,id) identity model).\n record.canonicalKind,\n record.canonicalId,\n record.branchId,\n record.sourceId,\n ].join(ID_SEPARATOR);\n const digest = await sha256Hex(tuple, ID_DIGEST_BYTES);\n return `prov_${digest}`;\n}\n\n/**\n * Upserts one `Provenance` node per record into the sidecar store, keyed by the\n * deterministic id (re-running the same merge is a no-op upsert, never a\n * duplicate). Returns the row count written. The caller wraps this for best-effort\n * behavior — a failure here must not fail an already-committed merge.\n */\nexport async function persistProvenanceRecords(\n store: Store<ProvenanceGraph>,\n targetGraphId: string,\n records: readonly ProvenanceRecord[],\n): Promise<number> {\n if (records.length === 0) {\n return 0;\n }\n const items = await Promise.all(\n records.map(async (record) => ({\n id: await provenanceNodeId(targetGraphId, record),\n props: {\n targetGraphId,\n role: record.role,\n canonicalId: record.canonicalId,\n canonicalKind: record.canonicalKind,\n branchId: record.branchId,\n sourceId: record.sourceId,\n },\n })),\n );\n await store.nodes.Provenance.bulkUpsertById(items);\n return items.length;\n}\n\n/** Filter for {@link readProvenance}. Each field, when set, narrows the result. */\nexport type ProvenanceQuery = Readonly<{\n branchId?: BranchId | string;\n canonicalId?: string;\n role?: \"node\" | \"edge\";\n}>;\n\n/**\n * Reads persisted provenance back, filtered and stably ordered. The sidecar is a\n * normal typed graph, so this is a thin ergonomic wrapper over\n * `store.nodes.Provenance.find()` (filtered in memory — provenance volumes are\n * modest; a query-builder `where` is the scale path). Answers \"which canonical\n * entities did branch X contribute to?\" and \"who contributed canonical Y?\".\n */\nexport async function readProvenance(\n store: Store<ProvenanceGraph>,\n query: ProvenanceQuery = {},\n): Promise<readonly ProvenanceNode[]> {\n const all = await store.nodes.Provenance.find();\n return all\n .filter(\n (node) =>\n (query.branchId === undefined || node.branchId === query.branchId) &&\n (query.canonicalId === undefined ||\n node.canonicalId === query.canonicalId) &&\n (query.role === undefined || node.role === query.role),\n )\n .sort((left, right) => compareStrings(left.id, right.id));\n}\n","import { requireDefined } from \"../utils/presence\";\n/**\n * Candidate SOURCES (design §4 / §6.1) — the RECALL layer of candidate generation.\n *\n * Candidate generation is three layers — sources → scoring → reconciler (§4). This\n * module is the FIRST layer: each source PROPOSES candidates and decides nothing\n * about a fuzzy match. A source emits three things:\n *\n * - `pairs` — unscored `(a, b)` node pairs handed to the shared scoring\n * stage (`scoring.ts`), which makes every fuzzy match decision.\n * - `forcedEdges` — DEFINITIONAL matches (a shared unique value) that bypass\n * scoring at {@link FORCED_MATCH_SCORE}.\n * - `baseMembers` — committed base nodes the source pulled into scope, so the\n * reconciler can seed + canonicalize a base endpoint without\n * re-querying the backend. EMPTY for staged-only sources.\n *\n * Two sources ship here — today's two blocking strategies (`blocking.ts`),\n * refactored behind the source interface:\n *\n * - {@link exactKeySource} (`exactKey`, §6.1) — the `block(node) => string`\n * bucket: same-bucket node pairs become fuzzy `pairs`. Staged-vs-staged.\n * - {@link uniqueSource} (`unique`, §6.1) — the unique-constraint signature\n * buckets: every same-signature pair is a FORCED edge (a shared unique value\n * is definitionally the same entity). Staged-vs-staged.\n *\n * Both read the SAME pre-computed `blockNodes` map off the scope (the UNION of the\n * `block()` key and the per-constraint signatures, `blocking.ts`), filtering it by\n * {@link isUniqueBucketKey}: `exactKey` owns the non-unique buckets, `unique` owns\n * the unique buckets. Sharing one blocked map (vs. re-blocking per source) keeps the\n * source split byte-identical to the old fused `generateCandidates` — a node with a\n * unique signature but no `block()` key lands ONLY in its unique bucket, never the\n * all-vs-all `unblocked` bucket.\n *\n * Determinism: the extraction visits buckets in sorted-key order over id-sorted\n * members and enumerates `i < j`, so proposals are emitted in a canonical order;\n * the scoring stage additionally dedups + sorts, so neither source's emission order\n * leaks into the merge result.\n */\nimport { isUniqueBucketKey, UNBLOCKED_BUCKET_KEY } from \"./blocking\";\nimport { MergeError } from \"./errors\";\nimport {\n compareMergeKeys,\n compareStrings,\n idOf,\n kindOf,\n type MergeKey,\n mergeKey,\n mergeKeyOf,\n} from \"./node-key\";\nimport type { CandidateEdge, CandidatePair } from \"./scoring\";\nimport { FORCED_MATCH_SCORE } from \"./scoring\";\nimport { fieldText } from \"./similarity\";\nimport type {\n GraphDef,\n JsonValue,\n Node,\n NodeId,\n NodeType,\n UniqueIntrospection,\n} from \"./typegraph-internal\";\nimport type { ResolveConfig } from \"./types\";\nimport { UnionFind } from \"./union-find\";\n\n/**\n * A committed BASE node a source pulled into the cluster universe (design §4\n * member contribution / §6.4-D). It carries the same `(id, kind, props)` a staged\n * member does, plus a reserved `\"base\"` origin so the reconciler can enforce\n * base-id-wins (§6.4-C) and tag provenance with the base sentinel (§6.4-D). EMPTY\n * for staged-only sources (`exactKey`, `unique`).\n */\nexport type BaseMember = Readonly<{\n id: NodeId<NodeType>;\n kind: string;\n props: Readonly<Record<string, JsonValue>>;\n origin: \"base\";\n}>;\n\n/**\n * What a candidate source emits for one kind: fuzzy `pairs` to score, FORCED\n * (definitional) edges to pass through unscored, and the committed `baseMembers`\n * it pulled into scope.\n */\ntype SourceResult = Readonly<{\n pairs: readonly CandidatePair[];\n forcedEdges: readonly CandidateEdge[];\n baseMembers: readonly BaseMember[];\n}>;\n\n/**\n * The minimal node-collection surface a base-querying source needs: the public\n * `bulkFindByConstraint` (typegraph 0.29.0). It computes each item's constraint key\n * from its props, returns the live committed match per item in INPUT ORDER\n * (`undefined` for misses, soft-deleted excluded), and is indexed by the `uniques`\n * table PK — so graph-merge never reconstructs constraint keys itself. A runtime,\n * kind-string-keyed view (like the commit's `TxNodes`) so a source can dispatch on\n * a kind string without threading the caller's concrete `Store<G>` generic.\n */\nexport type BaseNodeLookup = Readonly<{\n bulkFindByConstraint: (\n constraintName: string,\n items: readonly Readonly<{ props: Record<string, unknown> }>[],\n ) => Promise<readonly (Node<NodeType> | undefined)[]>;\n /**\n * The non-unique sibling (typegraph 0.30): for each item, the live committed nodes\n * sharing its declared-INDEX key (computed from props), returned per item in input\n * order, each inner array id-sorted, soft-deleted excluded. `limitPerInput` bounds\n * per-item fan-out (id-ordered, so the cap is deterministic). Candidate retrieval —\n * NOT a uniqueness/identity guarantee — so `baseKey` emits scored pairs, not forced\n * edges.\n */\n bulkFindByIndex: (\n indexName: string,\n items: readonly Readonly<{ props: Record<string, unknown> }>[],\n options?: Readonly<{ limitPerInput?: number }>,\n ) => Promise<readonly (readonly Node<NodeType>[])[]>;\n}>;\n\n/** Runtime, kind-string-keyed view of a store's node collections for base lookups. */\nexport type BaseLookupStore = Readonly<{\n nodes: Readonly<Record<string, BaseNodeLookup>>;\n}>;\n\n/**\n * The per-kind input a source generates over. `blocks` is the UNION `blockNodes`\n * result (`block()` key + per-constraint signatures) the staged sources read.\n *\n * The remaining fields are present only when a BASE-querying source (`baseUnique` /\n * `baseKey`, §6.2) is driven: the kind's materialized staged new `nodes` (the lookup\n * items), its `uniqueConstraints` (for `baseUnique`), the declared `blockIndex` name\n * (for `baseKey`, when the kind configured one), and the committed `store` to query\n * against. Staged-only sources (`exactKey`, `unique`) ignore them, so the public\n * `merge()` candidate path leaves them unset.\n */\nexport type SourceScope = Readonly<{\n kind: string;\n blocks: ReadonlyMap<string, readonly Node<NodeType>[]>;\n nodes?: readonly Node<NodeType>[];\n uniqueConstraints?: readonly UniqueIntrospection[];\n blockIndex?: string;\n /** When set, `exactKey` bounds the no-key (`\"unblocked\"`) bucket by sorted-\n * neighbourhood instead of all-vs-all (the `keyless` source, §6.2). */\n keyless?: KeylessConfig;\n store?: BaseLookupStore;\n}>;\n\n/**\n * A candidate source (design §4): proposes pairs (recall) + definitional forced\n * edges, and supplies the base members it pulled into scope. The `id` attributes\n * a source in reports and pins its determinism level (§7).\n */\nexport type CandidateSource = Readonly<{\n readonly id: string;\n generate(scope: SourceScope): Promise<SourceResult>;\n}>;\n\n/**\n * Orders a pair's two node IDENTITY keys (`(kind, id)`, not bare id) so the smaller\n * is `a`, with the matching node objects in `left`/`right`. Keying on the composite\n * identity is what keeps a `Patient` and an `Encounter` that share an id string from\n * being proposed as the same endpoint. Guarantees every proposal has a single\n * canonical `(a, b)` representation regardless of enumeration order.\n */\nfunction orderEndpoints<K extends NodeType>(\n left: Node<K>,\n right: Node<K>,\n): CandidatePair<K> {\n const leftKey = mergeKeyOf(left);\n const rightKey = mergeKeyOf(right);\n return compareMergeKeys(leftKey, rightKey) <= 0 ?\n { a: leftKey, b: rightKey, left, right }\n : { a: rightKey, b: leftKey, left: right, right: left };\n}\n\n/** Sorts a bucket's members by ascending node id (defensive — blocking already does). */\nfunction sortMembersById<K extends NodeType>(\n members: readonly Node<K>[],\n): readonly Node<K>[] {\n return [...members].sort((left, right) => compareStrings(left.id, right.id));\n}\n\n/** Visits the blocked buckets in sorted-key order. */\nfunction sortedBucketKeys(\n blocks: ReadonlyMap<string, readonly Node<NodeType>[]>,\n): readonly string[] {\n return [...blocks.keys()].sort((left, right) => compareStrings(left, right));\n}\n\n/** The system fields a {@link Node} carries alongside its schema props. */\nconst NODE_SYSTEM_FIELDS: ReadonlySet<string> = new Set([\"id\", \"kind\", \"meta\"]);\n\n/**\n * Extracts a node's schema PROPS from its spread runtime shape (`Node` spreads its\n * schema fields at the top level alongside `id` / `kind` / `meta`). Used to build a\n * base lookup's props from a staged node and a {@link BaseMember}'s props from the\n * returned committed node — without a second fetch or any knowledge of the schema.\n */\nfunction nodeProps(node: Node<NodeType>): Record<string, JsonValue> {\n const props: Record<string, JsonValue> = {};\n for (const [key, value] of Object.entries(\n node as unknown as Record<string, unknown>,\n )) {\n if (!NODE_SYSTEM_FIELDS.has(key)) {\n props[key] = value as JsonValue;\n }\n }\n return props;\n}\n\n/**\n * The bounded coarse source for the NO-KEY case (design §6.2, `keyless`): which\n * unblocked nodes to compare, and how far. `window` is the forward-neighbour count;\n * `sortFields` is the kind's similarity text fields, so the SORTED-NEIGHBOURHOOD sort\n * groups lexically-similar values adjacently (the same text the scorer reads).\n */\nexport type KeylessConfig = Readonly<{\n window: number;\n sortFields: readonly string[];\n}>;\n\n/**\n * Builds the {@link KeylessConfig} for a kind's resolve config (its `keyless.window`\n * plus the similarity text fields the sorted-neighbourhood pass sorts on), or\n * `undefined` when `keyless` is unset. The sort fields are the kind's similarity text\n * (so adjacency tracks the scorer's text); `custom` similarity exposes none → sort by\n * id only (bounded but semantically weak — a no-key custom kind wants `stagedVector`,\n * deferred §8).\n *\n * Shared by `merge()`'s source path AND the back-compat `generateCandidates()` helper,\n * so both honour `ResolveConfig.keyless` identically rather than the helper silently\n * ignoring it.\n */\nexport function keylessConfigFor<G extends GraphDef, K extends NodeType>(\n resolveConfig: ResolveConfig<G, K>,\n): KeylessConfig | undefined {\n if (resolveConfig.keyless === undefined) {\n return undefined;\n }\n const strategy = resolveConfig.similarity;\n const sortFields =\n strategy.kind === \"fulltext\" || strategy.kind === \"hybrid\" ? strategy.fields\n : strategy.kind === \"vector\" ? [strategy.field]\n : [];\n return { window: resolveConfig.keyless.window, sortFields };\n}\n\n/**\n * Single-pass SORTED-NEIGHBOURHOOD pairs over one bucket's members: sort by the\n * similarity-field text (tie-broken by id — a total order, so the output is a pure\n * function of the member SET), then propose each node only against its next `window`\n * neighbours. O(n·window) instead of O(n²); `window ≥ n-1` degenerates to all-vs-all.\n */\nfunction windowedPairs(\n members: readonly Node<NodeType>[],\n config: KeylessConfig,\n): readonly CandidatePair[] {\n const keyed = members.map((node) => ({\n node,\n key: fieldText(node, config.sortFields),\n }));\n keyed.sort((left, right) =>\n left.key === right.key ?\n compareStrings(left.node.id, right.node.id)\n : compareStrings(left.key, right.key),\n );\n const pairs: CandidatePair[] = [];\n for (let index = 0; index < keyed.length; index += 1) {\n const last = Math.min(index + config.window, keyed.length - 1);\n for (let index_ = index + 1; index_ <= last; index_ += 1) {\n pairs.push(\n orderEndpoints(\n requireDefined(keyed[index]).node,\n requireDefined(keyed[index_]).node,\n ),\n );\n }\n }\n return pairs;\n}\n\n/**\n * Extracts the FUZZY candidate pairs from the NON-unique (block / unblocked)\n * buckets: every `i < j` pair of a bucket's id-sorted members, in sorted-key\n * order. Cross-bucket duplicates are left for the scoring stage to dedup.\n *\n * When `keyless` is set, the shared `\"unblocked\"` (no-key) bucket is bounded by\n * single-pass sorted-neighbourhood ({@link windowedPairs}) instead of all-vs-all —\n * closing the O(n²) cliff (design §6.2). Keyed `block()` buckets are unaffected\n * (they are already bounded by the key). Unset preserves all-vs-all for every bucket.\n */\nexport function pairsFromBlocks(\n blocks: ReadonlyMap<string, readonly Node<NodeType>[]>,\n keyless?: KeylessConfig,\n): readonly CandidatePair[] {\n const pairs: CandidatePair[] = [];\n for (const bucketKey of sortedBucketKeys(blocks)) {\n if (isUniqueBucketKey(bucketKey)) {\n continue;\n }\n const members = sortMembersById(blocks.get(bucketKey) ?? []);\n if (keyless !== undefined && bucketKey === UNBLOCKED_BUCKET_KEY) {\n pairs.push(...windowedPairs(members, keyless));\n continue;\n }\n for (let index = 0; index < members.length; index += 1) {\n for (let index_ = index + 1; index_ < members.length; index_ += 1) {\n pairs.push(\n orderEndpoints(\n requireDefined(members[index]),\n requireDefined(members[index_]),\n ),\n );\n }\n }\n }\n return pairs;\n}\n\n/**\n * Extracts the FORCED (definitional) edges from the UNIQUE-constraint buckets:\n * every `i < j` pair of a bucket's id-sorted members, at {@link FORCED_MATCH_SCORE}.\n * Cross-bucket / cross-constraint duplicates are left for the scoring stage to dedup.\n */\nexport function forcedEdgesFromBlocks(\n blocks: ReadonlyMap<string, readonly Node<NodeType>[]>,\n): readonly CandidateEdge[] {\n const edges: CandidateEdge[] = [];\n for (const bucketKey of sortedBucketKeys(blocks)) {\n if (!isUniqueBucketKey(bucketKey)) {\n continue;\n }\n const members = sortMembersById(blocks.get(bucketKey) ?? []);\n for (let index = 0; index < members.length; index += 1) {\n for (let index_ = index + 1; index_ < members.length; index_ += 1) {\n const { a, b } = orderEndpoints(\n requireDefined(members[index]),\n requireDefined(members[index_]),\n );\n edges.push({ a, b, score: FORCED_MATCH_SCORE });\n }\n }\n }\n return edges;\n}\n\n/**\n * Ontology RETYPE candidate edges (the cross-kind STAGED source, §6.4 / T10).\n *\n * Node identity is strictly `(kind, id)`, so a `Patient` and an `Encounter` that\n * share an id string are DISTINCT and never fuse. But under `reconcileTypes:\n * \"ontology\"`, two STAGED-NEW nodes that share a bare id AND carry subtype-compatible\n * kinds are \"the same entity at a refined type\" (one branch staged `Doctor:x`,\n * another `SpecialistDoctor:x`). This source forces those distinct identities into one\n * cluster so the reconciler can collapse it to the most-specific kind. The same-id\n * identities are PARTITIONED into maximal subtype-comparable groups first, so an\n * unrelated kind sharing the id (`Encounter:x` beside `Doctor:x` / `SpecialistDoctor:x`)\n * is split into its own group and does NOT suppress the valid retype; a group only\n * fuses when its kinds still collapse to a single most-specific kind.\n *\n * `isRetypeCompatible` MUST be the same most-specific-common-kind test the reconciler\n * uses ({@link import(\"./type-reconcile\").mostSpecificCommonKind}), so a kind set\n * fuses here iff the reconciler would later collapse it. The caller passes STAGED\n * identities only; committed-base members stay outside this staged retype source.\n *\n * Deterministic: ids are visited in sorted order, the identities at each id are sorted\n * + deduped, and a star of forced edges from the minimum identity makes the fusion\n * transitive (the scoring stage dedups the forced set).\n */\nexport function ontologyRetypeEdges(\n stagedIdentities: Iterable<MergeKey>,\n isRetypeCompatible: (kinds: readonly string[]) => boolean,\n): readonly CandidateEdge[] {\n const identitiesById = new Map<string, MergeKey[]>();\n for (const identity of stagedIdentities) {\n const id = idOf(identity);\n const bucket = identitiesById.get(id);\n if (bucket === undefined) {\n identitiesById.set(id, [identity]);\n } else {\n bucket.push(identity);\n }\n }\n\n const edges: CandidateEdge[] = [];\n for (const id of [...identitiesById.keys()].sort(compareStrings)) {\n const identities = [...new Set(identitiesById.get(id))].sort(\n compareMergeKeys,\n );\n if (identities.length < 2) {\n continue; // a single kind at this id — nothing cross-kind to reconcile.\n }\n // Partition the same-id identities into maximal subtype-comparable GROUPS, so an\n // UNRELATED kind sharing the id (e.g. an `Encounter:x` next to a `Doctor:x` /\n // `SpecialistDoctor:x` refinement) does not suppress the valid retype: two\n // identities join a group when their kinds are pairwise retype-compatible, and the\n // relation is unioned transitively.\n const group = unionByCompatibility(identities, isRetypeCompatible);\n for (const members of groupsOf(identities, group)) {\n // Only fuse a group that still collapses to ONE most-specific kind (a single\n // minimum). Incompatible siblings linked only through a shared subtype do not —\n // fusing them would force the reconciler to flag the cluster and pick a kind.\n if (\n members.length < 2 ||\n !isRetypeCompatible(members.map((identity) => kindOf(identity)))\n ) {\n continue;\n }\n for (let index = 1; index < members.length; index += 1) {\n edges.push({\n a: requireDefined(members[0]),\n b: requireDefined(members[index]),\n score: FORCED_MATCH_SCORE,\n });\n }\n }\n }\n return edges;\n}\n\n/**\n * Union-find over a same-id identity set: `identity → group representative`, where two\n * identities share a representative iff their kinds are (transitively) pairwise\n * {@link isRetypeCompatible}. Pure over the identity SET (the representative chosen is\n * irrelevant — only the partition matters, and callers re-sort each group).\n */\nfunction unionByCompatibility(\n identities: readonly MergeKey[],\n isRetypeCompatible: (kinds: readonly string[]) => boolean,\n): ReadonlyMap<MergeKey, MergeKey> {\n // Partition only — the representative chosen is irrelevant (callers re-sort each\n // group), so any total order works; `compareMergeKeys` keeps it deterministic.\n const forest = new UnionFind<MergeKey>(compareMergeKeys);\n for (const identity of identities) {\n forest.add(identity);\n }\n for (let index = 0; index < identities.length; index += 1) {\n for (let index_ = index + 1; index_ < identities.length; index_ += 1) {\n if (\n isRetypeCompatible([\n kindOf(requireDefined(identities[index])),\n kindOf(requireDefined(identities[index_])),\n ])\n ) {\n forest.union(\n requireDefined(identities[index]),\n requireDefined(identities[index_]),\n );\n }\n }\n }\n return new Map(\n identities.map((identity) => [identity, forest.find(identity)]),\n );\n}\n\n/** Buckets identities by their union-find representative, each group id-sorted. */\nfunction groupsOf(\n identities: readonly MergeKey[],\n representativeOf: ReadonlyMap<MergeKey, MergeKey>,\n): readonly (readonly MergeKey[])[] {\n const byRoot = new Map<MergeKey, MergeKey[]>();\n for (const identity of identities) {\n const root = requireDefined(representativeOf.get(identity));\n const bucket = byRoot.get(root);\n if (bucket === undefined) {\n byRoot.set(root, [identity]);\n } else {\n bucket.push(identity);\n }\n }\n return [...byRoot.values()].map((group) => [...group].sort(compareMergeKeys));\n}\n\n/**\n * `exactKey` source (§6.1) — today's `block(node) => string` bucketing. Same-bucket\n * node pairs become fuzzy `pairs` for the scoring stage to decide. Staged-vs-staged,\n * fully deterministic, no base members.\n *\n * Also hosts the `keyless` source (§6.2): when `scope.keyless` is set, the no-key\n * (`\"unblocked\"`) bucket is bounded by sorted-neighbourhood rather than all-vs-all.\n * It rides `exactKey` rather than a parallel source because both operate on the same\n * staged blocked map and would otherwise double-emit the unblocked bucket.\n */\nexport const exactKeySource: CandidateSource = {\n id: \"exactKey\",\n generate(scope) {\n return Promise.resolve({\n pairs: pairsFromBlocks(scope.blocks, scope.keyless),\n forcedEdges: [],\n baseMembers: [],\n });\n },\n};\n\n/**\n * `unique` source (§6.1) — today's unique-constraint short-circuit. Every pair\n * sharing a unique signature is a FORCED edge: a shared unique value is\n * definitionally the same entity, so it merges regardless of similarity (differing\n * properties are reported as conflicts downstream, and the merged graph never\n * violates its own uniqueness). Staged-vs-staged, fully deterministic, no base\n * members.\n */\nexport const uniqueSource: CandidateSource = {\n id: \"unique\",\n generate(scope) {\n return Promise.resolve({\n pairs: [],\n forcedEdges: forcedEdgesFromBlocks(scope.blocks),\n baseMembers: [],\n });\n },\n};\n\n/**\n * `baseUnique` source (§6.2) — the first NEW-vs-BASE source. For each declared\n * unique constraint, it issues ONE batched `bulkFindByConstraint` over the staged\n * new nodes against the committed base store (TypeGraph's own constraint API,\n * indexed by the `uniques` PK; key computed from props, soft-deleted excluded). Each\n * hit is a DEFINITIONAL match — a staged node sharing a committed node's unique\n * value is the same entity — so it emits:\n *\n * - a FORCED edge between the staged node and the committed base node, and\n * - a {@link BaseMember} built from the returned committed node (no second fetch),\n * so the reconciler can seed + canonicalize the base endpoint (§4).\n *\n * Grouped by `(kind, constraint)` — one batched call per constraint — so each\n * constraint's own `fields` / `where` / `scope` / `collation` semantics are honoured\n * by construction; graph-merge never rebuilds keys. Deterministic: constraints are\n * visited in sorted name order, base members are deduped by id and id-sorted, and\n * the scoring stage dedups + sorts the forced edges.\n *\n * NOT part of {@link CANDIDATE_SOURCES}: the public `merge()` snapshot path stays\n * staged-vs-staged. This source is driven only by the synthetic new-vs-base scope\n * (later slice steps), which supplies the `nodes` / `uniqueConstraints` / `store`\n * the staged sources omit.\n */\nexport const baseUniqueSource: CandidateSource = {\n id: \"baseUnique\",\n async generate(scope) {\n const { kind, nodes, uniqueConstraints, store } = scope;\n if (\n nodes === undefined ||\n uniqueConstraints === undefined ||\n store === undefined\n ) {\n throw new MergeError(\n \"baseUniqueSource requires nodes, uniqueConstraints, and store in the source scope.\",\n { details: { kind, source: \"baseUnique\" } },\n );\n }\n\n const collection = store.nodes[kind];\n if (collection === undefined || nodes.length === 0) {\n return { pairs: [], forcedEdges: [], baseMembers: [] };\n }\n\n const forcedEdges: CandidateEdge[] = [];\n const baseMembers = new Map<string, BaseMember>();\n\n // The lookup items are the SAME for every constraint (one props bag per staged\n // node), so build them ONCE rather than per constraint, and fire the independent\n // per-constraint lookups concurrently. Results are consumed in sorted-constraint\n // order below, so the dedup-by-id keeps determinism despite the parallel I/O.\n const constraints = [...uniqueConstraints].sort((left, right) =>\n compareStrings(left.name, right.name),\n );\n const items = nodes.map((node) => ({ props: nodeProps(node) }));\n // `bulkFindByConstraint` re-validates each item's FULL props against the kind's\n // CREATE schema to compute the constraint key, so a non-idempotent create schema\n // (a transform/default/coercion) — or a staged node that otherwise fails the\n // schema — throws a typegraph error. Surface it as a typed MergeError carrying the\n // kind + constraint, rather than letting an opaque throw be masked as the generic\n // \"Merge failed while staging or committing\" wrapper downstream.\n const matchesByConstraint = await Promise.all(\n constraints.map(async (constraint) => {\n try {\n return await collection.bulkFindByConstraint(constraint.name, items);\n } catch (error) {\n throw new MergeError(\n `baseUniqueSource: new-vs-base lookup for constraint \"${constraint.name}\" on kind \"${kind}\" failed — a staged node's props could not be validated against the kind's schema for constraint-key computation.`,\n { details: { kind, constraint: constraint.name }, cause: error },\n );\n }\n }),\n );\n for (const matches of matchesByConstraint) {\n for (const [index, node] of nodes.entries()) {\n const base = matches[index];\n if (base === undefined) {\n continue;\n }\n const stagedNode = node;\n const stagedKey = mergeKey(stagedNode.kind, stagedNode.id);\n const baseKey = mergeKey(base.kind, base.id);\n // ALWAYS pull the committed node in as a base member, so the reconciler seeds +\n // canonicalizes it and enforces base-id-wins (§6.4-C) — including for a\n // same-(kind,id) re-discovery, where the committed value must still win over a\n // divergent staged prop. (Dropping the base member here is what made a same-id\n // re-add ERROR in the stale-overwrite guard instead of resolving onto the base.)\n if (!baseMembers.has(baseKey)) {\n baseMembers.set(baseKey, {\n origin: \"base\",\n id: base.id,\n kind: base.kind,\n props: nodeProps(base),\n });\n }\n // A same-(kind,id) re-discovery is already ONE identity (the base member lands\n // in the staged node's own cluster by key), so it needs no linking edge — a\n // self-loop would be a degenerate no-op. Skip ONLY the forced edge, not the\n // base member above.\n if (stagedKey === baseKey) {\n continue;\n }\n const { a, b } =\n compareMergeKeys(stagedKey, baseKey) <= 0 ?\n { a: stagedKey, b: baseKey }\n : { a: baseKey, b: stagedKey };\n forcedEdges.push({ a, b, score: FORCED_MATCH_SCORE });\n }\n }\n\n return {\n pairs: [],\n forcedEdges,\n baseMembers: [...baseMembers.values()].sort((left, right) =>\n compareStrings(left.id, right.id),\n ),\n };\n },\n};\n\n/**\n * `baseKey` source (§6.2, descriptor-backed block key) — the second NEW-vs-BASE\n * source. For the kind's declared block INDEX (named by `ResolveConfig.blockIndex`,\n * threaded onto the scope), it issues ONE batched `bulkFindByIndex` over the staged\n * new nodes against the committed base store (typegraph 0.30's non-unique index\n * lookup; key computed from props, soft-deleted excluded, fan-out bounded by\n * `limitPerInput`). Unlike {@link baseUniqueSource}, a shared block key is NOT\n * definitional — it is a candidate — so each new↔base hit emits:\n *\n * - a {@link CandidatePair} (staged ↔ base) handed to the shared scoring stage (it\n * becomes an edge only if it clears the kind's threshold), and\n * - a {@link BaseMember} built from the returned committed node (no second fetch).\n *\n * A same-(kind, id) hit needs no pair — the base member joins the staged node's own\n * cluster by key — so only its base member is emitted. graph-merge never reconstructs\n * the index key (typegraph owns `fields`/`scope`/`where`/collation), mirroring\n * `baseUnique`. Deterministic: typegraph returns matches per item in input order,\n * id-sorted; base members are deduped by id and id-sorted; the scoring stage dedups +\n * sorts the pairs. Field-set index keys only — a transform block key stays on the\n * staged-only opaque `block()` (§6.2).\n *\n * NOT part of {@link CANDIDATE_SOURCES}: the public `merge()` snapshot path stays\n * staged-vs-staged; this source runs only under the synthetic new-vs-base scope.\n */\nexport const baseKeySource: CandidateSource = {\n id: \"baseKey\",\n async generate(scope) {\n const { kind, nodes, blockIndex, store } = scope;\n // No declared block index for this kind → baseKey contributes nothing (a kind opts\n // into new-vs-base block-key recall by declaring an index + setting blockIndex).\n if (blockIndex === undefined) {\n return { pairs: [], forcedEdges: [], baseMembers: [] };\n }\n if (nodes === undefined || store === undefined) {\n throw new MergeError(\n \"baseKeySource requires nodes and store in the source scope.\",\n { details: { kind, source: \"baseKey\" } },\n );\n }\n\n const collection = store.nodes[kind];\n if (collection === undefined || nodes.length === 0) {\n return { pairs: [], forcedEdges: [], baseMembers: [] };\n }\n\n const items = nodes.map((node) => ({ props: nodeProps(node) }));\n // Like `bulkFindByConstraint`, an unknown index name / type-incompatible field\n // throws a typegraph error; surface it as a typed MergeError carrying the index +\n // kind rather than letting it be masked as the generic \"Merge failed\" wrapper.\n let matchesByNode: readonly (readonly Node<NodeType>[])[];\n try {\n matchesByNode = await collection.bulkFindByIndex(blockIndex, items);\n } catch (error) {\n throw new MergeError(\n `baseKeySource: new-vs-base lookup on index \"${blockIndex}\" for kind \"${kind}\" failed — the index is undeclared or a staged node's props are incompatible with its indexed fields.`,\n { details: { kind, index: blockIndex }, cause: error },\n );\n }\n\n const pairs: CandidatePair[] = [];\n const baseMembers = new Map<string, BaseMember>();\n for (const [index, node] of nodes.entries()) {\n const stagedNode = node;\n const stagedKey = mergeKey(stagedNode.kind, stagedNode.id);\n for (const base of matchesByNode[index] ?? []) {\n const baseKey = mergeKey(base.kind, base.id);\n if (!baseMembers.has(baseKey)) {\n baseMembers.set(baseKey, {\n origin: \"base\",\n id: base.id,\n kind: base.kind,\n props: nodeProps(base),\n });\n }\n // A same-(kind, id) re-discovery is already ONE identity; the base member lands\n // in the staged node's own cluster by key, so it needs no candidate pair.\n if (stagedKey === baseKey) {\n continue;\n }\n pairs.push(orderEndpoints(stagedNode, base));\n }\n }\n\n return {\n pairs,\n forcedEdges: [],\n baseMembers: [...baseMembers.values()].sort((left, right) =>\n compareStrings(left.id, right.id),\n ),\n };\n },\n};\n\n/**\n * The STAGED candidate sources the public `merge()` drives, in a fixed order (§6.1\n * \"phase: now\"). The scoring stage dedups + sorts the union, so this order does not\n * affect the merge result; it is fixed only for stable report attribution. The\n * new-vs-base {@link baseUniqueSource} / {@link baseKeySource} are deliberately NOT\n * here — they run only under the synthetic new-vs-base scope so the public snapshot\n * path stays staged-vs-staged.\n */\nexport const CANDIDATE_SOURCES: readonly CandidateSource[] = [\n exactKeySource,\n uniqueSource,\n];\n","import { requireDefined } from \"../utils/presence\";\n/**\n * Staging (design §6.4 rule 1, T7): run the state-diff (T3) for EVERY branch,\n * tag each diff item with its origin {@link BranchId}, and assemble the UNION\n * of all branches' diffs into a single {@link StagingSet}.\n *\n * Why union (not incremental):\n * Downstream candidate-generation (T6) and clustering (T8) must be\n * order-independent — shuffling the branch order MUST yield an identical\n * merge. If staging folded branches one-at-a-time into a mutating cumulative\n * state, the result could depend on fold order. Instead we COLLECT every\n * branch's tagged items into flat arrays, then GROUP and SORT once at the end,\n * so the {@link StagingSet} is a pure function of the unordered branch SET.\n *\n * Provenance tagging:\n * Every staged item carries the {@link BranchId} of the branch whose diff\n * produced it. An inherited node modified differently by two branches appears\n * once per branch (each tagged), which is exactly what the conflict-detection\n * phases (T8 / T8a) need. A new node introduced by one branch appears once,\n * tagged by that branch.\n *\n * Determinism:\n * - New nodes/edges are grouped by kind; the per-kind arrays are sorted by\n * `(id, branchId)`.\n * - Flat collections (modified / deleted) are sorted by `(kind, id, branchId)`.\n * - Bucket maps iterate in lexicographic kind order.\n * The `(…, branchId)` tail breaks ties when the same id is contributed by more\n * than one branch, so the ordering is total and stable.\n */\nimport { compareStrings, type MergeKey } from \"./node-key\";\nimport type {\n ChangedEdge,\n ChangedNode,\n DeletedEdge,\n DeletedNode,\n ModifiedEdge,\n ModifiedNode,\n} from \"./state-diff\";\nimport { diffAgainstBase } from \"./state-diff\";\nimport type { GraphDef, Store } from \"./typegraph-internal\";\nimport type { BranchId, GraphBranch } from \"./types\";\n\n/** A new fork node tagged with the branch that introduced it. */\nexport type StagedNewNode = Readonly<{\n branchId: BranchId;\n node: ChangedNode;\n}>;\n\n/** A modified inherited node tagged with the branch that modified it. */\nexport type StagedModifiedNode = Readonly<{\n branchId: BranchId;\n node: ModifiedNode;\n}>;\n\n/** A deleted inherited node tagged with the branch that deleted it. */\ntype StagedDeletedNode = Readonly<{\n branchId: BranchId;\n node: DeletedNode;\n}>;\n\n/** A new fork edge tagged with the branch that introduced it. */\nexport type StagedNewEdge = Readonly<{\n branchId: BranchId;\n edge: ChangedEdge;\n}>;\n\n/** A modified inherited edge tagged with the branch that modified it. */\nexport type StagedModifiedEdge = Readonly<{\n branchId: BranchId;\n edge: ModifiedEdge;\n}>;\n\n/** A deleted inherited edge tagged with the branch that deleted it. */\ntype StagedDeletedEdge = Readonly<{\n branchId: BranchId;\n edge: DeletedEdge;\n}>;\n\n/**\n * The provenance-tagged union of every branch's state-diff against the base.\n *\n * New items are bucketed by kind so downstream blocking/candidate-gen (T5/T6)\n * can iterate one kind at a time. Modified and deleted items are kept as flat,\n * fully-sorted arrays — conflict detection (T8/T8a) groups them by id itself.\n */\nexport type StagingSet = Readonly<{\n /** New fork nodes, bucketed by kind. Map iterates in lexicographic kind order. */\n newNodesByKind: ReadonlyMap<string, readonly StagedNewNode[]>;\n /** Modified inherited nodes (one entry per (id, branch) modification). */\n modifiedNodes: readonly StagedModifiedNode[];\n /** Deleted inherited nodes (one entry per (id, branch) deletion). */\n deletedNodes: readonly StagedDeletedNode[];\n /** New fork edges, bucketed by kind. Map iterates in lexicographic kind order. */\n newEdgesByKind: ReadonlyMap<string, readonly StagedNewEdge[]>;\n /** Modified inherited edges (one entry per (id, branch) modification). */\n modifiedEdges: readonly StagedModifiedEdge[];\n /** Deleted inherited edges (one entry per (id, branch) deletion). */\n deletedEdges: readonly StagedDeletedEdge[];\n /**\n * `(kind, id) -> version` for the nodes of the branch named by\n * `stageBranches`' `captureTargetStateFor` argument, observed by that\n * branch's diff enumeration. Empty when no branch was requested. The\n * incremental merge captures the committed target branch here to use as the\n * plan-time baseline for its commit-time lost-update guard.\n */\n targetNodeVersions: ReadonlyMap<MergeKey, number>;\n /**\n * `(kind, id) -> edge content signature` for the edges of the same captured\n * branch. The edge-half analogue of {@link targetNodeVersions} (edges carry no\n * version, so the guard fingerprints their content). Empty when no branch was\n * requested.\n */\n targetEdgeSignatures: ReadonlyMap<MergeKey, string>;\n}>;\n\n/**\n * Total order over `(id, branchId)`. Used for the new-node/new-edge per-kind\n * buckets, where every member already shares a kind so kind need not be keyed.\n */\nfunction compareByIdThenBranch(\n left: Readonly<{ id: string; branchId: BranchId }>,\n right: Readonly<{ id: string; branchId: BranchId }>,\n): number {\n const byId = compareStrings(left.id, right.id);\n return byId === 0 ? compareStrings(left.branchId, right.branchId) : byId;\n}\n\n/**\n * Total order over `(kind, id, branchId)`. Used for the flat modified/deleted\n * collections, which mix kinds.\n */\nfunction compareByKindIdBranch(\n left: Readonly<{ kind: string; id: string; branchId: BranchId }>,\n right: Readonly<{ kind: string; id: string; branchId: BranchId }>,\n): number {\n const byKind = compareStrings(left.kind, right.kind);\n if (byKind !== 0) {\n return byKind;\n }\n const byId = compareStrings(left.id, right.id);\n return byId === 0 ? compareStrings(left.branchId, right.branchId) : byId;\n}\n\n/**\n * Groups items carrying a `kind` into a kind-keyed map whose iteration order is\n * lexicographic by kind and whose per-kind lists are sorted by `(id, branchId)`.\n */\nfunction groupByKind<\n T extends Readonly<{ kind: string; id: string; branchId: BranchId }>,\n>(items: readonly T[]): ReadonlyMap<string, readonly T[]> {\n const buckets = new Map<string, T[]>();\n for (const item of items) {\n const bucket = buckets.get(item.kind);\n if (bucket === undefined) {\n buckets.set(item.kind, [item]);\n } else {\n bucket.push(item);\n }\n }\n const ordered = new Map<string, readonly T[]>();\n for (const kind of [...buckets.keys()].sort((left, right) =>\n compareStrings(left, right),\n )) {\n ordered.set(\n kind,\n [...requireDefined(buckets.get(kind))].sort((left, right) =>\n compareByIdThenBranch(left, right),\n ),\n );\n }\n return ordered;\n}\n\n/**\n * Stages the UNION of all branches' diffs against the base, provenance-tagged.\n *\n * Each branch is diffed against `baseStore` (the immutable reference — NEVER a\n * clone, per the Interchange `deletedAt` fidelity limitation), and every diff\n * item is tagged with that branch's id. All branches' tagged items are then\n * collected into flat arrays and grouped/sorted ONCE, so the result is a pure\n * function of the unordered branch set: passing the branches in any order yields\n * a structurally identical {@link StagingSet}.\n *\n * @param baseStore The immutable base store every branch is diffed against.\n * @param branches The branches to stage. Order does not affect the result.\n * @returns The provenance-tagged union staging set.\n */\nexport async function stageBranches<G extends GraphDef>(\n baseStore: Store<G>,\n branches: readonly GraphBranch<G>[],\n captureTargetStateFor?: BranchId,\n): Promise<StagingSet> {\n const newNodes: (StagedNewNode & { kind: string; id: string })[] = [];\n const modifiedNodes: (StagedModifiedNode & { kind: string; id: string })[] =\n [];\n const deletedNodes: (StagedDeletedNode & { kind: string; id: string })[] = [];\n const newEdges: (StagedNewEdge & { kind: string; id: string })[] = [];\n const modifiedEdges: (StagedModifiedEdge & { kind: string; id: string })[] =\n [];\n const deletedEdges: (StagedDeletedEdge & { kind: string; id: string })[] = [];\n\n let targetNodeVersions: ReadonlyMap<MergeKey, number> = new Map();\n let targetEdgeSignatures: ReadonlyMap<MergeKey, string> = new Map();\n for (const branch of branches) {\n const branchId = branch.id;\n const diff = await diffAgainstBase(\n baseStore,\n branch.store,\n branchId === captureTargetStateFor,\n );\n if (branchId === captureTargetStateFor) {\n targetNodeVersions = diff.forkNodeVersions;\n targetEdgeSignatures = diff.forkEdgeSignatures;\n }\n\n for (const node of diff.nodes.new) {\n newNodes.push({ branchId, node, kind: node.kind, id: node.id });\n }\n for (const node of diff.nodes.modified) {\n modifiedNodes.push({ branchId, node, kind: node.kind, id: node.id });\n }\n for (const node of diff.nodes.deleted) {\n deletedNodes.push({ branchId, node, kind: node.kind, id: node.id });\n }\n for (const edge of diff.edges.new) {\n newEdges.push({ branchId, edge, kind: edge.kind, id: edge.id });\n }\n for (const edge of diff.edges.modified) {\n modifiedEdges.push({ branchId, edge, kind: edge.kind, id: edge.id });\n }\n for (const edge of diff.edges.deleted) {\n deletedEdges.push({ branchId, edge, kind: edge.kind, id: edge.id });\n }\n }\n\n return {\n newNodesByKind: groupByKind(newNodes),\n modifiedNodes: [...modifiedNodes].sort((left, right) =>\n compareByKindIdBranch(left, right),\n ),\n deletedNodes: [...deletedNodes].sort((left, right) =>\n compareByKindIdBranch(left, right),\n ),\n newEdgesByKind: groupByKind(newEdges),\n modifiedEdges: [...modifiedEdges].sort((left, right) =>\n compareByKindIdBranch(left, right),\n ),\n deletedEdges: [...deletedEdges].sort((left, right) =>\n compareByKindIdBranch(left, right),\n ),\n targetNodeVersions,\n targetEdgeSignatures,\n };\n}\n","/**\n * Bounded retry for the merge commit transaction.\n *\n * The commit runs at `SERIALIZABLE` isolation (see `commitPlan` /\n * `commitIncrementalPlan`): under Postgres SSI a concurrent write that\n * invalidates the transaction's reads aborts one side with SQLSTATE 40001\n * (serialization failure); lock ordering between concurrent merges can also\n * surface 40P01 (deadlock). Both are TRANSIENT — the transaction did not\n * commit, and re-running it is the documented client protocol — so the commit\n * is retried a bounded number of times. The in-transaction `base@V`\n * re-validation runs on every attempt, so a retry that lands after a REAL\n * divergence fails deterministically with `BaseVersionMismatchError` instead\n * of committing a stale plan.\n *\n * SQLite and PGlite serialize writers (single connection), so retryable\n * conflicts cannot occur there and the wrapper is pass-through in practice.\n */\n\nimport { MergeError } from \"./errors\";\n\n/** SQLSTATEs that mean \"transaction aborted, safe to re-run verbatim\". */\nconst RETRYABLE_SQLSTATES: ReadonlySet<string> = new Set([\"40001\", \"40P01\"]);\n\n/**\n * Driver-message fallback for errors whose SQLSTATE was lost in wrapping.\n * Matches the fixed Postgres texts for serialization failure and deadlock.\n */\nconst RETRYABLE_MESSAGE_PATTERN =\n /could not serialize access|deadlock detected/i;\n\n/** Bounded number of commit attempts before giving up with a typed error. */\nexport const MAX_COMMIT_ATTEMPTS = 3;\n\n/**\n * Whether `error` (or anything in its cause chain) is a retryable transaction\n * conflict — a Postgres serialization failure (40001) or deadlock (40P01).\n * Walks the `cause` chain because drivers and wrappers (pg → Drizzle →\n * TypeGraph) re-wrap the original error; a visited set guards against cyclic\n * cause chains.\n */\nexport function isRetryableTxConflict(error: unknown): boolean {\n const seen = new Set<unknown>();\n let current: unknown = error;\n while (\n current !== undefined &&\n current !== null &&\n typeof current === \"object\" &&\n !seen.has(current)\n ) {\n seen.add(current);\n const candidate = current as Readonly<{\n code?: unknown;\n message?: unknown;\n cause?: unknown;\n }>;\n if (\n typeof candidate.code === \"string\" &&\n RETRYABLE_SQLSTATES.has(candidate.code)\n ) {\n return true;\n }\n if (\n typeof candidate.message === \"string\" &&\n RETRYABLE_MESSAGE_PATTERN.test(candidate.message)\n ) {\n return true;\n }\n current = candidate.cause;\n }\n return false;\n}\n\n/**\n * Runs `commit` (a function that opens and completes ONE transaction attempt),\n * retrying up to {@link MAX_COMMIT_ATTEMPTS} times on retryable conflicts.\n * Non-retryable errors propagate immediately; exhaustion raises a\n * {@link MergeError} carrying the final conflict as its cause.\n */\nexport async function withTxConflictRetry<T>(\n commit: () => Promise<T>,\n): Promise<T> {\n let lastConflict: unknown;\n for (let attempt = 1; attempt <= MAX_COMMIT_ATTEMPTS; attempt += 1) {\n try {\n return await commit();\n } catch (error) {\n if (!isRetryableTxConflict(error)) {\n throw error;\n }\n lastConflict = error;\n }\n }\n throw new MergeError(\n `Merge commit aborted by transaction conflicts (serialization failure or deadlock) on ${MAX_COMMIT_ATTEMPTS} consecutive attempts; giving up.`,\n {\n cause: lastConflict,\n details: { attempts: MAX_COMMIT_ATTEMPTS },\n suggestion:\n \"Reduce concurrent writes to the merge target, or serialize merges against it.\",\n },\n );\n}\n","import { requireDefined } from \"../utils/presence\";\n/**\n * Opt-in ontology type reconciliation (design §6 / §7, T10).\n *\n * When entity resolution (T8) collapses fork nodes into one cluster, those nodes\n * may carry DIFFERING `node.kind` values across branches — e.g. one branch staged\n * a `Doctor` while another staged the more-specific `SpecialistDoctor` for what is\n * really the same person. With `reconcileTypes: \"ontology\"` enabled, this module\n * uses the PUBLIC-closure glue (T2a, `closures.ts`) to decide whether those kinds\n * are subClassOf-compatible and, if so, collapses the cluster to the\n * MOST-SPECIFIC common type, recording a {@link TypeReconciliation}. Genuinely\n * incompatible kinds (siblings, disjoint trees) are FLAGGED — never silently\n * collapsed — and surfaced as a {@link DroppedItem}.\n *\n * MOST-SPECIFIC = the unique minimum of the subclass partial order restricted to\n * the cluster's distinct kinds: the kind `T` such that every OTHER kind in the\n * cluster is a (transitive) ancestor of `T` (`isReachable(closure, T, other)`),\n * or is EQUIVALENT to `T` (mutual reachability, from folded `equivalentTo`\n * relations). If several mutually-equivalent kinds tie for the minimum, the\n * lexicographically-smallest representative is chosen so the outcome is\n * deterministic. If no single minimum exists, the kinds are incompatible.\n *\n * This module is a PURE decision function — no I/O, no store access. The\n * orchestrator (T11) builds the {@link ReconcileClusterInput}s from the resolved\n * clusters + the staged nodes' kinds, then applies the returned\n * {@link TypeReconcileResult.retypeMap} to the canonical node's `kind` and to the\n * repointed edges' `fromKind` / `toKind` annotations while keeping endpoint ids\n * stable (the cascade described in step 2). `mode: \"off\"` is a guaranteed no-op.\n */\nimport type { SubClassClosure } from \"./closures\";\nimport { isReachable } from \"./closures\";\nimport { compareStrings, idOf, type MergeKey } from \"./node-key\";\nimport type {\n DroppedItem,\n ReconcileTypesMode,\n TypeReconciliation,\n} from \"./types\";\n\n/**\n * Reason recorded on a {@link DroppedItem} when a cluster's mixed kinds are\n * neither subClassOf-comparable nor equivalent and therefore CANNOT be collapsed.\n * The cluster is left untouched (its members keep their original kinds); this\n * record only flags the incompatibility for the {@link MergeReport}.\n */\nexport const INCOMPATIBLE_TYPES_FLAG_REASON =\n \"type-reconcile:incompatible-kinds\" as const;\n\n/**\n * One resolved cluster fed into type reconciliation: the canonical survivor id\n * (from T8 `pickClusterSurvivor`) and the DISTINCT kinds present across the cluster's\n * members. Single-kind clusters (one distinct kind) are no-ops and may be omitted\n * by the caller, but are handled defensively here too.\n */\nexport type ReconcileClusterInput = Readonly<{\n /** The canonical survivor IDENTITY (`(kind, id)`), so the retype keys on the same\n * composite identity the commit looks it up by — never a bare id shared across\n * kinds. */\n canonicalId: MergeKey;\n /** The distinct member kinds in the cluster. Order does not affect the result. */\n memberKinds: readonly string[];\n}>;\n\n/**\n * The outcome of reconciling every cluster's kinds.\n *\n * - `reconciliations`: one {@link TypeReconciliation} per multi-kind cluster that\n * collapsed to a single most-specific type.\n * - `retypeMap`: `canonicalId → toType` for exactly those reconciled clusters, so\n * the commit (T11) can cascade the retype onto the canonical node and the\n * repointed edges' endpoint-kind annotations.\n * - `dropped`: one `{ kind: \"node\" }` {@link DroppedItem} per cluster whose kinds\n * were incompatible (flagged, NOT collapsed) — its `id` is the canonical id and\n * its `reason` is {@link INCOMPATIBLE_TYPES_FLAG_REASON}.\n */\nexport type TypeReconcileResult = Readonly<{\n reconciliations: readonly TypeReconciliation[];\n /** `canonical (kind, id) → toType` for each reconciled cluster, keyed by the\n * composite identity so the commit cascade resolves a retype unambiguously even\n * when an id is shared across kinds. */\n retypeMap: ReadonlyMap<MergeKey, string>;\n dropped: readonly DroppedItem[];\n}>;\n\n/** Distinct, lexicographically-sorted kinds — the canonical kind set. */\nfunction distinctKinds(kinds: readonly string[]): readonly string[] {\n return [...new Set(kinds)].sort((left, right) => compareStrings(left, right));\n}\n\n/**\n * Reports whether two kinds are EQUIVALENT under the closure — distinct names\n * that fold to the same `equivalentTo` class, hence mutually reachable. (A kind is\n * not equivalent to itself here; identical names are handled by the caller.)\n */\nfunction areEquivalent(\n closure: SubClassClosure,\n left: string,\n right: string,\n): boolean {\n return (\n left !== right &&\n isReachable(closure, left, right) &&\n isReachable(closure, right, left)\n );\n}\n\n/**\n * Reports whether `candidate` is \"at or below\" `other` in the subclass order:\n * either it is a (transitive) subclass of `other`, or the two are equivalent. This\n * is the predicate the most-specific kind must satisfy against every OTHER kind in\n * the cluster.\n */\nfunction isAtOrBelow(\n closure: SubClassClosure,\n candidate: string,\n other: string,\n): boolean {\n if (candidate === other) {\n return true;\n }\n return (\n isReachable(closure, candidate, other) ||\n areEquivalent(closure, candidate, other)\n );\n}\n\n/**\n * Finds the MOST-SPECIFIC common kind among `kinds`, or `undefined` if the kinds\n * are incompatible (no single minimum of the subclass order).\n *\n * A kind qualifies as the minimum when every OTHER kind is at-or-above it\n * ({@link isAtOrBelow}). Several mutually-equivalent kinds can all qualify; the\n * lexicographically-smallest qualifier is returned so the choice is deterministic.\n * Siblings (e.g. two leaves under a shared parent) and disjoint trees yield no\n * qualifier → `undefined` (incompatible).\n */\nexport function mostSpecificCommonKind(\n closure: SubClassClosure,\n kinds: readonly string[],\n): string | undefined {\n const qualifiers = kinds.filter((candidate) =>\n kinds.every((other) => isAtOrBelow(closure, candidate, other)),\n );\n if (qualifiers.length === 0) {\n return undefined;\n }\n return requireDefined(\n [...qualifiers].sort((left, right) => compareStrings(left, right))[0],\n );\n}\n\n/**\n * Reconciles the differing kinds of each resolved cluster against the subClassOf\n * closure.\n *\n * For `mode: \"off\"` (the default) this is a guaranteed no-op: it returns zero\n * reconciliations, an empty retype map, and zero dropped items, regardless of the\n * clusters.\n *\n * For `mode: \"ontology\"`, each cluster with more than one distinct kind is\n * reconciled:\n *\n * - a single MOST-SPECIFIC common kind exists → the cluster collapses to it; a\n * {@link TypeReconciliation} is recorded (`fromTypes` = the distinct kinds,\n * `toType` = the chosen kind) and `canonicalId → toType` is added to\n * `retypeMap`. When the most-specific kind already equals the cluster's full\n * (single-element-after-collapse) intent — i.e. all kinds were equivalent and\n * fold to the same chosen representative — the reconciliation is still\n * recorded so the cascade can normalize the canonical node's kind.\n * - no single most-specific kind (siblings / disjoint trees) → the cluster is\n * FLAGGED incompatible: a `{ kind: \"node\" }` {@link DroppedItem} with reason\n * {@link INCOMPATIBLE_TYPES_FLAG_REASON} is recorded and the cluster is NOT\n * collapsed (no retype entry).\n *\n * Single-kind clusters never appear in the output. All output collections are\n * sorted by stable keys (`canonicalId`) so the result is a pure function of the\n * unordered cluster set.\n *\n * @param clusters The resolved clusters with their distinct member kinds.\n * @param closure The subClassOf closure from {@link buildSubClassClosure} (T2a).\n * @param mode `\"off\"` (no-op) or `\"ontology\"` (reconcile).\n */\nexport function reconcileTypes(\n clusters: readonly ReconcileClusterInput[],\n closure: SubClassClosure,\n mode: ReconcileTypesMode,\n): TypeReconcileResult {\n if (mode === \"off\") {\n return {\n reconciliations: [],\n retypeMap: new Map<MergeKey, string>(),\n dropped: [],\n };\n }\n\n const reconciliations: TypeReconciliation[] = [];\n const retypeMap = new Map<MergeKey, string>();\n const dropped: DroppedItem[] = [];\n\n for (const cluster of clusters) {\n const kinds = distinctKinds(cluster.memberKinds);\n if (kinds.length <= 1) {\n continue;\n }\n\n // The PUBLIC report fields (`entityId`, dropped `id`) carry the bare node id;\n // the internal retype keys on the full `(kind, id)` identity.\n const entityId = idOf(cluster.canonicalId);\n const toType = mostSpecificCommonKind(closure, kinds);\n if (toType === undefined) {\n dropped.push({\n kind: \"node\",\n id: entityId,\n reason: INCOMPATIBLE_TYPES_FLAG_REASON,\n });\n continue;\n }\n\n reconciliations.push({\n entityId,\n fromTypes: kinds,\n toType,\n });\n retypeMap.set(cluster.canonicalId, toType);\n }\n\n return {\n reconciliations: reconciliations.sort((left, right) =>\n compareStrings(left.entityId, right.entityId),\n ),\n retypeMap,\n dropped: dropped.sort((left, right) => compareStrings(left.id, right.id)),\n };\n}\n","import { requireDefined } from \"../utils/presence\";\n/**\n * `merge()` orchestrator (design §7.2, T11).\n *\n * Composes every phase built in T3–T10 into one DB-agnostic primitive:\n *\n * 1. PRECONDITION — compute the target's `base@V` and reject any branch whose\n * `base` token does not match it (`BaseVersionMismatchError`). A branch\n * forked from a divergent schema or base revision cannot be merged\n * safely (design §5.2 / §13.6).\n * 2. STAGE — `stageBranches` (T7): the provenance-tagged UNION of every\n * branch's state-diff against the immutable base.\n * 3. CANDIDATE-GEN — per resolved kind: build node-shaped objects from the\n * staged NEW nodes, `blockNodes` (T5, folding in unique constraints from\n * `introspect()`), `generateCandidates` (T6, fulltext Dice + custom; vector/\n * hybrid guarded). Kinds NOT in `options.resolve` merge by id only.\n * 4. CLUSTER — `connectedComponents` (T8) over the accumulated candidate edges\n * and every staged new-node id, with the optional diameter guard.\n * 5. CANONICALIZE — `canonicalizeCluster` (T8): min-id survivor + commutative\n * property union under the stable, non-wall-clock conflict policy.\n * 6. DELETE/MODIFY — `resolveDeleteModify` (T8a): the authoritative final\n * liveness of every inherited node + the delete/modify conflicts.\n * 7. TYPE-RECONCILE — `reconcileTypes` (T10) over the public-closure glue when\n * `reconcileTypes: \"ontology\"`; otherwise a no-op.\n * 8. EDGE REPOINT — `repointEdges` (T9): repoint every staged edge onto its\n * cluster canonical, drop edges to finally-deleted endpoints, dedupe + union\n * edge props under the same conflict policy.\n * 9. COMMIT — apply everything to `target` (default = base store) in a single\n * `store.transaction` when the backend is transactional, else non-atomically\n * with a report warning (out of the P0 acceptance path — SQLite + Postgres\n * are both transactional).\n * 10. REPORT — assemble the {@link MergeReport} with merged counts, every\n * resolution / conflict / reconciliation / drop, and the in-memory\n * {@link ProvenanceIndex}. With `persistProvenance`, ALSO upsert the\n * `{branch, sourceId}` records to a sidecar provenance graph (post-commit,\n * best-effort — a failure surfaces as a report warning, never a failed merge).\n *\n * DETERMINISM: every phase is order-independent (pure functions over the\n * unordered branch / staged sets, with a branch order captured ONCE for\n * conflict resolution), so shuffling `branches` yields a deep-equal report and an\n * identical committed graph. T12 proves this with a fast-check shuffle property.\n */\nimport {\n computeBaseVersion,\n computeContentComponent,\n computeSchemaComponent,\n contentComponentOf,\n hasRevisionAnchor,\n revisionAnchorOf,\n revisionOriginOf,\n} from \"./base-version\";\nimport { blockNodes } from \"./blocking\";\nimport { canonicalizeProps, edgeStateSignature } from \"./canonical-props\";\nimport type { CanonicalEntity, ClusterMember } from \"./canonicalize\";\nimport { BASE_PROVENANCE_BRANCH, canonicalizeCluster } from \"./canonicalize\";\nimport { buildSubClassClosure } from \"./closures\";\nimport type { ClusterResult } from \"./clustering\";\nimport {\n connectedComponents,\n enforceBaseGuard,\n enforceDiameter,\n} from \"./clustering\";\nimport type { ProvenanceWeights } from \"./conflict-policy\";\nimport { buildBranchRank } from \"./conflict-policy\";\nimport {\n reconcileEdgeModifications,\n reconcileModifications,\n resolveDeleteModify,\n resolveEdgeDeleteModify,\n} from \"./delete-modify\";\nimport type { MergedEdge, StagedEdge } from \"./edge-repoint\";\nimport { buildCanonicalMap, repointEdges } from \"./edge-repoint\";\nimport { BaseVersionMismatchError, MergeError } from \"./errors\";\nimport {\n compareMergeKeys,\n compareStrings,\n idOf,\n kindOf,\n type MergeKey,\n mergeKey,\n mergeKeyOf,\n} from \"./node-key\";\nimport type { NormalizedMergeOptions } from \"./options\";\nimport { normalizeMergeOptions } from \"./options\";\nimport {\n openProvenanceStore,\n persistProvenanceRecords,\n provenanceGraphId,\n} from \"./provenance-store\";\nimport type { Result } from \"./result\";\nimport { err, isErr, ok } from \"./result\";\nimport type { CandidateEdge, CandidatePair } from \"./scoring\";\nimport { compareCandidateEdges, scoreCandidates } from \"./scoring\";\nimport type { SimilarityContext } from \"./similarity\";\nimport { embeddingFields, fieldText } from \"./similarity\";\nimport type { BaseLookupStore, BaseMember, SourceScope } from \"./sources\";\nimport {\n baseKeySource,\n baseUniqueSource,\n CANDIDATE_SOURCES,\n keylessConfigFor,\n ontologyRetypeEdges,\n} from \"./sources\";\nimport type {\n StagedModifiedEdge,\n StagedModifiedNode,\n StagedNewEdge,\n StagedNewNode,\n StagingSet,\n} from \"./staging\";\nimport { stageBranches } from \"./staging\";\nimport { withTxConflictRetry } from \"./tx-retry\";\nimport type { ReconcileClusterInput } from \"./type-reconcile\";\nimport { mostSpecificCommonKind, reconcileTypes } from \"./type-reconcile\";\nimport type {\n Edge,\n EdgeId,\n GraphDef,\n JsonValue,\n Node,\n NodeId,\n NodeType,\n Store,\n TransactionBackend,\n TransactionOptions,\n UniqueIntrospection,\n} from \"./typegraph-internal\";\nimport {\n lockRecordedGraphWrite,\n readRecordedClock,\n readRevisionOrigin,\n storeBackend,\n transactionBackend,\n} from \"./typegraph-internal\";\nimport type {\n BaseAmbiguity,\n BaseVersion,\n BranchId,\n BranchProvenance,\n DeleteModifyConflict,\n DroppedItem,\n Embedder,\n EntityResolution,\n GraphBranch,\n MergeIncrementalArgs as MergeIncrementalArguments,\n MergeOptions,\n MergeReport,\n PropertyConflict,\n PropertyConflictPolicy,\n ProvenanceIndex,\n ProvenanceRecord,\n SimilarityStrategy,\n TypeReconciliation,\n} from \"./types\";\nimport { asBranchId } from \"./types\";\n\n/** A node id in its untyped (`NodeType`-default) branded form. */\ntype AnyNodeId = NodeId<NodeType>;\n\n/** Reserved synthetic branch id for the live target in `mergeIncremental()`. */\nconst COMMITTED_TARGET_BRANCH: BranchId = asBranchId(\"__committed_target__\");\n\n/**\n * Materializes a {@link Node}-shaped object from a staged new node's parsed\n * props. The blocking (T5) and similarity (T6) phases read schema fields directly\n * off the node (`node.name`), so the props must be spread at the top level with\n * `kind`/`id` alongside — exactly the runtime shape `Node<NodeType>` carries.\n */\nfunction asNode(staged: StagedNewNode): Node<NodeType> {\n return {\n kind: staged.node.kind,\n id: staged.node.id,\n ...staged.node.props,\n } as unknown as Node<NodeType>;\n}\n\n/**\n * Collects, per kind, every staged new node tagged by branch, in deterministic\n * `(id, branchId)` order. The staging set already buckets new nodes by kind in\n * lexicographic order; this re-sorts each bucket defensively so candidate-gen is\n * correct for any caller.\n */\nfunction newNodesByKind(\n staging: StagingSet,\n): ReadonlyMap<string, readonly StagedNewNode[]> {\n const ordered = new Map<string, readonly StagedNewNode[]>();\n for (const [kind, items] of staging.newNodesByKind) {\n ordered.set(\n kind,\n [...items].sort((left, right) => {\n const byId = compareStrings(left.node.id, right.node.id);\n return byId === 0 ?\n compareStrings(left.branchId, right.branchId)\n : byId;\n }),\n );\n }\n return ordered;\n}\n\n/**\n * Looks up a kind's declared unique constraints from the store introspection, so\n * blocking can short-circuit exact-match duplicates. Returns an empty array for a\n * kind with no constraints (or an unknown kind).\n */\nfunction uniqueConstraintsFor(\n introspectionKinds: ReadonlyMap<string, readonly UniqueIntrospection[]>,\n kind: string,\n): readonly UniqueIntrospection[] {\n return introspectionKinds.get(kind) ?? [];\n}\n\n/**\n * Precomputes the text→vector lookup the `vector`/`hybrid` scorers read.\n *\n * Runs the injected {@link Embedder} ONCE over the deduplicated, non-empty field\n * texts of every staged new node belonging to a `vector`/`hybrid` kind, in sorted\n * order. Embedding is per-text independent and the lookup is keyed by text, so the\n * map — and therefore every pairwise cosine — is a pure function of the staged node\n * SET, independent of branch/arrival order (the determinism contract). The text of\n * each node is taken via the SAME {@link fieldText} the scorer uses, so the\n * embedded key and the looked-up key always match.\n *\n * Returns an EMPTY map when no kind needs embeddings (or every text is empty). The\n * caller passes the map (vs. `undefined`) to {@link SimilarityContext} only when an\n * embedder was configured — that presence is what lets `scorePair` distinguish\n * \"embedder configured\" from \"vector/hybrid requested with no embedder\".\n *\n * This covers only STAGED node texts. COMMITTED base nodes pulled into staged↔base\n * candidate pairs by the base sources are not known until candidate generation\n * runs, so their texts are embedded there via {@link embedMissingPairTexts}.\n */\nasync function precomputeEmbeddings<G extends GraphDef>(\n byKind: ReadonlyMap<string, readonly StagedNewNode[]>,\n resolve: NormalizedMergeOptions<G>[\"resolve\"],\n embedder: Embedder,\n): Promise<ReadonlyMap<string, Float32Array>> {\n const texts = new Set<string>();\n for (const [kind, items] of byKind) {\n const config = resolve[kind];\n if (config === undefined) {\n continue;\n }\n const fields = embeddingFields(config.similarity);\n if (fields === undefined) {\n continue;\n }\n for (const staged of items) {\n const text = fieldText(asNode(staged), fields);\n if (text.length > 0) {\n texts.add(text);\n }\n }\n }\n\n const lookup = new Map<string, Float32Array>();\n if (texts.size === 0) {\n return lookup;\n }\n const orderedTexts = [...texts].sort((left, right) =>\n compareStrings(left, right),\n );\n const vectors = await embedder(orderedTexts);\n if (vectors.length !== orderedTexts.length) {\n throw new MergeError(\n `Embedder returned ${vectors.length} vectors for ${orderedTexts.length} texts; expected exactly one per text.`,\n {\n details: { texts: orderedTexts.length, vectors: vectors.length },\n suggestion:\n \"Ensure MergeOptions.embedder returns one vector per input text, in order.\",\n },\n );\n }\n for (const [index, text] of orderedTexts.entries()) {\n lookup.set(text, requireDefined(vectors[index]));\n }\n return lookup;\n}\n\n/**\n * Ensures every text scored for a `vector`/`hybrid` kind is in the embeddings\n * lookup. {@link precomputeEmbeddings} embeds only STAGED node texts; the base\n * sources (`baseKeySource`/`baseUniqueSource`) pull COMMITTED nodes into\n * staged↔base candidate pairs whose texts were never embedded — without this they\n * would score MIN_SCORE and a staged node would commit as a DUPLICATE instead of\n * merging onto its committed entity. Embeds any pair-endpoint text missing from\n * `base` and returns the augmented map (the original when nothing is missing).\n * Keyed by text and embedded in sorted order, so the result stays a pure function\n * of the node set (the determinism contract). Non-embedding strategies\n * (`fulltext`/`custom`) return `base` unchanged.\n */\nasync function embedMissingPairTexts(\n base: ReadonlyMap<string, Float32Array> | undefined,\n pairs: readonly CandidatePair[],\n strategy: SimilarityStrategy,\n embedder: Embedder,\n): Promise<ReadonlyMap<string, Float32Array>> {\n const existing = base ?? new Map<string, Float32Array>();\n const fields = embeddingFields(strategy);\n if (fields === undefined) {\n return existing;\n }\n const missing = new Set<string>();\n for (const pair of pairs) {\n for (const node of [pair.left, pair.right]) {\n const text = fieldText(node, fields);\n if (text.length > 0 && !existing.has(text)) {\n missing.add(text);\n }\n }\n }\n if (missing.size === 0) {\n return existing;\n }\n const orderedTexts = [...missing].sort((left, right) =>\n compareStrings(left, right),\n );\n const vectors = await embedder(orderedTexts);\n if (vectors.length !== orderedTexts.length) {\n throw new MergeError(\n `Embedder returned ${vectors.length} vectors for ${orderedTexts.length} texts; expected exactly one per text.`,\n {\n details: { texts: orderedTexts.length, vectors: vectors.length },\n suggestion:\n \"Ensure MergeOptions.embedder returns one vector per input text, in order.\",\n },\n );\n }\n const augmented = new Map(existing);\n for (const [index, text] of orderedTexts.entries()) {\n augmented.set(text, requireDefined(vectors[index]));\n }\n return augmented;\n}\n\n/**\n * Runs candidate generation for every kind that has a {@link ResolveConfig} by\n * driving the candidate SOURCES (`sources.ts`) over the shared SCORING stage\n * (`scoring.ts`, §4): per kind, each source proposes pairs + forced edges off the\n * scope, and the scoring stage turns them into the kind's candidate edges.\n * Accumulates edges + any base members across kinds and records comparison-ceiling\n * warnings. Kinds NOT in `resolve` (or with no staged new nodes) contribute no\n * candidate edges — they merge by id only.\n *\n * `useBaseSources` selects the resolution DIRECTION. The public snapshot `merge()`\n * passes `false` — only the staged sources (`exactKey`, `unique`) run, so no\n * committed node is pulled into scope (`baseMembers` is empty) and the path stays\n * staged-vs-staged. The synthetic new-vs-base scope passes `true`, adding\n * {@link baseUniqueSource} (which queries `target`) so a staged node re-discovering\n * a committed entity surfaces as a forced new↔base edge + a base member.\n *\n * Returns `err` when a kind's `onComparisonCeiling: \"error\"` ceiling trips or a\n * `vector`/`hybrid` strategy hits the no-embedder guard.\n */\nasync function generateAllCandidates<G extends GraphDef>(\n target: Store<G>,\n staging: StagingSet,\n options: NormalizedMergeOptions<G>,\n introspectionKinds: ReadonlyMap<string, readonly UniqueIntrospection[]>,\n ctx: SimilarityContext,\n useBaseSources: boolean,\n embedder: Embedder | undefined,\n): Promise<\n Result<\n Readonly<{\n edges: readonly CandidateEdge[];\n warnings: readonly string[];\n baseMembers: readonly BaseMember[];\n }>,\n MergeError\n >\n> {\n const allEdges: CandidateEdge[] = [];\n const warnings: string[] = [];\n const baseMembers: BaseMember[] = [];\n const byKind = newNodesByKind(staging);\n const sources =\n useBaseSources ?\n [...CANDIDATE_SOURCES, baseUniqueSource, baseKeySource]\n : CANDIDATE_SOURCES;\n // Base sources resolve staged nodes against the COMMITTED graph — the merge\n // TARGET, where prior runs' canonicals live — NOT the (possibly older) diff\n // reference. They coincide under the public snapshot path (target defaults to\n // store); they differ under the synthetic new-vs-base scope.\n const baseStore = target as unknown as BaseLookupStore;\n\n // Each kind's candidate generation is independent (results are concatenated, then\n // globally re-sorted below), so run them concurrently — under the base-source path\n // each kind's `bulkFindByConstraint` round-trip would otherwise serialise.\n const perKind = await Promise.all(\n [...byKind].map(\n async ([kind, items]): Promise<\n Result<\n Readonly<{\n edges: readonly CandidateEdge[];\n warnings: readonly string[];\n baseMembers: readonly BaseMember[];\n }>,\n MergeError\n >\n > => {\n const resolveConfig = options.resolve[kind];\n if (resolveConfig === undefined) {\n // No resolution config for this kind: merge by id only (no candidate\n // edges, so every new node stays a singleton cluster).\n return ok({ edges: [], warnings: [], baseMembers: [] });\n }\n\n const nodes = items.map((staged) => asNode(staged));\n const uniqueConstraints = uniqueConstraintsFor(\n introspectionKinds,\n kind,\n );\n const blocks = blockNodes(nodes, resolveConfig, uniqueConstraints);\n const keylessConfig = keylessConfigFor(resolveConfig);\n const scope: SourceScope = {\n kind,\n blocks,\n nodes,\n uniqueConstraints,\n store: baseStore,\n ...(resolveConfig.blockIndex === undefined ?\n {}\n : { blockIndex: resolveConfig.blockIndex }),\n ...(keylessConfig === undefined ? {} : { keyless: keylessConfig }),\n };\n\n const pairs: CandidatePair[] = [];\n const forcedEdges: CandidateEdge[] = [];\n const kindBaseMembers: BaseMember[] = [];\n for (const source of sources) {\n const produced = await source.generate(scope);\n pairs.push(...produced.pairs);\n forcedEdges.push(...produced.forcedEdges);\n kindBaseMembers.push(...produced.baseMembers);\n }\n\n // Base sources pull committed nodes into staged↔base pairs whose texts\n // were not in the staged-only precompute; embed them now so vector/hybrid\n // scoring can actually find them (otherwise the pair scores MIN_SCORE and\n // the staged node duplicates instead of merging onto the committed entity).\n const kindCtx =\n embedder === undefined ? ctx : (\n {\n ...ctx,\n embeddings: await embedMissingPairTexts(\n ctx.embeddings,\n pairs,\n resolveConfig.similarity,\n embedder,\n ),\n }\n );\n\n const scored = scoreCandidates(\n { pairs, forcedEdges },\n resolveConfig,\n kindCtx,\n options.onComparisonCeiling,\n options.maxComparisonsPerKind,\n );\n if (isErr(scored)) {\n return err(scored.error);\n }\n return ok({\n edges: scored.data.edges,\n warnings: scored.data.warnings.map(\n (warning) => `[${kind}] ${warning.message}`,\n ),\n baseMembers: kindBaseMembers,\n });\n },\n ),\n );\n\n for (const result of perKind) {\n if (isErr(result)) {\n return err(result.error);\n }\n allEdges.push(...result.data.edges);\n warnings.push(...result.data.warnings);\n baseMembers.push(...result.data.baseMembers);\n }\n\n return ok({\n // The ONE shared `(a, b)` edge comparator (id-first `(kind, id)` order), so this\n // stage emits edges in exactly the order clustering consumes them.\n edges: allEdges.sort((left, right) => compareCandidateEdges(left, right)),\n warnings,\n // Total order over the composite `(kind, id)` identity (two same-id/different-kind\n // base members would tie under a bare-id compare).\n baseMembers: baseMembers.sort((left, right) =>\n compareMergeKeys(mergeKeyOf(left), mergeKeyOf(right)),\n ),\n });\n}\n\n/**\n * Builds, per cluster, the {@link ClusterMember} contributions. A staged new node\n * contributes one member per branch that staged it (so a cross-branch property\n * disagreement surfaces as a conflict in the union, T8); a committed BASE node the\n * cluster pulled in contributes one `origin: \"base\"` member, carrying the reserved\n * {@link BASE_PROVENANCE_BRANCH} so it gap-fills the property union and survivor\n * selection can enforce base-id-wins (§6.4-C).\n */\nfunction clusterMembersFor(\n cluster: ClusterResult,\n newNodesById: ReadonlyMap<MergeKey, readonly StagedNewNode[]>,\n baseMembersById: ReadonlyMap<MergeKey, BaseMember>,\n): readonly ClusterMember[] {\n const members: ClusterMember[] = [];\n for (const key of cluster.members) {\n for (const staged of newNodesById.get(key) ?? []) {\n members.push({\n origin: \"staged\",\n id: staged.node.id,\n kind: staged.node.kind,\n branchId: staged.branchId,\n props: staged.node.props as Readonly<Record<string, JsonValue>>,\n });\n }\n const base = baseMembersById.get(key);\n if (base !== undefined) {\n members.push({\n origin: \"base\",\n id: base.id,\n kind: base.kind,\n branchId: BASE_PROVENANCE_BRANCH,\n props: base.props,\n });\n }\n }\n return members;\n}\n\n/**\n * Indexes the staged new nodes by id (preserving the per-id branch list), so\n * clustering / canonicalization can pull every branch's contribution for a node.\n */\nfunction indexNewNodesById(\n staging: StagingSet,\n): ReadonlyMap<MergeKey, readonly StagedNewNode[]> {\n const index = new Map<MergeKey, StagedNewNode[]>();\n for (const items of staging.newNodesByKind.values()) {\n for (const staged of items) {\n const key = mergeKeyOf(staged.node);\n const bucket = index.get(key);\n if (bucket === undefined) {\n index.set(key, [staged]);\n } else {\n bucket.push(staged);\n }\n }\n }\n return index;\n}\n\n/**\n * Flattens the staged NEW edges plus the surviving inherited MODIFIED edges into\n * the {@link StagedEdge} shape the repoint phase (T9) consumes (parsed props +\n * branch tag). Inherited edges that were not modified by any branch are unchanged\n * in the base and need no re-commit, so only modified inherited edges are folded\n * in here alongside the new edges.\n *\n * The modified inherited edges are the RECONCILED ones (one per id, 3-way merged\n * against base by {@link reconcileEdgeModifications}) — NOT the raw per-branch\n * `staging.modifiedEdges`. Staging each branch's full fork props separately would\n * make the repoint union treat unchanged-from-base fields as conflicts, dropping a\n * disjoint edit by another branch.\n */\nfunction buildStagedEdges(\n staging: StagingSet,\n modifiedEdges: readonly StagedModifiedEdge[],\n): readonly StagedEdge[] {\n const staged: StagedEdge[] = [];\n for (const items of staging.newEdgesByKind.values()) {\n for (const item of items) {\n staged.push(toStagedEdge(item.branchId, item));\n }\n }\n for (const item of modifiedEdges) {\n staged.push({\n id: item.edge.id,\n kind: item.edge.kind,\n fromId: item.edge.fromId,\n toId: item.edge.toId,\n fromKind: item.edge.fromKind,\n toKind: item.edge.toKind,\n props: item.edge.forkProps as Readonly<Record<string, JsonValue>>,\n branchId: item.branchId,\n });\n }\n return staged;\n}\n\n/** Projects a {@link StagedNewEdge} onto the repoint-phase {@link StagedEdge}. */\nfunction toStagedEdge(branchId: BranchId, item: StagedNewEdge): StagedEdge {\n return {\n id: item.edge.id,\n kind: item.edge.kind,\n fromId: item.edge.fromId,\n toId: item.edge.toId,\n fromKind: item.edge.fromKind,\n toKind: item.edge.toKind,\n props: item.edge.props as Readonly<Record<string, JsonValue>>,\n branchId,\n };\n}\n\n/**\n * Builds the report-only, in-memory provenance index from the full record list.\n * `byBranch(id)` answers which merged node / edge ids that branch contributed to:\n * a node id when the branch staged a new node that survived into a cluster's\n * canonical (or a surviving modification), an edge id when the branch staged an\n * edge that survived the repoint/dedupe. Collapses the records — which ALSO carry\n * each contribution's `sourceId` for the persisted sidecar — to deduped, sorted id\n * sets per branch (the unchanged report-only shape).\n */\nfunction buildProvenanceIndex(\n records: readonly ProvenanceRecord[],\n): ProvenanceIndex {\n const byBranch = new Map<\n BranchId,\n Readonly<{ nodeIds: Set<AnyNodeId>; edgeIds: Set<string> }>\n >();\n for (const record of records) {\n let entry = byBranch.get(record.branchId);\n if (entry === undefined) {\n entry = { nodeIds: new Set(), edgeIds: new Set() };\n byBranch.set(record.branchId, entry);\n }\n if (record.role === \"node\") {\n entry.nodeIds.add(record.canonicalId as AnyNodeId);\n } else {\n entry.edgeIds.add(record.canonicalId);\n }\n }\n\n const frozen = new Map<BranchId, BranchProvenance>();\n for (const [branchId, sets] of byBranch) {\n frozen.set(branchId, {\n nodeIds: [...sets.nodeIds].sort((left, right) =>\n compareStrings(left, right),\n ),\n edgeIds: [...sets.edgeIds]\n .sort((left, right) => compareStrings(left, right))\n .map((id) => id as Edge[\"id\"]),\n });\n }\n return {\n byBranch: (branchId: BranchId): BranchProvenance =>\n frozen.get(branchId) ?? { nodeIds: [], edgeIds: [] },\n };\n}\n\n/**\n * Appends a branch's contribution of a CANONICAL node id (`role: \"node\"`) or a\n * SURVIVING edge id (`role: \"edge\"`), keeping its source.\n */\nfunction pushProvenance(\n records: ProvenanceRecord[],\n role: ProvenanceRecord[\"role\"],\n branchId: BranchId,\n canonicalId: string,\n canonicalKind: string,\n sourceId: string,\n): void {\n records.push({ role, canonicalId, canonicalKind, branchId, sourceId });\n}\n\n/**\n * Empty per-branch trust weights — the fallback when the caller supplies no\n * {@link MergeOptions.provenanceWeights}. With empty weights the\n * `\"provenanceWeighted\"` policy degrades to the stable branch order (its\n * documented tie-break), i.e. `\"lastWriteWins\"` semantics.\n */\nconst EMPTY_WEIGHTS: ProvenanceWeights = new Map<BranchId, number>();\n\n/**\n * The fully-resolved (pre-commit) merge plan: everything the commit applies plus\n * everything the report records. Separated from the commit so the commit body is\n * a thin, mechanical application of an already-decided plan.\n *\n * Exported so the commit path can be unit-tested in isolation (e.g. proving that a\n * canonical entity whose id is an already-committed base node UPDATES that row and\n * repoints edges onto it, rather than inserting a duplicate — §6.2).\n */\nexport type MergePlan<G extends GraphDef> = Readonly<{\n canonicalEntities: readonly CanonicalEntity[];\n survivingModifications: readonly StagedModifiedNode[];\n nodeDeletions: ReadonlyMap<MergeKey, string>;\n edgeDeletions: ReadonlyMap<MergeKey, string>;\n mergedEdges: readonly MergedEdge[];\n // Base props of every inherited edge a fork MODIFIED, keyed by edge id. The\n // commit drops props a fork removed (a base key absent from the merged edge's\n // props) via {@link commitModificationProps} — edges, like nodes, are written\n // with PATCH semantics, so a removed key would otherwise survive. New edges\n // (never inherited) are absent from this map and need no deletion handling.\n inheritedEdgeBaseProps: ReadonlyMap<\n EdgeId,\n Readonly<Record<string, unknown>>\n >;\n retypeMap: ReadonlyMap<MergeKey, string>;\n resolutions: readonly EntityResolution[];\n propertyConflicts: readonly PropertyConflict<G>[];\n deleteModifyConflicts: readonly DeleteModifyConflict[];\n typeReconciliations: readonly TypeReconciliation[];\n dropped: readonly DroppedItem[];\n baseAmbiguities: readonly BaseAmbiguity[];\n provenanceRecords: readonly ProvenanceRecord[];\n warnings: readonly string[];\n}>;\n\n/**\n * Resolves the entire merge into a {@link MergePlan} WITHOUT touching the target.\n * Pure composition of the T3–T10 phases over the staged union; every step is\n * order-independent given the captured `branchRank`.\n */\nfunction planMerge<G extends GraphDef>(\n staging: StagingSet,\n candidateEdges: readonly CandidateEdge[],\n candidateWarnings: readonly string[],\n baseMembers: readonly BaseMember[],\n options: NormalizedMergeOptions<G>,\n branchRank: ReadonlyMap<BranchId, number>,\n subClassClosure: ReturnType<typeof buildSubClassClosure>,\n preferredBranchId?: BranchId,\n): MergePlan<G> {\n const provenanceRecords: ProvenanceRecord[] = [];\n // Per-branch trust weights for the `\"provenanceWeighted\"` policy, or empty when\n // the caller supplied none (then the policy falls back to the stable branch order).\n const weights = options.provenanceWeights ?? EMPTY_WEIGHTS;\n const recordProvenance = (\n role: ProvenanceRecord[\"role\"],\n branchId: BranchId,\n canonicalId: string,\n canonicalKind: string,\n sourceId: string,\n ): void => {\n if (branchId === preferredBranchId) {\n return;\n }\n pushProvenance(\n provenanceRecords,\n role,\n branchId,\n canonicalId,\n canonicalKind,\n sourceId,\n );\n };\n\n // (4) cluster over every staged new-node id + every base member id (so a forced\n // new↔base edge is not dropped as out-of-scope, clustering.ts:134) + the\n // candidate edges. Base members come only from base sources, so this set is\n // exactly the staged universe under the public snapshot path.\n const newNodesById = indexNewNodesById(staging);\n // A base member only belongs in the cluster universe if it actually PARTICIPATES:\n // it got an ACCEPTED candidate edge to a staged node (a forced `baseUnique` edge, or a\n // `baseKey`/fuzzy pair that cleared the threshold), or it shares a key with a staged\n // node (a same-(kind, id) rediscovery, which joins by key without an edge). A `baseKey`\n // hit whose fuzzy pair was REJECTED below threshold would otherwise be seeded as a\n // singleton cluster and re-committed — rewriting an unrelated committed row, inflating\n // `merged.nodes`, and recording spurious provenance under the base sentinel. Drop those\n // orphans here, now that scoring has decided which pairs survived.\n const acceptedEndpointKeys = new Set<MergeKey>();\n for (const edge of candidateEdges) {\n acceptedEndpointKeys.add(edge.a);\n acceptedEndpointKeys.add(edge.b);\n }\n const baseMembersById = new Map<MergeKey, BaseMember>();\n for (const member of baseMembers) {\n const key = mergeKeyOf(member);\n if (acceptedEndpointKeys.has(key) || newNodesById.has(key)) {\n baseMembersById.set(key, member);\n }\n }\n const newNodeIds = [...newNodesById.keys(), ...baseMembersById.keys()];\n\n // (3b) ONTOLOGY RETYPE edges (T10 input): identity stays strictly `(kind, id)`, but\n // under `reconcileTypes: \"ontology\"` two STAGED-new nodes sharing a bare id with\n // subtype-compatible kinds are the same entity at a refined type, so they are forced\n // into one cluster for the reconciler to collapse. Same most-specific-common-kind\n // test the reconciler uses (so a set fuses here iff it would collapse later);\n // staged-only (base members excluded — a committed-base retype is an inherited\n // mutation v1 refuses); `\"off\"` emits nothing, leaving identity strictly `(kind,id)`.\n const isOntology = options.reconcileTypes === \"ontology\";\n const preferKind =\n isOntology ?\n (kinds: readonly string[]): string | undefined =>\n mostSpecificCommonKind(subClassClosure, kinds)\n : undefined;\n const clusterEdges =\n isOntology ?\n [\n ...candidateEdges,\n ...ontologyRetypeEdges(\n newNodesById.keys(),\n (kinds) =>\n mostSpecificCommonKind(subClassClosure, kinds) !== undefined,\n ),\n ]\n : candidateEdges;\n\n // (4) component-level BASE GUARD (§6.4-A) runs on the RAW components, BEFORE the\n // diameter split — so a diameter guard can never sever a base↔base bridge into\n // single-base pieces and leave the ambiguity unreported. The committed entities are\n // always kept separate (the collapse is refused; a deliberate collapse is deferred,\n // §6.4-C), then the optional diameter guard splits the base-contained clusters.\n const baseIds = new Set<MergeKey>(baseMembersById.keys());\n const guard = enforceBaseGuard(\n connectedComponents(clusterEdges, newNodeIds),\n clusterEdges,\n baseIds,\n );\n const clusters =\n options.clusterMaxDiameter === undefined ?\n guard.clusters\n : enforceDiameter(guard.clusters, clusterEdges, options.clusterMaxDiameter);\n // The guard keys on composite `(kind, id)` identities; the public BaseAmbiguity\n // carries them in full, so a component spanning two same-id/different-kind committed\n // entities stays distinguishable in the report.\n const baseAmbiguities: BaseAmbiguity[] = guard.events.map((event) => ({\n baseIds: event.baseIds.map((key) => ({ kind: kindOf(key), id: idOf(key) })),\n memberIds: event.memberIds.map((key) => ({\n kind: kindOf(key),\n id: idOf(key),\n })),\n }));\n\n // (5) canonicalize each cluster: min-id survivor + commutative prop union.\n const canonicalEntities: CanonicalEntity[] = [];\n const resolutions: EntityResolution[] = [];\n const propertyConflicts: PropertyConflict<G>[] = [];\n // (7-input) the distinct member kinds per cluster, collected here so a committed\n // BASE member's kind is part of type reconciliation — a base↔staged kind divergence\n // (e.g. base `Doctor` vs staged `SpecialistDoctor`) must be reconciled/flagged, not\n // dropped because base members live outside `newNodesById`.\n const reconcileInputs: ReconcileClusterInput[] = [];\n for (const cluster of clusters) {\n const members = clusterMembersFor(cluster, newNodesById, baseMembersById);\n if (members.length === 0) {\n continue;\n }\n const entity = canonicalizeCluster(\n cluster,\n members,\n options.onPropertyConflict as PropertyConflictPolicy,\n branchRank,\n weights,\n options.canonical,\n options.onBasePropertyConflict as PropertyConflictPolicy,\n preferKind,\n preferredBranchId,\n );\n canonicalEntities.push(entity);\n reconcileInputs.push({\n canonicalId: mergeKey(entity.kind, entity.canonicalId),\n memberKinds: members.map((member) => member.kind),\n });\n // An EntityResolution records an actual MERGE — two or more distinct fork node\n // IDS collapsing into one canonical. Counted by distinct BARE id (not composite\n // identity): an ontology-retype cluster is several `(kind, id)` identities at ONE\n // id, which is a type reconciliation (recorded separately), not an id merge. A\n // singleton cluster records no resolution.\n const distinctMergedIds = new Set(\n cluster.members.map((member) => idOf(member)),\n );\n if (distinctMergedIds.size > 1) {\n resolutions.push(entity.resolution);\n }\n // Conflicts are recorded REGARDLESS of distinct-id count: two branches can\n // stage a new node under the SAME id with differing props, producing a genuine\n // cross-branch conflict inside a single-id cluster. `entity.conflicts` is\n // already gated by `resolved.conflicted`, so an agreeing single-member cluster\n // contributes none — but a real disagreement must not be silently auto-resolved\n // without a report entry.\n for (const conflict of entity.conflicts) {\n propertyConflicts.push(conflict as PropertyConflict<G>);\n }\n for (const member of members) {\n recordProvenance(\n \"node\",\n member.branchId,\n entity.canonicalId,\n entity.kind,\n member.id,\n );\n }\n }\n\n // (6) delete/modify resolution → authoritative final endpoint liveness.\n const deleteModify = resolveDeleteModify(\n staging,\n options.onDeleteModifyConflict,\n branchRank,\n preferredBranchId,\n );\n const nodeDeletions = new Map<MergeKey, string>();\n for (const deletion of deleteModify.nodeDeletions) {\n nodeDeletions.set(mergeKey(deletion.kind, deletion.id), deletion.kind);\n }\n for (const modification of deleteModify.survivingModifications) {\n recordProvenance(\n \"node\",\n modification.branchId,\n modification.node.id,\n modification.node.kind,\n modification.node.id,\n );\n }\n\n // Reconcile inherited nodes modified by 2+ branches into one merged record per\n // id (3-way against base), surfacing genuine disagreements as PropertyConflicts\n // instead of silently letting the last-committed branch win. Provenance above\n // already credited every contributing branch.\n const reconciledModifications = reconcileModifications(\n deleteModify.survivingModifications,\n options.onPropertyConflict as PropertyConflictPolicy,\n branchRank,\n weights,\n preferredBranchId,\n );\n for (const conflict of reconciledModifications.conflicts) {\n propertyConflicts.push(conflict as PropertyConflict<G>);\n }\n\n // (6-edge) the EDGE analogue of node delete/modify + reconcile. Inherited edge\n // deletions are applied (previously staged but never committed, so the edge\n // stayed live), and edges modified by 2+ branches are 3-way merged against base\n // so disjoint edits do not false-conflict (previously each branch's full fork\n // props were unioned, dropping a branch's independent edit). Provenance credits\n // every modifying branch (mirrors the node push), before reconcile collapses\n // them to one record per id.\n const edgeDeleteModify = resolveEdgeDeleteModify(\n staging,\n options.onDeleteModifyConflict,\n branchRank,\n preferredBranchId,\n );\n const edgeDeletions = new Map<MergeKey, string>();\n for (const deletion of edgeDeleteModify.edgeDeletions) {\n edgeDeletions.set(mergeKey(deletion.kind, deletion.id), deletion.kind);\n }\n for (const modification of edgeDeleteModify.survivingModifications) {\n recordProvenance(\n \"edge\",\n modification.branchId,\n modification.edge.id,\n modification.edge.kind,\n modification.edge.id,\n );\n }\n const reconciledEdgeModifications = reconcileEdgeModifications(\n edgeDeleteModify.survivingModifications,\n options.onPropertyConflict as PropertyConflictPolicy,\n branchRank,\n weights,\n preferredBranchId,\n );\n for (const conflict of reconciledEdgeModifications.conflicts) {\n propertyConflicts.push(conflict as PropertyConflict<G>);\n }\n\n // (7) opt-in ontology type reconciliation over the public-closure glue. Inputs\n // (incl. base member kinds) were collected per cluster in the canonicalize loop.\n const reconciliation = reconcileTypes(\n reconcileInputs,\n subClassClosure,\n options.reconcileTypes,\n );\n\n // (8) repoint every staged edge onto its cluster canonical + dedupe. Index the\n // canonical entities by their `(kind, id)` ONCE so the per-cluster survivor\n // lookup is O(1) — a linear scan per cluster would make the map build\n // O(clusters × entities), quadratic over the merged-node universe.\n const entityByIdentity = new Map<MergeKey, CanonicalEntity>();\n for (const entity of canonicalEntities) {\n entityByIdentity.set(mergeKey(entity.kind, entity.canonicalId), entity);\n }\n const canonicalOf = buildCanonicalMap(clusters, (cluster) =>\n pickClusterCanonical(cluster, entityByIdentity),\n );\n const stagedEdges = buildStagedEdges(\n staging,\n reconciledEdgeModifications.survivingModifications,\n );\n // An edge id can be staged by MORE THAN ONE branch (e.g. an inherited edge\n // modified by two branches), so map each id to the SET of contributing branches.\n // A plain last-write Map would credit only one branch's provenance.\n const stagedEdgeBranches = new Map<string, Set<BranchId>>();\n for (const staged of stagedEdges) {\n const branches = stagedEdgeBranches.get(staged.id);\n if (branches === undefined) {\n stagedEdgeBranches.set(staged.id, new Set([staged.branchId]));\n } else {\n branches.add(staged.branchId);\n }\n }\n const deletedNodeIdSet = new Set<MergeKey>(nodeDeletions.keys());\n const repoint = repointEdges<G>(\n stagedEdges,\n canonicalOf,\n deletedNodeIdSet,\n options.onPropertyConflict,\n branchRank,\n weights,\n preferredBranchId,\n );\n for (const merged of repoint.edges) {\n for (const sourceId of merged.mergedIds) {\n for (const branchId of stagedEdgeBranches.get(sourceId) ?? []) {\n recordProvenance(\"edge\", branchId, merged.id, merged.kind, sourceId);\n }\n }\n }\n\n const dropped: DroppedItem[] = [\n ...deleteModify.dropped,\n ...edgeDeleteModify.dropped,\n ...repoint.dropped,\n ...reconciliation.dropped,\n ].sort((left, right) =>\n compareStrings(`${left.kind}|${left.id}`, `${right.kind}|${right.id}`),\n );\n\n return {\n canonicalEntities,\n survivingModifications: reconciledModifications.survivingModifications,\n nodeDeletions,\n edgeDeletions,\n mergedEdges: repoint.edges,\n inheritedEdgeBaseProps: new Map(\n reconciledEdgeModifications.survivingModifications.map((modification) => [\n modification.edge.id,\n modification.edge.baseProps,\n ]),\n ),\n retypeMap: reconciliation.retypeMap,\n // Order report arrays by the composite (kind, id) identity — never a bare id\n // or a `|`-joined string. A bare id ties two different-kind entities that\n // share an id, and a `|` separator collides on caller-supplied ids/property\n // names that contain `|`; either makes the comparator non-total, so the\n // returned order would depend on stable-sort + insertion order and break the\n // order-independence the whole subsystem guarantees.\n resolutions: resolutions.sort((left, right) =>\n compareMergeKeys(\n mergeKey(left.kind, left.canonicalId),\n mergeKey(right.kind, right.canonicalId),\n ),\n ),\n propertyConflicts: [...propertyConflicts, ...repoint.conflicts].sort(\n (left, right) => {\n const byEntity = compareMergeKeys(\n mergeKey(left.kind, left.entityId),\n mergeKey(right.kind, right.entityId),\n );\n return byEntity === 0 ?\n compareStrings(left.property, right.property)\n : byEntity;\n },\n ),\n deleteModifyConflicts: [\n ...deleteModify.conflicts,\n ...edgeDeleteModify.conflicts,\n ].sort((left, right) =>\n compareMergeKeys(\n mergeKey(left.kind, left.entityId),\n mergeKey(right.kind, right.entityId),\n ),\n ),\n typeReconciliations: reconciliation.reconciliations,\n dropped,\n baseAmbiguities: baseAmbiguities.sort((left, right) =>\n compareMergeKeys(\n mergeKey(\n requireDefined(left.baseIds[0]).kind,\n requireDefined(left.baseIds[0]).id,\n ),\n mergeKey(\n requireDefined(right.baseIds[0]).kind,\n requireDefined(right.baseIds[0]).id,\n ),\n ),\n ),\n provenanceRecords,\n warnings: candidateWarnings,\n };\n}\n\n/**\n * The canonical survivor identity of a cluster, taken DIRECTLY from its already-resolved\n * {@link CanonicalEntity} so edge repoint reuses the exact survivor `canonicalizeCluster`\n * chose (base-id-wins, the `options.canonical` hook, and the most-specific-kind pick all\n * already applied there). This is the SINGLE survivor-selection point: re-deriving it\n * here by a second rule could split the canonical between the node write and the edge\n * repoint, so this never re-runs the hook.\n *\n * Every non-empty cluster yields exactly one canonical entity whose `(kind, id)` is one\n * of its members (the survivor is always a cluster member), so the lookup always hits;\n * a miss is an internal invariant violation, not a fallback.\n *\n * `entityByIdentity` maps each canonical entity's `(kind, id)` → entity, built once by\n * the caller, so finding a cluster's survivor is O(cluster.members) rather than a scan\n * of every canonical entity.\n */\nfunction pickClusterCanonical(\n cluster: ClusterResult,\n entityByIdentity: ReadonlyMap<MergeKey, CanonicalEntity>,\n): MergeKey {\n for (const member of cluster.members) {\n if (entityByIdentity.has(member)) {\n return member;\n }\n }\n throw new MergeError(\n \"Internal invariant: cluster has no canonical entity in pickClusterCanonical.\",\n { details: { members: cluster.members.map((member) => idOf(member)) } },\n );\n}\n\n/**\n * Builds the prop bag to COMMIT for an inherited modification, HONORING property\n * deletions. A fork's `forkProps` is its full intended state, so a base property\n * ABSENT from it was removed by that fork. The commit upsert shallow-merges the\n * written props onto the existing (base) row, so a removed key would otherwise\n * survive; writing it as `undefined` makes the row write drop it (the props column\n * is JSON-serialized, which omits `undefined`), so the fork's deletion is applied\n * instead of being silently reverted to the base value.\n */\nfunction commitModificationProps(\n baseProps: Readonly<Record<string, unknown>>,\n forkProps: Readonly<Record<string, unknown>>,\n): Record<string, unknown> {\n const props: Record<string, unknown> = { ...forkProps };\n for (const key of Object.keys(baseProps)) {\n if (!(key in forkProps)) {\n props[key] = undefined;\n }\n }\n return props;\n}\n\n/**\n * Applies a resolved {@link MergePlan} through a transaction's collection API.\n * Shared by `commitPlan()` and the guarded `mergeIncremental()` commit path so\n * both modes execute the same resolved semantics.\n */\nasync function applyMergePlan<G extends GraphDef>(\n plan: MergePlan<G>,\n nodesApi: TxNodes,\n edgesApi: TxEdges,\n): Promise<Readonly<{ nodes: number; edges: number }>> {\n // Counted by composite `(kind, id)` identity, so two different-kind nodes that\n // share an id string each count once (and never collide in the dedupe set).\n const committedNodeIds = new Set<MergeKey>();\n\n // Identities written as canonical cluster entities, and the fork props of every\n // surviving inherited modification keyed by identity. On the new-vs-base path a\n // committed node can be BOTH a base-member cluster survivor AND an inherited\n // modification; without coordinating the two writes the canonical upsert (built\n // from the cluster union, which carries the OLDER base props) would clobber the\n // modification's fork edit. We therefore fold the fork props into the canonical\n // write and skip the standalone modification write for that identity.\n const canonicalIdentities = new Set<MergeKey>();\n for (const entity of plan.canonicalEntities) {\n canonicalIdentities.add(mergeKey(entity.kind, entity.canonicalId));\n }\n const survivingModProps = new Map<\n MergeKey,\n Readonly<{\n baseProps: Readonly<Record<string, unknown>>;\n forkProps: Readonly<Record<string, unknown>>;\n }>\n >();\n for (const modification of plan.survivingModifications) {\n survivingModProps.set(mergeKeyOf(modification.node), {\n baseProps: modification.node.baseProps,\n forkProps: modification.node.forkProps,\n });\n }\n\n // Surviving inherited modifications, skipping any node finally deleted OR folded\n // into a canonical cluster write below. Property deletions the fork made are\n // honored via {@link commitModificationProps}.\n for (const modification of plan.survivingModifications) {\n const identity = mergeKeyOf(modification.node);\n if (plan.nodeDeletions.has(identity) || canonicalIdentities.has(identity)) {\n continue;\n }\n const collection = nodeCollection(nodesApi, modification.node.kind);\n await collection.upsertByIdFromRecord(\n modification.node.id,\n commitModificationProps(\n modification.node.baseProps,\n modification.node.forkProps,\n ),\n );\n committedNodeIds.add(identity);\n }\n\n // New canonical cluster nodes (survivors), with retype cascade. When the survivor\n // is also an inherited modification, merge the fork edit's props ON TOP of the\n // cluster union so the explicit fork edit is not lost to the (older) base props\n // the union carried.\n for (const entity of plan.canonicalEntities) {\n const identity = mergeKey(entity.kind, entity.canonicalId);\n if (plan.nodeDeletions.has(identity)) {\n continue;\n }\n const kind = plan.retypeMap.get(identity) ?? entity.kind;\n const modification = survivingModProps.get(identity);\n // Fold the fork edit ON TOP of the cluster union, honoring the fork's property\n // deletions (which surface as `undefined` and so override the union's value).\n const props =\n modification === undefined ?\n entity.props\n : {\n ...entity.props,\n ...commitModificationProps(\n modification.baseProps,\n modification.forkProps,\n ),\n };\n const collection = nodeCollection(nodesApi, kind);\n await collection.upsertByIdFromRecord(entity.canonicalId, props);\n committedNodeIds.add(mergeKey(kind, entity.canonicalId));\n }\n\n // Soft-delete every finally-deleted node (key encodes the kind; the value repeats\n // it for the collection lookup).\n for (const [identity, kind] of plan.nodeDeletions) {\n const collection = nodeCollection(nodesApi, kind);\n await collection.delete(idOf(identity));\n }\n\n // Soft-delete every finally-deleted inherited edge. These ids are disjoint from\n // the merged-edge upserts below (deleted edges are not staged), so order is\n // immaterial. Without this an inherited edge deleted in a branch stayed live.\n for (const [identity, kind] of plan.edgeDeletions) {\n await edgeCollection(edgesApi, kind).delete(idOf(identity));\n }\n\n // Repointed + deduped edges, grouped by kind so each kind is one batched\n // round-trip (upsert-by-id is order-independent). The retype cascade keys on\n // each endpoint's full `(kind, id)` identity.\n const edgesByKind = new Map<string, EdgeUpsert[]>();\n for (const edge of plan.mergedEdges) {\n const fromKind = plan.retypeMap.get(mergeKey(edge.fromKind, edge.fromId));\n const toKind = plan.retypeMap.get(mergeKey(edge.toKind, edge.toId));\n // Honor a fork's property deletion on an inherited edge: drop base keys absent\n // from the merged props (the edge upsert PATCH-merges, so a removed key would\n // otherwise survive). New edges have no base entry, so their props pass through.\n const edgeBaseProps = plan.inheritedEdgeBaseProps.get(edge.id);\n const props =\n edgeBaseProps === undefined ?\n edge.props\n : commitModificationProps(edgeBaseProps, edge.props);\n const item: EdgeUpsert = {\n id: edge.id,\n from: { kind: fromKind ?? edge.fromKind, id: edge.fromId },\n to: { kind: toKind ?? edge.toKind, id: edge.toId },\n props,\n };\n const existing = edgesByKind.get(edge.kind);\n if (existing === undefined) {\n edgesByKind.set(edge.kind, [item]);\n } else {\n existing.push(item);\n }\n }\n let committedEdges = 0;\n for (const [kind, items] of edgesByKind) {\n await edgeCollection(edgesApi, kind).bulkUpsertById(items);\n committedEdges += items.length;\n }\n\n return { nodes: committedNodeIds.size, edges: committedEdges };\n}\n\n/**\n * Applies a resolved {@link MergePlan} to the target via the typed transaction\n * collection API. Surviving inherited modifications are upserted by id, canonical\n * cluster nodes are upserted by id with their unioned + (optionally) retyped\n * props, finally-deleted nodes are soft-deleted, and repointed/deduped edges are\n * upserted by id. Returns the merged node / edge counts.\n *\n * UPDATE-NOT-INSERT (§6.2): every node write is an `upsertById`, so a canonical\n * entity whose id is an ALREADY-COMMITTED base node UPDATES that committed row in\n * place — the committed identity is stable and every edge repointed onto it (the\n * merged edges already carry the canonical endpoint) attaches to the surviving\n * row, never a duplicate insert. This is what lets a base member be the canonical\n * survivor once base sources land. Exported for isolated commit-path testing.\n *\n * COALESCE INTERACTION: when the target store was created with\n * `coalesceUnchangedUpserts`, a canonical/inherited upsert whose props already\n * equal the committed row is skipped (no write, no recorded row). This is sound\n * for merge and needs no bypass: the base@V guard runs BEFORE any upsert\n * (see {@link assertTargetUnchanged}), conflicts are resolved at plan time, and\n * an upsert-by-id never rewrites endpoints — so coalescing only elides writes\n * that would persist a byte-identical value, leaving the merged state\n * identical. It merely declines to re-stamp recorded time on rows the merge did\n * not actually change, which is exactly the option's intent.\n */\nexport async function commitPlan<G extends GraphDef>(\n target: Store<G>,\n plan: MergePlan<G>,\n expectedBaseVersion?: BaseVersion,\n): Promise<Readonly<{ nodes: number; edges: number }>> {\n if (!storeBackend(target).capabilities.transactions) {\n throw new MergeError(\n \"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.)\",\n { details: { capability: \"transactions\" } },\n );\n }\n return withTxConflictRetry(() =>\n target.transaction(async (tx) => {\n // TOCTOU guard: the plan was resolved from reads taken OUTSIDE this\n // transaction, so the target may have been written between the base@V\n // precondition and this commit. Revision-anchored stores check their\n // durable clock under the graph write lock; legacy stores re-derive the\n // content fingerprint through this transaction's snapshot. Either proof\n // ensures the plan still describes the live target before committing.\n if (expectedBaseVersion !== undefined) {\n await assertTargetUnchanged(\n transactionBackend(tx),\n target,\n expectedBaseVersion,\n );\n }\n return applyMergePlan(\n plan,\n tx.nodes as unknown as TxNodes,\n tx.edges as unknown as TxEdges,\n );\n }, mergeCommitTransactionOptions(target)),\n );\n}\n\n/**\n * Isolation for the merge commit transaction. SERIALIZABLE closes the window\n * between the in-transaction re-validation reads and COMMIT on multi-writer\n * Postgres (SSI aborts a racing writer with SQLSTATE 40001, which\n * {@link withTxConflictRetry} retries); SQLite and PGlite serialize writers by\n * construction, and the SQLite backend ignores the option.\n */\nconst MERGE_COMMIT_TX_OPTIONS = {\n isolationLevel: \"serializable\",\n} as const satisfies TransactionOptions;\n\nfunction mergeCommitTransactionOptions<G extends GraphDef>(\n target: Store<G>,\n): TransactionOptions | undefined {\n // Recorded-time capture only supports read-committed transactions because it\n // allocates its durable clock inside the write transaction. Revision-anchored\n // merges hold that same per-graph lock before checking the anchor, which\n // closes the TOCTOU gap without asking a history store for SERIALIZABLE.\n return target.historyEnabled ? undefined : MERGE_COMMIT_TX_OPTIONS;\n}\n\n/**\n * The in-transaction half of the base@V guard: revision-anchored targets read\n * their durable clock under the graph lock; legacy targets recompute their\n * content fingerprint through the transaction-scoped backend. The schema\n * component cannot drift because it is a pure function of the in-memory graph\n * definition.\n */\nasync function assertTargetUnchanged<G extends GraphDef>(\n txBackend: TransactionBackend,\n target: Store<G>,\n expectedBaseVersion: BaseVersion,\n): Promise<void> {\n if (hasRevisionAnchor(expectedBaseVersion)) {\n // All tracked writers acquire this lock before touching graph rows and\n // advance the same clock before committing. Holding it around the\n // read→apply sequence makes the O(1) anchor check a TOCTOU guard without\n // relying on the transaction's snapshot being the latest committed state.\n await lockRecordedGraphWrite(txBackend, target.graphId);\n const expectedOrigin = revisionOriginOf(expectedBaseVersion);\n const liveOrigin = await readRevisionOrigin(\n txBackend,\n target.revisionSchema,\n target.graphId,\n );\n if (liveOrigin !== expectedOrigin) {\n throw new BaseVersionMismatchError(\n \"The merge branch was forked from a different revision-tracked store; the resolved plan was not applied.\",\n {\n details: { expectedOrigin, liveOrigin },\n suggestion:\n \"Merge the branch back into its original base store, or fork a new branch from this target.\",\n },\n );\n }\n const liveRevision = await readRecordedClock(\n txBackend,\n target.revisionSchema,\n target.graphId,\n );\n const expectedRevision = revisionAnchorOf(expectedBaseVersion);\n if (liveRevision !== expectedRevision) {\n throw new BaseVersionMismatchError(\n \"The merge target was modified between the revision-anchor check and the commit transaction; the resolved plan was not applied.\",\n {\n details: { expectedRevision, liveRevision },\n suggestion:\n \"Re-run the merge (and re-branch if the divergence is real), or route all graph writes through the revision-tracked Store.\",\n },\n );\n }\n return;\n }\n const liveContent = await computeContentComponent(\n txBackend,\n target.graphId,\n target.graph,\n );\n const expectedContent = contentComponentOf(expectedBaseVersion);\n if (liveContent !== expectedContent) {\n throw new BaseVersionMismatchError(\n \"The merge target was modified between the base@V check and the commit transaction; the resolved plan no longer describes the live target and was not applied.\",\n {\n details: {\n expectedContentFingerprint: expectedContent,\n liveContentFingerprint: liveContent,\n },\n suggestion:\n \"Re-run the merge (and re-branch if the divergence is real), or serialize writers against merges on this target.\",\n },\n );\n }\n}\n\n/**\n * Runtime-keyed view of the transaction's node collections. The typed\n * `tx.nodes` is keyed by the graph's concrete kinds; the orchestrator dispatches\n * on kind STRINGS, so it indexes through this widened record. Each entry exposes\n * the subset of the collection API the commit uses.\n */\ntype TxNodes = Record<string, NodeCollectionLike>;\n\n/** Runtime-keyed view of the transaction's edge collections. See {@link TxNodes}. */\ntype TxEdges = Record<string, EdgeCollectionLike>;\n\n/** The node-collection surface the commit uses (runtime, kind-string keyed). */\ntype NodeCollectionLike = Readonly<{\n getById: (\n id: string,\n options?: Readonly<{ temporalMode?: \"includeTombstones\" }>,\n ) => Promise<Node | undefined>;\n getByIds: (\n ids: readonly string[],\n options?: Readonly<{ temporalMode?: \"includeTombstones\" }>,\n ) => Promise<readonly (Node | undefined)[]>;\n bulkCreate: (\n items: readonly Readonly<{\n id?: string;\n props: Record<string, unknown>;\n }>[],\n ) => Promise<unknown>;\n update: (id: string, props: Record<string, unknown>) => Promise<unknown>;\n upsertByIdFromRecord: (\n id: string,\n data: Record<string, unknown>,\n ) => Promise<unknown>;\n delete: (id: string) => Promise<void>;\n}>;\n\n/** The edge-collection surface the commit uses (runtime, kind-string keyed). */\ntype EdgeCollectionLike = Readonly<{\n getById: (\n id: string,\n options?: Readonly<{ temporalMode?: \"includeTombstones\" }>,\n ) => Promise<Edge | undefined>;\n getByIds: (\n ids: readonly string[],\n options?: Readonly<{ temporalMode?: \"includeTombstones\" }>,\n ) => Promise<readonly (Edge | undefined)[]>;\n bulkCreate: (\n items: readonly Readonly<{\n id?: string;\n from: Readonly<{ kind: string; id: string }>;\n to: Readonly<{ kind: string; id: string }>;\n props?: Record<string, unknown>;\n }>[],\n ) => Promise<unknown>;\n bulkUpsertById: (\n items: readonly Readonly<{\n id: string;\n from: Readonly<{ kind: string; id: string }>;\n to: Readonly<{ kind: string; id: string }>;\n props?: Record<string, unknown>;\n }>[],\n ) => Promise<unknown>;\n delete: (id: string) => Promise<void>;\n}>;\n\n/** A single edge upsert payload (the element of a {@link EdgeCollectionLike} batch). */\ntype EdgeUpsert = Parameters<EdgeCollectionLike[\"bulkUpsertById\"]>[0][number];\n\n/** Resolves a node collection by kind, failing loudly on an unknown kind. */\nfunction nodeCollection(nodes: TxNodes, kind: string): NodeCollectionLike {\n const collection = nodes[kind];\n if (collection === undefined) {\n throw new MergeError(`No node collection for kind \"${kind}\".`, {\n details: { kind },\n });\n }\n return collection;\n}\n\n/** Resolves an edge collection by kind, failing loudly on an unknown kind. */\nfunction edgeCollection(edges: TxEdges, kind: string): EdgeCollectionLike {\n const collection = edges[kind];\n if (collection === undefined) {\n throw new MergeError(`No edge collection for kind \"${kind}\".`, {\n details: { kind },\n });\n }\n return collection;\n}\n\n/**\n * Validates the `base@V` precondition: every branch's `base` token MUST equal the\n * target's current base version. A mismatch means the branch forked from a\n * divergent schema or base revision, which cannot be merged safely.\n */\nasync function validateBaseVersions<G extends GraphDef>(\n target: Store<G>,\n branches: readonly GraphBranch<G>[],\n): Promise<Result<BaseVersion, BaseVersionMismatchError>> {\n const targetVersion = await computeBaseVersion(target);\n for (const branch of branches) {\n if (branch.base !== targetVersion) {\n return err(\n new BaseVersionMismatchError(\n `Branch \"${branch.id}\" forked from base@V \"${branch.base}\", which does not match the merge target's current base@V \"${targetVersion}\".`,\n {\n details: {\n branchId: branch.id,\n branchBase: branch.base,\n targetBase: targetVersion,\n },\n },\n ),\n );\n }\n }\n return ok(targetVersion);\n}\n\n/** Normalizes options, converting an invalid-option throw into a typed result. */\nfunction tryNormalize<G extends GraphDef>(\n optionsInput: MergeOptions<G>,\n): Result<NormalizedMergeOptions<G>, MergeError> {\n try {\n return ok(normalizeMergeOptions(optionsInput));\n } catch (error) {\n return err(new MergeError(\"Invalid merge options.\", { cause: error }));\n }\n}\n\n/**\n * The shared resolve→commit→report pipeline behind both `merge()` (snapshot,\n * staged-vs-staged) and `mergeAgainstBase()` (synthetic new-vs-base). It stages the\n * union of branch diffs, generates candidates (with or without the base sources per\n * `useBaseSources`), resolves the plan, commits, and assembles the report. The\n * `base@V` precondition is the CALLER's responsibility — `merge()` enforces it,\n * the synthetic scope deliberately bypasses it (§6.4-B).\n */\nasync function resolveMerge<G extends GraphDef>(\n store: Store<G>,\n target: Store<G>,\n branches: readonly GraphBranch<G>[],\n options: NormalizedMergeOptions<G>,\n useBaseSources: boolean,\n incremental?: IncrementalConfig,\n expectedBaseVersion?: BaseVersion,\n): Promise<Result<MergeReport<G>, MergeError>> {\n // Reserved BranchIds are used for non-user contributions. Reject real branches\n // that try to mint them rather than silently corrupting conflict/provenance state.\n let targetBranchSeen = false;\n for (const branch of branches) {\n if (branch.id === BASE_PROVENANCE_BRANCH) {\n return err(\n new MergeError(\n `Branch id \"${BASE_PROVENANCE_BRANCH}\" is reserved for committed-base provenance and cannot be used as a branch id.`,\n { details: { branchId: branch.id } },\n ),\n );\n }\n if (branch.id === COMMITTED_TARGET_BRANCH) {\n if (\n incremental?.targetBranchId !== COMMITTED_TARGET_BRANCH ||\n targetBranchSeen\n ) {\n return err(\n new MergeError(\n `Branch id \"${COMMITTED_TARGET_BRANCH}\" is reserved for the committed incremental target and cannot be used as a branch id.`,\n { details: { branchId: branch.id } },\n ),\n );\n }\n targetBranchSeen = true;\n }\n }\n\n try {\n // (2) stage the provenance-tagged union of every branch's diff. For the\n // incremental path, capture the committed target branch's node versions from\n // its diff enumeration — the plan-time baseline for the commit-time\n // lost-update guard (assertInheritedTargetUnchanged).\n const preferredBranchId = incremental?.targetBranchId;\n const staging = await stageBranches(store, branches, preferredBranchId);\n\n // Capture the stable branch order ONCE (never wall-clock).\n const branchIds = branches.map((branch) => branch.id);\n const branchOrder =\n preferredBranchId === undefined ?\n (options.branchOrder ?? [])\n : [\n preferredBranchId,\n ...(options.branchOrder ?? []).filter(\n (branchId) => branchId !== preferredBranchId,\n ),\n ];\n const branchRank = buildBranchRank(branchOrder, branchIds);\n\n // Introspection snapshot: unique constraints for blocking + ontology closure.\n const introspection = store.introspect();\n const introspectionKinds = new Map<\n string,\n readonly UniqueIntrospection[]\n >();\n for (const kind of introspection.kinds) {\n introspectionKinds.set(kind.name, kind.unique);\n }\n const subClassClosure = buildSubClassClosure(introspection.ontology);\n\n // (3) candidate generation across every resolved kind. When an embedder is\n // configured, precompute the STAGED texts' vectors ONCE (a batched step) so\n // the per-pair `vector`/`hybrid` scoring is a pure in-memory cosine; base-node\n // texts pulled into staged↔base pairs are embedded inside generateAllCandidates\n // (they are not known until the base sources run). With no embedder,\n // `embeddings` stays absent and a vector/hybrid kind surfaces\n // SimilarityUnavailableError in candidate generation.\n const embeddings =\n options.embedder === undefined ?\n undefined\n : await precomputeEmbeddings(\n newNodesByKind(staging),\n options.resolve,\n options.embedder,\n );\n const ctx: SimilarityContext = {\n backend: storeBackend(store),\n ...(embeddings === undefined ? {} : { embeddings }),\n };\n const candidates = await generateAllCandidates(\n target,\n staging,\n options,\n introspectionKinds,\n ctx,\n useBaseSources,\n options.embedder,\n );\n if (isErr(candidates)) {\n return err(candidates.error);\n }\n\n // (4–8) resolve the whole merge into a commit-ready plan.\n const plan = planMerge(\n staging,\n candidates.data.edges,\n candidates.data.warnings,\n candidates.data.baseMembers,\n options,\n branchRank,\n subClassClosure,\n preferredBranchId,\n );\n\n // (9) commit to the target. Incremental mode commits through the guarded path\n // (the existing-target-id write guard, §6.6); snapshot mode commits directly,\n // re-validating the captured base@V inside the transaction (TOCTOU guard).\n const merged =\n incremental === undefined ?\n await commitPlan(target, plan, expectedBaseVersion)\n : await commitIncrementalPlan(target, plan, {\n stagedNewByKind: newNodesByKind(staging),\n options,\n introspectionKinds,\n // The committed (kind, id) keys the base sources matched at PLAN time;\n // anything NEW the in-tx re-probe surfaces is a window write.\n plannedBaseMatchKeys: new Set(\n candidates.data.baseMembers.map((member) => mergeKeyOf(member)),\n ),\n targetNodeVersions: staging.targetNodeVersions,\n targetEdgeSignatures: staging.targetEdgeSignatures,\n });\n\n // (10) assemble the report. The full provenance records are always built in the\n // plan; the in-memory index is gated by `provenance`, and on-graph persistence\n // by `persistProvenance`.\n const provenance: ProvenanceIndex =\n options.provenance ?\n buildProvenanceIndex(plan.provenanceRecords)\n : { byBranch: () => ({ nodeIds: [], edgeIds: [] }) };\n\n const warnings = [...plan.warnings];\n let provenancePersisted: MergeReport<G>[\"provenancePersisted\"];\n if (options.persistProvenance) {\n // POST-COMMIT, best-effort: the graph is already committed, so a provenance\n // write failure must NOT fail the merge — it surfaces as a warning. The\n // sidecar node ids are deterministic, so this UPSERTS (idempotent re-runs).\n try {\n const provenanceStore = await openProvenanceStore(\n storeBackend(target),\n target.graphId,\n );\n const count = await persistProvenanceRecords(\n provenanceStore,\n target.graphId,\n plan.provenanceRecords,\n );\n provenancePersisted = {\n graphId: provenanceGraphId(target.graphId),\n count,\n };\n } catch (error) {\n warnings.push(\n \"provenance persistence failed (graph committed; provenance not persisted): \" +\n (error instanceof Error ? error.message : String(error)),\n );\n }\n }\n\n const report: MergeReport<G> = {\n merged,\n resolutions: plan.resolutions,\n conflicts: plan.propertyConflicts,\n deleteModifyConflicts: plan.deleteModifyConflicts,\n typeReconciliations: plan.typeReconciliations,\n dropped: plan.dropped,\n baseAmbiguities: plan.baseAmbiguities,\n provenance,\n warnings,\n ...(provenancePersisted === undefined ? {} : { provenancePersisted }),\n };\n return ok(report);\n } catch (error) {\n // A typed MergeError thrown deeper (e.g. the incremental guard's stale-overwrite\n // refusal) carries its own precise message — surface it directly rather than\n // masking it behind the generic wrapper, which is reserved for opaque failures\n // (a backend error, a malformed row).\n if (error instanceof MergeError) {\n return err(error);\n }\n return err(\n new MergeError(\n `Merge failed while staging or committing: ${describeCause(error)}`,\n { cause: error },\n ),\n );\n }\n}\n\n/**\n * Merges a set of branches back into a target store (design §7.2).\n *\n * Validates that every branch forked from the target's current `base@V`, stages\n * the union of their diffs, resolves entities / conflicts / types through the\n * T3–T10 phases, and commits the merged result to `target` (default: the base\n * `store`) in a single transaction. Returns a {@link MergeReport} on success.\n *\n * This is the SNAPSHOT entry point: candidate generation runs the staged sources\n * only (`exactKey`, `unique`) — it never resolves a staged node against the\n * committed base. New-vs-base resolution is the separate {@link mergeAgainstBase}\n * scope, which has a weaker `base@V` contract.\n *\n * Errors are RETURNED (never thrown) as a typed {@link MergeError} subclass:\n * `BaseVersionMismatchError` for the precondition, `MergeError` for a\n * comparison-ceiling overrun / commit failure, `SimilarityUnavailableError` for a\n * `vector`/`hybrid` strategy with no configured vector strategy.\n *\n * @param store The base store the branches forked from. Used as the default merge\n * target and as the immutable diff reference.\n * @param branches The branches to merge. ORDER DOES NOT AFFECT THE RESULT — the\n * report and committed graph are identical across any permutation.\n * @param optionsInput Caller-facing {@link MergeOptions}; normalized internally.\n */\nexport async function merge<G extends GraphDef>(\n store: Store<G>,\n branches: readonly GraphBranch<G>[],\n optionsInput: MergeOptions<G> = {},\n): Promise<Result<MergeReport<G>, MergeError>> {\n const normalized = tryNormalize(optionsInput);\n if (isErr(normalized)) {\n return err(normalized.error);\n }\n const options = normalized.data;\n const target = options.target ?? store;\n\n // (1) base@V precondition — the snapshot contract. The validated token is\n // re-checked INSIDE the commit transaction (see `commitPlan`), so a target\n // write landing between this check and the commit fails typed instead of\n // committing a stale plan.\n const precondition = await validateBaseVersions(target, branches);\n if (isErr(precondition)) {\n return err(precondition.error);\n }\n\n return resolveMerge(\n store,\n target,\n branches,\n options,\n false,\n undefined,\n precondition.data,\n );\n}\n\n/**\n * SYNTHETIC new-vs-base merge scope (design §8 \"Slice 1\"). Runs the full\n * candidate-source + scoring + reconciler pipeline WITH the base sources active —\n * so a staged node re-discovering a committed entity resolves against it\n * (base-id-wins, update-not-insert) — while DELIBERATELY bypassing the `base@V`\n * snapshot precondition (§6.4-B) rather than fighting it.\n *\n * This is the lower-level scope the slice's mechanism is built and exercised behind\n * (the fixed-point + determinism gates drive it directly), and it is intentionally\n * NOT re-exported from the package barrel. The public incremental surface over it\n * is {@link mergeIncremental} (§6.6), which adds the fork-point precondition, the\n * keep-base pin, and the transaction-scoped existing-row guard. `merge()` and its\n * snapshot precondition are unchanged.\n */\nexport async function mergeAgainstBase<G extends GraphDef>(\n store: Store<G>,\n branches: readonly GraphBranch<G>[],\n optionsInput: MergeOptions<G> = {},\n): Promise<Result<MergeReport<G>, MergeError>> {\n const normalized = tryNormalize(optionsInput);\n if (isErr(normalized)) {\n return err(normalized.error);\n }\n const options = normalized.data;\n const target = options.target ?? store;\n\n // No branch-level base@V precondition here (the synthetic scope's contract),\n // but PLAN STABILITY still holds: the token captured before any planning\n // read is re-validated inside the commit transaction, so the target must not\n // move while THIS merge is in flight.\n const expectedBaseVersion = await computeBaseVersion(target);\n return resolveMerge(\n store,\n target,\n branches,\n options,\n true,\n undefined,\n expectedBaseVersion,\n );\n}\n\n// --- mergeIncremental: full fork-point-vs-live-target entry point (§6.6) -------\n\n/** Internal config carried into {@link resolveMerge} for incremental mode. */\ntype IncrementalConfig = Readonly<{\n targetBranchId: BranchId;\n}>;\n\n/**\n * Incremental precondition: every branch must have forked from THIS fork-point, so\n * the fork-point diff (fork-point → branch) is honest. The analogue of\n * {@link validateBaseVersions}, repointed from `target` to `forkPoint` (§6.6).\n */\nasync function validateForkPointVersions<G extends GraphDef>(\n forkPoint: Store<G>,\n branches: readonly GraphBranch<G>[],\n): Promise<Result<BaseVersion, BaseVersionMismatchError>> {\n const forkVersion = await computeBaseVersion(forkPoint);\n for (const branch of branches) {\n if (branch.base !== forkVersion) {\n return err(\n new BaseVersionMismatchError(\n `Branch \"${branch.id}\" forked from base@V \"${branch.base}\", which does not match the fork-point's base@V \"${forkVersion}\". mergeIncremental() requires every branch to have forked from the supplied forkPoint.`,\n {\n details: {\n branchId: branch.id,\n branchBase: branch.base,\n forkPointBase: forkVersion,\n },\n },\n ),\n );\n }\n }\n return ok(forkVersion);\n}\n\n/**\n * The minimal schema surface the write guards need: a kind's Zod schema, called the\n * SAME way the commit calls it (`safeParse`). Structural so the guard couples to the\n * parse behaviour, not a zod version.\n */\ntype PropsSchema = Readonly<{\n safeParse: (\n value: unknown,\n ) => { success: true; data: unknown } | { success: false };\n}>;\n\ntype RevalidatingWriteAnalysis =\n | Readonly<{\n status: \"valid\";\n /** Whether TypeGraph's re-validating write would change persisted bytes. */\n storageWouldChange: boolean;\n /** Whether declared schema fields would change, ignoring unknown stored keys. */\n schemaWouldChange: boolean;\n /** Whether the write would drop current props not preserved by the schema. */\n stripsCurrentProps: boolean;\n }>\n | Readonly<{ status: \"invalid\" }>;\n\n/** The declared schema for a node kind off the public `GraphDef` registry (or none). */\nfunction nodeSchemaFor<G extends GraphDef>(\n target: Store<G>,\n kind: string,\n): PropsSchema | undefined {\n const registry = target.graph.nodes as Record<\n string,\n Readonly<{ type?: Readonly<{ schema?: PropsSchema }> }> | undefined\n >;\n return registry[kind]?.type?.schema;\n}\n\n/** The declared schema for an edge kind off the public `GraphDef` registry (or none). */\nfunction edgeSchemaFor<G extends GraphDef>(\n target: Store<G>,\n kind: string,\n): PropsSchema | undefined {\n const registry = target.graph.edges as Record<\n string,\n Readonly<{ type?: Readonly<{ schema?: PropsSchema }> }> | undefined\n >;\n return registry[kind]?.type?.schema;\n}\n\n/**\n * Models TypeGraph's re-validating update semantics for one row:\n * `schema.safeParse({...current, ...planned})`, then storing the parsed result. This\n * is NOT used as a pre-transaction write guard anymore; `mergeIncremental()` calls it\n * inside the target transaction to decide between create/update/skip/error.\n */\nfunction analyzeRevalidatingWrite(\n schema: PropsSchema | undefined,\n current: Readonly<Record<string, unknown>>,\n planned: Readonly<Record<string, unknown>>,\n): RevalidatingWriteAnalysis {\n const merged = { ...current, ...planned };\n if (schema === undefined) {\n const storageWouldChange =\n canonicalizeProps(merged) !== canonicalizeProps(current);\n return {\n status: \"valid\",\n storageWouldChange,\n schemaWouldChange: storageWouldChange,\n stripsCurrentProps: false,\n };\n }\n\n const currentParsed = schema.safeParse(current);\n const mergedParsed = schema.safeParse(merged);\n if (!currentParsed.success || !mergedParsed.success) {\n return { status: \"invalid\" };\n }\n const normalizedCurrent = currentParsed.data as Record<string, unknown>;\n const normalizedMerged = mergedParsed.data as Record<string, unknown>;\n return {\n status: \"valid\",\n storageWouldChange:\n canonicalizeProps(normalizedMerged) !== canonicalizeProps(current),\n schemaWouldChange:\n canonicalizeProps(normalizedMerged) !==\n canonicalizeProps(normalizedCurrent),\n stripsCurrentProps:\n canonicalizeProps(normalizedCurrent) !== canonicalizeProps(current),\n };\n}\n\nexport function writeWouldChangeRow(\n schema: PropsSchema | undefined,\n committed: Readonly<Record<string, unknown>>,\n planned: Readonly<Record<string, unknown>>,\n): boolean {\n const analysis = analyzeRevalidatingWrite(schema, committed, planned);\n return analysis.status === \"valid\" ? analysis.storageWouldChange : false;\n}\n\n/**\n * Public node objects spread props at top-level. Strip TypeGraph structural keys so\n * write comparisons operate on the persisted props bag only.\n */\nfunction nodeProps(node: Node): Record<string, unknown> {\n const props: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(node)) {\n if (key === \"id\" || key === \"kind\" || key === \"meta\") continue;\n props[key] = value;\n }\n return props;\n}\n\n/**\n * Public edge objects spread props at top-level. Strip TypeGraph structural keys so\n * write comparisons operate on the persisted props bag only.\n */\nfunction edgeProps(edge: Edge): Record<string, unknown> {\n const props: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(edge)) {\n if (\n key === \"id\" ||\n key === \"kind\" ||\n key === \"fromKind\" ||\n key === \"fromId\" ||\n key === \"toKind\" ||\n key === \"toId\" ||\n key === \"meta\"\n ) {\n continue;\n }\n props[key] = value;\n }\n return props;\n}\n\nconst INCLUDE_TOMBSTONES = { temporalMode: \"includeTombstones\" as const };\n\nfunction finalEdgeFrom<G extends GraphDef>(\n edge: MergedEdge,\n plan: MergePlan<G>,\n) {\n return {\n kind:\n plan.retypeMap.get(mergeKey(edge.fromKind, edge.fromId)) ?? edge.fromKind,\n id: edge.fromId,\n };\n}\n\nfunction finalEdgeTo<G extends GraphDef>(edge: MergedEdge, plan: MergePlan<G>) {\n return {\n kind: plan.retypeMap.get(mergeKey(edge.toKind, edge.toId)) ?? edge.toKind,\n id: edge.toId,\n };\n}\n\nfunction assertValidRevalidatingWrite(\n analysis: RevalidatingWriteAnalysis,\n message: string,\n details: Record<string, unknown>,\n): asserts analysis is Extract<RevalidatingWriteAnalysis, { status: \"valid\" }> {\n if (analysis.status === \"invalid\") {\n throw new MergeError(message, { details });\n }\n}\n\nfunction describeCause(cause: unknown): string {\n return cause instanceof Error ? cause.message : String(cause);\n}\n\ntype PlannedNodeWrite = Readonly<{\n identity: MergeKey;\n kind: string;\n id: AnyNodeId;\n props: Readonly<Record<string, unknown>>;\n}>;\n\nfunction plannedNodeWrites<G extends GraphDef>(\n plan: MergePlan<G>,\n): readonly PlannedNodeWrite[] {\n const canonicalIdentities = new Set<MergeKey>();\n for (const entity of plan.canonicalEntities) {\n canonicalIdentities.add(mergeKey(entity.kind, entity.canonicalId));\n }\n const survivingModProps = new Map<\n MergeKey,\n Readonly<Record<string, unknown>>\n >();\n for (const modification of plan.survivingModifications) {\n survivingModProps.set(\n mergeKeyOf(modification.node),\n modification.node.forkProps,\n );\n }\n\n const writes: PlannedNodeWrite[] = [];\n for (const modification of plan.survivingModifications) {\n const identity = mergeKeyOf(modification.node);\n if (plan.nodeDeletions.has(identity) || canonicalIdentities.has(identity)) {\n continue;\n }\n writes.push({\n identity,\n kind: modification.node.kind,\n id: modification.node.id,\n props: modification.node.forkProps,\n });\n }\n for (const entity of plan.canonicalEntities) {\n const sourceIdentity = mergeKey(entity.kind, entity.canonicalId);\n if (plan.nodeDeletions.has(sourceIdentity)) {\n continue;\n }\n const kind = plan.retypeMap.get(sourceIdentity) ?? entity.kind;\n const forkProps = survivingModProps.get(sourceIdentity);\n writes.push({\n identity: mergeKey(kind, entity.canonicalId),\n kind,\n id: entity.canonicalId,\n props:\n forkProps === undefined ?\n entity.props\n : { ...entity.props, ...forkProps },\n });\n }\n return writes;\n}\n\nfunction edgeWriteSignature<G extends GraphDef>(\n edge: MergedEdge,\n plan: MergePlan<G>,\n): string {\n const from = finalEdgeFrom(edge, plan);\n const to = finalEdgeTo(edge, plan);\n return JSON.stringify([\n edge.kind,\n from.kind,\n from.id,\n to.kind,\n to.id,\n canonicalizeProps(edge.props),\n ]);\n}\n\nasync function validateIncrementalNodeWrites<G extends GraphDef>(\n target: Store<G>,\n nodesApi: TxNodes,\n plan: MergePlan<G>,\n): Promise<void> {\n const writes = plannedNodeWrites(plan);\n const nodeIdsByKind = new Map<string, AnyNodeId[]>();\n for (const write of writes) {\n const bucket = nodeIdsByKind.get(write.kind) ?? [];\n bucket.push(write.id);\n nodeIdsByKind.set(write.kind, bucket);\n }\n\n const currentByIdentity = new Map<MergeKey, Node | undefined>();\n for (const [kind, ids] of nodeIdsByKind) {\n const rows = await nodeCollection(nodesApi, kind).getByIds(\n ids,\n INCLUDE_TOMBSTONES,\n );\n for (const [index, id] of ids.entries()) {\n currentByIdentity.set(mergeKey(kind, id), rows[index]);\n }\n }\n\n for (const write of writes) {\n const current = currentByIdentity.get(write.identity);\n if (current === undefined) {\n continue;\n }\n if (current.meta.deletedAt !== undefined) {\n throw new MergeError(\n `mergeIncremental() would resurrect soft-deleted committed node \"${write.id}\" (kind \"${write.kind}\").`,\n { details: { id: write.id, kind: write.kind } },\n );\n }\n const analysis = analyzeRevalidatingWrite(\n nodeSchemaFor(target, write.kind),\n nodeProps(current),\n write.props,\n );\n assertValidRevalidatingWrite(\n analysis,\n `mergeIncremental() found an existing committed node \"${write.id}\" (kind \"${write.kind}\") whose current props do not validate against the active schema.`,\n { id: write.id, kind: write.kind },\n );\n if (analysis.stripsCurrentProps && analysis.schemaWouldChange) {\n throw new MergeError(\n `mergeIncremental() would update committed node \"${write.id}\" (kind \"${write.kind}\") but the write would strip existing props outside the active schema (lossy base update).`,\n { details: { id: write.id, kind: write.kind } },\n );\n }\n }\n}\n\nasync function validateIncrementalEdgeWrites<G extends GraphDef>(\n target: Store<G>,\n edgesApi: TxEdges,\n plan: MergePlan<G>,\n): Promise<void> {\n const signatureById = new Map<EdgeId, string>();\n for (const edge of plan.mergedEdges) {\n const signature = edgeWriteSignature(edge, plan);\n const existing = signatureById.get(edge.id);\n if (existing !== undefined && existing !== signature) {\n throw new MergeError(\n `mergeIncremental() would overwrite committed edge \"${edge.id}\" with multiple planned endpoint/prop shapes (edge.id collision).`,\n { details: { id: edge.id } },\n );\n }\n signatureById.set(edge.id, signature);\n }\n\n // Bucket the planned edges by their PLANNED kind and fetch each kind's ids in a\n // single round-trip. An edge belongs to exactly one kind, so this does O(edges)\n // lookups instead of scanning EVERY schema edge kind for every id (the old\n // O(edgeKinds × edges) fan-out that held the write lock far longer than needed).\n const plannedKindById = new Map<EdgeId, string>();\n const idsByKind = new Map<string, EdgeId[]>();\n for (const edge of plan.mergedEdges) {\n if (plannedKindById.has(edge.id)) {\n continue; // shape already deduped by the signature guard above\n }\n plannedKindById.set(edge.id, edge.kind);\n const bucket = idsByKind.get(edge.kind) ?? [];\n bucket.push(edge.id);\n idsByKind.set(edge.kind, bucket);\n }\n const existingById = new Map<string, Edge>();\n for (const [kind, ids] of idsByKind) {\n const rows = await edgeCollection(edgesApi, kind).getByIds(\n ids,\n INCLUDE_TOMBSTONES,\n );\n for (const [index, id] of ids.entries()) {\n const row = rows[index];\n if (row !== undefined) {\n existingById.set(id, row);\n }\n }\n }\n\n // Cross-kind collision guard: edge ids are GLOBALLY unique, so an id NOT found\n // under its planned kind may still be committed under a DIFFERENT kind — a silent\n // overwrite hazard. Scan the schema's edge kinds for ONLY those not-found ids,\n // through the transaction's collections (never `target.backend`, whose separate\n // connection would deadlock against the tx-held one). An update-only merge finds\n // every edge in the bucketed pass above, so this fallback is empty.\n const notFound = [...plannedKindById.keys()]\n .filter((id) => !existingById.has(id))\n .sort((left, right) => compareStrings(left, right));\n if (notFound.length > 0) {\n // Sequential: all queries share the same transaction client (a single\n // pg PoolClient). Concurrent client.query() calls on a PoolClient queue\n // with a deprecation warning in pg@8 and become an error in pg@9.\n const crossKindById = new Map<string, Edge>();\n for (const kind of Object.keys(target.graph.edges)) {\n const rows = await edgeCollection(edgesApi, kind).getByIds(\n notFound,\n INCLUDE_TOMBSTONES,\n );\n for (const [index, id] of notFound.entries()) {\n const row = rows[index];\n if (row !== undefined && !crossKindById.has(id)) {\n crossKindById.set(id, row);\n }\n }\n }\n for (const id of notFound) {\n const row = crossKindById.get(id);\n if (row === undefined) {\n continue;\n }\n if (row.meta.deletedAt !== undefined) {\n throw new MergeError(\n `mergeIncremental() would resurrect soft-deleted committed edge \"${id}\" (kind \"${row.kind}\").`,\n { details: { id, committedKind: row.kind } },\n );\n }\n throw new MergeError(\n `mergeIncremental() would overwrite committed edge \"${id}\" (kind \"${row.kind}\") with a different-kind edge \"${requireDefined(plannedKindById.get(id))}\" of the same id.`,\n {\n details: {\n id,\n committedKind: row.kind,\n plannedKind: requireDefined(plannedKindById.get(id)),\n },\n },\n );\n }\n }\n\n for (const edge of plan.mergedEdges) {\n const current = existingById.get(edge.id);\n if (current === undefined) {\n continue;\n }\n // `current` was fetched under `edge.kind`, so its kind matches by construction;\n // a different committed kind for this id is caught by the cross-kind guard above.\n if (current.meta.deletedAt !== undefined) {\n throw new MergeError(\n `mergeIncremental() would resurrect soft-deleted committed edge \"${edge.id}\" (kind \"${current.kind}\").`,\n { details: { id: edge.id, committedKind: current.kind } },\n );\n }\n\n const from = finalEdgeFrom(edge, plan);\n const to = finalEdgeTo(edge, plan);\n if (\n current.fromId !== from.id ||\n current.fromKind !== from.kind ||\n current.toId !== to.id ||\n current.toKind !== to.kind\n ) {\n throw new MergeError(\n `mergeIncremental() would overwrite committed edge \"${edge.id}\" (kind \"${edge.kind}\") with different endpoints.`,\n { details: { id: edge.id, kind: edge.kind } },\n );\n }\n\n const analysis = analyzeRevalidatingWrite(\n edgeSchemaFor(target, edge.kind),\n edgeProps(current),\n edge.props,\n );\n assertValidRevalidatingWrite(\n analysis,\n `mergeIncremental() found an existing committed edge \"${edge.id}\" (kind \"${edge.kind}\") whose current props do not validate against the active schema.`,\n { id: edge.id, kind: edge.kind },\n );\n if (analysis.stripsCurrentProps && analysis.schemaWouldChange) {\n throw new MergeError(\n `mergeIncremental() would update committed edge \"${edge.id}\" (kind \"${edge.kind}\") but the write would strip existing props outside the active schema.`,\n { details: { id: edge.id, kind: edge.kind } },\n );\n }\n }\n}\n\n/**\n * The reads `commitIncrementalPlan` needs to re-run the NEW-vs-BASE identity\n * resolution INSIDE the commit transaction — the inputs to {@link\n * collectBaseMatchKeys}, plus the set of committed `(kind, id)` keys those base\n * sources matched at PLAN time. Comparing the two closes the identity-resolution\n * TOCTOU window (see {@link assertBaseResolutionStable}).\n */\ntype IncrementalCommitGuard<G extends GraphDef> = Readonly<{\n stagedNewByKind: ReadonlyMap<string, readonly StagedNewNode[]>;\n options: NormalizedMergeOptions<G>;\n introspectionKinds: ReadonlyMap<string, readonly UniqueIntrospection[]>;\n plannedBaseMatchKeys: ReadonlySet<MergeKey>;\n /**\n * `(kind, id) -> version` for every committed target node observed while\n * planning (the target-branch diff enumeration). The commit-time guard\n * re-reads the rows the plan writes OR deletes and refuses if any inherited\n * row's version advanced in the plan→commit window — a concurrent write the\n * stale plan would otherwise overwrite (lost update).\n */\n targetNodeVersions: ReadonlyMap<MergeKey, number>;\n /**\n * `(kind, id) -> content signature` for every committed target edge observed\n * while planning. The edge-half analogue of {@link targetNodeVersions}: edges\n * have no version, so the guard fingerprints their mergeable content\n * (endpoints, liveness, canonical props) and refuses if the fingerprint of an\n * edge the plan upserts OR deletes drifted in the plan→commit window.\n */\n targetEdgeSignatures: ReadonlyMap<MergeKey, string>;\n}>;\n\n/**\n * Re-runs the NEW-vs-BASE identity probes — each kind's unique constraints\n * (`baseUnique`) and its declared block index (`baseKey`) — for the staged new\n * nodes against `lookupStore`, returning the set of committed `(kind, id)` keys\n * those probes surface. It computes the lookup keys from the SAME staged props\n * the planner used (typegraph owns key derivation), so the result over the\n * plan-time target reproduces `candidates.baseMembers`, and the result over the\n * tx-snapshot target reveals any committed row that became a match in between.\n *\n * Probes are issued STRICTLY SEQUENTIALLY (one awaited query at a time): inside\n * the commit transaction these run on the single tx-held client, where\n * concurrent `client.query()` calls queue with a pg deprecation warning that\n * becomes an error in pg@9.\n */\nasync function collectBaseMatchKeys<G extends GraphDef>(\n lookupStore: BaseLookupStore,\n guard: IncrementalCommitGuard<G>,\n): Promise<ReadonlySet<MergeKey>> {\n const matched = new Set<MergeKey>();\n for (const [kind, stagedNodes] of guard.stagedNewByKind) {\n const resolveConfig = guard.options.resolve[kind];\n // A kind with no resolve config has no base recall — it never pulls a\n // committed row into scope, so it carries no identity-resolution TOCTOU.\n if (resolveConfig === undefined) {\n continue;\n }\n const collection = lookupStore.nodes[kind];\n if (collection === undefined || stagedNodes.length === 0) {\n continue;\n }\n const items = stagedNodes.map((staged) => ({ props: staged.node.props }));\n\n for (const constraint of uniqueConstraintsFor(\n guard.introspectionKinds,\n kind,\n )) {\n const matches = await collection.bulkFindByConstraint(\n constraint.name,\n items,\n );\n for (const base of matches) {\n if (base !== undefined) {\n matched.add(mergeKeyOf(base));\n }\n }\n }\n\n if (resolveConfig.blockIndex !== undefined) {\n const matchesByItem = await collection.bulkFindByIndex(\n resolveConfig.blockIndex,\n items,\n );\n for (const perItem of matchesByItem) {\n for (const base of perItem) {\n matched.add(mergeKeyOf(base));\n }\n }\n }\n }\n return matched;\n}\n\n/**\n * The identity-resolution half of the incremental TOCTOU guard. The planner\n * resolves each branch addition against the target's committed rows from reads\n * taken OUTSIDE this transaction (`baseUnique`/`baseKey` in candidate\n * generation). A committed row sharing a branch addition's unique-constraint or\n * block-index key that LANDS in the plan→commit window is invisible to the\n * per-row write guards — they only re-fetch the plan's own write ids — so the\n * stale plan would commit the addition under its own id, leaving a duplicate the\n * base-source resolution would otherwise have collapsed. A unique-constraint\n * collision is still caught at write time by the uniques side-table, but only as\n * a late, opaque failure mid-apply; a non-unique BLOCK-INDEX collision has no\n * such backstop and commits the duplicate SILENTLY. This guard refuses both\n * early and typed, before any row is touched.\n *\n * Re-deriving the matched base keys through the TX-scoped store and comparing\n * them to the plan-time set proves no new identity match appeared. SERIALIZABLE\n * isolation makes the proof race-free on multi-writer Postgres: a concurrent\n * insert that this read would have to see aborts one side with a retryable\n * serialization failure; the retry re-runs this probe and fails typed.\n */\nasync function assertBaseResolutionStable<G extends GraphDef>(\n lookupStore: BaseLookupStore,\n guard: IncrementalCommitGuard<G>,\n): Promise<void> {\n const liveKeys = await collectBaseMatchKeys(lookupStore, guard);\n const appeared = [...liveKeys]\n .filter((key) => !guard.plannedBaseMatchKeys.has(key))\n .sort((left, right) => compareMergeKeys(left, right));\n if (appeared.length === 0) {\n return;\n }\n throw new BaseVersionMismatchError(\n `mergeIncremental() resolved its branch additions against the target as of planning, but ${appeared.length} committed row(s) matching a branch addition's identity key (a unique constraint or block index) were inserted before the commit transaction. Committing the plan would create duplicate entities the base-source resolution would otherwise have collapsed.`,\n {\n details: { appeared },\n suggestion:\n \"Re-run mergeIncremental(); the re-planned merge resolves the branch additions against the now-committed rows.\",\n },\n );\n}\n\n/** A `(kind, id)` the plan will mutate whose identity was an observed target row. */\ntype InheritedTargetRef = Readonly<{ kind: string; id: string }>;\n\n/** Anything keyed by {@link MergeKey} that can answer a membership check. */\ntype MergeKeyMembership = Readonly<{ has(key: MergeKey): boolean }>;\n\n/**\n * Buckets the plan's inherited-target mutations by kind, deduped by identity, for\n * a single batched re-read per kind. `identities` filters to the rows observed at\n * plan time (new rows the plan creates have no baseline and are skipped). Both a\n * write and a delete of the same identity collapse to one entry — either way the\n * row is re-checked once.\n */\nfunction bucketInheritedRefsByKind(\n refs: Iterable<InheritedTargetRef>,\n identities: MergeKeyMembership,\n): ReadonlyMap<string, readonly string[]> {\n const seen = new Set<MergeKey>();\n const idsByKind = new Map<string, string[]>();\n for (const ref of refs) {\n const identity = mergeKey(ref.kind, ref.id);\n if (!identities.has(identity) || seen.has(identity)) {\n continue;\n }\n seen.add(identity);\n const bucket = idsByKind.get(ref.kind) ?? [];\n bucket.push(ref.id);\n idsByKind.set(ref.kind, bucket);\n }\n return idsByKind;\n}\n\n/**\n * The version-check (nodes) and signature-check (edges) halves of the\n * incremental TOCTOU guard share one skeleton — bucket refs by kind, batch-fetch\n * the current rows, compare each against its plan-time baseline, and throw on\n * the first mismatch. `Row` is the fetched row shape and `Expected` the\n * comparable baseline value (a node version or an edge content signature).\n */\nasync function assertInheritedUnchanged<Row, Expected>(\n args: Readonly<{\n refs: readonly InheritedTargetRef[];\n expected: ReadonlyMap<MergeKey, Expected>;\n fetchRows: (\n kind: string,\n ids: readonly string[],\n ) => Promise<readonly (Row | undefined)[]>;\n deriveValue: (row: Row | undefined) => Expected | undefined;\n buildError: (\n id: string,\n kind: string,\n expected: Expected,\n current: Expected | undefined,\n ) => Error;\n }>,\n): Promise<void> {\n if (args.expected.size === 0) {\n return;\n }\n const idsByKind = bucketInheritedRefsByKind(args.refs, args.expected);\n for (const [kind, ids] of idsByKind) {\n const rows = await args.fetchRows(kind, ids);\n for (const [index, id] of ids.entries()) {\n const expected = requireDefined(args.expected.get(mergeKey(kind, id)));\n const current = args.deriveValue(rows[index]);\n if (current === expected) {\n continue;\n }\n throw args.buildError(id, kind, expected, current);\n }\n }\n}\n\n/**\n * The inherited-target-row half of the incremental TOCTOU guard. The plan folds\n * the live target in as a preferred branch and resolves inherited modifications\n * against the target rows it enumerated OUTSIDE this transaction. If a committed\n * row the plan mutates was changed in the plan→commit window, applying the plan\n * would discard that write (a silent lost update) — the per-row write guards only\n * check resurrection / lossy strips, not that the row still holds the value the\n * plan merged from.\n *\n * Covers every path that mutates a committed target row: node writes and node\n * deletions (checked by `version`), and edge upserts and edge deletions (checked\n * by content signature, since edges carry no version). For each, it re-reads the\n * committed row through the tx snapshot and refuses if it drifted (or vanished).\n * SERIALIZABLE + retry then re-plans against the now-committed value, exactly as\n * the snapshot path's {@link assertTargetUnchanged} does for full-graph drift.\n */\nasync function assertInheritedTargetUnchanged<G extends GraphDef>(\n nodesApi: TxNodes,\n edgesApi: TxEdges,\n guard: IncrementalCommitGuard<G>,\n plan: MergePlan<G>,\n): Promise<void> {\n // Disjoint collections (nodes vs. edges) with no shared state — safe to run\n // concurrently.\n await Promise.all([\n assertInheritedNodesUnchanged(nodesApi, guard, plan),\n assertInheritedEdgesUnchanged(edgesApi, guard, plan),\n ]);\n}\n\n/** Version-checks every committed target node the plan writes or deletes. */\nasync function assertInheritedNodesUnchanged<G extends GraphDef>(\n nodesApi: TxNodes,\n guard: IncrementalCommitGuard<G>,\n plan: MergePlan<G>,\n): Promise<void> {\n const nodeRefs: InheritedTargetRef[] = plannedNodeWrites(plan).map(\n (write) => ({ kind: write.kind, id: write.id }),\n );\n for (const [identity, kind] of plan.nodeDeletions) {\n nodeRefs.push({ kind, id: idOf(identity) });\n }\n await assertInheritedUnchanged<Node, number>({\n refs: nodeRefs,\n expected: guard.targetNodeVersions,\n fetchRows: (kind, ids) =>\n nodeCollection(nodesApi, kind).getByIds(ids, INCLUDE_TOMBSTONES),\n deriveValue: (row) => row?.meta.version,\n buildError: (id, kind, expected, current) =>\n new BaseVersionMismatchError(\n `mergeIncremental() observed committed node \"${id}\" (kind \"${kind}\") at version ${expected} while planning, but it changed before the commit transaction; the resolved plan no longer describes the live target and was not applied.`,\n {\n details: {\n id,\n kind,\n expectedVersion: expected,\n currentVersion: current,\n },\n suggestion:\n \"Re-run mergeIncremental(); the re-planned merge resolves the inherited modifications against the now-committed rows.\",\n },\n ),\n });\n}\n\n/**\n * Signature-checks every committed target edge the plan upserts or deletes. Edges\n * carry no `version`, so the plan-time baseline is a content fingerprint\n * ({@link edgeStateSignature}) captured over the target's edge enumeration; a\n * changed fingerprint means the committed edge's endpoints, liveness, or props\n * drifted in the plan→commit window.\n */\nasync function assertInheritedEdgesUnchanged<G extends GraphDef>(\n edgesApi: TxEdges,\n guard: IncrementalCommitGuard<G>,\n plan: MergePlan<G>,\n): Promise<void> {\n const edgeRefs: InheritedTargetRef[] = plan.mergedEdges.map((edge) => ({\n kind: edge.kind,\n id: edge.id,\n }));\n for (const [identity, kind] of plan.edgeDeletions) {\n edgeRefs.push({ kind, id: idOf(identity) });\n }\n await assertInheritedUnchanged<Edge, string>({\n refs: edgeRefs,\n expected: guard.targetEdgeSignatures,\n fetchRows: (kind, ids) =>\n edgeCollection(edgesApi, kind).getByIds(ids, INCLUDE_TOMBSTONES),\n deriveValue: (row) =>\n row === undefined ? undefined : (\n edgeStateSignature({\n fromKind: row.fromKind,\n fromId: row.fromId,\n toKind: row.toKind,\n toId: row.toId,\n live: row.meta.deletedAt === undefined,\n props: edgeProps(row),\n })\n ),\n buildError: (id, kind) =>\n new BaseVersionMismatchError(\n `mergeIncremental() observed committed edge \"${id}\" (kind \"${kind}\") while planning, but its endpoints, liveness, or props changed before the commit transaction; the resolved plan no longer describes the live target and was not applied.`,\n {\n details: { id, kind },\n suggestion:\n \"Re-run mergeIncremental(); the re-planned merge resolves the inherited modifications against the now-committed rows.\",\n },\n ),\n });\n}\n\n/**\n * The full incremental commit path (§6.6). The planner has already folded the live\n * target in as a preferred synthetic branch, so this path preflights destructive\n * row hazards inside the target transaction and then applies the normal merge plan.\n */\nasync function commitIncrementalPlan<G extends GraphDef>(\n target: Store<G>,\n plan: MergePlan<G>,\n guard: IncrementalCommitGuard<G>,\n): Promise<Readonly<{ nodes: number; edges: number }>> {\n if (!storeBackend(target).capabilities.transactions) {\n throw new MergeError(\n \"mergeIncremental() requires a transaction-capable target backend. Incremental writes must preflight existing rows and commit atomically; non-transactional fallback would allow partial graph writes.\",\n { details: { capability: \"transactions\" } },\n );\n }\n\n // Legacy targets use SERIALIZABLE + retry: the per-row guards read inside\n // this transaction, and SSI turns a conflicting concurrent write into a\n // retryable abort. Recorded-history targets cannot use SERIALIZABLE because\n // capture allocates its clock in read-committed mode; they instead acquire the\n // same graph write lock as every captured write before the guards run. In\n // PostgreSQL read committed each subsequent statement sees committed work that\n // landed before the lock was acquired, while the lock excludes later tracked\n // writes until this plan commits.\n return withTxConflictRetry(() =>\n target.transaction(async (tx) => {\n if (target.revisionTrackingEnabled) {\n await lockRecordedGraphWrite(transactionBackend(tx), target.graphId);\n }\n const nodesApi = tx.nodes as unknown as TxNodes;\n const edgesApi = tx.edges as unknown as TxEdges;\n // Identity-resolution TOCTOU guard: the base-source lookups ran OUTSIDE\n // this transaction, so re-derive them here (tx snapshot) and refuse the\n // plan if a matching committed row appeared in the window. `tx` exposes\n // the same `.nodes` collection record a `BaseLookupStore` needs.\n await assertBaseResolutionStable(tx as unknown as BaseLookupStore, guard);\n // Inherited-row TOCTOU guard: refuse if a committed node OR edge the plan\n // writes or deletes changed since it was observed at plan time (lost update).\n await assertInheritedTargetUnchanged(nodesApi, edgesApi, guard, plan);\n await validateIncrementalNodeWrites(target, nodesApi, plan);\n await validateIncrementalEdgeWrites(target, edgesApi, plan);\n return applyMergePlan(plan, nodesApi, edgesApi);\n }, mergeCommitTransactionOptions(target)),\n );\n}\n\n/**\n * Incremental merge — the public fork-point-vs-live-target entry point (design\n * §6.4-B / §6.6). It treats `forkPoint` as the immutable ancestor, folds the live\n * `target` in as a preferred committed branch, resolves branch additions against\n * committed rows, and propagates inherited node/edge modifications and deletions\n * through the same three-way merge planner.\n *\n * Object-form args so the two same-typed stores (`forkPoint`, `target`) cannot be\n * swapped. `options.target` is ignored — `target` is the explicit arg.\n *\n * Preconditions (typed errors): every branch forked from `forkPoint`\n * (`branch.base === computeBaseVersion(forkPoint)`); `forkPoint` and `target` share a\n * schema hash (schema drift is fatal; target CONTENT may have advanced); and\n * `onBasePropertyConflict` is `\"flag\"` (keep-base for committed-row conflicts).\n */\nexport async function mergeIncremental<G extends GraphDef>(\n args: MergeIncrementalArguments<G>,\n): Promise<Result<MergeReport<G>, MergeError>> {\n const { forkPoint, target, branches } = args;\n\n const normalized = tryNormalize(args.options ?? {});\n if (isErr(normalized)) {\n return err(normalized.error);\n }\n const options = normalized.data;\n\n // Keep-base pin: committed rows remain authoritative under unresolved base\n // conflicts. A non-keep-base policy would let a stale branch value overwrite a\n // newer committed value.\n if (options.onBasePropertyConflict !== \"flag\") {\n return err(\n new MergeError(\n 'mergeIncremental() requires onBasePropertyConflict: \"flag\" (keep-base); a non-keep-base policy could overwrite a newer committed base value with a stale branch value.',\n { details: {} },\n ),\n );\n }\n\n // Every branch must have forked from THIS fork-point (honest diff).\n const forkPrecondition = await validateForkPointVersions(forkPoint, branches);\n if (isErr(forkPrecondition)) {\n return err(forkPrecondition.error);\n }\n const forkVersion = forkPrecondition.data;\n\n // Schema half of base@V stays a hard precondition; target CONTENT may advance.\n const [forkSchema, targetSchema] = await Promise.all([\n computeSchemaComponent(forkPoint),\n computeSchemaComponent(target),\n ]);\n if (forkSchema !== targetSchema) {\n return err(\n new MergeError(\n \"mergeIncremental() requires target and forkPoint to share a schema; schema drift is not supported (the target content may differ — only the schema must match).\",\n { details: {} },\n ),\n );\n }\n\n const targetBranch: GraphBranch<G> = {\n id: COMMITTED_TARGET_BRANCH,\n base: forkVersion,\n store: target,\n };\n return resolveMerge(\n forkPoint,\n target,\n [targetBranch, ...branches],\n options,\n true,\n { targetBranchId: COMMITTED_TARGET_BRANCH },\n );\n}\n"]}
|