@nicia-ai/typegraph 0.49.0 → 0.51.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 -0
- package/dist/backend/drizzle/indexes.cjs +11 -9
- package/dist/backend/drizzle/indexes.d.cts +1 -1
- package/dist/backend/drizzle/indexes.d.ts +1 -1
- package/dist/backend/drizzle/indexes.js +7 -5
- package/dist/backend/index.cjs +190 -53
- package/dist/backend/index.d.cts +90 -4
- package/dist/backend/index.d.ts +90 -4
- package/dist/backend/index.js +9 -12
- package/dist/backend/postgres/index.cjs +36 -28
- package/dist/backend/postgres/index.d.cts +7 -7
- package/dist/backend/postgres/index.d.ts +7 -7
- package/dist/backend/postgres/index.js +19 -15
- package/dist/backend/postgres/pglite-store.cjs +7 -62
- package/dist/backend/postgres/pglite-store.cjs.map +1 -1
- package/dist/backend/postgres/pglite-store.d.cts +8 -8
- package/dist/backend/postgres/pglite-store.d.ts +8 -8
- package/dist/backend/postgres/pglite-store.js +7 -62
- package/dist/backend/postgres/pglite-store.js.map +1 -1
- package/dist/backend/postgres/pglite.cjs +21 -17
- package/dist/backend/postgres/pglite.d.cts +3 -3
- package/dist/backend/postgres/pglite.d.ts +3 -3
- package/dist/backend/postgres/pglite.js +20 -16
- package/dist/backend/sqlite/index.cjs +33 -25
- package/dist/backend/sqlite/index.d.cts +7 -7
- package/dist/backend/sqlite/index.d.ts +7 -7
- package/dist/backend/sqlite/index.js +17 -13
- package/dist/backend/sqlite/libsql.cjs +24 -20
- package/dist/backend/sqlite/libsql.cjs.map +1 -1
- package/dist/backend/sqlite/libsql.d.cts +3 -3
- package/dist/backend/sqlite/libsql.d.ts +3 -3
- package/dist/backend/sqlite/libsql.js +19 -15
- package/dist/backend/sqlite/libsql.js.map +1 -1
- package/dist/backend/sqlite/local-store.cjs +9 -64
- package/dist/backend/sqlite/local-store.cjs.map +1 -1
- package/dist/backend/sqlite/local-store.d.cts +8 -8
- package/dist/backend/sqlite/local-store.d.ts +8 -8
- package/dist/backend/sqlite/local-store.js +8 -64
- package/dist/backend/sqlite/local-store.js.map +1 -1
- package/dist/backend/sqlite/local.cjs +25 -20
- package/dist/backend/sqlite/local.d.cts +3 -3
- package/dist/backend/sqlite/local.d.ts +3 -3
- package/dist/backend/sqlite/local.js +21 -16
- package/dist/chunk-2CVDZCXH.cjs +1278 -0
- package/dist/chunk-2CVDZCXH.cjs.map +1 -0
- package/dist/{chunk-MYKHJI2J.js → chunk-2DWTBNSH.js} +3 -3
- package/dist/{chunk-MYKHJI2J.js.map → chunk-2DWTBNSH.js.map} +1 -1
- package/dist/{chunk-JB6T4GLL.cjs → chunk-2KCTP3U2.cjs} +870 -528
- package/dist/chunk-2KCTP3U2.cjs.map +1 -0
- package/dist/{chunk-OORXGFL5.cjs → chunk-322TBTOQ.cjs} +48 -48
- package/dist/{chunk-OORXGFL5.cjs.map → chunk-322TBTOQ.cjs.map} +1 -1
- package/dist/{chunk-FA2AFWLP.cjs → chunk-36SX6QXP.cjs} +31 -12
- package/dist/chunk-36SX6QXP.cjs.map +1 -0
- package/dist/{chunk-SDBBMD4N.js → chunk-36VYWVQU.js} +3 -3
- package/dist/{chunk-SDBBMD4N.js.map → chunk-36VYWVQU.js.map} +1 -1
- package/dist/chunk-4DKY6RIU.js +1253 -0
- package/dist/chunk-4DKY6RIU.js.map +1 -0
- package/dist/chunk-4QKOZYMV.js +9 -0
- package/dist/chunk-4QKOZYMV.js.map +1 -0
- package/dist/{chunk-WIC7DRXW.js → chunk-57JM6NW3.js} +9 -19
- package/dist/chunk-57JM6NW3.js.map +1 -0
- package/dist/chunk-5WWEYV4H.cjs +5113 -0
- package/dist/chunk-5WWEYV4H.cjs.map +1 -0
- package/dist/chunk-6KQEICJ6.cjs +12 -0
- package/dist/{chunk-MKJ4KXL5.cjs.map → chunk-6KQEICJ6.cjs.map} +1 -1
- package/dist/{chunk-DZAICA5J.js → chunk-6NKSE5AU.js} +4 -4
- package/dist/{chunk-DZAICA5J.js.map → chunk-6NKSE5AU.js.map} +1 -1
- package/dist/{chunk-KKBDXCLQ.js → chunk-6NLYIMJO.js} +4 -4
- package/dist/{chunk-KKBDXCLQ.js.map → chunk-6NLYIMJO.js.map} +1 -1
- package/dist/{chunk-BFUOME67.cjs → chunk-7B7I7YAW.cjs} +20 -11
- package/dist/chunk-7B7I7YAW.cjs.map +1 -0
- package/dist/{chunk-ZDKTPBGV.js → chunk-7G5IYROL.js} +6 -548
- package/dist/chunk-7G5IYROL.js.map +1 -0
- package/dist/{chunk-3DMMGT6S.js → chunk-7QFRK6PU.js} +4 -8
- package/dist/chunk-7QFRK6PU.js.map +1 -0
- package/dist/chunk-A4C4NJ5U.cjs +12 -0
- package/dist/chunk-A4C4NJ5U.cjs.map +1 -0
- package/dist/{chunk-CHAOFCHV.js → chunk-AH2A74OZ.js} +3 -3
- package/dist/{chunk-CHAOFCHV.js.map → chunk-AH2A74OZ.js.map} +1 -1
- package/dist/{chunk-UGHQV7MP.cjs → chunk-B3MN7EJR.cjs} +228 -162
- package/dist/chunk-B3MN7EJR.cjs.map +1 -0
- package/dist/{chunk-TZEGUG6D.cjs → chunk-BZ5MVITP.cjs} +4 -4
- package/dist/{chunk-TZEGUG6D.cjs.map → chunk-BZ5MVITP.cjs.map} +1 -1
- package/dist/{chunk-YVF2EM7B.js → chunk-CAI6SMP6.js} +3 -3
- package/dist/{chunk-YVF2EM7B.js.map → chunk-CAI6SMP6.js.map} +1 -1
- package/dist/{chunk-JONXFAPO.js → chunk-CBOD7TXH.js} +5 -5
- package/dist/{chunk-JONXFAPO.js.map → chunk-CBOD7TXH.js.map} +1 -1
- package/dist/{chunk-FQPEMEWX.cjs → chunk-CRZ56SZU.cjs} +81 -32
- package/dist/chunk-CRZ56SZU.cjs.map +1 -0
- package/dist/{chunk-DO7SAMEK.cjs → chunk-D3GWARN7.cjs} +47 -47
- package/dist/{chunk-DO7SAMEK.cjs.map → chunk-D3GWARN7.cjs.map} +1 -1
- package/dist/{chunk-QTD6HX4O.js → chunk-D3OUDFU7.js} +5 -5
- package/dist/{chunk-QTD6HX4O.js.map → chunk-D3OUDFU7.js.map} +1 -1
- package/dist/{chunk-2QGYQBS2.cjs → chunk-DWUDZ66O.cjs} +10 -10
- package/dist/{chunk-2QGYQBS2.cjs.map → chunk-DWUDZ66O.cjs.map} +1 -1
- package/dist/chunk-EKG2UXNX.cjs +23 -0
- package/dist/chunk-EKG2UXNX.cjs.map +1 -0
- package/dist/chunk-FMMW3KX7.cjs +148 -0
- package/dist/chunk-FMMW3KX7.cjs.map +1 -0
- package/dist/{chunk-XVWOYKIK.js → chunk-FZHF5UWR.js} +3 -3
- package/dist/{chunk-XVWOYKIK.js.map → chunk-FZHF5UWR.js.map} +1 -1
- package/dist/chunk-H2VWDQWC.cjs +571 -0
- package/dist/chunk-H2VWDQWC.cjs.map +1 -0
- package/dist/chunk-H4FY6OZK.js +13 -0
- package/dist/chunk-H4FY6OZK.js.map +1 -0
- package/dist/{chunk-EDN4Y4ZG.cjs → chunk-H5IJSROF.cjs} +9 -15
- package/dist/chunk-H5IJSROF.cjs.map +1 -0
- package/dist/chunk-HZUB5CON.js +27 -0
- package/dist/chunk-HZUB5CON.js.map +1 -0
- package/dist/{chunk-NACVVDWB.js → chunk-I5IOSA27.js} +103 -105
- package/dist/chunk-I5IOSA27.js.map +1 -0
- package/dist/{chunk-OI2GQ25X.cjs → chunk-I7YAY2VQ.cjs} +7 -7
- package/dist/{chunk-OI2GQ25X.cjs.map → chunk-I7YAY2VQ.cjs.map} +1 -1
- package/dist/chunk-IRCWIA3R.js +20 -0
- package/dist/chunk-IRCWIA3R.js.map +1 -0
- package/dist/chunk-IVQBLXBK.cjs +55 -0
- package/dist/chunk-IVQBLXBK.cjs.map +1 -0
- package/dist/{chunk-7SQSZN2J.js → chunk-IZD4HTCP.js} +5 -5
- package/dist/{chunk-7SQSZN2J.js.map → chunk-IZD4HTCP.js.map} +1 -1
- package/dist/{chunk-3FPR224C.cjs → chunk-JHRUZ73O.cjs} +116 -107
- package/dist/chunk-JHRUZ73O.cjs.map +1 -0
- package/dist/{chunk-EZEEWCFJ.cjs → chunk-JQKMEKKW.cjs} +525 -298
- package/dist/chunk-JQKMEKKW.cjs.map +1 -0
- package/dist/chunk-JVA3KDEA.cjs +691 -0
- package/dist/chunk-JVA3KDEA.cjs.map +1 -0
- package/dist/{chunk-5K2BKEBD.js → chunk-K46SDNQD.js} +10 -4
- package/dist/chunk-K46SDNQD.js.map +1 -0
- package/dist/{chunk-7LZJNLA5.js → chunk-K67P5DLL.js} +108 -42
- package/dist/chunk-K67P5DLL.js.map +1 -0
- package/dist/{chunk-3G5W2U2L.cjs → chunk-KACEYDYV.cjs} +335 -258
- package/dist/chunk-KACEYDYV.cjs.map +1 -0
- package/dist/{chunk-JFRT7S3B.cjs → chunk-L6EVYIID.cjs} +318 -478
- package/dist/chunk-L6EVYIID.cjs.map +1 -0
- package/dist/{chunk-SHFBB23Q.js → chunk-LI4K2KEJ.js} +6 -4
- package/dist/chunk-LI4K2KEJ.js.map +1 -0
- package/dist/chunk-LKZDQ2B4.js +1581 -0
- package/dist/chunk-LKZDQ2B4.js.map +1 -0
- package/dist/{chunk-WODMN3Q2.cjs → chunk-LLFPQOBA.cjs} +27 -27
- package/dist/{chunk-WODMN3Q2.cjs.map → chunk-LLFPQOBA.cjs.map} +1 -1
- package/dist/{chunk-P6YLZTRE.js → chunk-LZMQ3SFK.js} +3 -3
- package/dist/{chunk-P6YLZTRE.js.map → chunk-LZMQ3SFK.js.map} +1 -1
- package/dist/{chunk-HEV35TGT.js → chunk-M3VTS3F6.js} +13 -4
- package/dist/chunk-M3VTS3F6.js.map +1 -0
- package/dist/{chunk-TQHGE7UC.cjs → chunk-M5MSP3BI.cjs} +18 -10
- package/dist/chunk-M5MSP3BI.cjs.map +1 -0
- package/dist/{chunk-D4QLTJSM.js → chunk-NBOS7BY3.js} +63 -23
- package/dist/chunk-NBOS7BY3.js.map +1 -0
- package/dist/chunk-NGQDGL5X.js +140 -0
- package/dist/chunk-NGQDGL5X.js.map +1 -0
- package/dist/{chunk-SIT26LAZ.cjs → chunk-NLX5OWK7.cjs} +33 -5
- package/dist/chunk-NLX5OWK7.cjs.map +1 -0
- package/dist/chunk-NUQ2YFFH.cjs +1637 -0
- package/dist/chunk-NUQ2YFFH.cjs.map +1 -0
- package/dist/{chunk-UMGZDVOA.cjs → chunk-OGL4X4PH.cjs} +206 -208
- package/dist/chunk-OGL4X4PH.cjs.map +1 -0
- package/dist/{chunk-LRQKXRXO.cjs → chunk-OTNTGEXR.cjs} +4 -4
- package/dist/{chunk-LRQKXRXO.cjs.map → chunk-OTNTGEXR.cjs.map} +1 -1
- package/dist/chunk-OTWE63BW.js +53 -0
- package/dist/chunk-OTWE63BW.js.map +1 -0
- package/dist/chunk-PC5NGH5A.js +549 -0
- package/dist/chunk-PC5NGH5A.js.map +1 -0
- package/dist/{chunk-26YKDNUD.cjs → chunk-PS3TUWJM.cjs} +12 -10
- package/dist/chunk-PS3TUWJM.cjs.map +1 -0
- package/dist/{chunk-OMZ37BM2.js → chunk-PVFFH7TL.js} +5 -5
- package/dist/{chunk-OMZ37BM2.js.map → chunk-PVFFH7TL.js.map} +1 -1
- package/dist/chunk-QCD5JKU4.cjs +15 -0
- package/dist/chunk-QCD5JKU4.cjs.map +1 -0
- package/dist/{chunk-UGHG7PGX.js → chunk-QG5VEOKX.js} +30 -4
- package/dist/chunk-QG5VEOKX.js.map +1 -0
- package/dist/{chunk-TUNPBZY3.cjs → chunk-QLLZM5I3.cjs} +4 -4
- package/dist/{chunk-TUNPBZY3.cjs.map → chunk-QLLZM5I3.cjs.map} +1 -1
- package/dist/{chunk-BRRP76WO.js → chunk-RCBG6YMT.js} +781 -375
- package/dist/chunk-RCBG6YMT.js.map +1 -0
- package/dist/{chunk-LTXQOEIC.js → chunk-RI7RJH4G.js} +281 -204
- package/dist/chunk-RI7RJH4G.js.map +1 -0
- package/dist/{chunk-GYEG3ZLZ.cjs → chunk-RJMHU2MG.cjs} +121 -18
- package/dist/chunk-RJMHU2MG.cjs.map +1 -0
- package/dist/{chunk-GLHXM7C4.js → chunk-RVUL2HXY.js} +61 -23
- package/dist/chunk-RVUL2HXY.js.map +1 -0
- package/dist/chunk-RWUWTJQY.cjs +30 -0
- package/dist/chunk-RWUWTJQY.cjs.map +1 -0
- package/dist/{chunk-2O4PCIZ6.cjs → chunk-S5GU4LUN.cjs} +13 -13
- package/dist/{chunk-2O4PCIZ6.cjs.map → chunk-S5GU4LUN.cjs.map} +1 -1
- package/dist/{chunk-JPD2CTC3.js → chunk-SDPWO2Z5.js} +7 -7
- package/dist/{chunk-JPD2CTC3.js.map → chunk-SDPWO2Z5.js.map} +1 -1
- package/dist/{chunk-OVI7IXYX.js → chunk-SLGGT2XD.js} +3 -3
- package/dist/{chunk-OVI7IXYX.js.map → chunk-SLGGT2XD.js.map} +1 -1
- package/dist/{chunk-ROR5ZR6A.cjs → chunk-TIJUA4I6.cjs} +45 -45
- package/dist/{chunk-ROR5ZR6A.cjs.map → chunk-TIJUA4I6.cjs.map} +1 -1
- package/dist/{chunk-AOSSQDVO.cjs → chunk-TM54OBHX.cjs} +13 -13
- package/dist/{chunk-AOSSQDVO.cjs.map → chunk-TM54OBHX.cjs.map} +1 -1
- package/dist/{chunk-KF6K7TGH.js → chunk-TYEYRCXL.js} +766 -433
- package/dist/chunk-TYEYRCXL.js.map +1 -0
- package/dist/{chunk-Z2JCLZFJ.js → chunk-UKOVGCRN.js} +2151 -570
- package/dist/chunk-UKOVGCRN.js.map +1 -0
- package/dist/chunk-UYKDYE5D.cjs +12 -0
- package/dist/{chunk-CICO5GXD.cjs.map → chunk-UYKDYE5D.cjs.map} +1 -1
- package/dist/{chunk-S5TERQVW.js → chunk-VAAC7L57.js} +284 -66
- package/dist/chunk-VAAC7L57.js.map +1 -0
- package/dist/{chunk-7UOLHNWC.cjs → chunk-VKHXYVN7.cjs} +22 -33
- package/dist/chunk-VKHXYVN7.cjs.map +1 -0
- package/dist/{chunk-6NGW27EO.cjs → chunk-VLBTRXA2.cjs} +10 -10
- package/dist/{chunk-6NGW27EO.cjs.map → chunk-VLBTRXA2.cjs.map} +1 -1
- package/dist/{chunk-YIURNGXI.js → chunk-VUQZNUHU.js} +22 -6
- package/dist/chunk-VUQZNUHU.js.map +1 -0
- package/dist/{chunk-YYUHLYM2.cjs → chunk-WDM5WQK4.cjs} +183 -143
- package/dist/chunk-WDM5WQK4.cjs.map +1 -0
- package/dist/{chunk-ZFMCDJGB.js → chunk-WFSYYU4W.js} +70 -220
- package/dist/chunk-WFSYYU4W.js.map +1 -0
- package/dist/{chunk-SR725PWF.cjs → chunk-WRBV2FNH.cjs} +2065 -1659
- package/dist/chunk-WRBV2FNH.cjs.map +1 -0
- package/dist/{chunk-MRDBBHIZ.cjs → chunk-X4GDXBOP.cjs} +2 -2
- package/dist/chunk-X4GDXBOP.cjs.map +1 -0
- package/dist/chunk-XORONCV3.js +202 -0
- package/dist/chunk-XORONCV3.js.map +1 -0
- package/dist/{chunk-D5R42W5D.js → chunk-XZW2CTNO.js} +115 -12
- package/dist/chunk-XZW2CTNO.js.map +1 -0
- package/dist/{chunk-ZLONH2UD.js → chunk-YDEJQWOL.js} +2 -2
- package/dist/chunk-YDEJQWOL.js.map +1 -0
- package/dist/{chunk-2TYSSBU5.js → chunk-YT2IVFAI.js} +30 -21
- package/dist/chunk-YT2IVFAI.js.map +1 -0
- package/dist/chunk-ZGVTNKTX.cjs +217 -0
- package/dist/chunk-ZGVTNKTX.cjs.map +1 -0
- package/dist/core/index.cjs +29 -28
- package/dist/core/index.d.cts +4 -4
- package/dist/core/index.d.ts +4 -4
- package/dist/core/index.js +9 -8
- package/dist/{ddl-D_oW-EVO.d.ts → ddl-BvcbgzHo.d.ts} +3 -3
- package/dist/{ddl-BL1NZLMY.d.cts → ddl-Ufebz5q5.d.cts} +3 -3
- package/dist/graph-extension/index.cjs +21 -20
- package/dist/graph-extension/index.d.cts +2 -4
- package/dist/graph-extension/index.d.ts +2 -4
- package/dist/graph-extension/index.js +5 -4
- package/dist/graph-merge/index.cjs +324 -307
- package/dist/graph-merge/index.cjs.map +1 -1
- package/dist/graph-merge/index.d.cts +8 -9
- package/dist/graph-merge/index.d.ts +8 -9
- package/dist/graph-merge/index.js +51 -34
- package/dist/graph-merge/index.js.map +1 -1
- package/dist/index.cjs +224 -222
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -12
- package/dist/index.d.ts +11 -12
- package/dist/index.js +38 -36
- package/dist/index.js.map +1 -1
- package/dist/indexes/index.cjs +15 -13
- package/dist/indexes/index.d.cts +4 -4
- package/dist/indexes/index.d.ts +4 -4
- package/dist/indexes/index.js +8 -6
- package/dist/{ingestion-import-target-dNeL7iAv.d.ts → ingestion-import-target-CAs1OX-l.d.cts} +1 -1
- package/dist/{ingestion-import-target-XPxZYw89.d.cts → ingestion-import-target-DCQSPfNx.d.ts} +1 -1
- package/dist/interchange/index.cjs +57 -54
- package/dist/interchange/index.cjs.map +1 -1
- package/dist/interchange/index.d.cts +19 -8
- package/dist/interchange/index.d.ts +19 -8
- package/dist/interchange/index.js +21 -18
- package/dist/interchange/index.js.map +1 -1
- package/dist/local-store-impl-6DDTFM32.cjs +77 -0
- package/dist/local-store-impl-6DDTFM32.cjs.map +1 -0
- package/dist/local-store-impl-OXTOVU2J.js +75 -0
- package/dist/local-store-impl-OXTOVU2J.js.map +1 -0
- package/dist/{manager-CYaff3n3.d.cts → manager-B68OrPR2.d.ts} +29 -2
- package/dist/{manager-D9eRT_ns.d.ts → manager-D_t7oK69.d.cts} +29 -2
- package/dist/pglite-store-impl-6EMZGL7K.js +73 -0
- package/dist/pglite-store-impl-6EMZGL7K.js.map +1 -0
- package/dist/pglite-store-impl-GJG3Y7RP.cjs +75 -0
- package/dist/pglite-store-impl-GJG3Y7RP.cjs.map +1 -0
- package/dist/{postgres-CcL4bAHS.d.ts → postgres-BPLSVyHM.d.ts} +279 -2
- package/dist/{postgres-DMj39MEu.d.cts → postgres-CqvtFC2y.d.cts} +279 -2
- package/dist/profiler/index.d.cts +9 -9
- package/dist/profiler/index.d.ts +9 -9
- package/dist/provenance/index.cjs +59 -44
- package/dist/provenance/index.cjs.map +1 -1
- package/dist/provenance/index.d.cts +7 -7
- package/dist/provenance/index.d.ts +7 -7
- package/dist/provenance/index.js +28 -13
- package/dist/provenance/index.js.map +1 -1
- package/dist/{repair-validity-windows-BFNZvd_H.d.cts → repair-validity-windows-DEzCKAdy.d.cts} +7 -3
- package/dist/{repair-validity-windows-DlUSqwCg.d.ts → repair-validity-windows-GMdaS2AH.d.ts} +7 -3
- package/dist/resolve-D_H8MHtq.d.ts +1805 -0
- package/dist/resolve-WEW8gWws.d.cts +1805 -0
- package/dist/schema/index.cjs +48 -46
- package/dist/schema/index.d.cts +4 -6
- package/dist/schema/index.d.ts +4 -6
- package/dist/schema/index.js +21 -19
- package/dist/{searchable-bpE1bBfc.d.ts → searchable-C_UREI9K.d.ts} +1 -1
- package/dist/{searchable-DHJMh_nj.d.cts → searchable-ClgET_i7.d.cts} +1 -1
- package/dist/{sqlite-YppHrNFb.d.cts → sqlite-D1mXO9Kp.d.cts} +310 -2
- package/dist/{sqlite-D7Oz0SQh.d.ts → sqlite-MZA3oZNB.d.ts} +310 -2
- package/dist/{store-bphCSo7z.d.cts → store-CuFX7fCx.d.cts} +117 -31
- package/dist/{store-DRrFCx5x.d.ts → store-D-ZjXQpW.d.ts} +117 -31
- package/dist/{temporal-CbnLzTmM.d.ts → temporal-CpyEiRY8.d.cts} +1 -1
- package/dist/{temporal-5GqpYCk2.d.cts → temporal-y0Aep9Su.d.ts} +1 -1
- package/dist/{types-BqFZTQmV.d.cts → types-6yf0Vv-_.d.cts} +2016 -94
- package/dist/{types-BqFZTQmV.d.ts → types-6yf0Vv-_.d.ts} +2016 -94
- package/dist/{types-Bx74kaTt.d.ts → types-DzJ4dlzk.d.cts} +1 -1
- package/dist/{types-CXAhpW-c.d.cts → types-_vVSB9k-.d.ts} +1 -1
- package/dist/{where-O-k2wgYm.d.ts → where-DuG2LCLe.d.ts} +1 -1
- package/dist/{where-DI_Fqz-X.d.cts → where-Mhf_yyKX.d.cts} +1 -1
- package/package.json +7 -2
- package/dist/chunk-26YKDNUD.cjs.map +0 -1
- package/dist/chunk-2TYSSBU5.js.map +0 -1
- package/dist/chunk-3DMMGT6S.js.map +0 -1
- package/dist/chunk-3FPR224C.cjs.map +0 -1
- package/dist/chunk-3G5W2U2L.cjs.map +0 -1
- package/dist/chunk-3KOY4FH3.cjs +0 -934
- package/dist/chunk-3KOY4FH3.cjs.map +0 -1
- package/dist/chunk-3QNZ5SAJ.cjs +0 -3502
- package/dist/chunk-3QNZ5SAJ.cjs.map +0 -1
- package/dist/chunk-3U5ABFDW.cjs +0 -259
- package/dist/chunk-3U5ABFDW.cjs.map +0 -1
- package/dist/chunk-5K2BKEBD.js.map +0 -1
- package/dist/chunk-5PRKMB24.cjs +0 -124
- package/dist/chunk-5PRKMB24.cjs.map +0 -1
- package/dist/chunk-6LN7FIVU.js +0 -107
- package/dist/chunk-6LN7FIVU.js.map +0 -1
- package/dist/chunk-6SWPJEYN.js +0 -1126
- package/dist/chunk-6SWPJEYN.js.map +0 -1
- package/dist/chunk-7LZJNLA5.js.map +0 -1
- package/dist/chunk-7UOLHNWC.cjs.map +0 -1
- package/dist/chunk-BFUOME67.cjs.map +0 -1
- package/dist/chunk-BRRP76WO.js.map +0 -1
- package/dist/chunk-CICO5GXD.cjs +0 -12
- package/dist/chunk-D4QLTJSM.js.map +0 -1
- package/dist/chunk-D5R42W5D.js.map +0 -1
- package/dist/chunk-EDN4Y4ZG.cjs.map +0 -1
- package/dist/chunk-EZEEWCFJ.cjs.map +0 -1
- package/dist/chunk-FA2AFWLP.cjs.map +0 -1
- package/dist/chunk-FQPEMEWX.cjs.map +0 -1
- package/dist/chunk-GLHXM7C4.js.map +0 -1
- package/dist/chunk-GYEG3ZLZ.cjs.map +0 -1
- package/dist/chunk-HDL2ARHX.cjs +0 -1156
- package/dist/chunk-HDL2ARHX.cjs.map +0 -1
- package/dist/chunk-HEV35TGT.js.map +0 -1
- package/dist/chunk-I4GAZH5Z.js +0 -913
- package/dist/chunk-I4GAZH5Z.js.map +0 -1
- package/dist/chunk-JB6T4GLL.cjs.map +0 -1
- package/dist/chunk-JBQQ7THH.js +0 -20
- package/dist/chunk-JBQQ7THH.js.map +0 -1
- package/dist/chunk-JFRT7S3B.cjs.map +0 -1
- package/dist/chunk-KF6K7TGH.js.map +0 -1
- package/dist/chunk-L3LQNR34.cjs +0 -1254
- package/dist/chunk-L3LQNR34.cjs.map +0 -1
- package/dist/chunk-LTXQOEIC.js.map +0 -1
- package/dist/chunk-MKJ4KXL5.cjs +0 -12
- package/dist/chunk-MRDBBHIZ.cjs.map +0 -1
- package/dist/chunk-NACVVDWB.js.map +0 -1
- package/dist/chunk-NVY5CJFP.js +0 -244
- package/dist/chunk-NVY5CJFP.js.map +0 -1
- package/dist/chunk-PWLJ77UV.cjs +0 -23
- package/dist/chunk-PWLJ77UV.cjs.map +0 -1
- package/dist/chunk-S5TERQVW.js.map +0 -1
- package/dist/chunk-SHFBB23Q.js.map +0 -1
- package/dist/chunk-SIT26LAZ.cjs.map +0 -1
- package/dist/chunk-SR725PWF.cjs.map +0 -1
- package/dist/chunk-TQHGE7UC.cjs.map +0 -1
- package/dist/chunk-UGHG7PGX.js.map +0 -1
- package/dist/chunk-UGHQV7MP.cjs.map +0 -1
- package/dist/chunk-UMGZDVOA.cjs.map +0 -1
- package/dist/chunk-WIC7DRXW.js.map +0 -1
- package/dist/chunk-YIURNGXI.js.map +0 -1
- package/dist/chunk-YYUHLYM2.cjs.map +0 -1
- package/dist/chunk-Z2JCLZFJ.js.map +0 -1
- package/dist/chunk-ZDKTPBGV.js.map +0 -1
- package/dist/chunk-ZFMCDJGB.js.map +0 -1
- package/dist/chunk-ZLONH2UD.js.map +0 -1
- package/dist/index-COs_z6nV.d.cts +0 -1132
- package/dist/index-D7d1u2gr.d.ts +0 -1132
- package/dist/materialize-indexes-DJ3ykH59.d.ts +0 -266
- package/dist/materialize-indexes-DTtAnvfY.d.cts +0 -266
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/backend/types.ts","../src/query/compiler/schema.ts","../src/backend/capabilities/bundle-registry.ts","../src/backend/capabilities/bind.ts","../src/backend/capabilities/write-fence.ts"],"names":["typeGraphGlobalSymbol","ConfigurationError","MAX_PG_IDENTIFIER_LENGTH","isSqlFragment","sql","createDataKeyedBag"],"mappings":"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","file":"chunk-NUQ2YFFH.cjs","sourcesContent":["/**\n * Backend interface types for TypeGraph storage.\n *\n * The backend abstracts database operations, allowing different\n * SQL implementations (SQLite, PostgreSQL) behind a common interface.\n */\nimport {\n type Cardinality,\n type IndexEntity,\n type JsonValue,\n type KindEntity,\n type TemporalMode,\n} from \"../core/types\";\nimport { type SqlTableNames } from \"../query/compiler/schema\";\nimport { type FulltextStrategy } from \"../query/dialect/fulltext-strategy\";\nimport {\n type VectorSlot,\n type VectorStrategy,\n} from \"../query/dialect/vector-strategy\";\nimport { type SqlFragment } from \"../query/sql-fragment\";\nimport {\n type CompiledRowsSql,\n type CompiledSelectSql,\n type CompiledStatementSql,\n type CompiledTemporaryStatementSql,\n} from \"../query/sql-intent\";\nimport { type SerializedSchema } from \"../schema/types\";\nimport { typeGraphGlobalSymbol } from \"../utils/global-symbol\";\n\n// ============================================================\n// Vector Search Types\n// ============================================================\n\n/**\n * Supported vector similarity metrics.\n */\nexport type VectorMetric = \"cosine\" | \"l2\" | \"inner_product\";\n\n/**\n * Supported vector index types.\n */\nexport type VectorIndexType = \"hnsw\" | \"ivfflat\" | \"none\";\n\n/**\n * The mechanism a strategy uses to combine a row filter with an *approximate*\n * (ANN) vector search.\n *\n * Every approximate search TypeGraph issues carries at least one filter: the\n * liveness predicate that excludes soft-deleted and out-of-validity rows. Add\n * a `.where(...)` predicate and it narrows further. Engines differ in where\n * they apply it relative to the index traversal:\n *\n * - `\"filter-pushdown\"` — the filter constrains the ANN candidate set itself.\n * sqlite-vec's `vec0` KNN accepts primary-key `IN (SELECT …)` pushdown.\n * - `\"iterative-scan\"` — the engine re-enters the index, gathering more\n * candidates until `LIMIT` rows survive the filter *or* it hits its own scan\n * bound. pgvector >= 0.8 (`hnsw.iterative_scan` / `ivfflat.iterative_scan`,\n * applied automatically by the backend).\n * - `\"post-filter\"` — the engine retrieves a fixed multiple of the page from\n * the ANN index and applies the filter afterwards. libSQL's DiskANN\n * `vector_top_k` is a table function with no filter pushdown, so this is the\n * only shape available to it.\n *\n * This names what the strategy *asks the engine to do*. Whether the engine can\n * honor it — and whether honoring it is enough to fill a page — is\n * {@link FilteredApproximateSearch.guaranteesFullPage}.\n */\nexport type FilteredApproximateSearchMode =\n \"filter-pushdown\" | \"iterative-scan\" | \"post-filter\";\n\n/**\n * How a filtered approximate (ANN) vector search behaves, and whether it can\n * silently return fewer rows than `limit` while more matches exist.\n *\n * Read `guaranteesFullPage` — not `mode` — to decide whether a short page is\n * possible. Only `\"filter-pushdown\"` guarantees a full page:\n *\n * - **sqlite-vec** pushes the filter into the KNN. Exact.\n * - **pgvector** re-enters the index, but the iterative scan stops at\n * `hnsw.max_scan_tuples` / `ivfflat.max_probes`, and on **pgvector < 0.8**\n * there is no iterative scan at all — the backend detects that at runtime,\n * warns once, and the search stays `ef_search`-bounded, behaving like\n * `\"post-filter\"`. Neither case is visible in a statically-declared `mode`,\n * which is exactly why the guarantee is a separate field.\n * - **libSQL** over-fetches a fixed multiple of the page and filters\n * afterwards, so it under-fills once more than that headroom is filtered out.\n *\n * A store with heavy tombstone drift — routine in a temporal store — is what\n * turns a short page from a theoretical caveat into an observed one. Exact\n * (`approximate: false`) searches are unaffected on every engine: they scan, so\n * the filter reaches every row.\n */\nexport type FilteredApproximateSearch = Readonly<{\n mode: FilteredApproximateSearchMode;\n /**\n * `true` only when a filtered approximate search is guaranteed to return\n * `limit` rows whenever `limit` matching rows exist — no engine-side scan\n * bound, no version dependence, no over-fetch headroom to exhaust.\n */\n guaranteesFullPage: boolean;\n}>;\n\n/**\n * Whether an engine exposes a PER-SEARCH knob for the ANN candidate frontier —\n * the parameter {@link VectorSearchParams.efSearch} maps onto.\n *\n * Declared, never inferred: `efSearch` is an accepted option, so a backend that\n * cannot apply it must refuse it rather than ignore it (AGENTS.md contract\n * discipline). This capability is what the shared refusal predicate reads, and\n * what a caller reads to know whether passing `efSearch` will be honored.\n *\n * - **pgvector**: `hnsw.ef_search`, applied per search with `SET LOCAL` inside\n * the search's own transaction — hence `requiresTransactionScope`, since a\n * session-wide `SET` would leak the override into concurrent searches.\n * - **sqlite-vec**: `tunable: false`. A vec0 KNN takes `k` and nothing else;\n * there is no frontier to widen.\n * - **libSQL DiskANN**: `tunable: false`. `vector_top_k(idx, q, k)` is a table\n * function with no per-query parameters; DiskANN's `search_l` is fixed at\n * index-creation time.\n */\nexport type VectorSearchFrontierTuning =\n | Readonly<{\n tunable: true;\n /** Engine-native parameter `efSearch` maps to (`\"hnsw.ef_search\"`). */\n parameter: string;\n /**\n * The one index type whose search honors the parameter. `efSearch` on a\n * slot of any other index type is refused, not ignored: an IVFFlat or\n * brute-force slot would silently discard it.\n */\n indexType: VectorIndexType;\n /**\n * `true` when applying the parameter needs a transaction to scope it to\n * the one search. A backend that reports `transactions: false` refuses\n * `efSearch` rather than leaking a session-wide setting.\n */\n requiresTransactionScope: boolean;\n }>\n | Readonly<{\n tunable: false;\n /**\n * Why this engine has no per-search frontier knob — surfaced in the\n * refusal's details so the state is named rather than implied.\n */\n reason: string;\n }>;\n\n/**\n * Vector search capabilities.\n */\nexport type VectorCapabilities = Readonly<{\n /** Whether the backend supports vector operations */\n supported: boolean;\n /** Supported similarity metrics */\n metrics: readonly VectorMetric[];\n /** Supported index types */\n indexTypes: readonly VectorIndexType[];\n /** Maximum dimensions supported */\n maxDimensions: number;\n /**\n * How a filtered approximate search bounds recall — and whether it can\n * silently return a short page. See {@link FilteredApproximateSearch}.\n *\n * Required, so a new vector strategy cannot omit the declaration and inherit\n * an engine promise it does not keep.\n */\n filteredApproximateSearch: FilteredApproximateSearch;\n /**\n * Whether a per-search ANN frontier override (`efSearch`) can be applied.\n * See {@link VectorSearchFrontierTuning}.\n *\n * Required, so a new vector strategy must state whether it honors the\n * option instead of inheriting silence — the exact defect this closes.\n */\n searchFrontierTuning: VectorSearchFrontierTuning;\n}>;\n\n// ============================================================\n// Fulltext Search Types\n// ============================================================\n\n/**\n * Query modes for fulltext search.\n *\n * - \"websearch\": Google-style syntax (quoted phrases, +required, -excluded).\n * Postgres: `websearch_to_tsquery`. SQLite: translated to FTS5 MATCH.\n * - \"phrase\": treats the whole query as a phrase.\n * Postgres: `phraseto_tsquery`. SQLite: FTS5 `\"...\"` phrase.\n * - \"plain\": splits on whitespace and ANDs terms.\n * Postgres: `plainto_tsquery`. SQLite: default FTS5 AND.\n * - \"raw\": dialect-native syntax passed through unchanged.\n */\nexport type FulltextQueryMode = \"websearch\" | \"phrase\" | \"plain\" | \"raw\";\n\n/**\n * Fulltext search capabilities declared by a backend.\n */\nexport type FulltextCapabilities = Readonly<{\n /** Whether the backend supports fulltext operations */\n supported: boolean;\n /**\n * Language / tokenizer names understood by this backend.\n * Postgres: installed regconfigs (english, simple, ...).\n * SQLite FTS5: tokenizer names (unicode61, porter, trigram).\n */\n languages: readonly string[];\n /** Whether phrase queries are supported. */\n phraseQueries: boolean;\n /** Whether prefix (`foo*`) queries are supported. */\n prefixQueries: boolean;\n /** Whether highlighting / snippets are supported. */\n highlighting: boolean;\n}>;\n\n/**\n * Whole-graph analytics capabilities declared by a backend.\n *\n * `supported` means the backend can pin one transactional connection while\n * an algorithm creates, updates, and drops session-local temporary state.\n * `mathFunctions` records whether transcendental SQL functions needed by\n * deferred algorithms such as MCL/spectral are available; exact WCC does not\n * require them.\n */\nexport type GraphAnalyticsCapabilities = Readonly<{\n supported: boolean;\n mathFunctions: boolean;\n}>;\n\n/**\n * How much of the contribution health lifecycle a backend can serve.\n *\n * The three rungs escalate — probe (read-only) → repair\n * (non-destructive) → rebuild (destructive) — and each is declared\n * separately because a backend can genuinely stop at any of them. A\n * backend that provisions contributions but cannot probe its own catalog\n * is a real gap, and the honest answer to `store.probeContributions()`\n * there is a refusal, not `ready`: \"assessed and healthy\" and \"never\n * looked\" must never share a return value.\n */\nexport type ContributionCapabilities = Readonly<{\n /**\n * Whether strategy-owned contribution tables are provisioned and\n * attested by durable markers on this backend at all. `false` means\n * there is nothing to assess, and the probe reports no entries rather\n * than refusing.\n */\n supported: boolean;\n /**\n * Whether the backend can cross its durable markers against the live\n * catalog — `store.probeContributions()` and\n * `store.verifyContributions()`. False with `supported: true` is the\n * declared gap: both refuse with `ConfigurationError`.\n */\n probe: boolean;\n /**\n * Whether the backend can run the destructive drop → recreate →\n * repopulate → stamp rebuild (`store.rebuildContribution()`). Requires\n * both a strategy that declares `dropDdl` and a transactional schema\n * fence to run it under; false means `rebuildContribution` refuses.\n *\n * Describes the fulltext projection only. `rebuildContribution(\"vector\")`\n * refuses on every backend regardless of this flag — embeddings exist\n * only in the storage a rebuild would drop, so there is nothing to\n * reconstruct them from — and `reembedVectorField` is the sanctioned\n * destructive path there.\n */\n rebuild: boolean;\n}>;\n\n// ============================================================\n// SQL Dialect & Capabilities\n// ============================================================\n\nimport { type SqlDialect } from \"../query/dialect/types\";\n\nexport type { SqlDialect } from \"../query/dialect/types\";\n\nimport { type RecursiveTraversalCapability } from \"./capabilities/recursive-traversal\";\n\nexport type { RecursiveTraversalCapability } from \"./capabilities/recursive-traversal\";\n\nimport { type PessimisticLockCapabilities } from \"./capabilities/write-fence\";\n\nexport type { PessimisticLockCapabilities } from \"./capabilities/write-fence\";\n\n/**\n * Backend capabilities that vary by dialect.\n */\nexport type BackendCapabilities = Readonly<{\n /** Whether the backend supports atomic transactions (D1 does not) */\n transactions: boolean;\n /** Whether the backend supports SQL window functions such as ROW_NUMBER() */\n windowFunctions: boolean;\n /**\n * Whether `updateNode` / `updateEdge` honor `clearValidTo: true` by storing\n * SQL NULL in `valid_to`. Absent is `false`: custom backends must opt in so\n * the store refuses every explicit clear-bearing call before lookup,\n * coalescing, or write instead of making support depend on row state.\n */\n clearValidTo?: boolean;\n /**\n * Whether the backend's `execute()` supports `UPDATE … RETURNING`. Absent or\n * `true` means supported (every engine TypeGraph ships — SQLite ≥ 3.35,\n * PostgreSQL ≥ 8.2 — supports it). A custom backend whose engine cannot run\n * `RETURNING` must set this to `false` so recorded-time history capture\n * (`history: true`), which relies on `UPDATE … RETURNING` on its hot path,\n * is refused up front instead of failing mid-flush.\n */\n returning?: boolean;\n /**\n * Maximum number of bound parameters the engine accepts in one statement.\n * SQLite defaults to 999 (raisable at compile time via\n * `SQLITE_MAX_VARIABLE_NUMBER`), while hosted SQLite runtimes may impose a\n * lower platform ceiling. PostgreSQL's wire protocol encodes a 65535-count,\n * but postgres.js accepts at most 65533 bound values, so the bundled\n * PostgreSQL capability advertises that lower shared-driver ceiling.\n * Recorded-time capture and recorded point reads size their multi-row\n * statements to this ceiling — the same budget the backend's own batched\n * inserts use — instead of a conservative dialect-blind constant. Custom\n * runtimes can override a detected or probed limit here, but hosted platform\n * hard ceilings may only be lowered. Absent means the recorded-time fallback\n * budget applies.\n */\n maxBindParameters?: number;\n /**\n * Whether this backend supplies the claim relations that fence declared\n * constraints (`uniques`, re-keyed onto claim axes, plus\n * `typegraph_edge_claims`) AND implements the claim members.\n *\n * Absent means `false`: the backend predates the claim relations, keeps every\n * fence it has today, and is listed as such in the parity matrix. Never\n * INFERRED from member presence — a projection that forwarded `capabilities`\n * while dropping a method would otherwise yield a verdict read from a\n * different object than the write goes to. `claimSupport`\n * (`store/claims/backing.ts`) is the one reader, and it refuses a backend\n * whose declaration and surface disagree in either direction.\n */\n readonly constraintClaims?: boolean;\n /** Vector search capabilities (undefined if not configured) */\n vector?: VectorCapabilities | undefined;\n /** Fulltext search capabilities (undefined if not configured) */\n fulltext?: FulltextCapabilities | undefined;\n /** Whole-graph analytics capabilities (undefined when unavailable). */\n graphAnalytics?: GraphAnalyticsCapabilities | undefined;\n /**\n * How far up the contribution health ladder this backend goes\n * (undefined on a backend with no contribution machinery at all,\n * equivalent to every member `false`).\n */\n contributions?: ContributionCapabilities | undefined;\n /**\n * Whether this engine can compute a bounded transitive closure of a\n * relation in one round trip (a recursive CTE, or a graph-native\n * expansion operator).\n *\n * Absent means SUPPORTED. Every engine TypeGraph ships supports it, and\n * every custom backend on this release already has every recursion site\n * run against it unconditionally: making absence mean `false` would\n * refuse traversals that work today. See\n * {@link RecursiveTraversalCapability} for the full contract.\n */\n recursiveTraversal?: RecursiveTraversalCapability | undefined;\n /**\n * Whether this engine can serialize concurrent writers, and how: keyed\n * advisory locks, relation-level table locks, or a single writer slot that\n * serializes by construction.\n *\n * Absent means `unfenced` for any backend the first-party factories did\n * not build (`resolveWriteFencePlan`, `src/backend/capabilities/write-fence.ts`):\n * an undeclared custom backend is refused at construction for Operational\n * Identity and for TypeGraph-owned recorded-clock allocation\n * (`history` / `revisionTracking`) rather than silently emitting locks the\n * engine may not honor. Every first-party backend declares this member\n * (`SQLITE_CAPABILITIES`, `POSTGRES_CAPABILITIES`), so the refusal is\n * reachable only by a backend this library did not build.\n */\n pessimisticLocks?: PessimisticLockCapabilities | undefined;\n /**\n * Who allocates recorded-time revisions. `\"typegraph-relations\"` (the\n * default, and every first-party backend) means TypeGraph owns a clock row\n * and performs the read/advance/write that `lockRecordedClock` fences —\n * which is undegradable, so an `unfenced` engine is refused at\n * construction. `\"engine-native\"` means the engine supplies the recorded\n * axis itself (WS9's ruled BraidDB posture: pinned-handle `AS OF`).\n *\n * TODAY THE ENGINE-NATIVE READ/WRITE PATH DOES NOT EXIST YET (follow-up\n * F8, owned by WS9). The capture path allocates the TypeGraph clock\n * unconditionally, so declaring `\"engine-native\"` and enabling\n * clock-allocating history/revision tracking is refused at construction by\n * its own typed error naming the interim state\n * (`refuseEngineNativeRecordedTimeNotYetImplemented`,\n * `src/backend/capabilities/recorded-time-ownership.ts`).\n */\n recordedTimeOwnership?: \"typegraph-relations\" | \"engine-native\";\n}>;\n\n/** Keeps session-scoped analytics honest when a required SQL feature is absent. */\nexport function normalizeGraphAnalyticsCapabilities(\n capabilities: BackendCapabilities,\n): BackendCapabilities {\n if (\n capabilities.graphAnalytics?.supported !== true ||\n (capabilities.transactions &&\n capabilities.windowFunctions &&\n capabilities.returning !== false)\n ) {\n return capabilities;\n }\n return {\n ...capabilities,\n graphAnalytics: { ...capabilities.graphAnalytics, supported: false },\n };\n}\n\n// ============================================================\n// Row Types (Database Records)\n// ============================================================\n\n/**\n * A node/edge row's `props` column as the driver returned it: SQLite always\n * yields the JSON text; PostgreSQL drivers yield the jsonb value already\n * parsed. Keeping the driver's shape avoids a per-row\n * parse→stringify→re-parse round trip on the PostgreSQL read path —\n * consumers normalize through {@link rowPropsToObject} /\n * {@link rowPropsToJsonText} at the point of use.\n */\nexport type RowProps = string | Readonly<Record<string, unknown>>;\n\n/** The row's props as an object, parsing only when the driver gave text. */\nexport function rowPropsToObject(props: RowProps): Record<string, unknown> {\n return typeof props === \"string\" ?\n (JSON.parse(props) as Record<string, unknown>)\n : props;\n}\n\n/** The row's props as JSON text, serializing only when the driver gave an object. */\nexport function rowPropsToJsonText(props: RowProps): string {\n return typeof props === \"string\" ? props : JSON.stringify(props);\n}\n\n/**\n * A row from the typegraph_nodes table.\n */\nexport type NodeRow = Readonly<{\n graph_id: string;\n kind: string;\n id: string;\n props: RowProps;\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/**\n * A {@link NodeRow} proven live (not soft-deleted). Functions that must only\n * ever touch live rows — the live-row update pipeline, soft delete — take\n * this type so a caller holding a possibly-tombstoned row is forced through\n * {@link isLiveNodeRow} first, instead of silently running live-row side\n * effects (uniqueness reservations, embedding/fulltext sync) for a row that\n * stays invisible.\n */\nexport type LiveNodeRow = NodeRow & Readonly<{ deleted_at: undefined }>;\n\n/**\n * A {@link NodeRow} proven soft-deleted. A resurrect targets exactly this\n * shape; see {@link isTombstonedNodeRow}.\n */\nexport type TombstonedNodeRow = NodeRow & Readonly<{ deleted_at: string }>;\n\nexport function isLiveNodeRow(row: NodeRow): row is LiveNodeRow {\n return row.deleted_at === undefined;\n}\n\nexport function isTombstonedNodeRow(row: NodeRow): row is TombstonedNodeRow {\n return row.deleted_at !== undefined;\n}\n\n/**\n * The read-only slice of a backend. Give this type to code that is\n * semantically a read — probes, gates, support-graph loads — so a read path\n * structurally CANNOT open a write transaction, mutate rows, or execute raw\n * SQL: those members do not exist on the type. Extend the pick as read paths\n * need more of the read surface.\n */\nexport type GraphReadBackend = Pick<\n GraphBackend,\n | \"dialect\"\n | \"getNode\"\n | \"getEdge\"\n | \"findNodesByKind\"\n | \"findEdgesByKind\"\n | \"findEdgesConnectedTo\"\n>;\n\n/**\n * A row from the typegraph_edges table.\n */\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: RowProps;\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 * A row from the typegraph_node_uniques table.\n */\nexport type UniqueRow = Readonly<{\n graph_id: string;\n node_kind: string;\n constraint_name: string;\n key: string;\n node_id: string;\n concrete_kind: string;\n deleted_at: string | undefined;\n}>;\n\n/**\n * A row from the typegraph_schema_versions table.\n */\nexport type SchemaVersionRow = Readonly<{\n graph_id: string;\n version: number;\n schema_hash: string;\n schema_doc: string; // JSON string\n created_at: string;\n is_active: boolean;\n}>;\n\n// ============================================================\n// Insert Parameters\n// ============================================================\n\n/**\n * Parameters for inserting a node.\n */\nexport type InsertNodeParams = Readonly<{\n graphId: string;\n kind: string;\n id: string;\n props: Readonly<Record<string, unknown>>;\n /**\n * Omitted (`undefined`): the insert stamps its own creation timestamp —\n * UNLESS a stated `validTo` at or before that instant would make the stored\n * window readable at no coordinate, in which case the row is stored with no\n * lower bound (\"ended at T, start unknown\"). See\n * `resolveStampedValidityLowerBound`, which every insert builder decides\n * through. Custom backend implementations can import that owner from\n * `@nicia-ai/typegraph/backend` rather than reimplementing the rule.\n * `null`: preserves an explicit open-left validity window (no lower\n * bound) — used by interchange import to round-trip a row that was\n * already NULL, instead of re-stamping it to the import's own timestamp.\n */\n validFrom?: string | null;\n validTo?: string;\n}>;\n\n/**\n * A backend validity-end mutation. Omission preserves the stored end,\n * `validTo` sets it, and `clearValidTo` reopens the window. The union keeps the\n * two write actions mutually exclusive without exposing SQL `NULL`.\n */\nexport type BackendValidityEndMutation =\n | Readonly<{ validTo?: string; clearValidTo?: never }>\n | Readonly<{ validTo?: never; clearValidTo: true }>;\n\n/** Parameters for updating a node. */\nexport type UpdateNodeParams = Readonly<{\n graphId: string;\n kind: string;\n id: string;\n props: Readonly<Record<string, unknown>>;\n /**\n * Applied when resurrecting a tombstone, which RESETS the window. Omitted\n * means the resurrection instant — unless a stated `validTo` at or before it\n * would leave the row readable at no coordinate, in which case the\n * resurrection stores no lower bound. Same rule, same owner, as an insert:\n * `resolveStampedValidityLowerBound`.\n *\n * The store's own resurrection paths never omit it. Their window guard has to\n * judge the bound the write will STORE, so they resolve it through that owner\n * against the instant they sampled and pass the result — `null` included,\n * which is how \"store no lower bound\" is spelled here. Omission is for callers\n * with no such verdict to honor; it lets this builder decide against its own,\n * strictly later sample.\n */\n validFrom?: string | null;\n /**\n * The effective `valid_from` this write ASSERTS the target row already\n * carries, stated only by a caller whose decision DEPENDED on it.\n *\n * `(graph_id, kind, id)` does not pin a row across time. A caller that\n * validated the document's window against the bound it probed — interchange\n * import's `onConflict: \"update\"` is the case — decided what to write from a\n * value a concurrent `hardDelete` + recreate can replace between the probe\n * and the write, so a predicate on identity alone lets that decision land on\n * a row it was never computed for: the document's stated `validFrom` is\n * ignored, or a `valid_to` is persisted below the new row's `valid_from`.\n * Stating the bound here puts it in the UPDATE's own `WHERE`, which is the\n * only placement the race cannot slip past.\n *\n * NULL-SAFE: `null` asserts the row has NO lower bound (`IS NULL`), a string\n * asserts equality, and omitting it asserts nothing. `null` and `undefined`\n * are therefore NOT interchangeable here — see `expectedValidFromPredicate`.\n *\n * A backend MUST apply the predicate when it is present, on the same terms as\n * {@link UpdateEdgeParams.kind}: silently ignoring it re-opens the window the\n * caller stated it to close. A write whose stated bound does not match affects\n * zero rows and surfaces as a `no_row_returned` `DatabaseOperationError`.\n */\n expectedValidFrom?: string | null;\n incrementVersion?: boolean;\n /** If true, clears deleted_at (un-deletes the node). Used by upsert. */\n clearDeleted?: boolean;\n}> &\n BackendValidityEndMutation;\n\n/**\n * Parameters for updating a set of live nodes selected by a compiled\n * TypeGraph query.\n *\n * The candidate query must expose the named node-id column from the same graph\n * and kind. The backend independently fences the rows it writes to\n * `graphId` and `kind`; constructing the matching candidate query remains the\n * caller's responsibility.\n * Property values replace top-level keys, including preserving an explicit\n * JSON `null` value.\n *\n * This is a storage primitive: callers that expose it as a graph mutation are\n * responsible for schema validation and for synchronizing uniqueness,\n * fulltext, and vector sidecars. The result contains after-images only; callers\n * that need previous property values must freeze the candidate set and retain\n * its before-images in the same transaction before invoking this method.\n */\nexport type UpdateNodeSetParams = Readonly<{\n graphId: string;\n kind: string;\n patch: Readonly<Record<string, JsonValue>>;\n /** Top-level properties to remove (the storage form of an `undefined` patch value). */\n unsetProperties?: readonly string[];\n candidateIds: CompiledSelectSql;\n /** Projected SQL column holding the candidate node id (for example `n_id`). */\n candidateIdColumn: string;\n}>;\n\n/** The after-images changed by {@link GraphBackend.updateNodeSet}. */\nexport type UpdateNodeSetResult = Readonly<{\n affectedCount: number;\n rows: readonly NodeRow[];\n}>;\n\n/**\n * Parameters for deleting a node (soft delete).\n */\nexport type DeleteNodeParams = Readonly<{\n graphId: string;\n kind: string;\n id: string;\n}>;\n\n/**\n * Parameters for inserting an edge.\n */\nexport type InsertEdgeParams = Readonly<{\n graphId: string;\n id: string;\n kind: string;\n fromKind: string;\n fromId: string;\n toKind: string;\n toId: string;\n props: Readonly<Record<string, unknown>>;\n /**\n * Omitted (`undefined`): the insert stamps its own creation timestamp —\n * UNLESS a stated `validTo` at or before that instant would make the stored\n * window readable at no coordinate, in which case the row is stored with no\n * lower bound (\"ended at T, start unknown\"). See\n * `resolveStampedValidityLowerBound`, which every insert builder decides\n * through. Custom backend implementations can import that owner from\n * `@nicia-ai/typegraph/backend` rather than reimplementing the rule.\n * `null`: preserves an explicit open-left validity window (no lower\n * bound) — used by interchange import to round-trip a row that was\n * already NULL, instead of re-stamping it to the import's own timestamp.\n */\n validFrom?: string | null;\n validTo?: string;\n}>;\n\n/**\n * Write-only session exposed inside {@link GraphBackend.trustedImport}.\n *\n * The caller has accepted the trusted-import contract: properties, endpoint\n * references, uniqueness, and cardinality are not validated. Backends may\n * therefore use engine-native ingestion primitives that bypass the normal\n * store write pipeline.\n */\nexport type TrustedImportSession = Readonly<{\n insertNodes: (params: readonly InsertNodeParams[]) => Promise<void>;\n insertEdges: (params: readonly InsertEdgeParams[]) => Promise<void>;\n}>;\n\n/**\n * Parameters for updating an edge.\n */\nexport type UpdateEdgeParams = Readonly<{\n graphId: string;\n id: string;\n /**\n * The kind this write ASSERTS the target row already carries.\n *\n * Edge ids are graph-global while public collections are kind-scoped, so a\n * kind-scoped write has an expected kind and must not land on a row carrying\n * a different one. Stating it here puts the predicate in the write\n * statement's own `WHERE`, which is the only placement a concurrent\n * `hardDelete` + recreate cannot slip past: a read-then-write pair keyed on\n * `(graph_id, id)` alone re-resolves that id between the read and the write\n * under PostgreSQL READ COMMITTED. A write whose stated kind does not match\n * affects zero rows.\n *\n * A backend MUST apply the predicate when it is present — silently ignoring\n * it re-opens the window the caller stated it to close, and the ignoring\n * backend looks correct until it is raced.\n * `tests/edge-write-self-verification.test.ts` asserts the behavior against\n * the built-in backends.\n *\n * Omitted where the operation legitimately spans kinds: the node delete\n * cascade removes every connected edge whatever its kind, so it states none.\n * {@link DeleteEdgeParams} and {@link HardDeleteEdgeParams} carry the same\n * field with the same contract.\n */\n kind?: string;\n /**\n * The ENDPOINTS this write asserts the target row already carries, stated\n * only by a write that actually checked them.\n *\n * Kind alone does not pin a row's identity. An edge's endpoints are immutable\n * for a given row, but the ID is not: a concurrent `hardDelete` + recreate\n * under the SAME kind with DIFFERENT endpoints satisfies a kind-only\n * predicate, so an upsert that resolved this id BY endpoints could otherwise\n * write to an edge pointing somewhere it never looked. Carrying them here\n * closes that, on the same terms and in the same `WHERE` as `kind`.\n *\n * All four move together or not at all — they are one assertion. A plain\n * `update` on a kind-scoped collection states none of them, because it\n * resolved the edge by id and kind and made no claim about where it points;\n * predicating on endpoints it never checked would refuse legitimate writes.\n * The same MUST-apply contract as `kind` binds a backend that receives them.\n */\n fromKind?: string;\n fromId?: string;\n toKind?: string;\n toId?: string;\n props: Readonly<Record<string, unknown>>;\n /**\n * Applied when resurrecting a tombstone, where it asserts a COMPLETE window:\n * `validTo` is rewritten alongside it (omitted `validTo` reopens the window).\n * Omitting `validFrom` on a resurrection leaves the stored window in place.\n */\n validFrom?: string | null;\n /**\n * The effective `valid_from` this write asserts the target row already\n * carries. Same three states, same NULL-safety, and the same MUST-apply\n * contract as {@link UpdateNodeParams.expectedValidFrom}; stated by the same\n * kind of caller, one whose verdict READ that bound.\n *\n * Separate from the immutable-identity components above because it is not\n * immutable: a resurrection rewrites `valid_from`. It is asserted for the\n * opposite reason — precisely because it can change, a decision computed from\n * it must be fenced against it having changed.\n */\n expectedValidFrom?: string | null;\n /**\n * The `valid_to` state a constraint decision read. NULL-safe and MUST apply\n * when present, like `expectedValidFrom`; used to fence ended-to-open edges.\n */\n expectedValidTo?: string | null;\n clearDeleted?: boolean;\n}> &\n BackendValidityEndMutation;\n\n/**\n * Parameters for deleting an edge (soft delete).\n */\nexport type DeleteEdgeParams = Readonly<{\n graphId: string;\n id: string;\n /** See {@link UpdateEdgeParams.kind}. */\n kind?: string;\n}>;\n\n/**\n * Parameters for hard deleting a node (permanent removal).\n */\nexport type HardDeleteNodeParams = Readonly<{\n graphId: string;\n kind: string;\n id: string;\n}>;\n\n/**\n * Parameters for hard deleting an edge (permanent removal).\n */\nexport type HardDeleteEdgeParams = Readonly<{\n graphId: string;\n id: string;\n /** See {@link UpdateEdgeParams.kind}. */\n kind?: string;\n}>;\n\n/** Parameters for a batched edge delete (soft or hard). */\nexport type DeleteEdgesBatchParams = Readonly<{\n graphId: string;\n ids: readonly string[];\n}>;\n\n// ============================================================\n// Embedding Parameters\n// ============================================================\n\n/**\n * Parameters for inserting or updating an embedding.\n *\n * `dimensions`, `metric`, and `indexType` together resolve the slot's\n * typed per-`(nodeKind, fieldPath)` storage (the strategy needs the fixed\n * dimension for the column type, and the metric/index type to address the\n * right ANN structure). The store populates them from the schema's\n * `embedding()` declaration via `getEmbeddingDimensions()` /\n * `getEmbeddingIndex()`; the backend constructs a `VectorSlot` from them\n * and stays graph-agnostic.\n */\nexport type UpsertEmbeddingParams = Readonly<{\n graphId: string;\n nodeKind: string;\n nodeId: string;\n fieldPath: string;\n embedding: readonly number[];\n dimensions: number;\n metric: VectorMetric;\n indexType: VectorIndexType;\n}>;\n\n/**\n * One row of a batched embedding upsert.\n */\nexport type UpsertEmbeddingBatchRow = Readonly<{\n nodeId: string;\n embedding: readonly number[];\n}>;\n\n/**\n * Parameters for a batched embedding upsert. Homogeneous per vector slot:\n * one graph, one node kind, one field, many nodes. Duplicate `nodeId`\n * values within a batch are deduplicated last-write-wins by the backend\n * (a multi-row upsert cannot affect one row twice).\n */\nexport type UpsertEmbeddingBatchParams = Readonly<{\n graphId: string;\n nodeKind: string;\n fieldPath: string;\n dimensions: number;\n metric: VectorMetric;\n indexType: VectorIndexType;\n rows: readonly UpsertEmbeddingBatchRow[];\n}>;\n\n/**\n * Parameters for deleting an embedding.\n *\n * `dimensions` / `metric` / `indexType` mirror {@link UpsertEmbeddingParams}\n * so the backend can resolve the slot's typed per-`(nodeKind, fieldPath)`\n * storage and idempotently ensure it exists before the DELETE. That\n * matters because a delete can run before any embedding was ever written\n * (e.g. a node hard-deleted having never carried one), and on Postgres a\n * DELETE against a missing relation inside a transaction aborts the whole\n * transaction. The store populates them from the schema's `embedding()`\n * declaration, exactly as for upserts.\n */\nexport type DeleteEmbeddingParams = Readonly<{\n graphId: string;\n nodeKind: string;\n nodeId: string;\n fieldPath: string;\n dimensions: number;\n metric: VectorMetric;\n indexType: VectorIndexType;\n}>;\n\n/**\n * Parameters for vector similarity search.\n */\nexport type VectorSearchParams = Readonly<{\n graphId: string;\n nodeKind: string;\n fieldPath: string;\n queryEmbedding: readonly number[];\n metric: VectorMetric;\n /**\n * Fixed vector dimension `N` for the searched `(nodeKind, fieldPath)`\n * slot. The store populates it from the schema's `embedding()`\n * declaration via `getEmbeddingDimensions()`; the backend uses it to\n * construct the `VectorSlot` whose typed storage the strategy scans.\n */\n dimensions: number;\n /**\n * Index type materialized for this slot. `\"none\"` means brute-force\n * only; otherwise the strategy may route through its ANN structure.\n * The store populates it from `getEmbeddingIndex()`.\n */\n indexType: VectorIndexType;\n limit: number;\n minScore?: number;\n /**\n * Subquery of eligible node ids (single column, exposed as `node_id`).\n * When present, the search statement computes top-k over this candidate\n * set — the store passes its compiled current-read query here so\n * `where` predicates push down into the search SQL. Exact on engines\n * whose search form takes the filter inside retrieval (pgvector,\n * sqlite-vec, tsvector, FTS5); libSQL's DiskANN cannot pre-filter, so\n * it post-filters an over-fetched ANN set and recall against the\n * candidate set is bounded by that headroom. When absent, the backend\n * restricts to CURRENT nodes of the kind — non-tombstoned AND inside\n * their validity window — matching a `current` read.\n */\n candidates?: SqlFragment;\n /**\n * Rows to skip AFTER ranking (pagination). The engine fetches\n * `limit + offset` ranked candidates and discards the first `offset`.\n */\n offset?: number;\n /**\n * HNSW search frontier for this query (pgvector `hnsw.ef_search`).\n * Sizes the dynamic candidate list the index scan maintains: higher\n * trades latency for recall. The floor for the over-fetch to fill its\n * candidate set is `efSearch >= limit`; ~2–4× is the high-recall\n * target. Applied transaction-locally (`SET LOCAL`) on the Postgres\n * HNSW path only.\n *\n * APPLIED OR REFUSED, never ignored. Read\n * `capabilities.vector.searchFrontierTuning` to know which you get:\n *\n * - `tunable: false` (sqlite-vec, libSQL DiskANN — no per-search frontier\n * knob exists): `UnsupportedBackendCapabilityError`.\n * - a slot whose index type is not the tunable one (pgvector IVFFlat or\n * brute-force): `ConfigurationError`.\n * - `requiresTransactionScope` on a backend reporting\n * `transactions: false` (for example `drizzle-orm/neon-http`):\n * `UnsupportedBackendCapabilityError`, because `SET LOCAL` has no frame\n * to be local to.\n */\n efSearch?: number;\n}>;\n\n/**\n * Result from a vector similarity search.\n */\nexport type VectorSearchResult = Readonly<{\n nodeId: string;\n /**\n * Cosine metric returns similarity score (higher is better).\n * L2 and inner_product return raw distance (lower is better).\n */\n score: number;\n}>;\n\n/**\n * Parameters for a single-statement hybrid (vector + fulltext, RRF-fused)\n * search. The store facade resolves every default before calling — the\n * per-source candidate depths (`k`), the fusion constants, and the shared\n * `candidates` subquery — so the backend composes `SqlFragment` values without policy.\n */\nexport type HybridSearchParams = Readonly<{\n graphId: string;\n nodeKind: string;\n vector: Readonly<{\n fieldPath: string;\n queryEmbedding: readonly number[];\n metric: VectorMetric;\n dimensions: number;\n indexType: VectorIndexType;\n /** Candidate depth of the vector source (rows entering fusion). */\n k: number;\n minScore?: number;\n efSearch?: number;\n }>;\n fulltext: Readonly<{\n query: string;\n mode?: FulltextQueryMode;\n language?: string;\n /** Candidate depth of the fulltext source (rows entering fusion). */\n k: number;\n minScore?: number;\n includeSnippets?: boolean;\n }>;\n fusion: Readonly<{\n /** RRF rank constant (`1 / (k + rank)`). */\n k: number;\n vectorWeight: number;\n fulltextWeight: number;\n }>;\n /** Fused rows to return after `offset`. */\n limit: number;\n /** Fused rows to skip (rank-relative pagination). */\n offset?: number;\n /** See {@link VectorSearchParams.candidates}; applies to both sources. */\n candidates?: SqlFragment;\n}>;\n\n/**\n * One fused hybrid hit, hydrated in the same statement: the node row\n * rides along so the caller needs no follow-up id fetch.\n */\nexport type HybridSearchRow = Readonly<{\n node: NodeRow;\n fusedScore: number;\n vectorRank?: number;\n vectorScore?: number;\n fulltextRank?: number;\n fulltextScore?: number;\n snippet?: string;\n}>;\n\n/**\n * Parameters for creating a vector index.\n */\nexport type CreateVectorIndexParams = Readonly<{\n graphId: string;\n nodeKind: string;\n fieldPath: string;\n dimensions: number;\n metric: VectorMetric;\n indexType: VectorIndexType;\n /** Index-specific parameters */\n indexParams?: Readonly<{\n /** HNSW: max connections per layer */\n m?: number;\n /** HNSW: construction search depth */\n efConstruction?: number;\n /** IVFFlat: number of lists */\n lists?: number;\n }>;\n /**\n * Build the index without taking an `AccessExclusiveLock` on live\n * tables (Postgres `CREATE INDEX CONCURRENTLY`). Mirrors the\n * `concurrent` flag the relational DDL path uses inside\n * `materializeIndexes()`. Cannot be set inside a transaction —\n * callers (`materializeIndexes()`) run at top level. Backends that\n * don't have a CONCURRENTLY equivalent (SQLite) ignore this flag.\n */\n concurrent?: boolean;\n}>;\n\n/**\n * Parameters for dropping a vector index.\n */\nexport type DropVectorIndexParams = Readonly<{\n graphId: string;\n nodeKind: string;\n fieldPath: string;\n}>;\n\n// ============================================================\n// Fulltext Parameters\n// ============================================================\n\n/**\n * Parameters for inserting or updating a fulltext entry.\n *\n * One row per node. Callers concatenate the searchable fields into\n * `content` so a single MATCH query can find terms spread across fields.\n *\n * Note: `createFulltextIndex` / `dropFulltextIndex` were removed as\n * dead code in #PR_E. The fulltext table's canonical index (Postgres\n * GIN on `tsv`, SQLite FTS5 virtual table) is created with the table\n * itself by `bootstrapTables` per the active `FulltextStrategy`;\n * per-kind fulltext indexes are an \"advanced strategy\" surface that\n * doesn't fit the relational-style declaration model and is reserved\n * for future work.\n */\nexport type UpsertFulltextParams = Readonly<{\n graphId: string;\n nodeKind: string;\n nodeId: string;\n content: string;\n language: string;\n}>;\n\n/**\n * Parameters for deleting a single fulltext entry.\n */\nexport type DeleteFulltextParams = Readonly<{\n graphId: string;\n nodeKind: string;\n nodeId: string;\n}>;\n\n/**\n * A single row in a fulltext batch upsert.\n */\nexport type FulltextBatchRow = Readonly<{\n nodeId: string;\n content: string;\n language: string;\n}>;\n\n/**\n * Parameters for a batched fulltext upsert.\n *\n * Homogeneous: one graph, one node kind, many nodes. Duplicate `nodeId`\n * values within a single batch are deduplicated last-write-wins by the\n * builders before SQL generation — Postgres `ON CONFLICT` errors on\n * repeated conflict keys in one statement, and SQLite `DELETE + INSERT`\n * would create duplicate virtual-table rows otherwise.\n */\nexport type UpsertFulltextBatchParams = Readonly<{\n graphId: string;\n nodeKind: string;\n rows: readonly FulltextBatchRow[];\n}>;\n\n/**\n * Parameters for a batched fulltext delete.\n */\nexport type DeleteFulltextBatchParams = Readonly<{\n graphId: string;\n nodeKind: string;\n nodeIds: readonly string[];\n}>;\n\n/**\n * Parameters for fulltext search.\n */\nexport type FulltextSearchParams = Readonly<{\n graphId: string;\n nodeKind: string;\n /** The user-supplied query string. */\n query: string;\n /** How to parse `query`. Default: \"websearch\". */\n mode?: FulltextQueryMode;\n /**\n * Language for query parsing. The store facade resolves the kind's\n * declared language and passes it here, so the tsquery is a plan-time\n * constant (GIN-servable); when absent the backend falls back to the\n * per-row language column.\n * Postgres: passed as the regconfig to `to_tsquery` / `websearch_to_tsquery`.\n * SQLite: informational only (FTS5 tokenizer is fixed at table-create time).\n */\n language?: string;\n /** Max rows to return. */\n limit: number;\n /** Minimum rank to include (backend-dependent units). */\n minScore?: number;\n /** Whether to return a highlighted snippet per match. */\n includeSnippets?: boolean;\n /**\n * Subquery of eligible node ids (single column). When present, the\n * search statement computes top-k over this candidate set — the store\n * passes its compiled current-read query here so `where` predicates,\n * subclass expansion, and valid-time currency all push down into the\n * search SQL. Exact on engines whose search form takes the filter\n * inside retrieval (pgvector, sqlite-vec, tsvector, FTS5); libSQL's\n * DiskANN cannot pre-filter, so it post-filters an over-fetched ANN\n * set and recall against the candidate set is bounded by that\n * headroom. When absent, the backend restricts to CURRENT nodes of\n * the kind — non-tombstoned AND inside their validity window —\n * matching a `current` read.\n */\n candidates?: SqlFragment;\n /**\n * Rows to skip AFTER ranking (pagination). The engine fetches\n * `limit + offset` ranked candidates and discards the first `offset`.\n */\n offset?: number;\n}>;\n\n/**\n * Result from a fulltext search.\n *\n * Score semantics differ by backend; prefer `rank` (1-based) when fusing\n * with another source via RRF.\n */\nexport type FulltextSearchResult = Readonly<{\n nodeId: string;\n /**\n * Backend-native relevance score.\n * Postgres: `ts_rank_cd` (higher is better).\n * SQLite FTS5: negated `bm25()` (higher is better; FTS5 returns lower-is-better).\n */\n score: number;\n /** 1-based rank within the result set, suitable for RRF. */\n rank: number;\n /** Highlighted snippet of the content (if `includeSnippets` was set). */\n snippet?: string;\n}>;\n\n/**\n * Parameters for creating a fulltext index.\n *\n * The canonical index (Postgres GIN on `tsv`, SQLite FTS5 virtual table)\n * is created when the fulltext table itself is created. This is reserved\n * for advanced per-kind specializations.\n */\n\n// ============================================================\n// Index Materialization Status\n// ============================================================\n\n/**\n * Per-deployment record for a single declared index.\n *\n * Identified by `indexName` because SQL index names are physical,\n * database-global identifiers — `graphId` is provenance, not identity.\n * `materializedAt` is null until the first successful CREATE INDEX\n * completes; `lastAttemptedAt` is always set, even on failure.\n */\n/**\n * Parameters for atomically claiming an index build (see\n * `claimIndexMaterialization`). The declaration fields ride along so a\n * fresh claim row is honest while the build is in flight.\n */\nexport type ClaimIndexMaterializationParams = Readonly<{\n indexName: string;\n graphId: string;\n entity: IndexEntity;\n kind: string;\n signature: string;\n schemaVersion: number;\n /** Opaque claim identity; release is token-guarded. */\n token: string;\n /** A claim older than this is stale and may be taken over. */\n leaseMs: number;\n}>;\n\n/** Parameters for releasing a build claim (token-guarded). */\nexport type ReleaseIndexMaterializationClaimParams = Readonly<{\n indexName: string;\n token: string;\n}>;\n\nexport type IndexMaterializationRow = Readonly<{\n indexName: string;\n graphId: string;\n entity: IndexEntity;\n kind: string;\n signature: string;\n schemaVersion: number;\n materializedAt: string | undefined;\n lastAttemptedAt: string;\n lastError: string | undefined;\n}>;\n\n/**\n * Parameters for upserting a materialization attempt.\n *\n * On success: pass `materializedAt` (ISO timestamp) and undefined `error`.\n * On failure: pass undefined `materializedAt` (preserve any existing\n * timestamp from a prior success) and the error message.\n */\nexport type RecordIndexMaterializationParams = Readonly<{\n indexName: string;\n graphId: string;\n entity: IndexEntity;\n kind: string;\n signature: string;\n schemaVersion: number;\n attemptedAt: string;\n /** ISO timestamp on success; undefined on failure (preserves existing). */\n materializedAt: string | undefined;\n /** Error message on failure; undefined on success (clears existing). */\n error: string | undefined;\n}>;\n\n// ============================================================\n// Contribution Materializations (#135 — durable strategy-owned\n// storage marker, sibling of index materializations)\n// ============================================================\n\n/**\n * Durable identity of a strategy-owned table contribution (#129),\n * scoped to a graph. This is the primary key of\n * `typegraph_contribution_materializations`.\n *\n * `logicalName` is the stable slot (\"fulltext\"); `owner` is the\n * producing strategy (\"tsvector\" / \"fts5\"); `tableName` is the resolved\n * physical name (custom per-deployment names must be distinguishable).\n * `graphId` is part of identity here — unlike the index status table\n * where the physical index name is database-global, two graphs can each\n * own a logically-identical fulltext contribution.\n */\nexport type ContributionMaterializationIdentity = Readonly<{\n graphId: string;\n logicalName: string;\n owner: string;\n tableName: string;\n}>;\n\n/**\n * Per-deployment record that a strategy-owned contribution has been\n * durably materialized against this database.\n *\n * `signature` is intentionally NOT part of the identity: a row with the\n * same identity but a different signature means \"materialized artifact\n * is stale/drifted\" — a loud error on the hot path, never a silent\n * re-materialize. `materializedAt` is undefined until the first\n * successful materialization; `lastAttemptedAt` is always set.\n */\nexport type ContributionMaterializationRow = Readonly<{\n graphId: string;\n logicalName: string;\n owner: string;\n tableName: string;\n signature: string;\n materializedAt: string | undefined;\n lastAttemptedAt: string;\n lastError: string | undefined;\n}>;\n\n/**\n * Parameters for upserting a contribution-materialization attempt.\n * Same success/failure contract as\n * {@link RecordIndexMaterializationParams}: on failure pass undefined\n * `materializedAt` so a prior successful timestamp is preserved via\n * COALESCE, and the error message.\n */\nexport type RecordContributionMaterializationParams = Readonly<{\n graphId: string;\n logicalName: string;\n owner: string;\n tableName: string;\n signature: string;\n attemptedAt: string;\n /** ISO timestamp on success; undefined on failure (preserves existing). */\n materializedAt: string | undefined;\n /** Error message on failure; undefined on success (clears existing). */\n error: string | undefined;\n}>;\n\n/**\n * Why a contribution is not usable. Most members are a disagreement\n * between the durable marker and the physical catalog; one\n * (`failed-materialization`) is a state the two agree on and that is\n * broken anyway. A contribution that is genuinely healthy — or that was\n * simply never attempted — is not reported at all.\n *\n * - `orphaned-marker` — the marker records a successful materialization\n * but the physical table is gone (a partial restore, an out-of-band\n * `DROP`, a schema-scoped restore that missed the contribution\n * tables). The state {@link GraphBackend.verifyContributions} exists\n * to surface: nothing on the open path probes the catalog, so this\n * database opens clean and fails at the first dependent read or write.\n * - `missing-marker` — the physical table exists but no marker attests\n * it as initialized (no row, no recorded success, or a recorded\n * failure). Reads and writes are refused with\n * `StoreNotInitializedError` even though storage is present. These\n * three causes share one state because they share one repair; check\n * {@link ContributionDiagnostic.lastError} to tell them apart.\n * - `failed-materialization` — the marker records a *failed* attempt\n * and no table was produced. Marker and catalog agree here, so this\n * is not a disagreement — but it is where a contribution lands when\n * provisioning genuinely broke (the `fts5` module is absent, the role\n * lacks `CREATE`, the extension was never loaded), and calling it\n * healthy on the grounds that both sides agree would be the one\n * answer this method must never give. Distinguished from a\n * contribution that was never attempted, which has no marker row and\n * is correctly silent. {@link ContributionDiagnostic.lastError}\n * carries the reason it failed.\n * - `stale` — the table exists and the marker records a prior success\n * at a different signature (a strategy swap, or a declared embedding\n * dimension that has moved ahead of the provisioned table).\n *\n * **Do not re-frame this union as \"how the marker disagrees with the\n * catalog.\"** It was described that way once, and the description was\n * load-bearing in the wrong direction: under it, a marker recording a\n * failed attempt with no table looks like agreement, therefore not a\n * disagreement, therefore correctly silent — and a contribution that\n * had genuinely broken was reported as healthy. The gap read as\n * principled rather than as an oversight precisely because the framing\n * endorsed it. \"Why the contribution is unusable\" is the question that\n * makes `failed-materialization` obviously belong, and any future\n * tidy-up that narrows the framing back will re-open the same hole.\n */\nexport type ContributionDiagnosticState =\n \"orphaned-marker\" | \"missing-marker\" | \"failed-materialization\" | \"stale\";\n\n/**\n * One contribution that is not usable, reported by\n * {@link GraphBackend.verifyContributions}.\n *\n * The identity fields come from the active contribution declaration and\n * match the durable-marker identity contract, so a caller can route an entry\n * to its repair without reconstructing any internal naming contract. A\n * `missing-marker` entry may have no marker row at all.\n *\n * **Route on {@link ContributionDiagnosticState}, not on whether the\n * entry is a vector slot.** The repair differs per state and the wrong\n * choice destroys data: `store.reembedVectorField` drops and recreates\n * storage, so applying it to a `missing-marker` — where the table is\n * intact and only the bookkeeping is wrong — discards every embedding\n * to fix a marker, and without an `embed` callback it leaves the field\n * empty. Prefer `store.repairContributions()` for `missing-marker` and\n * `failed-materialization`; it resolves the current strategy declarations\n * internally and keeps the normal signature-drift guard enabled. It reports\n * `stale` and `orphaned-marker` as `requires-rebuild`. See the per-state\n * repair table in the troubleshooting guide.\n */\nexport type ContributionDiagnostic = Readonly<{\n /** Producing strategy, e.g. `\"fts5\"` / `\"tsvector\"` / `\"pgvector\"`. */\n owner: string;\n /** Stable logical slot, e.g. `\"fulltext\"`. Never the SQL name. */\n logicalName: string;\n /** Resolved physical table name that was probed. */\n physicalName: string;\n /** Node kind — vector slots only. */\n kind?: string;\n /** Embedding field path — vector slots only. */\n fieldPath?: string;\n state: ContributionDiagnosticState;\n /**\n * The error the marker recorded against its last attempt, when it\n * recorded one. Absent otherwise.\n *\n * This is the part of the picture the catalog cannot supply. `state`\n * says what to do — the states are chosen so that each maps to one\n * repair — while this says *why it broke*, which is a different\n * question and often a different investigation. A failed attempt with no\n * table surfaces as `failed-materialization`; when the table exists but\n * the marker does not attest a successful materialization, it surfaces as\n * `missing-marker`. This field distinguishes only failures whose marker\n * recorded a reason; a missing row has no `lastError`. Present on any state\n * whose marker row carries an error, not just those two states.\n */\n lastError?: string;\n}>;\n\n/**\n * Outcome of one contribution considered by\n * {@link GraphBackend.repairContributions}.\n *\n * Repair targets are always resolved from the backend's current strategy\n * declarations. The diagnostic is returned for operator context only; callers\n * never pass diagnostics or physical DDL back into the repair API.\n */\nexport type ContributionRepairEntry =\n | Readonly<{\n diagnostic: ContributionDiagnostic;\n status: \"repaired\";\n }>\n | Readonly<{\n diagnostic: ContributionDiagnostic;\n status: \"requires-rebuild\";\n }>\n | Readonly<{\n diagnostic: ContributionDiagnostic;\n status: \"failed\";\n error: string;\n }>;\n\n/** Result of a contribution repair pass followed by a fresh verification. */\nexport type ContributionRepairResult = Readonly<{\n results: readonly ContributionRepairEntry[];\n remaining: readonly ContributionDiagnostic[];\n}>;\n\n// ============================================================\n// Contribution readiness probe (#377)\n// ============================================================\n\n/**\n * The search projection a probe entry summarizes. Deliberately the\n * logical *class* rather than one physical table: a caller asking \"is\n * search ready?\" is deciding whether to issue a fulltext or a vector\n * query, and a per-`(kind, field)` breakdown of pgvector tables answers\n * a question they did not ask. The physical detail an operator needs to\n * act is one `verifyContributions()` call away, and\n * {@link ContributionProbeEntry.detail} names the affected slots.\n */\nexport type ContributionProbeContribution = \"fulltext\" | \"vector\";\n\n/**\n * Readiness of one search projection.\n *\n * - `ready` — every contribution backing this projection is attested by\n * its durable marker and present in the catalog. Not a promise about\n * future coherence: a write that lands after the probe returns is\n * outside what any assessment can cover.\n * - `degraded` — at least one contribution is unusable. Dependent operations\n * may be refused with a typed contribution error, fail at the engine boundary\n * when compiled SQL directly references missing storage, or observe\n * incomplete storage.\n * {@link ContributionProbeEntry.detail} says which and why.\n * - `building` — **reserved.** No shipped path publishes it. Recording\n * an in-flight marker would need a fifth\n * {@link ContributionDiagnosticState} and would widen the hot-path\n * gate's verdict set; the destructive rebuild instead runs inside one\n * transaction, so a concurrent probe observes the state before or\n * after it and never a partial one. Reserved rather than removed so a\n * future streaming/async materializer can populate it without a\n * breaking change — treat it as \"not `ready`\" today.\n */\nexport type ContributionProbeState = \"ready\" | \"degraded\" | \"building\";\n\n/**\n * One search projection's readiness, from\n * {@link GraphBackend.probeContributions}.\n */\nexport type ContributionProbeEntry = Readonly<{\n contribution: ContributionProbeContribution;\n state: ContributionProbeState;\n /**\n * Operator-facing summary of why the projection is not `ready` —\n * e.g. `\"fulltext table \\\"typegraph_node_fulltext\\\" is missing\n * (orphaned-marker)\"`. Absent on a `ready` entry.\n *\n * Human-readable and not a stable format: route on `state`, and call\n * `store.verifyContributions()` for the structured per-table\n * diagnostics this string is derived from.\n */\n detail?: string;\n}>;\n\n/**\n * Result of {@link GraphBackend.probeContributions}.\n *\n * A projection with no declared contributions is omitted rather than\n * reported `ready`, so an empty `entries` array means \"nothing to\n * assess\" — a graph with no `searchable()` or `embedding()` fields, or a\n * backend with no contribution support — never \"assessed and healthy\".\n */\nexport type ContributionProbeResult = Readonly<{\n /**\n * The durable graph revision the assessment was taken at, so a caller\n * can place this probe in the graph's committed history.\n *\n * Graph-global, like the clock it reads: it advances on every committed\n * capture from any writer, so an advance between two probes means\n * \"something committed in between\", never \"the write this caller just\n * made landed\". Confirm a specific write by observing the write itself.\n *\n * Absent unless the Store is revision-tracked (`revisionTracking:\n * true` or `history: true`) — the same condition under which\n * `store.revisionNow()` returns a value. This is the one honest shape:\n * a store with no durable revision clock has no revision to stamp, and\n * substituting a wall-clock timestamp or the schema version would be a\n * materially weaker guarantee wearing the name of a stronger one. The\n * schema version in particular does not advance on data writes, so it\n * could not order a probe against a caller's write at all.\n */\n graphRevision?: string;\n entries: readonly ContributionProbeEntry[];\n}>;\n\n// ============================================================\n// Destructive contribution rebuild (#337)\n// ============================================================\n\n/**\n * Which search projection {@link GraphBackend.rebuildContribution}\n * targets. Scoped explicitly at the call site rather than inferred from\n * a diagnostic: the operation destroys storage, so which storage is the\n * caller's decision to state, not TypeGraph's to guess.\n */\nexport type ContributionRebuildScope = ContributionProbeContribution;\n\n/**\n * What a rebuild's `repopulate` callback reconstructed. Reported back so\n * the rebuild result can distinguish \"recreated empty storage\" from\n * \"recreated and refilled\", which is the difference between a finished\n * repair and half of one.\n */\nexport type ContributionRepopulationStats = Readonly<{\n /** Nodes scanned. */\n processed: number;\n /** Content rows written. */\n repopulated: number;\n /** Nodes whose stored `props` could not be read as an object. */\n skipped: number;\n}>;\n\n/** Outcome of one destructive contribution rebuild. */\nexport type ContributionRebuildResult = Readonly<{\n /** Physical tables dropped and recreated, in the order rebuilt. */\n rebuilt: readonly string[];\n /** Nodes scanned while reconstructing content from stored rows. */\n processed: number;\n /** Content rows written into the recreated storage. */\n repopulated: number;\n /**\n * Nodes whose stored `props` could not be read as an object, so no\n * content row could be reconstructed for them. Non-zero means the\n * rebuilt index is missing those nodes; the IDs come back from\n * `store.search.rebuildFulltext()`, which reports them individually.\n */\n skipped: number;\n}>;\n\n// ============================================================\n// Kind Removals (data-cleanup status)\n// ============================================================\n\n/**\n * One row of the per-deployment `typegraph_kind_removals` table:\n * a graph-extension kind that has been removed from the schema and whose\n * data may or may not have been cleaned up yet.\n */\nexport type KindRemovalRow = Readonly<{\n graphId: string;\n kindName: string;\n entity: KindEntity;\n schemaVersion: number;\n /** ISO timestamp when the data-cleanup pass succeeded; undefined while pending. */\n removedAt: string | undefined;\n lastAttemptedAt: string;\n lastError: string | undefined;\n}>;\n\n/**\n * Upsert payload for a kind-removal status row. On removal-commit:\n * pass `removedAt: undefined` (the pending state). On successful\n * data-cleanup: pass `removedAt` set and `error: undefined`. On\n * cleanup failure: pass `removedAt: undefined` (preserves any prior\n * timestamp from a partial success on a different replica) and the\n * error message.\n */\nexport type RecordKindRemovalParams = Readonly<{\n graphId: string;\n kindName: string;\n entity: KindEntity;\n schemaVersion: number;\n attemptedAt: string;\n /** ISO timestamp on success; undefined while pending or on failure. */\n removedAt: string | undefined;\n /** Error message on failure; undefined on success or while pending. */\n error: string | undefined;\n}>;\n\n// ============================================================\n// Query Types\n// ============================================================\n\n/** @internal Capability token for connection-local temporary writes. */\nexport const INTERNAL_TEMPORARY_WRITES: unique symbol = typeGraphGlobalSymbol(\n \"internal-temporary-writes-v1\",\n);\n\n/**\n * Transaction options.\n */\nexport type TransactionOptions = Readonly<{\n /** Transaction isolation level (if supported) */\n isolationLevel?:\n \"read_uncommitted\" | \"read_committed\" | \"repeatable_read\" | \"serializable\";\n /**\n * Transaction access mode (if supported). `read_only` is intended for\n * multi-statement reads that need one snapshot and must not perform writes.\n */\n accessMode?: \"read_only\" | \"read_write\";\n}>;\n\n/** @internal Transaction options available only to TypeGraph-owned execution. */\nexport type InternalTransactionOptions = TransactionOptions &\n Readonly<{\n /**\n * Permit writes only to connection-local temporary state. The iterative\n * operation primitive uses this when an engine rejects temporary DDL in a\n * read-only transaction.\n */\n temporaryWrites?: typeof INTERNAL_TEMPORARY_WRITES;\n }>;\n\n// ============================================================\n// Backend Interface\n// ============================================================\n\n/**\n * The physical names of the four Operational Identity relations: the current\n * assertion ledger, its recorded-time twin, and the two DERIVED relations\n * (closure, separation) rebuilt from the ledger.\n *\n * Named once so the two ports that speak about them —\n * {@link GraphBackend.ensureIdentityTables} and\n * {@link GraphBackend.identityTableDdl} — cannot drift apart.\n */\nexport type IdentityTableNames = Readonly<{\n identityAssertions: string;\n recordedIdentityAssertions: string;\n identityClosure: string;\n identitySeparation: string;\n}>;\n\n/**\n * The physical names of the three recorded relations. Named once so the\n * ports that speak about them cannot drift apart — the {@link IdentityTableNames}\n * precedent.\n */\nexport type RecordedTableNames = Readonly<{\n recordedClock: string;\n recordedEdges: string;\n recordedNodes: string;\n}>;\n\n/**\n * One recorded relation's provisioning DDL, with the roles the caller needs\n * SEPARATED rather than positional.\n */\nexport type RecordedRelationDdl = Readonly<{\n /** The single `CREATE TABLE` statement. */\n createTable: string;\n /** Its index/constraint statements, in application order. */\n indexes: readonly string[];\n /**\n * The name the ENGINE will have given this relation's PRIMARY KEY constraint\n * once `createTable` has executed, or `undefined` on an engine that does not\n * name PK constraints separately (SQLite).\n *\n * NOT \"the name the DDL text declares\": both bundled emitters push an unnamed\n * inline `PRIMARY KEY (…)` (`ddl.ts:114-118`, `:441-445`), so on PostgreSQL the\n * server derives `<table>_pkey`. The point of the field is that the derivation\n * is an ENGINE convention, and the only honest source of it is whoever authored\n * the DDL for that engine — a migration that reconstructs it bakes one adapter's\n * convention in.\n *\n * The name is returned UNREDUCED. Reducing an over-long identifier is a\n * separate decision with a separate owner (`shortenedIdentifier`), and it\n * applies only to the RENAME's target. The source name is the *temporary*\n * table's PK name, and temp table names are hash-derived and short BY\n * CONSTRUCTION (`` `__tg_${role}_${shortHash(tableName)}` ``, an 8-char\n * hash, so `<temp>_pkey` is at most ~21 bytes for any configured table\n * name) — nowhere near the 63-byte ceiling. So the split is a structural\n * fact about the temp-name shape, not a claim about PostgreSQL's\n * truncation semantics: `shortenedIdentifier` is the identity on the\n * source for every reachable input, and its effect is observable only on\n * the target.\n *\n * A backend must apply this option consistently across name sets: return a\n * name for both the temporary and final relation, or `undefined` for both.\n * The migration refuses a mixed pair because silently dropping either name\n * would leave the swapped relation with a backend-inconsistent constraint.\n */\n primaryKeyConstraintName?: string | undefined;\n}>;\n\n/**\n * The database-global extensions TypeGraph installs on a caller's behalf.\n *\n * The extent is closed on purpose: {@link GraphBackend.ensureExtension}\n * interpolates the name into DDL, so the allowlist — not the caller — is what\n * decides the identifier can be trusted. `pg_trgm` backs `method: \"trigram\"`\n * index materialization; `vector` backs pgvector storage.\n */\nexport const DATABASE_EXTENSION_NAMES = [\"pg_trgm\", \"vector\"] as const;\n\n/** A name {@link GraphBackend.ensureExtension} accepts. */\nexport type DatabaseExtensionName = (typeof DATABASE_EXTENSION_NAMES)[number];\n\n/**\n * The GraphBackend interface abstracts database operations.\n *\n * Implementations should provide:\n * - SQLite backend via better-sqlite3 or libsql\n * - PostgreSQL backend via pg or postgres\n *\n * Every function is receiver-free (`this: void`). Implementations must close\n * over their state instead of reading `this`, which makes saved optional\n * capabilities and other detached port calls safe by construction.\n */\nexport type GraphBackend = Readonly<{\n /** The SQL dialect */\n dialect: SqlDialect;\n /** Backend capabilities */\n capabilities: BackendCapabilities;\n /** Table names used by this backend (for query schema auto-derivation) */\n tableNames?: SqlTableNames | undefined;\n /**\n * Optional fulltext strategy override. When present, both the compiler\n * (for `$fulltext.matches()` in query builder) and backend-direct\n * search paths use this instead of the dialect's default strategy —\n * allowing a Postgres backend to ship pg_trgm, ParadeDB, pgroonga etc.\n * When absent, the dialect's default strategy is used.\n */\n fulltextStrategy?: FulltextStrategy | undefined;\n /**\n * Optional vector strategy this backend is wired with. The query\n * compiler reads it (via `compileQuery` options) to emit per-`(kind,\n * field)` relevance scans for `field.similarTo(...)` predicates, and\n * the index-materialization / removal paths read its deterministic\n * `tableName(...)` to address the right physical per-field storage.\n * `undefined` when the backend has no vector support (e.g. a generic\n * SQLite backend without sqlite-vec).\n */\n vectorStrategy?: VectorStrategy | undefined;\n\n // === Node Operations ===\n insertNode: (this: void, params: InsertNodeParams) => Promise<NodeRow>;\n insertNodeNoReturn?: (this: void, params: InsertNodeParams) => Promise<void>;\n insertNodesBatch?: (\n this: void,\n params: readonly InsertNodeParams[],\n ) => Promise<void>;\n insertNodesBatchReturning?: (\n this: void,\n params: readonly InsertNodeParams[],\n ) => Promise<readonly NodeRow[]>;\n updateNode: (this: void, params: UpdateNodeParams) => Promise<NodeRow>;\n updateNodeSet?: (\n this: void,\n params: UpdateNodeSetParams,\n ) => Promise<UpdateNodeSetResult>;\n deleteNode: (this: void, params: DeleteNodeParams) => Promise<void>;\n hardDeleteNode: (this: void, params: HardDeleteNodeParams) => Promise<void>;\n getNode: (\n this: void,\n graphId: string,\n kind: string,\n id: string,\n ) => Promise<NodeRow | undefined>;\n getNodes?: (\n this: void,\n graphId: string,\n kind: string,\n ids: readonly string[],\n ) => Promise<readonly NodeRow[]>;\n\n // === Edge Operations ===\n insertEdge: (this: void, params: InsertEdgeParams) => Promise<EdgeRow>;\n insertEdgeNoReturn?: (this: void, params: InsertEdgeParams) => Promise<void>;\n insertEdgesBatch?: (\n this: void,\n params: readonly InsertEdgeParams[],\n ) => Promise<void>;\n insertEdgesBatchReturning?: (\n this: void,\n params: readonly InsertEdgeParams[],\n ) => Promise<readonly EdgeRow[]>;\n updateEdge: (this: void, params: UpdateEdgeParams) => Promise<EdgeRow>;\n deleteEdge: (this: void, params: DeleteEdgeParams) => Promise<void>;\n hardDeleteEdge: (this: void, params: HardDeleteEdgeParams) => Promise<void>;\n /**\n * Batched {@link deleteEdge}: one soft-delete statement per bind-budget\n * chunk instead of one per edge. Optional — cascade deletes fall back to\n * the per-edge form when unset. Same per-row semantics (idempotent on\n * already-tombstoned rows).\n */\n deleteEdgesBatch?: (\n this: void,\n params: DeleteEdgesBatchParams,\n ) => Promise<void>;\n /** Batched {@link hardDeleteEdge}; see {@link deleteEdgesBatch}. */\n hardDeleteEdgesBatch?: (\n this: void,\n params: DeleteEdgesBatchParams,\n ) => Promise<void>;\n getEdge: (\n this: void,\n graphId: string,\n id: string,\n ) => Promise<EdgeRow | undefined>;\n getEdges?: (\n this: void,\n graphId: string,\n ids: readonly string[],\n ) => Promise<readonly EdgeRow[]>;\n\n // === Edge Cardinality Operations ===\n countEdgesFrom: (this: void, params: CountEdgesFromParams) => Promise<number>;\n edgeExistsBetween: (\n this: void,\n params: EdgeExistsBetweenParams,\n ) => Promise<boolean>;\n\n // === Edge Query Operations ===\n findEdgesConnectedTo: (\n this: void,\n params: FindEdgesConnectedToParams,\n ) => Promise<readonly EdgeRow[]>;\n\n // === Collection Query Operations ===\n findNodesByKind: (\n this: void,\n params: FindNodesByKindParams,\n ) => Promise<readonly NodeRow[]>;\n countNodesByKind: (\n this: void,\n params: CountNodesByKindParams,\n ) => Promise<number>;\n findEdgesByKind: (\n this: void,\n params: FindEdgesByKindParams,\n ) => Promise<readonly EdgeRow[]>;\n /**\n * Reads the edges of a SET of endpoints in one statement per bind-budget\n * chunk — see {@link FindEdgesByEndpointSetParams}.\n *\n * **Optional, and its absence is the capability signal.** `store.edges.<kind>\n * .bulkFindFrom` / `.bulkFindTo` check for this method before issuing any\n * read and refuse with a typed `ConfigurationError` when it is missing,\n * rather than degrading to a per-endpoint loop. A caller reaching for a bulk\n * endpoint read is asking for set-oriented statements; quietly giving them N\n * singleton statements is the surprise the method exists to prevent.\n *\n * Both bundled Drizzle backends implement it. A custom backend that does not\n * simply omits it and the bulk reads refuse; the singleton `findEdgesByKind`\n * path is unaffected.\n */\n findEdgesByEndpointSet?: (\n this: void,\n params: FindEdgesByEndpointSetParams,\n ) => Promise<readonly EdgeRow[]>;\n /**\n * Reads several edge kinds from a heterogeneous set of endpoints without\n * issuing one statement per licensed `(edge kind, endpoint kind)` pair.\n *\n * Optional for custom backends. Store-level heterogeneous bulk reads refuse\n * when it is absent rather than hiding a per-kind/per-endpoint fallback.\n */\n findEdgesByHeterogeneousEndpointSet?: (\n this: void,\n params: FindEdgesByHeterogeneousEndpointSetParams,\n ) => Promise<readonly EdgeRow[]>;\n countEdgesByKind: (\n this: void,\n params: CountEdgesByKindParams,\n ) => Promise<number>;\n\n // === Unique Constraint Operations ===\n insertUnique: (this: void, params: InsertUniqueParams) => Promise<void>;\n /**\n * Batched variant of `insertUnique`: one multi-row statement per chunk\n * with the same per-entry conflict semantics (throws `UniquenessError`\n * for the first entry whose key a different live node holds). Optional —\n * callers fall back to per-entry `insertUnique` when unset.\n */\n insertUniqueBatch?: (\n this: void,\n entries: readonly InsertUniqueParams[],\n ) => Promise<void>;\n deleteUnique: (this: void, params: DeleteUniqueParams) => Promise<void>;\n /**\n * Permanently removes every uniqueness sidecar owned by the specified\n * concrete nodes. Optional capability used by set-based updates before they\n * rebuild reservations from the returned node after-images.\n */\n hardDeleteUniquesByNodeIds?: (\n this: void,\n params: HardDeleteUniquesByNodeIdsParams,\n ) => Promise<void>;\n /**\n * Permanently removes every uniqueness claim owned by nodes of one concrete\n * kind, at whatever axis each claim sits on. THE definition of \"the claims\n * this kind owns\" — kind removal reaps through it so it can neither leak a\n * claim whose axis is a sibling kind nor delete a surviving sibling's claim.\n * Optional capability.\n */\n hardDeleteUniquesByConcreteKind?: (\n this: void,\n params: HardDeleteUniquesByConcreteKindParams,\n ) => Promise<void>;\n checkUnique: (\n this: void,\n params: CheckUniqueParams,\n ) => Promise<UniqueRow | undefined>;\n checkUniqueBatch?: (\n this: void,\n params: CheckUniqueBatchParams,\n ) => Promise<readonly UniqueRow[]>;\n\n // === Edge Cardinality Claim Operations ===\n /**\n * Takes the claim on one edge cardinality axis, in two statements: a\n * decision-free create-or-lock that reports the committed holder, and — only\n * when that holder is a different edge — a conditional takeover that succeeds\n * exactly when the incumbent is no longer an edge the axis and key describe.\n *\n * The claim is the FENCE for a declared cardinality: `(kind, from)` and\n * `(kind, from, to)` are predicates the edges primary key `(graph_id, id)`\n * cannot enforce, so without this relation two concurrent writers can both\n * pass the probe and both commit. Read through the `constraintClaims`\n * capability, never through member presence — see `claimSupport`\n * (`store/claims/backing.ts`).\n */\n claimEdgeCardinality?: (\n this: void,\n params: ClaimEdgeCardinalityParams,\n ) => Promise<EdgeClaimOutcome>;\n /**\n * Batched variant of `claimEdgeCardinality`: one multi-row create-or-lock\n * statement, then a takeover statement only for the entries a different edge\n * holds. Outcomes are returned positionally, one per entry.\n *\n * Callers must not pass two entries with the same conflict target\n * (`axis`, `key`): a multi-row upsert cannot affect one row twice.\n */\n claimEdgeCardinalityBatch?: (\n this: void,\n entries: readonly ClaimEdgeCardinalityParams[],\n ) => Promise<readonly EdgeClaimOutcome[]>;\n /**\n * Housekeeping only: drops the claim rows named edges hold, so hard deletes,\n * kind removal and `clearGraph` do not grow the relation without bound. The\n * FENCE never depends on it having run — a claim whose holder is no longer\n * live (or, for `oneActive`, no longer active) is taken over in place.\n */\n purgeEdgeClaims?: (\n this: void,\n params: PurgeEdgeClaimsParams,\n ) => Promise<void>;\n\n /**\n * Read-only diagnostic: the rows that make a declared constraint currently\n * violated, for a caller (`store.verifyConstraintFences()`) that folds them\n * onto the claim axes they contend for.\n *\n * It reads the ENTITY relations for the two families whose pre-upgrade\n * violations no claim row records — a database written before the claim\n * relations existed holds no edge claims at all — and the `uniques` relation\n * for uniqueness, where a pre-upgrade duplicate is exactly two live rows\n * sitting at two different `node_kind`s. A scan of a claim relation's primary\n * key can find neither, which is why this is not one.\n *\n * Returns the contending ROWS, not the verdict: the axis a `uniques` row\n * belongs to is a fold over the graph's subclass component, and the key an\n * edge's claim sits on is `EDGE_CARDINALITY_SPECS`' — both of which live\n * above the backend, so a backend that decided either would be a second\n * spelling of a decision the fence already owns.\n *\n * Writes nothing: no DDL, no claim writes. Safe on a replica and under a\n * least-privilege role. Present only on backends that can run the audit;\n * `store.verifyConstraintFences()` refuses with a typed error when absent\n * rather than reporting an empty (and therefore reassuring) result.\n */\n readConstraintFenceViolations?: (\n this: void,\n params: ReadConstraintFenceViolationsParams,\n ) => Promise<ConstraintFenceViolationRows>;\n\n // === Schema Operations ===\n getActiveSchema: (\n this: void,\n graphId: string,\n ) => Promise<SchemaVersionRow | undefined>;\n getSchemaVersion: (\n this: void,\n graphId: string,\n version: number,\n ) => Promise<SchemaVersionRow | undefined>;\n /**\n * Atomically inserts a new schema version and activates it as a single\n * transactional unit, with optimistic compare-and-swap on the currently\n * active version.\n *\n * - If `expected.kind === \"active\"` and the actual active version\n * differs, throws `StaleVersionError` (caller should refetch and\n * retry).\n * - If a row already exists at `params.version` with the same\n * `schemaHash`, returns it idempotently — reactivating it if it was\n * left inactive by an earlier crashed commit.\n * - If a row already exists at `params.version` with a different\n * `schemaHash`, throws `SchemaContentConflictError`.\n *\n * Requires `capabilities.transactions === true`. On non-transactional\n * backends (e.g. Cloudflare D1, drizzle-orm/neon-http) this method\n * throws `ConfigurationError` rather than running with degraded\n * atomicity that would silently re-introduce the orphan-row crash\n * window the primitive exists to eliminate.\n */\n commitSchemaVersion: (\n this: void,\n params: CommitSchemaVersionParams,\n ) => Promise<SchemaVersionRow>;\n /**\n * Commit a schema version only if every requested kind is empty. The probes\n * and schema CAS run under one backend-owned write fence, preventing a\n * participating schema-managed Store write from landing between the final\n * count and commit. Raw Stores and direct backend writes are not fenced.\n */\n commitSchemaVersionIfKindsEmpty?: (\n this: void,\n params: CommitSchemaVersionParams,\n probes: readonly Readonly<{\n entity: \"node\" | \"edge\";\n kind: string;\n }>[],\n ) => Promise<\n | Readonly<{ status: \"committed\"; row: SchemaVersionRow }>\n | Readonly<{\n status: \"populated\";\n kinds: readonly Readonly<{\n entity: \"node\" | \"edge\";\n kind: string;\n count: number;\n }>[];\n }>\n >;\n /**\n * Acquire the transaction-scoped shared fence for a schema-managed graph\n * write, then verify that the active schema still matches the Store that is\n * issuing it. Official transactional backends provide this method; custom\n * backends may omit it, in which case schema-managed Store writes fail\n * closed rather than racing a schema change. This method must be called on a\n * transaction-scoped backend. PostgreSQL locks the active schema row, so a\n * concurrent change either becomes visible at read committed or raises the\n * database's native serialization failure at stronger isolation.\n *\n * On rejection the thrown `StaleVersionError` reports the active\n * version this transaction can observe after the conflict resolves, so\n * `details.actual` names the version that won rather than the absence the\n * blocked read momentarily saw.\n */\n lockSchemaVersionForWrite?: (\n this: void,\n params: Readonly<{ graphId: string; expectedVersion: number }>,\n ) => Promise<void>;\n /**\n * Internal schema-lifecycle seam for features whose data preflight must\n * commit atomically with the schema CAS. The callback runs in the same\n * write transaction after the schema write fence is acquired and before the\n * version write; it receives no schema-version write methods, so callers\n * cannot bypass the CAS.\n *\n * The preflight target is a {@link SchemaCommitPreflightBackend}: the\n * transaction backend plus the schema-write DDL primitive, because a\n * transition may have to CREATE the storage its own preflight then fills —\n * and creating it outside this transaction would publish it empty whenever\n * the commit is refused.\n *\n * @internal\n */\n commitSchemaVersionWithPreflight?: (\n this: void,\n params: CommitSchemaVersionParams,\n preflight: (target: SchemaCommitPreflightBackend) => Promise<void>,\n ) => Promise<SchemaVersionRow>;\n /**\n * Atomically flips the active schema pointer to an existing version,\n * with optimistic compare-and-swap on the currently active version.\n * Used by `rollbackSchema` and any other \"promote/demote existing\n * version\" workflow. Throws `StaleVersionError` on CAS mismatch and\n * `MigrationError` if the target version row does not exist.\n *\n * Same transactional requirements as `commitSchemaVersion`.\n */\n setActiveVersion: (\n this: void,\n params: SetActiveVersionParams,\n ) => Promise<void>;\n\n /**\n * Run an administrative callback while holding the same per-graph lock as\n * schema commits. The callback receives the transaction-scoped backend, so\n * its reads, DML, and DDL are committed atomically before another schema\n * writer can proceed.\n *\n * This is intentionally absent from {@link TransactionBackend}: nesting a\n * schema-write lock from an already-open transaction can deadlock. It is an\n * optional backend capability so custom backends can decline operations\n * that require a schema fence rather than silently running them unsafely.\n */\n schemaWriteTransaction?: <T>(\n this: void,\n graphId: string,\n fn: (\n tx: TransactionBackend &\n Readonly<{\n executeStatement: NonNullable<TransactionBackend[\"executeStatement\"]>;\n tableExists: (this: void, tableName: string) => Promise<boolean>;\n executeSchemaDdl: (this: void, ddl: string) => Promise<void>;\n deleteSchemaVectorSlotContribution: (\n this: void,\n slot: VectorSlot,\n ) => Promise<void>;\n }>,\n ) => Promise<T>,\n ) => Promise<T>;\n\n // === Embedding Operations (optional - depends on vector capabilities) ===\n upsertEmbedding?: (\n this: void,\n params: UpsertEmbeddingParams,\n ) => Promise<void>;\n /**\n * Batched variant of `upsertEmbedding` for one vector slot. Optional —\n * callers fall back to per-row `upsertEmbedding` when unset.\n */\n upsertEmbeddingBatch?: (\n this: void,\n params: UpsertEmbeddingBatchParams,\n ) => Promise<void>;\n deleteEmbedding?: (\n this: void,\n params: DeleteEmbeddingParams,\n ) => Promise<void>;\n deleteEmbeddingBatch?: (\n this: void,\n params: Omit<DeleteEmbeddingParams, \"nodeId\"> &\n Readonly<{ nodeIds: readonly string[] }>,\n ) => Promise<void>;\n /**\n * KNN search over one `(nodeKind, fieldPath)` slot. Top-k is computed\n * over CURRENT nodes only — non-tombstoned AND inside their validity\n * window, matching a `current` read — so index drift (embedding rows\n * whose node was deleted or expired outside the store pipeline) can\n * neither surface nor crowd current rows out of the top-k. Custom\n * backends implementing this member must honor the same contract. Exact on pgvector >= 0.8 (HNSW via\n * `hnsw.iterative_scan = strict_order`; IVFFlat via\n * `ivfflat.iterative_scan = relaxed_order` plus a re-sort of the\n * bounded set; probe-bounded below 0.8) and sqlite-vec;\n * libSQL's DiskANN over-fetches 4x and post-filters (recall bounded by\n * that headroom).\n */\n vectorSearch?: (\n this: void,\n params: VectorSearchParams,\n ) => Promise<readonly VectorSearchResult[]>;\n createVectorIndex?: (\n this: void,\n params: CreateVectorIndexParams,\n ) => Promise<void>;\n dropVectorIndex?: (\n this: void,\n params: DropVectorIndexParams,\n ) => Promise<void>;\n /**\n * Single-statement hybrid search: both sources, RRF fusion, liveness\n * join, and node hydration composed into ONE statement — replacing the\n * facade's two search round trips plus id-hydration fetch. Optional;\n * the store falls back to the multi-statement path when unset (custom\n * backends, engines without window functions). Same liveness contract\n * as `vectorSearch` / `fulltextSearch`.\n */\n hybridSearch?: (\n this: void,\n params: HybridSearchParams,\n ) => Promise<readonly HybridSearchRow[]>;\n\n // === Fulltext Operations (optional - depends on fulltext capabilities) ===\n upsertFulltext?: (this: void, params: UpsertFulltextParams) => Promise<void>;\n deleteFulltext?: (this: void, params: DeleteFulltextParams) => Promise<void>;\n /**\n * Batched variant of `upsertFulltext`. Optional — callers fall back to\n * per-row `upsertFulltext` when unset.\n */\n upsertFulltextBatch?: (\n this: void,\n params: UpsertFulltextBatchParams,\n ) => Promise<void>;\n /**\n * Batched variant of `deleteFulltext`. Optional — callers fall back to\n * per-row `deleteFulltext` when unset.\n */\n deleteFulltextBatch?: (\n this: void,\n params: DeleteFulltextBatchParams,\n ) => Promise<void>;\n /**\n * Ranked fulltext search over one node kind. Like `vectorSearch`, top-k\n * is computed over CURRENT nodes only — non-tombstoned AND inside their\n * validity window (exact on both engines — plain WHERE, no top-k table\n * function involved). Custom backends implementing this member must\n * honor the same contract.\n */\n fulltextSearch?: (\n this: void,\n params: FulltextSearchParams,\n ) => Promise<readonly FulltextSearchResult[]>;\n\n // === Index Materialization (used by store.materializeIndexes) ===\n /**\n * Idempotently ensure ONLY the `typegraph_index_materializations`\n * table exists — separate from `bootstrapTables` so that\n * `materializeIndexes` doesn't pull in the full base-table DDL set\n * just to access the status table.\n *\n * Why focused: `bootstrapTables` issues 20+ `CREATE TABLE / CREATE\n * INDEX IF NOT EXISTS` statements covering every base table. Two\n * concurrent calls (e.g. two replicas of the same `schema_doc` both\n * starting up and calling `materializeIndexes`) race on\n * Postgres SHARE locks and DEADLOCK. Restricting the ensure-step to\n * the single status table eliminates the cross-table race entirely\n * — concurrent `CREATE TABLE IF NOT EXISTS` for one specific table\n * is well-behaved on Postgres.\n */\n ensureIndexMaterializationsTable?: (this: void) => Promise<void>;\n\n /**\n * Install the PostgreSQL `pg_trgm` extension under a database-global\n * concurrency fence. Relational trigram index materialization calls this\n * before emitting its index DDL; non-PostgreSQL backends omit it.\n *\n * @deprecated The `pg_trgm`-only spelling of {@link GraphBackend.ensureExtension},\n * which says the same thing for every extension the library installs. It is\n * retained — and still consulted, after `ensureExtension` — so a backend\n * written against 0.47 keeps its fence; the bundled PostgreSQL backend\n * implements it by delegating. Implement `ensureExtension` in new backends.\n */\n ensureTrigramExtension?: (this: void) => Promise<void>;\n\n /**\n * Idempotently ensure ONLY the `typegraph_revision_origins` table exists.\n *\n * Revision-tracked stores use this per-graph, durable random origin together\n * with the recorded clock to prevent two independent stores with coincident\n * timestamps from sharing a merge base anchor. It is focused rather than\n * using `bootstrapTables` so existing deployments can adopt revision anchors\n * without replaying all base-table DDL during a merge read.\n */\n ensureRevisionOriginsTable?: (this: void) => Promise<void>;\n\n /**\n * Idempotently ensure ONLY the three Operational Identity relations exist —\n * the current-assertions table, the recorded-time assertions table, and the\n * derived closure and separation tables — with their indexes and CHECK\n * constraints (CREATE TABLE / CREATE INDEX IF NOT EXISTS).\n *\n * First enablement of identity on an existing populated deployment attaches\n * via `createStore` / `createSqliteBackend` / `createPostgresBackend`, none\n * of which run DDL, so the enablement preflight would otherwise\n * SELECT/DELETE/INSERT tables that do not exist yet. The store calls this\n * before the enablement locks and closure rebuild. Focused rather than\n * `bootstrapTables` for the same concurrency rationale as\n * {@link ensureRevisionOriginsTable}. Stores call it before opening the\n * schema-commit transaction so DDL does not re-enter its per-graph lock.\n * Returns the logical names that were absent before this call. Callers set\n * `provisionMissing` only for safe first enablement; on an already-enabled\n * graph, missing ledger tables are deliberately left absent so a failed open\n * cannot make its next retry silently accept empty replacement storage.\n *\n * @internal\n */\n ensureIdentityTables?: (\n this: void,\n tableNames: IdentityTableNames,\n options: Readonly<{ provisionMissing: boolean }>,\n ) => Promise<readonly string[]>;\n\n /**\n * The idempotent CREATE statements for exactly the identity relations —\n * the same DDL {@link ensureIdentityTables} issues, handed back as data\n * instead of executed.\n *\n * Pure and synchronous: it executes nothing and probes no catalog, so it is\n * safe to call from inside an already-open transaction, where invoking a\n * top-level backend method would re-enter the backend's serialized statement\n * queue and deadlock. That is the whole point. Provisioning a missing DERIVED\n * relation (closure, separation) on an already-enabled graph has to CREATE it\n * and FILL it in one transaction, because a created-but-empty derived\n * relation is readable and answers every question with \"nothing\" — for the\n * separation relation, \"nothing\" means \"not separated\", which is exactly the\n * answer that lets a contradictory merge commit.\n *\n * A backend that omits this cannot offer that atomicity. Callers do not fall\n * back: when a fill is owed, the upgrade is REFUSED with the typed\n * `IDENTITY_UPGRADE_REQUIRES_ATOMIC_DDL` error naming this port — creating\n * and filling back-to-back would publish the readable-empty state the\n * paragraph above forbids.\n *\n * @internal\n */\n identityTableDdl?: (\n this: void,\n tableNames: IdentityTableNames,\n ) => readonly string[];\n\n /**\n * The provisioning DDL for the three recorded relations under the given\n * physical names, keyed by logical relation. Used only by the offline legacy\n * preview-schema migration, which builds temp tables, copies, and swaps —\n * so it is called TWICE per migration, once per name set, and the migration\n * (not the backend) composes the temp `createTable` with the final `indexes`.\n *\n * A backend that omits this cannot be migrated FROM the timestamp-only\n * preview schema — a schema only the bundled Drizzle backends ever created.\n * `migrateLegacyRecordedTime` REFUSES with `UnsupportedBackendCapabilityError`\n * naming this port rather than emitting DDL it cannot author.\n *\n * @internal\n */\n recordedTableDdl?: (\n this: void,\n tableNames: RecordedTableNames,\n ) => Readonly<Record<keyof RecordedTableNames, RecordedRelationDdl>>;\n\n /**\n * Look up a recorded materialization for a declared index by its\n * physical SQL index name. Returns `undefined` if no row exists.\n */\n getIndexMaterialization?: (\n this: void,\n indexName: string,\n ) => Promise<IndexMaterializationRow | undefined>;\n /**\n * Bulk variant of `getIndexMaterialization`: load every recorded\n * materialization whose `indexName` (status key) is in `statusKeys`,\n * in a single round-trip. Returned rows are unordered — callers index\n * by `indexName`. Optional; consumers fall back to per-key\n * `getIndexMaterialization` when unset.\n */\n getIndexMaterializations?: (\n this: void,\n statusKeys: readonly string[],\n ) => Promise<readonly IndexMaterializationRow[]>;\n /**\n * Upsert a materialization attempt — success or failure. Failure rows\n * preserve any prior `materializedAt` so the historical successful\n * timestamp survives across error windows.\n */\n recordIndexMaterialization?: (\n this: void,\n params: RecordIndexMaterializationParams,\n ) => Promise<void>;\n /**\n * Atomically claims the build of one index across every materializer\n * (process- and pool-safe: the status row's own atomicity is the mutex).\n * Returns true when this caller now holds the claim. Backends whose\n * index builds cannot deadlock across callers (SQLite: engine-level\n * write serialization, no CONCURRENTLY) omit it; `materializeIndexes`\n * then builds without a claim, exactly as before.\n */\n claimIndexMaterialization?: (\n this: void,\n params: ClaimIndexMaterializationParams,\n ) => Promise<boolean>;\n /** Releases a claim taken by `claimIndexMaterialization` (token-guarded). */\n releaseIndexMaterializationClaim?: (\n this: void,\n params: ReleaseIndexMaterializationClaimParams,\n ) => Promise<void>;\n\n // === Contribution Materialization (#135 — durable strategy-owned\n // storage marker, sibling of the index status table) ===\n\n /**\n * Idempotently ensure ONLY the\n * `typegraph_contribution_materializations` table exists. Same\n * focused-bootstrap rationale as `ensureIndexMaterializationsTable`:\n * a single `CREATE TABLE IF NOT EXISTS` is concurrency-safe under\n * replica startup, where the full `bootstrapTables` set risks a\n * Postgres SHARE-lock deadlock.\n */\n ensureContributionMaterializationsTable?: (this: void) => Promise<void>;\n\n /**\n * Look up the durable materialization marker for one strategy-owned\n * contribution identity. Returns `undefined` when no row exists\n * (\"never initialized\").\n */\n getContributionMaterialization?: (\n this: void,\n identity: ContributionMaterializationIdentity,\n ) => Promise<ContributionMaterializationRow | undefined>;\n\n /**\n * Upsert a contribution-materialization attempt — success or failure.\n * Failure rows preserve any prior `materializedAt` via COALESCE so a\n * later failed re-attempt doesn't erase the historical success.\n */\n recordContributionMaterialization?: (\n this: void,\n params: RecordContributionMaterializationParams,\n ) => Promise<void>;\n\n /**\n * Resolve (once per backend instance, cached) and assert the durable\n * materialization markers for every `runtimeEnsure` contribution this\n * backend's strategy declares, for `graphId`. Throws\n * `StoreNotInitializedError` when a marker is missing, stale\n * (signature drift), or recorded a failed last attempt.\n *\n * This is the single read-side gate the fulltext hot-path wrappers\n * and `store.transaction()` consult. It performs ZERO DDL and ZERO\n * marker writes — initialization is the exclusive job of the async\n * boot path (`createStoreWithSchema` → `ensureRuntimeContributions`).\n */\n assertRuntimeContributionsInitialized?: (\n this: void,\n graphId: string,\n ) => Promise<void>;\n\n // === Kind Removal Status ===\n\n /**\n * Bootstraps the per-deployment `typegraph_kind_removals` table so\n * `store.evolve()` can check pending removals and the removal verbs can\n * persist and materialize removal status. Mirrors the focused-bootstrap\n * rationale documented on `ensureIndexMaterializationsTable` — the full\n * `bootstrapTables` touches every base table and risks Postgres SHARE-lock\n * deadlock under concurrent replica startup.\n */\n ensureKindRemovalsTable?: (this: void) => Promise<void>;\n\n /**\n * List graph-extension kind removals whose data-cleanup pass has not yet\n * succeeded for this `graphId`. Returns rows with\n * `removedAt: undefined`. Order is unspecified; callers materialize\n * one-at-a-time and don't depend on it.\n */\n getPendingKindRemovals?: (\n this: void,\n graphId: string,\n ) => Promise<readonly KindRemovalRow[]>;\n\n /**\n * List ALL kind-removal rows for a `graphId` — pending and completed.\n * Used by `materializeRemovals()` reconciliation to detect rows that\n * are missing entirely (the `removeKinds()` crash window) versus\n * already completed. Without this distinction the reconciler would\n * have to upsert every expected historical removal on every call,\n * churning `last_attempted_at` on rows that long since succeeded.\n * Order is unspecified.\n */\n getAllKindRemovals?: (\n this: void,\n graphId: string,\n ) => Promise<readonly KindRemovalRow[]>;\n\n /**\n * Upsert a kind-removal status row. `removedAt: undefined` records\n * the pending state at schema-commit time; `removedAt: <iso>`\n * marks the data cleanup successful. The COALESCE rule on `removedAt`\n * mirrors `recordIndexMaterialization` so a later failure doesn't\n * clobber the historical successful timestamp from another replica.\n */\n recordKindRemoval?: (\n this: void,\n params: RecordKindRemovalParams,\n ) => Promise<void>;\n\n // === Reconciliation Watermark ===\n\n /**\n * Bootstraps the per-deployment `typegraph_reconciliation_markers`\n * table so `materializeRemovals()` can persist reconciliation\n * progress. Same focused-bootstrap rationale as the other status\n * tables — full `bootstrapTables` risks Postgres SHARE-lock\n * deadlock under concurrent replica startup.\n */\n ensureReconciliationMarkersTable?: (this: void) => Promise<void>;\n\n // === Table Contributions (#129) ===\n\n /**\n * Materializes every contribution flagged `runtimeEnsure` — the\n * strategy-owned runtime tables (fulltext today) that drizzle-kit-\n * managed setups don't create. Called once after a successful schema\n * load. Deliberately scoped: base/drizzle-visible tables are\n * `runtimeEnsure: false`, so this does not regress startup into\n * broad DDL/probing across every table.\n *\n * The canonical durable-marker writer (#135): for each runtime\n * contribution it short-circuits when the marker already records a\n * matching signature, otherwise runs the idempotent `createDdl` and\n * records the marker (success or failure) keyed by `graphId`.\n */\n ensureRuntimeContributions?: (this: void, graphId: string) => Promise<void>;\n\n /**\n * Privileged materializer for one embedding `(kind, field)` slot's\n * `ownedTables` contribution(s): creates the per-field vector table and\n * records its durable marker, idempotently. The vector counterpart of\n * `ensureRuntimeContributions` — vectors are per-`(kind, field)` and\n * graph-derived, so the store enumerates slots (via\n * `resolveEmbeddingFields`) and uses the batch counterpart at boot under\n * the privileged role. Pass `{ force: true }` to overwrite the marker\n * at the current signature, bypassing the drift-guard — the sanctioned\n * path `store.reembedVectorField()` uses after recreating storage at a\n * new dimension. Pass `{ onDrift: \"skip\" }` to leave an\n * already-provisioned slot whose shape has since changed untouched\n * (warn + no-op) instead of refusing — the boot/evolve path, so a\n * declared dimension change never blocks startup before the operator\n * can run `reembedVectorField`. Present only on backends wired with a\n * vector strategy.\n */\n ensureVectorSlotContribution?: (\n this: void,\n slot: VectorSlot,\n options?: Readonly<{ force?: boolean; onDrift?: \"throw\" | \"skip\" }>,\n ) => Promise<void>;\n\n /**\n * Batch form of `ensureVectorSlotContribution`, used by privileged boot to\n * resolve every slot's durable markers with one graph-scoped query. The\n * singular method remains available for re-embedding and compatibility.\n */\n ensureVectorSlotContributions?: (\n this: void,\n slots: readonly VectorSlot[],\n options?: Readonly<{ force?: boolean; onDrift?: \"throw\" | \"skip\" }>,\n ) => Promise<void>;\n\n /**\n * SELECT-only gate for one embedding `(kind, field)` slot: asserts the\n * durable marker(s) for the slot's `ownedTables` contribution(s),\n * cached per backend instance. Throws `StoreNotInitializedError` when\n * the slot is missing, stale (signature drift), or recorded a failed\n * last attempt. The vector counterpart of\n * `assertRuntimeContributionsInitialized`, consulted by the verified\n * runtime attach. Performs ZERO DDL and ZERO writes. Present only on\n * backends wired with a vector strategy.\n */\n assertVectorSlotInitialized?: (this: void, slot: VectorSlot) => Promise<void>;\n\n /**\n * Batch form of `assertVectorSlotInitialized`, used by verified attach to\n * resolve every slot's durable markers with one graph-scoped query.\n */\n assertVectorSlotsInitialized?: (\n this: void,\n slots: readonly VectorSlot[],\n ) => Promise<void>;\n\n /**\n * Forget one embedding `(kind, field)` slot's durable contribution\n * marker(s). Called after the slot's per-field table is dropped\n * (vector-field reclaim) so a later `ensureVectorSlotContribution`\n * re-creates the table instead of trusting an orphaned \"initialized\"\n * marker. Does NOT drop the table itself (the caller already did).\n * Present only on backends wired with a vector strategy.\n */\n deleteVectorSlotContribution?: (\n this: void,\n slot: VectorSlot,\n ) => Promise<void>;\n\n /**\n * Diagnostic: compare each contribution currently expected for `graphId`\n * against its durable marker and the physical catalog.\n *\n * Covers the strategy-owned `runtimeEnsure` contributions (fulltext)\n * plus the `ownedTables` contribution(s) of each supplied vector slot.\n * Returns one {@link ContributionDiagnostic} per detected unusable\n * contribution. A recorded failed materialization is unusable even when\n * marker and catalog agree that no table was produced. A contribution with\n * neither a marker nor a table is treated as never attempted and omitted;\n * marker rows outside the current declaration set are not audited. An empty\n * array therefore is not proof that storage was initialized.\n *\n * Deliberately NOT part of the open path. `ensureRuntimeContributions`\n * and `assertRuntimeContributionsInitialized` short-circuit on a\n * per-instance signature cache and then on the marker row alone, which\n * is the right default for a hot path but leaves a database whose\n * contribution tables were dropped out of band opening clean and\n * failing at the first dependent read or write. This method is the explicit,\n * operator-invoked catalog probe that fills that gap: it issues one uncached\n * existence query per distinct physical table and performs ZERO DDL\n * and ZERO writes, so it is safe under a least-privilege runtime role.\n *\n * Present only on backends that can probe their own catalog.\n */\n verifyContributions?: (\n this: void,\n graphId: string,\n vectorSlots: readonly VectorSlot[],\n ) => Promise<readonly ContributionDiagnostic[]>;\n\n /**\n * Re-audit current contribution declarations and non-destructively repair\n * `missing-marker` and `failed-materialization` findings. The backend must\n * resolve every target itself; it must not accept caller-provided physical\n * identities or DDL. `stale` and `orphaned-marker` findings are returned as\n * `requires-rebuild` because repairing either can require destructive data\n * reconstruction.\n *\n * Present only on backends that can both probe their catalog and run the\n * strategy-owned contribution DDL.\n */\n repairContributions?: (\n this: void,\n graphId: string,\n vectorSlots: readonly VectorSlot[],\n ) => Promise<ContributionRepairResult>;\n\n /**\n * Read-only readiness probe: the same marker-versus-catalog audit\n * `verifyContributions` performs, projected onto one entry per search\n * projection. Shares that method's detection logic exactly — a second\n * implementation would be free to disagree with the one the hot-path\n * gate actually consults, and a health check that disagrees with the\n * gate is worse than none.\n *\n * Writes nothing: no DDL, no marker writes, no effect on the\n * per-instance caches the hot path relies on. Safe on a read path, on\n * a replica, and under a least-privilege role.\n *\n * Present only on backends that can probe their catalog; a backend\n * that provisions contributions without this method declares the gap\n * as `capabilities.contributions.probe === false`.\n */\n probeContributions?: (\n this: void,\n graphId: string,\n vectorSlots: readonly VectorSlot[],\n ) => Promise<readonly ContributionProbeEntry[]>;\n\n /**\n * Destructively rebuild one search projection for one graph: clear that\n * graph's rows from the projection's storage, ensure the storage matches\n * the current `createDdl`, reconstruct the graph's content, and stamp the\n * durable marker at the current signature.\n *\n * This is the repair `repairContributions` deliberately refuses to\n * perform, and it must never be reachable from it. A `stale`\n * contribution's table exists at the *old* physical shape, so the\n * idempotent `CREATE ... IF NOT EXISTS` in the ordinary ensure path\n * no-ops; re-stamping the marker there would leave it blessing a table\n * whose shape is wrong, which is exactly what the drift guard exists\n * to prevent. Only a drop makes the recreate meaningful, and destroying\n * content is a decision the caller states rather than one a flag named\n * `force` implies.\n *\n * The fulltext projection's storage is one physical table shared by every\n * graph in the database, while this call is fenced per graph.\n * Implementations must therefore scope the teardown to `graphId` and may\n * drop the storage only when doing so destroys no other graph's rows;\n * when the recorded shape is stale and the drop that would repair it is\n * not available, they refuse (`shared-storage-in-use`) rather than\n * re-stamp a shape nothing verified.\n *\n * Runs the whole sequence inside one transaction under the same\n * per-graph fence as a schema commit, so an interrupted rebuild leaves\n * the contribution exactly as it was rather than attested-but-empty.\n *\n * `repopulate` receives that transaction and reconstructs content from\n * rows TypeGraph already stores. The inversion exists because deciding\n * *what* content a node contributes needs the schema registry, which\n * is a Store-layer concern the backend must not reach into.\n *\n * @param scope which projection to rebuild. Implementations must\n * refuse `\"vector\"`: embeddings live only in the storage this would\n * drop, so there is nothing to reconstruct them from.\n */\n rebuildContribution?: (\n this: void,\n graphId: string,\n scope: ContributionRebuildScope,\n repopulate: (\n target: TransactionBackend,\n ) => Promise<ContributionRepopulationStats>,\n ) => Promise<ContributionRebuildResult>;\n\n /**\n * Bootstraps the fulltext storage table the active `FulltextStrategy`\n * owns. Same focused-bootstrap rationale as the other `ensure*Table`\n * methods: idempotent and concurrency-safe under replica startup.\n *\n * Superseded by `ensureRuntimeContributions()` (#129); retained as\n * a thin back-compat wrapper for backends/callers predating #129. Not\n * machine-`@deprecated` because the manager still calls it as the\n * pre-#129 fallback. #135 removed the remaining hot-path callers and\n * routed this through the durable-marker writer.\n */\n ensureFulltextTable?: (this: void, graphId: string) => Promise<void>;\n\n /**\n * Read the high-water mark schema version for which\n * `materializeRemovals` reconciliation has already verified history\n * for `graphId`. Returns `undefined` when no marker has been\n * recorded yet. Used to skip already-checked transitions in the\n * recovery walk.\n */\n getReconciliationMarker?: (\n this: void,\n graphId: string,\n ) => Promise<number | undefined>;\n\n /**\n * Persist the reconciliation high-water mark for `graphId`. Called\n * after `materializeRemovals` completes a clean walk; subsequent\n * calls walk only versions newer than this marker. Idempotent\n * upsert by `graphId`.\n */\n setReconciliationMarker?: (\n this: void,\n graphId: string,\n version: number,\n ) => Promise<void>;\n\n // === Graph Lifecycle ===\n /**\n * Hard-deletes all data for a graph (nodes, edges, uniques, embeddings, schema versions).\n * Intended for import-replacement workflows. No hooks, no per-row logic.\n */\n clearGraph: (this: void, graphId: string) => Promise<void>;\n\n /**\n * Creates the base TypeGraph tables if they don't already exist.\n *\n * Called automatically by `createStoreWithSchema()` when a fresh database\n * is detected. Users who manage DDL themselves via `createStore()` never\n * hit this path.\n */\n bootstrapTables?: (this: void) => Promise<void>;\n\n /**\n * Refreshes the backend's query-planner statistics.\n *\n * Call this once after a large initial import or bulk backfill. Without\n * up-to-date statistics, the planner can pick suboptimal execution plans\n * — on PostgreSQL this is the difference between a 0.5ms and a 5ms\n * forward traversal; on SQLite it's the difference between 0.9ms and\n * 23ms fulltext search. Autovacuum / background statistics collection\n * will catch up eventually, but calling this explicitly after a bulk\n * load gives you correct latencies immediately.\n *\n * Implementations:\n * - SQLite runs `ANALYZE`, which populates `sqlite_stat1`\n * - PostgreSQL runs `ANALYZE` on the TypeGraph-managed tables\n *\n * Safe to call at any time; costs a few tens of milliseconds on the\n * sizes this library is designed for.\n */\n refreshStatistics: (this: void) => Promise<void>;\n\n /**\n * Runs an intentionally trusted, all-or-nothing initial import.\n *\n * Optional because only backends that can pin one transaction and use a\n * native high-throughput write path expose it. Implementations must reject\n * a database whose TypeGraph node or edge tables already contain rows. They\n * may temporarily remove rebuildable secondary indexes, but must restore\n * them before committing. Any callback, insert, or rebuild failure rolls the\n * entire operation back.\n *\n * This is a top-level-only lifecycle operation and is deliberately absent\n * from {@link TransactionBackend}. When `schemaWrite` is supplied, the\n * import acquires and validates that Store version's managed-write fence\n * before checking emptiness or writing. Omitting it retains the raw,\n * unversioned import behavior.\n */\n trustedImport?: <T>(\n this: void,\n fn: (session: TrustedImportSession) => Promise<T>,\n options?: Readonly<{\n schemaWrite?: Readonly<{ graphId: string; expectedVersion: number }>;\n }>,\n ) => Promise<T>;\n\n // === Query Execution ===\n execute: <T>(this: void, query: CompiledRowsSql) => Promise<readonly T[]>;\n\n /**\n * Execute a non-row-returning SQL statement bound to this backend or\n * transaction. Optional because custom backends may only expose the public\n * row-returning query path; features that need statement execution must\n * capability-check and fail loudly.\n */\n executeStatement?: (this: void, query: CompiledStatementSql) => Promise<void>;\n\n /**\n * Execute an internally compiled statement against connection-local\n * temporary state. History wrappers preserve this path because it cannot\n * mutate graph or history tables; callers cannot construct its branded\n * input through the public API.\n */\n executeTemporaryStatement?: (\n this: void,\n query: CompiledTemporaryStatementSql,\n ) => Promise<void>;\n\n /** Execute pre-compiled SQL text with bound parameters. Available on sync SQLite and pg backends. */\n executeRaw?: <T>(\n this: void,\n sqlText: string,\n params: readonly unknown[],\n ) => Promise<readonly T[]>;\n\n /** Compile a TypeGraph `SqlFragment` to `{ sql, params }` without executing. */\n compileSql?: (\n this: void,\n query: SqlFragment,\n ) => Readonly<{ sql: string; params: readonly unknown[] }>;\n\n /**\n * Execute a DDL statement that returns no rows (CREATE INDEX,\n * CREATE TABLE, ALTER TABLE, etc.). Separate from `executeRaw`\n * because some drivers (better-sqlite3) require `.run()` for DDL\n * and `.all()` for queries — the ambiguity can't be resolved by\n * inspecting the SQL string portably.\n *\n * Postgres path can use this for `CREATE INDEX CONCURRENTLY`, which\n * cannot run inside a transaction. Implementations must execute the\n * statement outside `transaction(...)`.\n */\n executeDdl?: (this: void, ddl: string) => Promise<void>;\n\n /**\n * Installs a database-global extension idempotently, tolerating the\n * concurrent-install race.\n *\n * `CREATE EXTENSION IF NOT EXISTS` is not a concurrency primitive on\n * PostgreSQL: the existence check cannot see another session's uncommitted\n * `pg_extension` row, so the loser of a race waits for the winner and is\n * then handed SQLSTATE 23505 instead of the harmless \"already exists\"\n * notice (#446). A backend implementing this member owns that retry, and\n * may additionally serialize same-extension installers behind a fence of its\n * own (the bundled PostgreSQL backend takes a transaction advisory lock\n * keyed on the extension, #475).\n *\n * This is the one member the library asks for an extension install; it\n * supersedes {@link GraphBackend.ensureTrigramExtension}, which said the same\n * thing for one extension.\n *\n * Like `executeDdl`, implementations MUST run the statement at the\n * top-level backend, never inside `transaction(...)`: the 23505 aborts the\n * enclosing transaction, so a retry issued inside one would only collect\n * `25P02` on the way out. That is why this member is absent from\n * {@link TransactionBackend}.\n */\n ensureExtension?: (this: void, name: DatabaseExtensionName) => Promise<void>;\n\n // === Transaction ===\n /** Runs TypeGraph operations inside a backend-owned transaction. */\n transaction: <T>(\n this: void,\n fn: (tx: TransactionBackend) => Promise<T>,\n options?: TransactionOptions,\n ) => Promise<T>;\n\n // === Lifecycle ===\n close: (this: void) => Promise<void>;\n}>;\n\n/**\n * Adapter-native transaction interoperability layered on top of the portable\n * TypeGraph backend. Only adapter entrypoints expose this capability.\n */\nexport type AdapterBackend<TNativeTransaction> = GraphBackend &\n Readonly<{\n /**\n * Runs TypeGraph operations and exposes the exact adapter-native handle\n * bound to the same transaction.\n */\n transactionWithNative: <T>(\n this: void,\n fn: (\n tx: TransactionBackend,\n nativeTransaction: TNativeTransaction,\n ) => Promise<T>,\n options?: TransactionOptions,\n ) => Promise<T>;\n /** Adopts a caller-owned, already-open adapter transaction. */\n adoptTransaction: (\n this: void,\n externalTransaction: TNativeTransaction,\n ) => TransactionBackend;\n }>;\n\nexport type BackendIdentity = Pick<\n GraphBackend,\n | \"dialect\"\n | \"capabilities\"\n | \"tableNames\"\n | \"fulltextStrategy\"\n | \"vectorStrategy\"\n>;\n\nexport type NodeEntityReadBackend = Pick<\n GraphBackend,\n \"getNode\" | \"getNodes\" | \"findNodesByKind\" | \"countNodesByKind\"\n>;\n\nexport type NodeEntityWriteBackend = Pick<\n GraphBackend,\n | \"insertNode\"\n | \"insertNodeNoReturn\"\n | \"insertNodesBatch\"\n | \"insertNodesBatchReturning\"\n | \"updateNode\"\n | \"updateNodeSet\"\n | \"deleteNode\"\n | \"hardDeleteNode\"\n>;\n\nexport type EdgeEntityReadBackend = Pick<\n GraphBackend,\n | \"getEdge\"\n | \"getEdges\"\n | \"countEdgesFrom\"\n | \"edgeExistsBetween\"\n | \"findEdgesConnectedTo\"\n | \"findEdgesByKind\"\n | \"findEdgesByEndpointSet\"\n | \"findEdgesByHeterogeneousEndpointSet\"\n | \"countEdgesByKind\"\n>;\n\nexport type EdgeEntityWriteBackend = Pick<\n GraphBackend,\n | \"insertEdge\"\n | \"insertEdgeNoReturn\"\n | \"insertEdgesBatch\"\n | \"insertEdgesBatchReturning\"\n | \"updateEdge\"\n | \"deleteEdge\"\n | \"deleteEdgesBatch\"\n | \"hardDeleteEdge\"\n | \"hardDeleteEdgesBatch\"\n>;\n\nexport type GraphEntityReadBackend = NodeEntityReadBackend &\n EdgeEntityReadBackend;\n\nexport type GraphEntityWriteBackend = NodeEntityWriteBackend &\n EdgeEntityWriteBackend;\n\nexport type UniqueConstraintBackend = Pick<\n GraphBackend,\n | \"insertUnique\"\n | \"insertUniqueBatch\"\n | \"deleteUnique\"\n | \"hardDeleteUniquesByNodeIds\"\n | \"hardDeleteUniquesByConcreteKind\"\n | \"checkUnique\"\n | \"checkUniqueBatch\"\n>;\n\nexport type SchemaReadBackend = Pick<\n GraphBackend,\n \"getActiveSchema\" | \"getSchemaVersion\"\n>;\n\nexport type SchemaCommitBackend = Pick<\n GraphBackend,\n \"commitSchemaVersion\" | \"commitSchemaVersionIfKindsEmpty\" | \"setActiveVersion\"\n>;\n\nexport type SchemaWriteFenceBackend = Pick<\n GraphBackend,\n \"lockSchemaVersionForWrite\"\n>;\n\nexport type VectorOperationBackend = Pick<\n GraphBackend,\n | \"upsertEmbedding\"\n | \"upsertEmbeddingBatch\"\n | \"deleteEmbedding\"\n | \"deleteEmbeddingBatch\"\n | \"vectorSearch\"\n | \"createVectorIndex\"\n | \"dropVectorIndex\"\n>;\n\nexport type FulltextOperationBackend = Pick<\n GraphBackend,\n | \"upsertFulltext\"\n | \"deleteFulltext\"\n | \"upsertFulltextBatch\"\n | \"deleteFulltextBatch\"\n | \"fulltextSearch\"\n>;\n\nexport type IndexMaterializationBackend = Pick<\n GraphBackend,\n | \"ensureIndexMaterializationsTable\"\n | \"getIndexMaterialization\"\n | \"getIndexMaterializations\"\n | \"recordIndexMaterialization\"\n>;\n\nexport type ContributionMaterializationBackend = Pick<\n GraphBackend,\n | \"ensureContributionMaterializationsTable\"\n | \"getContributionMaterialization\"\n | \"recordContributionMaterialization\"\n | \"assertRuntimeContributionsInitialized\"\n | \"ensureRuntimeContributions\"\n | \"ensureFulltextTable\"\n>;\n\nexport type RemovalMaterializationBackend = Pick<\n GraphBackend,\n | \"ensureKindRemovalsTable\"\n | \"getPendingKindRemovals\"\n | \"getAllKindRemovals\"\n | \"recordKindRemoval\"\n | \"ensureReconciliationMarkersTable\"\n | \"getReconciliationMarker\"\n | \"setReconciliationMarker\"\n>;\n\nexport type GraphLifecycleBackend = Pick<\n GraphBackend,\n \"clearGraph\" | \"bootstrapTables\"\n>;\n\nexport type QueryExecutionBackend = Pick<GraphBackend, \"execute\">;\n\nexport type RawQueryExecutionBackend = Pick<\n GraphBackend,\n \"executeRaw\" | \"compileSql\"\n>;\n\nexport type SqlCompilationBackend = Pick<GraphBackend, \"compileSql\">;\n\nexport type RawStatementExecutionBackend = Pick<\n GraphBackend,\n \"executeStatement\" | \"executeTemporaryStatement\" | \"executeDdl\"\n>;\n\nexport type BackendMaintenance = Pick<GraphBackend, \"refreshStatistics\">;\n\nexport type BackendTransactions = Pick<GraphBackend, \"transaction\">;\n\nexport type AdapterBackendTransactions<TNativeTransaction> = Pick<\n AdapterBackend<TNativeTransaction>,\n \"transactionWithNative\" | \"adoptTransaction\"\n>;\n\nexport type BackendLifecycle = Pick<GraphBackend, \"close\">;\n\n/**\n * Read-oriented transaction projection exposed by portable transaction\n * contexts. It preserves snapshot-aware graph reads and TypeGraph-compiled\n * row queries while excluding graph writes, arbitrary raw SQL, DDL,\n * transaction adoption, and lifecycle control.\n */\nexport type TransactionReadBackend = Readonly<\n BackendIdentity &\n GraphEntityReadBackend &\n SchemaReadBackend &\n QueryExecutionBackend &\n SqlCompilationBackend\n>;\n\n/**\n * Transaction backend — a backend scoped to a transaction.\n *\n * This is an explicit facet composition, not `Omit<GraphBackend, ...>`.\n * New top-level-only backend methods therefore do not silently appear on\n * transaction-scoped backends. `commitSchemaVersion`, `setActiveVersion`,\n * `refreshStatistics`, `transaction`, `adoptTransaction`, and `close` stay\n * deliberately absent: their guarantees depend on the top-level backend or\n * lifecycle owner rather than an already-open transaction.\n */\nexport type TransactionBackend = Readonly<\n BackendIdentity &\n GraphEntityReadBackend &\n GraphEntityWriteBackend &\n UniqueConstraintBackend &\n // The edge cardinality claim relation's surface. Inline rather than a named\n // member type: it is a different relation from `uniques` with a different\n // key, and naming it would add a type the public surface references but no\n // entrypoint exports.\n Pick<\n GraphBackend,\n \"claimEdgeCardinality\" | \"claimEdgeCardinalityBatch\" | \"purgeEdgeClaims\"\n > &\n SchemaReadBackend &\n Pick<GraphBackend, \"lockSchemaVersionForWrite\"> &\n VectorOperationBackend &\n FulltextOperationBackend &\n IndexMaterializationBackend &\n ContributionMaterializationBackend &\n RemovalMaterializationBackend &\n GraphLifecycleBackend &\n QueryExecutionBackend &\n RawQueryExecutionBackend &\n RawStatementExecutionBackend\n>;\n\n/**\n * Transaction backend exposed only while the backend's schema-write lock is\n * held. Unlike the ordinary top-level `executeDdl` port, this DDL primitive is\n * explicitly transaction-scoped and must use the callback's transaction.\n *\n * @internal\n */\nexport type SchemaWriteTransactionBackend = TransactionBackend &\n Readonly<{\n executeStatement: NonNullable<TransactionBackend[\"executeStatement\"]>;\n tableExists: (this: void, tableName: string) => Promise<boolean>;\n executeSchemaDdl: (this: void, ddl: string) => Promise<void>;\n deleteSchemaVectorSlotContribution: (\n this: void,\n slot: VectorSlot,\n ) => Promise<void>;\n }>;\n\n/**\n * The target a schema-commit preflight runs against: a transaction backend\n * that MAY also carry the schema-write DDL primitive.\n *\n * Optional, deliberately. Both bundled backends pass the same\n * {@link SchemaWriteTransactionBackend} their `schemaWriteTransaction` exposes,\n * so DDL is available there; a custom backend may implement\n * {@link GraphBackend.commitSchemaVersionWithPreflight} over a transaction that\n * cannot run DDL. Declaring the port as present-or-absent lets a preflight that\n * needs it refuse with a typed error naming the capability, instead of calling\n * `undefined` — or, far worse, skipping the DDL and continuing.\n *\n * @internal\n */\nexport type SchemaCommitPreflightBackend = TransactionBackend &\n Readonly<{\n executeSchemaDdl?: (this: void, ddl: string) => Promise<void>;\n }>;\n\n/**\n * Builds the actual runtime projection exposed as `TransactionContext.backend`.\n * This is an explicit object rather than a type-only narrowing so portable\n * callers cannot discover write or arbitrary-SQL methods on the underlying\n * transaction backend at runtime.\n *\n * @internal\n */\nexport function createTransactionReadBackend(\n backend: TransactionBackend,\n): TransactionReadBackend {\n const getNodes = backend.getNodes;\n const getEdges = backend.getEdges;\n const compileSql = backend.compileSql;\n\n return Object.freeze({\n dialect: backend.dialect,\n capabilities: backend.capabilities,\n ...(backend.tableNames === undefined ?\n {}\n : { tableNames: backend.tableNames }),\n ...(backend.fulltextStrategy === undefined ?\n {}\n : { fulltextStrategy: backend.fulltextStrategy }),\n ...(backend.vectorStrategy === undefined ?\n {}\n : { vectorStrategy: backend.vectorStrategy }),\n getNode: (graphId, kind, id) => backend.getNode(graphId, kind, id),\n ...(getNodes === undefined ?\n {}\n : {\n getNodes: (graphId: string, kind: string, ids: readonly string[]) =>\n getNodes(graphId, kind, ids),\n }),\n getEdge: (graphId, id) => backend.getEdge(graphId, id),\n ...(getEdges === undefined ?\n {}\n : {\n getEdges: (graphId: string, ids: readonly string[]) =>\n getEdges(graphId, ids),\n }),\n countEdgesFrom: (params) => backend.countEdgesFrom(params),\n edgeExistsBetween: (params) => backend.edgeExistsBetween(params),\n findEdgesConnectedTo: (params) => backend.findEdgesConnectedTo(params),\n findNodesByKind: (params) => backend.findNodesByKind(params),\n countNodesByKind: (params) => backend.countNodesByKind(params),\n findEdgesByKind: (params) => backend.findEdgesByKind(params),\n countEdgesByKind: (params) => backend.countEdgesByKind(params),\n getActiveSchema: (graphId) => backend.getActiveSchema(graphId),\n getSchemaVersion: (graphId, version) =>\n backend.getSchemaVersion(graphId, version),\n execute: <T>(query: CompiledRowsSql) => backend.execute<T>(query),\n ...(compileSql === undefined ?\n {}\n : { compileSql: (query: SqlFragment) => compileSql(query) }),\n });\n}\n\n/**\n * Closes an owned resource after provisioning fails without replacing the\n * original domain error with a secondary cleanup failure.\n */\nexport async function closeAfterFailure(\n resource: Readonly<{ close: () => void | Promise<void> }>,\n provisioningError: unknown,\n): Promise<never> {\n try {\n await resource.close();\n } catch {\n // The provisioning failure remains the actionable error. Managed close is\n // retryable when the resource is returned, but a failed factory has no\n // handle it can safely expose for a second attempt.\n }\n throw provisioningError;\n}\n\n/** Options for {@link runOptionallyInTransaction}. */\nexport type RunOptionallyInTransactionOptions = Readonly<{\n /**\n * Pass only when the toplevel backend method would recurse — pass the\n * operation-level backend so the no-transaction path doesn't loop back\n * through the same toplevel method.\n */\n fallback?: GraphBackend | TransactionBackend;\n /**\n * Options for the transaction this opens — most usefully\n * `accessMode: \"read_only\"`, which lets a multi-statement READ declare itself\n * to the engine instead of only promising it (SQLite issues `BEGIN` rather\n * than reserving the single writer slot with `BEGIN IMMEDIATE`; PostgreSQL\n * issues `BEGIN … READ ONLY`).\n *\n * Scopes the transaction and nothing else, so it is not honored on the\n * fallthrough path: a backend reporting `transactions: false` opens no\n * transaction to configure. The callback receives an explicit execution\n * context stating whether a transaction was opened, so callers never infer\n * atomicity from backend object identity.\n */\n transaction?: TransactionOptions;\n}>;\n\n/** What {@link runOptionallyInTransaction} actually did for this invocation. */\nexport type OptionalTransactionExecution = Readonly<{\n /** True only when the helper opened a transaction around the callback. */\n atomic: boolean;\n}>;\n\n/**\n * Runs `fn` inside a transaction when given a top-level backend that supports\n * one, falling through to a direct invocation otherwise. Lets call sites benefit\n * from atomicity on backends that have transactions while staying functional on\n * backends that don't (Cloudflare D1, `drizzle-orm/neon-http` over HTTP), and\n * avoids opening nested transactions when the caller already holds a\n * transaction-scoped backend. The single-statement race window is already\n * implicit on any backend that reports `transactions: false`; callers that\n * cannot tolerate it must branch on the capability themselves.\n */\nexport async function runOptionallyInTransaction<T>(\n backend: GraphBackend | TransactionBackend,\n fn: (\n target: GraphBackend | TransactionBackend,\n execution: OptionalTransactionExecution,\n ) => Promise<T>,\n options?: RunOptionallyInTransactionOptions,\n): Promise<T> {\n if (\"transaction\" in backend && backend.capabilities.transactions) {\n return backend.transaction(\n (tx) => fn(tx, { atomic: true }),\n options?.transaction,\n );\n }\n return fn(options?.fallback ?? backend, { atomic: false });\n}\n\n// ============================================================\n// Additional Parameter Types\n// ============================================================\n\n/**\n * Parameters for inserting a unique constraint entry.\n */\nexport type InsertUniqueParams = Readonly<{\n graphId: string;\n nodeKind: string;\n constraintName: string;\n key: string;\n nodeId: string;\n concreteKind: string;\n}>;\n\n/**\n * Parameters for releasing a unique constraint entry.\n *\n * Every release is scoped to the claim's OWNER — the pair\n * `(concreteKind, nodeId)`, because a node id is unique only within its kind.\n * The two shapes differ only in whether the claim AXIS participates:\n *\n * - **Lifecycle release** (`nodeKind` absent) — \"give up every claim this node\n * holds for this constraint and key, whatever axis it sits on\". Soft delete,\n * an update's key-change release and the resurrect diff use it, so a claim\n * written under an older axis is still released by newer code.\n * - **Compensating release** (`nodeKind` present) — \"undo exactly the row I\n * just claimed, at the axis I claimed it on\". A failed write's rollback uses\n * it, so it touches neither a row that predates the write nor one another\n * node holds.\n */\nexport type DeleteUniqueParams = Readonly<{\n graphId: string;\n /**\n * The claim axis (`uniques.node_kind`) the release is restricted to. Absent\n * releases the owner's claims at every axis — see the two shapes above.\n */\n nodeKind?: string;\n constraintName: string;\n key: string;\n /** The claim owner's concrete kind (`uniques.concrete_kind`). */\n concreteKind: string;\n /** The claim owner's node id (`uniques.node_id`). */\n nodeId: string;\n}>;\n\n/** Parameters for permanently clearing uniqueness sidecars by node identity. */\nexport type HardDeleteUniquesByNodeIdsParams = Readonly<{\n graphId: string;\n concreteKind: string;\n nodeIds: readonly string[];\n}>;\n\n/** Parameters for permanently clearing every uniqueness claim a kind owns. */\nexport type HardDeleteUniquesByConcreteKindParams = Readonly<{\n graphId: string;\n concreteKind: string;\n}>;\n\n/**\n * One edge cardinality claim, named by the components its axis, its key and its\n * holder-liveness predicate are all built from.\n *\n * The components are passed RAW rather than pre-rendered: `EDGE_CARDINALITY_SPECS`\n * (`store/claims/edge-claims.ts`) is the one table that decides which endpoints\n * the key covers and what a holder must still be, and both the TypeScript probe\n * and the SQL builder read it. A caller that rendered the axis and key itself\n * would be a second spelling of that decision.\n */\nexport type ClaimEdgeCardinalityParams = Readonly<{\n graphId: string;\n /** The declared cardinality; `many` declares nothing and never claims. */\n cardinality: Exclude<Cardinality, \"many\">;\n edgeKind: string;\n /** The edge that will hold the axis if this claim lands. */\n edgeId: string;\n fromKind: string;\n fromId: string;\n toKind: string;\n toId: string;\n}>;\n\n/**\n * What a claim statement decided.\n *\n * `refused` carries the incumbent so the caller can say which edge holds the\n * axis; the typed refusal itself is the store's, built from the same\n * `checkCardinality` / `checkUniqueEdge` owners the probe uses, so a caller\n * cannot tell which layer refused.\n */\nexport type EdgeClaimOutcome =\n | Readonly<{ status: \"claimed\" }>\n | Readonly<{ status: \"refused\"; holderEdgeId: string }>;\n\n/** Parameters for the housekeeping purge of claims held by named edges. */\nexport type PurgeEdgeClaimsParams = Readonly<{\n graphId: string;\n edgeIds: readonly string[];\n}>;\n\n/** One edge kind's declared cardinality, as the fence audit reads it. */\nexport type EdgeCardinalityDeclaration = Readonly<{\n edgeKind: string;\n /** `many` declares nothing, so it is unrepresentable here. */\n cardinality: Exclude<Cardinality, \"many\">;\n}>;\n\n/**\n * What a constraint-fence audit asks the database about: the declarations the\n * graph carries, one list per family.\n *\n * The declarations are passed rather than discovered because the backend holds\n * no schema — and because the `uniqueConstraintNames` restriction is\n * load-bearing rather than an optimization: the `uniques` relation also holds\n * disjointness claims, whose `node_kind` is a pair label rather than a kind and\n * for which no uniqueness axis can be computed. Those rows are covered by\n * `disjointKindPairs`, from the nodes relation.\n */\nexport type ReadConstraintFenceViolationsParams = Readonly<{\n graphId: string;\n /** Every unique constraint name the graph declares, in any scope. */\n uniqueConstraintNames: readonly string[];\n /** Every declared `disjointWith` pair, each read as one intersection. */\n disjointKindPairs: readonly (readonly [string, string])[];\n /** Every edge kind declaring a cardinality other than `many`. */\n edgeCardinalities: readonly EdgeCardinalityDeclaration[];\n}>;\n\n/**\n * One live `uniques` row that shares its `(constraint_name, key)` with at least\n * one other live row — a candidate, not a verdict: two rows contend only when\n * their `node_kind`s fold onto ONE claim axis, which the caller decides.\n */\nexport type ContendedUniqueRow = Readonly<{\n nodeKind: string;\n constraintName: string;\n key: string;\n concreteKind: string;\n nodeId: string;\n}>;\n\n/**\n * One live edge that shares its declared cardinality's population with at least\n * one other live edge. The endpoints are returned whole so the caller can name\n * the claim key through the one builder that renders it.\n */\nexport type ContendedEdgeRow = Readonly<{\n edgeKind: string;\n cardinality: Exclude<Cardinality, \"many\">;\n edgeId: string;\n fromKind: string;\n fromId: string;\n toKind: string;\n toId: string;\n}>;\n\n/** One node id live under BOTH kinds of a declared disjoint pair. */\nexport type DisjointOverlapRow = Readonly<{\n kinds: readonly [string, string];\n nodeId: string;\n}>;\n\n/** Everything one constraint-fence audit read, per family. */\nexport type ConstraintFenceViolationRows = Readonly<{\n contendedUniqueRows: readonly ContendedUniqueRow[];\n contendedEdgeRows: readonly ContendedEdgeRow[];\n disjointOverlaps: readonly DisjointOverlapRow[];\n}>;\n\n/**\n * Parameters for checking a unique constraint.\n */\nexport type CheckUniqueParams = Readonly<{\n graphId: string;\n nodeKind: string;\n constraintName: string;\n key: string;\n /** If true, also returns soft-deleted entries. Used by get-or-create operations. */\n includeDeleted?: boolean;\n}>;\n\n/**\n * Parameters for batch-checking unique constraints.\n */\nexport type CheckUniqueBatchParams = Readonly<{\n graphId: string;\n nodeKind: string;\n constraintName: string;\n keys: readonly string[];\n /** If true, also returns soft-deleted entries. Used by get-or-create operations. */\n includeDeleted?: boolean;\n}>;\n\n/**\n * Parameters for inserting a schema version.\n *\n * Used internally by backend implementations. Public callers go through\n * `commitSchemaVersion`, which handles the insert + activate atomically\n * with CAS guarantees.\n */\nexport type InsertSchemaParams = Readonly<{\n graphId: string;\n version: number;\n schemaHash: string;\n schemaDoc: SerializedSchema;\n isActive: boolean;\n}>;\n\n/**\n * The caller's claim about the currently-active schema version, used as\n * the optimistic compare-and-swap guard for `commitSchemaVersion`.\n *\n * - `{ kind: \"initial\" }` — caller is committing the first-ever version\n * for this graph and asserts no active version exists yet.\n * - `{ kind: \"active\", version: N }` — caller observed version N as\n * active and is committing version N+1 against that baseline. The\n * commit fails with `StaleVersionError` if some other writer has\n * advanced or rolled back the pointer in the meantime.\n *\n * Tagged-union form (rather than a magic `version: 0` sentinel) because\n * the two cases have materially different semantics: the initial path\n * skips the \"deactivate prior\" UPDATE, and the no-active-row state is\n * a *valid* expected state, not an out-of-band signal.\n */\nexport type CommitSchemaVersionExpected =\n Readonly<{ kind: \"initial\" }> | Readonly<{ kind: \"active\"; version: number }>;\n\n/**\n * Parameters for `commitSchemaVersion`.\n */\nexport type CommitSchemaVersionParams = Readonly<{\n graphId: string;\n /** CAS guard — see `CommitSchemaVersionExpected`. */\n expected: CommitSchemaVersionExpected;\n /** The new version to insert and activate. */\n version: number;\n schemaHash: string;\n schemaDoc: SerializedSchema;\n}>;\n\nexport type SchemaKindEmptinessProbe = Readonly<{\n entity: \"node\" | \"edge\";\n kind: string;\n}>;\n\nexport type PopulatedSchemaKind = SchemaKindEmptinessProbe &\n Readonly<{ count: number }>;\n\nexport type CommitSchemaVersionIfKindsEmptyResult =\n | Readonly<{ status: \"committed\"; row: SchemaVersionRow }>\n | Readonly<{\n status: \"populated\";\n kinds: readonly PopulatedSchemaKind[];\n }>;\n\nexport type LockSchemaVersionForWriteParams = Readonly<{\n graphId: string;\n expectedVersion: number;\n}>;\n\n/**\n * Optional schema-managed write identity for a trusted import. Supplying it\n * acquires and validates the Store version's transaction-scoped schema fence;\n * omitting it leaves the import outside the versioned guarantee.\n */\nexport type TrustedImportOptions = Readonly<{\n schemaWrite?: Readonly<{ graphId: string; expectedVersion: number }>;\n}>;\n\n/**\n * Parameters for `setActiveVersion`.\n *\n * Flips the active pointer from `expected` to `version` for an existing\n * row. CAS prevents overwriting a concurrent rollback or commit.\n */\nexport type SetActiveVersionParams = Readonly<{\n graphId: string;\n /** CAS guard. Same semantics as `commitSchemaVersion.expected`. */\n expected: CommitSchemaVersionExpected;\n /** The version to mark active. Must already exist. */\n version: number;\n}>;\n\n/**\n * Parameters for counting edges from a source node.\n */\nexport type CountEdgesFromParams = Readonly<{\n graphId: string;\n edgeKind: string;\n fromKind: string;\n fromId: string;\n /** If true, only count edges where valid_to IS NULL */\n activeOnly?: boolean;\n}>;\n\n/**\n * Parameters for checking if an edge exists between two nodes.\n */\nexport type EdgeExistsBetweenParams = Readonly<{\n graphId: string;\n edgeKind: string;\n fromKind: string;\n fromId: string;\n toKind: string;\n toId: string;\n}>;\n\n/**\n * Parameters for finding edges connected to a node.\n */\nexport type FindEdgesConnectedToParams = Readonly<{\n graphId: string;\n nodeKind: string;\n nodeId: string;\n}>;\n\n/**\n * Parameters for finding nodes by kind.\n */\nexport type FindNodesByKindParams = Readonly<{\n graphId: string;\n kind: string;\n /** Max rows to return. */\n limit?: number;\n /** Offset. Present for backward compat; rebuild uses `after` instead. */\n offset?: number;\n /** If true, exclude deleted nodes. Default true. */\n excludeDeleted?: boolean;\n /** Temporal mode for filtering by validity period. */\n temporalMode?: TemporalMode;\n /** Timestamp for \"current\" and \"asOf\" temporal modes. */\n asOf?: string;\n /**\n * Stable ordering for keyset pagination. Default: \"created_at\" (existing\n * behavior). Rebuild should use \"id\" for iteration that is stable under\n * concurrent writes and shared timestamps.\n */\n orderBy?: \"id\" | \"created_at\";\n /**\n * Keyset cursor. Returns rows strictly greater (by `orderBy`) than this\n * value. When `orderBy: \"id\"`, compared lexicographically. Mutually\n * exclusive with `offset` — callers pick one.\n */\n after?: string;\n}>;\n\n/**\n * Parameters for counting nodes by kind.\n */\nexport type CountNodesByKindParams = Readonly<{\n graphId: string;\n kind: string;\n /** If true, exclude deleted nodes. Default true. */\n excludeDeleted?: boolean;\n /** Temporal mode for filtering by validity period. */\n temporalMode?: TemporalMode;\n /** Timestamp for \"current\" and \"asOf\" temporal modes. */\n asOf?: string;\n}>;\n\n/**\n * Parameters for finding edges by kind.\n */\nexport type FindEdgesByKindParams = Readonly<{\n graphId: string;\n kind: string;\n fromKind?: string;\n fromId?: string;\n toKind?: string;\n toId?: string;\n limit?: number;\n offset?: number;\n /** If true, exclude deleted edges. Default true. */\n excludeDeleted?: boolean;\n /** Temporal mode for filtering by validity period. */\n temporalMode?: TemporalMode;\n /** Timestamp for \"current\" and \"asOf\" temporal modes. */\n asOf?: string;\n /**\n * Stable ordering for keyset pagination. Default: \"created_at\" (existing\n * behavior). Use \"id\" for iteration that is stable under shared `created_at`\n * timestamps — the offset path orders by the NON-unique `created_at`, so a\n * full enumeration must page by the unique `id` to avoid skipping a row at a\n * page boundary. Mirrors {@link FindNodesByKindParams.orderBy}.\n */\n orderBy?: \"id\" | \"created_at\";\n /**\n * Keyset cursor. Returns rows strictly greater (by `orderBy`) than this value.\n * When `orderBy: \"id\"`, compared lexicographically. Mutually exclusive with\n * `offset` — callers pick one. Mirrors {@link FindNodesByKindParams.after}.\n */\n after?: string;\n}>;\n\n/**\n * The endpoint side a {@link FindEdgesByEndpointSetParams} read fans out over.\n */\nexport type EdgeEndpointSide = \"from\" | \"to\";\n\n/**\n * Parameters for reading the edges of a SET of endpoints in one statement per\n * bind-budget chunk — the widened form of {@link FindEdgesByKindParams}'s\n * scalar `fromId` / `toId`.\n *\n * Deliberately a SEPARATE parameter type on a separate operation rather than\n * optional fields on `FindEdgesByKindParams`. A backend that did not implement\n * set membership would still type-check while ignoring the id list, and would\n * then return every edge of the kind — which the caller would rebucket into a\n * correct-looking answer at unbounded cost. Splitting the operation makes that\n * failure unreachable: support is detected by the method's presence, before any\n * read is issued.\n *\n * The shape also makes the previously-validated illegal states\n * unrepresentable. One `side` instead of two independent id lists means both\n * endpoints can never fan out at once; no scalar `fromId` / `toId` field means\n * a scalar and a set can never disagree; no `limit` / `offset` / `after` means\n * a global slice can never be requested across a read the backend splits into\n * bind-budget chunks.\n */\nexport type FindEdgesByEndpointSetParams = Readonly<{\n graphId: string;\n kind: string;\n /** Which endpoint column the id set constrains. */\n side: EdgeEndpointSide;\n /**\n * Kind of the fanned-out endpoint. Required: it is the index prefix that\n * makes the set a seek rather than a scan, so a set is always scoped to one\n * endpoint kind and a heterogeneous page costs one read per distinct kind.\n */\n endpointKind: string;\n /**\n * Endpoint NODE ids to match — deliberately not named `ids`, which in the\n * backend params vocabulary means edge ids (see\n * {@link DeleteEdgesBatchParams}); the write-surface assertion in\n * `recorded-capture/write-surface.ts` classifies params structurally and a\n * `{ graphId, ids }` read would be misread as a write.\n *\n * The backend deduplicates before splitting the list across bind-budget\n * chunks — a repeated id spanning two chunks would return its edges twice.\n * An empty list reads nothing and yields no rows.\n */\n endpointIds: readonly string[];\n /**\n * Maximum rows per distinct endpoint id, applied inside the statement (via\n * `ROW_NUMBER()` over the read's own ordering) rather than by the caller.\n * Only meaningful on a backend whose `capabilities.windowFunctions` is true;\n * callers must still cap client-side, so a backend that ignores this returns\n * a superset rather than a wrong answer. Unlike a global `limit`, a\n * per-endpoint cap composes with chunking: each endpoint's rows fall\n * entirely within one chunk.\n */\n limitPerEndpoint?: number;\n /** If true, exclude deleted edges. Default true. */\n excludeDeleted?: boolean;\n /** Temporal mode for filtering by validity period. */\n temporalMode?: TemporalMode;\n /** Timestamp for \"current\" and \"asOf\" temporal modes. */\n asOf?: string;\n}>;\n\n/**\n * Parameters for reading several edge kinds from several endpoint kinds.\n *\n * The endpoint pairs are joined as a relation, so round trips are independent\n * of the number of licensed edge-kind/endpoint-kind combinations. Large source\n * sets may still be split to respect the backend's bind-parameter budget.\n */\nexport type FindEdgesByHeterogeneousEndpointSetParams = Readonly<{\n graphId: string;\n side: EdgeEndpointSide;\n endpoints: readonly Readonly<{ kind: string; id: string }>[];\n edgeKinds: readonly string[];\n limitPerEndpoint?: number;\n /** If true, exclude deleted edges. Default true. */\n excludeDeleted?: boolean;\n /** Temporal mode for filtering by validity period. */\n temporalMode?: TemporalMode;\n /** Timestamp for \"current\" and \"asOf\" temporal modes. */\n asOf?: string;\n}>;\n\n/**\n * Parameters for counting edges by kind.\n */\nexport type CountEdgesByKindParams = Readonly<{\n graphId: string;\n kind: string;\n fromKind?: string;\n fromId?: string;\n toKind?: string;\n toId?: string;\n /** If true, exclude deleted edges. Default true. */\n excludeDeleted?: boolean;\n /** Temporal mode for filtering by validity period. */\n temporalMode?: TemporalMode;\n /** Timestamp for \"current\" and \"asOf\" temporal modes. */\n asOf?: string;\n}>;\n\n// ============================================================\n// Default Capabilities\n// ============================================================\n\n/**\n * Conservative per-statement bound-parameter floor for SQLite. The\n * compiled-in `SQLITE_MAX_VARIABLE_NUMBER` defaulted to 999 before SQLite\n * 3.32.0; drivers whose real ceiling cannot be probed (async/remote\n * connections) keep this floor. Single source of truth for\n * {@link SQLITE_CAPABILITIES} and the SQLite backend's batch math fallback.\n */\nexport const SQLITE_MAX_BIND_PARAMETERS = 999;\n\n/**\n * `SQLITE_MAX_VARIABLE_NUMBER` default since SQLite 3.32.0 (better-sqlite3\n * also compiles it in explicitly). Used when a synchronous driver's probe\n * confirms a modern build.\n */\nexport const MODERN_SQLITE_MAX_BIND_PARAMETERS = 32_766;\n\n/**\n * Cloudflare D1's documented per-statement bound-parameter ceiling. Far\n * below the classic SQLite floor, so D1 detection must cap the budget or\n * batched writes fail at runtime.\n */\nexport const D1_MAX_BIND_PARAMETERS = 100;\n\n/**\n * Cloudflare SQLite-backed Durable Objects' documented per-statement\n * bound-parameter ceiling. The resolved `do-sqlite` execution profile must\n * advertise this limit so every capability-driven batch path stays below it.\n */\nexport const DURABLE_OBJECT_MAX_BIND_PARAMETERS = 100;\n\n/**\n * Safe bound-parameter ceiling shared by every bundled PostgreSQL driver.\n * The protocol count can represent 65535, but postgres.js rejects a statement\n * with 65534 bound values, so backend batch math uses the lower portable limit.\n */\nexport const POSTGRES_MAX_BIND_PARAMETERS = 65_533;\n\n/**\n * Default capabilities for SQLite.\n */\nexport const SQLITE_CAPABILITIES: BackendCapabilities = Object.freeze({\n transactions: true, // SQLite supports transactions\n windowFunctions: true, // SQLite has supported window functions since 3.25.0\n clearValidTo: true,\n returning: true, // SQLite has supported RETURNING since 3.35.0\n // The bundled schema ships both claim relations and the shared operation\n // backend implements every claim member.\n constraintClaims: true,\n maxBindParameters: SQLITE_MAX_BIND_PARAMETERS,\n // Generic SQLite builds do not guarantee ENABLE_MATH_FUNCTIONS. The local\n // better-sqlite3 factory overrides this flag for its bundled build contract.\n graphAnalytics: Object.freeze({ supported: true, mathFunctions: false }),\n recursiveTraversal: Object.freeze({ supported: true }),\n pessimisticLocks: Object.freeze({\n advisoryLocks: false,\n tableLocks: false,\n serializedWriters: true,\n }),\n});\n\n/**\n * Default capabilities for PostgreSQL.\n */\nexport const POSTGRES_CAPABILITIES: BackendCapabilities = Object.freeze({\n transactions: true, // PostgreSQL supports transactions\n windowFunctions: true, // PostgreSQL supports ROW_NUMBER() and related windows\n clearValidTo: true,\n returning: true, // PostgreSQL has supported RETURNING since 8.2\n // The bundled schema ships both claim relations and the shared operation\n // backend implements every claim member.\n constraintClaims: true,\n maxBindParameters: POSTGRES_MAX_BIND_PARAMETERS,\n graphAnalytics: Object.freeze({ supported: true, mathFunctions: true }),\n recursiveTraversal: Object.freeze({ supported: true }),\n pessimisticLocks: Object.freeze({\n advisoryLocks: true,\n tableLocks: true,\n serializedWriters: false,\n }),\n});\n","/**\n * SQL Schema Configuration for Query Compilation\n *\n * Provides table and column identifiers that the query compiler uses.\n * This allows the compiler to work with custom table names instead of\n * hard-coded defaults.\n */\nimport { type VectorIndexType, type VectorMetric } from \"../../backend/types\";\nimport { MAX_PG_IDENTIFIER_LENGTH } from \"../../constants\";\nimport { ConfigurationError } from \"../../errors\";\nimport { typeGraphGlobalSymbol } from \"../../utils/global-symbol\";\nimport { isSqlFragment, sql, type SqlFragment } from \"../sql-fragment\";\n\nconst SQL_SCHEMA_BRAND: unique symbol = typeGraphGlobalSymbol(\"sql-schema-v1\");\n\n/**\n * Table names for TypeGraph SQL schema.\n *\n * Carries every customizable physical-table name the backend exposes,\n * including the secondary tables (`uniques`, `edgeClaims`) that the query compiler\n * itself doesn't reference but `materializeRemovals` and other\n * cleanup paths need to address by name. Backends without a\n * `uniques` table (custom embeddings-only stores) leave it as the\n * default — the cleanup path is a no-op for kinds with no unique\n * rows.\n */\nexport type SqlTableNames = Readonly<{\n /** Nodes table name (default: \"typegraph_nodes\") */\n nodes: string;\n /** Edges table name (default: \"typegraph_edges\") */\n edges: string;\n /** Recorded node relation table name (default: \"typegraph_recorded_nodes\") */\n recordedNodes?: string | undefined;\n /** Recorded edge relation table name (default: \"typegraph_recorded_edges\") */\n recordedEdges?: string | undefined;\n /** Recorded-time commit clock table name (default: \"typegraph_recorded_clock\") */\n recordedClock?: string | undefined;\n /** Durable per-graph revision-origin table name (default: \"typegraph_revision_origins\") */\n revisionOrigins?: string | undefined;\n /** Identity assertion ledger (default: \"typegraph_identity_assertions\") */\n identityAssertions?: string | undefined;\n /** Recorded identity assertion relation */\n recordedIdentityAssertions?: string | undefined;\n /** Derived current identity closure */\n identityClosure?: string | undefined;\n /** Derived separation relation over identity classes */\n identitySeparation?: string | undefined;\n /** Node fulltext table name (default: \"typegraph_node_fulltext\") */\n fulltext: string;\n /** Node uniques table name (default: \"typegraph_node_uniques\") */\n uniques: string;\n /** Edge cardinality claim table name (default: \"typegraph_edge_claims\") */\n edgeClaims?: string | undefined;\n}>;\n\nexport type ResolvedSqlTableNames = Readonly<{\n /** Nodes table name */\n nodes: string;\n /** Edges table name */\n edges: string;\n /** Recorded node relation table name */\n recordedNodes: string;\n /** Recorded edge relation table name */\n recordedEdges: string;\n /** Recorded-time commit clock table name */\n recordedClock: string;\n /** Durable per-graph revision-origin table name */\n revisionOrigins: string;\n identityAssertions: string;\n recordedIdentityAssertions: string;\n identityClosure: string;\n identitySeparation: string;\n /** Node fulltext table name */\n fulltext: string;\n /** Node uniques table name */\n uniques: string;\n /** Edge cardinality claim table name */\n edgeClaims: string;\n}>;\n\ntype SqlSchemaFields = Readonly<{\n /** Table names */\n tables: ResolvedSqlTableNames;\n /** Get a `SqlFragment` reference to the nodes table. */\n nodesTable: SqlFragment;\n /** Get a `SqlFragment` reference to the edges table. */\n edgesTable: SqlFragment;\n /** Get a `SqlFragment` reference to the recorded node relation. */\n recordedNodesTable: SqlFragment;\n /** Get a `SqlFragment` reference to the recorded edge relation. */\n recordedEdgesTable: SqlFragment;\n /** Get a `SqlFragment` reference to the recorded-time commit clock. */\n recordedClockTable: SqlFragment;\n /** Get a `SqlFragment` reference to the durable per-graph revision origins. */\n revisionOriginsTable: SqlFragment;\n /** Get a `SqlFragment` reference to the identity assertion ledger. */\n identityAssertionsTable: SqlFragment;\n /** Get a `SqlFragment` reference to the recorded identity assertion relation. */\n recordedIdentityAssertionsTable: SqlFragment;\n /** Get a `SqlFragment` reference to the derived identity closure. */\n identityClosureTable: SqlFragment;\n /** Get a `SqlFragment` reference to the derived identity separation relation. */\n identitySeparationTable: SqlFragment;\n /** Get a `SqlFragment` reference to the fulltext table. */\n fulltextTable: SqlFragment;\n}>;\n\n/**\n * SQL schema configuration for query compilation.\n * Contains table identifiers and utility methods for generating `SqlFragment` references.\n *\n * Branded and frozen by {@link createSqlSchema}; callers should not construct\n * schema-shaped objects by hand.\n */\nexport abstract class SqlSchema implements SqlSchemaFields {\n declare private readonly typeGraphSqlSchemaBrand: true;\n abstract readonly tables: ResolvedSqlTableNames;\n abstract readonly nodesTable: SqlFragment;\n abstract readonly edgesTable: SqlFragment;\n abstract readonly recordedNodesTable: SqlFragment;\n abstract readonly recordedEdgesTable: SqlFragment;\n abstract readonly recordedClockTable: SqlFragment;\n abstract readonly revisionOriginsTable: SqlFragment;\n abstract readonly identityAssertionsTable: SqlFragment;\n abstract readonly recordedIdentityAssertionsTable: SqlFragment;\n abstract readonly identityClosureTable: SqlFragment;\n abstract readonly identitySeparationTable: SqlFragment;\n abstract readonly fulltextTable: SqlFragment;\n}\n\nclass SqlSchemaDescriptor extends SqlSchema {\n declare readonly [SQL_SCHEMA_BRAND]: true;\n readonly tables: ResolvedSqlTableNames;\n readonly nodesTable: SqlFragment;\n readonly edgesTable: SqlFragment;\n readonly recordedNodesTable: SqlFragment;\n readonly recordedEdgesTable: SqlFragment;\n readonly recordedClockTable: SqlFragment;\n readonly revisionOriginsTable: SqlFragment;\n readonly identityAssertionsTable: SqlFragment;\n readonly recordedIdentityAssertionsTable: SqlFragment;\n readonly identityClosureTable: SqlFragment;\n readonly identitySeparationTable: SqlFragment;\n readonly fulltextTable: SqlFragment;\n\n constructor(fields: SqlSchemaFields) {\n super();\n Object.defineProperty(this, SQL_SCHEMA_BRAND, {\n configurable: false,\n enumerable: false,\n value: true,\n writable: false,\n });\n this.tables = fields.tables;\n this.nodesTable = fields.nodesTable;\n this.edgesTable = fields.edgesTable;\n this.recordedNodesTable = fields.recordedNodesTable;\n this.recordedEdgesTable = fields.recordedEdgesTable;\n this.recordedClockTable = fields.recordedClockTable;\n this.revisionOriginsTable = fields.revisionOriginsTable;\n this.identityAssertionsTable = fields.identityAssertionsTable;\n this.recordedIdentityAssertionsTable =\n fields.recordedIdentityAssertionsTable;\n this.identityClosureTable = fields.identityClosureTable;\n this.identitySeparationTable = fields.identitySeparationTable;\n this.fulltextTable = fields.fulltextTable;\n Object.freeze(this);\n }\n}\n\n/**\n * Default table names matching the standard TypeGraph schema.\n */\nconst DEFAULT_TABLE_NAMES: ResolvedSqlTableNames = {\n nodes: \"typegraph_nodes\",\n edges: \"typegraph_edges\",\n recordedNodes: \"typegraph_recorded_nodes\",\n recordedEdges: \"typegraph_recorded_edges\",\n recordedClock: \"typegraph_recorded_clock\",\n revisionOrigins: \"typegraph_revision_origins\",\n identityAssertions: \"typegraph_identity_assertions\",\n recordedIdentityAssertions: \"typegraph_recorded_identity_assertions\",\n identityClosure: \"typegraph_identity_closure\",\n identitySeparation: \"typegraph_identity_separation\",\n fulltext: \"typegraph_node_fulltext\",\n uniques: \"typegraph_node_uniques\",\n edgeClaims: \"typegraph_edge_claims\",\n};\n\nfunction resolveTableNames(\n names: Partial<SqlTableNames>,\n): ResolvedSqlTableNames {\n return {\n nodes: names.nodes ?? DEFAULT_TABLE_NAMES.nodes,\n edges: names.edges ?? DEFAULT_TABLE_NAMES.edges,\n recordedNodes: names.recordedNodes ?? DEFAULT_TABLE_NAMES.recordedNodes,\n recordedEdges: names.recordedEdges ?? DEFAULT_TABLE_NAMES.recordedEdges,\n recordedClock: names.recordedClock ?? DEFAULT_TABLE_NAMES.recordedClock,\n revisionOrigins:\n names.revisionOrigins ?? DEFAULT_TABLE_NAMES.revisionOrigins,\n identityAssertions:\n names.identityAssertions ?? DEFAULT_TABLE_NAMES.identityAssertions,\n recordedIdentityAssertions:\n names.recordedIdentityAssertions ??\n DEFAULT_TABLE_NAMES.recordedIdentityAssertions,\n identityClosure:\n names.identityClosure ?? DEFAULT_TABLE_NAMES.identityClosure,\n identitySeparation:\n names.identitySeparation ?? DEFAULT_TABLE_NAMES.identitySeparation,\n fulltext: names.fulltext ?? DEFAULT_TABLE_NAMES.fulltext,\n uniques: names.uniques ?? DEFAULT_TABLE_NAMES.uniques,\n edgeClaims: names.edgeClaims ?? DEFAULT_TABLE_NAMES.edgeClaims,\n };\n}\n\n/**\n * Regex for valid SQL identifiers.\n * Must start with a letter or underscore.\n * Can contain letters, digits, underscores, and dollar signs.\n * Dollar signs are a PostgreSQL extension but commonly supported.\n */\nconst VALID_IDENTIFIER_PATTERN = /^[a-z_][a-z0-9_$]*$/i;\n\n/**\n * Validates that a table name is a valid SQL identifier.\n *\n * @throws Error if the table name is invalid\n */\nfunction validateTableName(name: string, label: string): void {\n if (!name || name.length === 0) {\n throw new ConfigurationError(`${label} table name cannot be empty`);\n }\n if (name.length > MAX_PG_IDENTIFIER_LENGTH) {\n throw new ConfigurationError(\n `${label} table name exceeds maximum length of ${MAX_PG_IDENTIFIER_LENGTH} characters`,\n );\n }\n if (!VALID_IDENTIFIER_PATTERN.test(name)) {\n throw new ConfigurationError(\n `${label} table name \"${name}\" is not a valid SQL identifier. ` +\n `Table names must start with a letter or underscore and contain only letters, digits, underscores, or dollar signs.`,\n );\n }\n}\n\nfunction freezeSqlSchema(fields: SqlSchemaFields): SqlSchema {\n return new SqlSchemaDescriptor(fields);\n}\n\nfunction isSqlSchema(schema: unknown): schema is SqlSchema {\n if (typeof schema !== \"object\" || schema === null) return false;\n const candidate = schema as Record<PropertyKey, unknown>;\n return (\n candidate[SQL_SCHEMA_BRAND] === true &&\n typeof candidate[\"tables\"] === \"object\" &&\n candidate[\"tables\"] !== null &&\n Object.isFrozen(candidate[\"tables\"]) &&\n isSqlFragment(candidate[\"nodesTable\"]) &&\n isSqlFragment(candidate[\"edgesTable\"]) &&\n isSqlFragment(candidate[\"recordedNodesTable\"]) &&\n isSqlFragment(candidate[\"recordedEdgesTable\"]) &&\n isSqlFragment(candidate[\"recordedClockTable\"]) &&\n isSqlFragment(candidate[\"revisionOriginsTable\"]) &&\n isSqlFragment(candidate[\"fulltextTable\"]) &&\n Object.isFrozen(candidate)\n );\n}\n\nexport function requireSqlSchema(\n schema: unknown,\n surface = \"SqlSchema\",\n): SqlSchema {\n if (isSqlSchema(schema)) return schema;\n throw new ConfigurationError(\n `${surface} must be created with createSqlSchema(...).`,\n { code: \"INVALID_SQL_SCHEMA\", surface },\n {\n suggestion:\n \"Pass the result of createSqlSchema(...) instead of a plain schema-shaped object.\",\n },\n );\n}\n\n/**\n * Creates a SqlSchema configuration from table names.\n *\n * Table names are validated to ensure they are valid SQL identifiers.\n * This prevents SQL injection and ensures compatibility across databases.\n *\n * @param names - Optional custom table names (defaults to standard names)\n * @returns SqlSchema configuration for query compilation\n * @throws Error if any table name is invalid\n *\n * @example\n * ```typescript\n * // Use default table names\n * const schema = createSqlSchema();\n *\n * // Use custom table names\n * const schema = createSqlSchema({\n * nodes: \"myapp_nodes\",\n * edges: \"myapp_edges\",\n * fulltext: \"myapp_fulltext\",\n * });\n * ```\n */\nexport function createSqlSchema(names: Partial<SqlTableNames> = {}): SqlSchema {\n const tables = resolveTableNames(names);\n\n // Validate all table names\n validateTableName(tables.nodes, \"nodes\");\n validateTableName(tables.edges, \"edges\");\n validateTableName(tables.recordedNodes, \"recordedNodes\");\n validateTableName(tables.recordedEdges, \"recordedEdges\");\n validateTableName(tables.recordedClock, \"recordedClock\");\n validateTableName(tables.revisionOrigins, \"revisionOrigins\");\n validateTableName(tables.identityAssertions, \"identityAssertions\");\n validateTableName(\n tables.recordedIdentityAssertions,\n \"recordedIdentityAssertions\",\n );\n validateTableName(tables.identityClosure, \"identityClosure\");\n validateTableName(tables.identitySeparation, \"identitySeparation\");\n validateTableName(tables.fulltext, \"fulltext\");\n validateTableName(tables.uniques, \"uniques\");\n validateTableName(tables.edgeClaims, \"edgeClaims\");\n\n return freezeSqlSchema({\n tables: Object.freeze(tables),\n nodesTable: sql.identifier(tables.nodes),\n edgesTable: sql.identifier(tables.edges),\n recordedNodesTable: sql.identifier(tables.recordedNodes),\n recordedEdgesTable: sql.identifier(tables.recordedEdges),\n recordedClockTable: sql.identifier(tables.recordedClock),\n revisionOriginsTable: sql.identifier(tables.revisionOrigins),\n identityAssertionsTable: sql.identifier(tables.identityAssertions),\n recordedIdentityAssertionsTable: sql.identifier(\n tables.recordedIdentityAssertions,\n ),\n identityClosureTable: sql.identifier(tables.identityClosure),\n identitySeparationTable: sql.identifier(tables.identitySeparation),\n fulltextTable: sql.identifier(tables.fulltext),\n });\n}\n\n/**\n * The recorded/system-time relation a read coordinate may reconstruct from.\n *\n * TypeGraph's built-in capture relation is bound by `createStore(..., {\n * history: true })`. Hosts can also bind externally populated row-compatible\n * recorded relations through `recordedRelation({ schema })`. Keeping both as\n * explicit values separates the read contract from the write-capture mechanism\n * so future external/TMS-owned recorded relations can feed the same query\n * machinery without changing StoreView or ReadCoordinate.\n */\nconst EXTERNAL_RECORDED_READ_SOURCE: unique symbol = typeGraphGlobalSymbol(\n \"external-recorded-read-source-v1\",\n);\n\nexport type ExternalRecordedReadSource = Readonly<{\n source: \"external\";\n schema: SqlSchema;\n [EXTERNAL_RECORDED_READ_SOURCE]: true;\n}>;\n\ntype ExternalRecordedReadSourceCandidate = Readonly<{\n source?: unknown;\n schema?: unknown;\n [EXTERNAL_RECORDED_READ_SOURCE]?: unknown;\n}>;\n\nconst TYPEGRAPH_RECORDED_READ_SOURCE: unique symbol = typeGraphGlobalSymbol(\n \"typegraph-recorded-read-source-v1\",\n);\n\nexport type TypeGraphRecordedReadSource = Readonly<{\n source: \"typegraph-capture\";\n schema: SqlSchema;\n [TYPEGRAPH_RECORDED_READ_SOURCE]: true;\n}>;\n\ntype RecordedReadSource =\n ExternalRecordedReadSource | TypeGraphRecordedReadSource;\n\nexport type RecordedReadBinding = RecordedReadSource;\n\nexport type RecordedRelationOptions = Readonly<{\n schema: SqlSchema;\n}>;\n\nexport function recordedRelation(\n options: RecordedRelationOptions,\n): ExternalRecordedReadSource {\n const schema = requireSqlSchema(options.schema, \"recordedRelation schema\");\n return Object.freeze({\n source: \"external\",\n schema,\n [EXTERNAL_RECORDED_READ_SOURCE]: true as const,\n });\n}\n\nexport function requireExternalRecordedReadSource(\n source: unknown,\n): ExternalRecordedReadSource | undefined {\n if (source === undefined) return undefined;\n if (isExternalRecordedReadSource(source)) return source;\n throw new ConfigurationError(\n \"recordedRead must be created with recordedRelation({ schema }).\",\n { code: \"INVALID_RECORDED_READ_SOURCE\" },\n {\n suggestion:\n \"Pass { recordedRead: recordedRelation({ schema }) } for an externally populated recorded relation. Use { history: true } when TypeGraph should capture writes.\",\n },\n );\n}\n\nfunction isExternalRecordedReadSource(\n source: unknown,\n): source is ExternalRecordedReadSource {\n if (typeof source !== \"object\" || source === null) return false;\n const candidate = source as ExternalRecordedReadSourceCandidate;\n return (\n candidate.source === \"external\" &&\n candidate[EXTERNAL_RECORDED_READ_SOURCE] === true &&\n isSqlSchema(candidate.schema) &&\n Object.isFrozen(candidate)\n );\n}\n\nexport function createRecordedReadBinding(\n schema: SqlSchema,\n): TypeGraphRecordedReadSource {\n const readSchema = requireSqlSchema(schema, \"recorded read binding schema\");\n return Object.freeze({\n source: \"typegraph-capture\",\n schema: readSchema,\n [TYPEGRAPH_RECORDED_READ_SOURCE]: true as const,\n });\n}\n\nexport function requireRecordedReadBinding(\n binding: unknown,\n surface: string,\n): RecordedReadBinding {\n if (isRecordedReadBinding(binding)) return binding;\n if (binding !== undefined) {\n throw new ConfigurationError(\n \"Recorded-time reads require a recorded read relation created by TypeGraph.\",\n { code: \"INVALID_RECORDED_READ_BINDING\", surface },\n {\n suggestion:\n \"Use createStore(graph, backend, { history: true }) or { recordedRead: recordedRelation({ schema }) } instead of passing a plain object.\",\n },\n );\n }\n throw new ConfigurationError(\n \"Recorded-time reads require a recorded read relation.\",\n { code: \"RECORDED_READ_REQUIRES_BINDING\", surface },\n {\n suggestion:\n \"Create the store with createStore(graph, backend, { history: true }) to bind TypeGraph's built-in captured relation, or pass { recordedRead: recordedRelation({ schema }) } for an externally populated recorded relation.\",\n },\n );\n}\n\ntype TypeGraphRecordedReadSourceCandidate = Readonly<{\n source?: unknown;\n schema?: unknown;\n [TYPEGRAPH_RECORDED_READ_SOURCE]?: unknown;\n}>;\n\nfunction isTypeGraphRecordedReadSource(\n source: unknown,\n): source is TypeGraphRecordedReadSource {\n if (typeof source !== \"object\" || source === null) return false;\n const candidate = source as TypeGraphRecordedReadSourceCandidate;\n return (\n candidate.source === \"typegraph-capture\" &&\n candidate[TYPEGRAPH_RECORDED_READ_SOURCE] === true &&\n isSqlSchema(candidate.schema) &&\n Object.isFrozen(candidate)\n );\n}\n\nfunction isRecordedReadBinding(\n binding: unknown,\n): binding is RecordedReadBinding {\n return (\n isExternalRecordedReadSource(binding) ||\n isTypeGraphRecordedReadSource(binding)\n );\n}\n\n/**\n * Returns a schema view whose primary node/edge sources are the recorded-time\n * relations. The recorded relations are row-compatible with the live tables\n * for every column the query compiler, subgraph extractor, and algorithms\n * already read; the temporal filter adds the `recorded_from/to` predicate.\n */\nexport function recordedReadSqlSchema(binding: RecordedReadBinding): SqlSchema {\n const { schema } = requireRecordedReadBinding(\n binding,\n \"recorded-read-schema\",\n );\n return freezeSqlSchema({\n tables: schema.tables,\n nodesTable: schema.recordedNodesTable,\n edgesTable: schema.recordedEdgesTable,\n recordedNodesTable: schema.recordedNodesTable,\n recordedEdgesTable: schema.recordedEdgesTable,\n recordedClockTable: schema.recordedClockTable,\n revisionOriginsTable: schema.revisionOriginsTable,\n identityAssertionsTable: schema.identityAssertionsTable,\n recordedIdentityAssertionsTable: schema.recordedIdentityAssertionsTable,\n identityClosureTable: schema.identityClosureTable,\n identitySeparationTable: schema.identitySeparationTable,\n fulltextTable: schema.fulltextTable,\n });\n}\n\n/**\n * Resolves the read schema for a coordinate: the live schema when no recorded\n * pin is set, or the recorded-relation view when `recordedAsOf` is present. The\n * single place every read path decides whether to source the recorded tables.\n */\nexport function recordedReadSchemaFor(\n schema: SqlSchema,\n recordedAsOf: string | undefined,\n binding: RecordedReadBinding | undefined,\n surface: string,\n): SqlSchema {\n const baseSchema = requireSqlSchema(schema, `${surface} schema`);\n if (recordedAsOf === undefined) return baseSchema;\n return recordedReadSqlSchema(requireRecordedReadBinding(binding, surface));\n}\n\n/**\n * Default SqlSchema using standard TypeGraph table names.\n */\nexport const DEFAULT_SQL_SCHEMA: SqlSchema = createSqlSchema();\n\n/**\n * The compiler's resolved view of one declared embedding field — the\n * `(dimensions, metric, indexType)` a {@link VectorStrategy} needs to\n * name and scan the field's typed per-`(kind, field)` storage. Sourced\n * from the registered node schema's `embedding()` declaration when the\n * store builds its compile options.\n */\nexport type VectorSlotDescriptor = Readonly<{\n dimensions: number;\n metric: VectorMetric;\n indexType: VectorIndexType;\n}>;\n\n/**\n * Map of declared embedding slots keyed by {@link vectorSlotKey} -\n * `\"<nodeKind>\\0<fieldPath>\"` (NUL-separated). Carries every `(concrete kind,\n * fieldPath)` that declares an embedding field, so the compiler's\n * `field.similarTo(...)` CTE can UNION ALL the per-field tables for the\n * kinds in an alias that actually declare the field (only\n * `includeSubClasses` yields more than one).\n */\nexport type VectorSlotMap = ReadonlyMap<string, VectorSlotDescriptor>;\n\n/** NUL-delimited composite key for {@link VectorSlotMap}. */\nexport function vectorSlotKey(nodeKind: string, fieldPath: string): string {\n return `${nodeKind}\\u0000${fieldPath}`;\n}\n\n/**\n * CTE aliases used by the standard query emitter. Joining on these names\n * across multiple builder files is fragile when typed as raw strings —\n * import these constants instead.\n */\nexport const ALIAS_CTE_PREFIX = \"cte_\" as const;\nexport const EMBEDDINGS_CTE_ALIAS = \"cte_embeddings\" as const;\nexport const FULLTEXT_CTE_ALIAS = \"cte_fulltext\" as const;\nexport const HYBRID_CANDIDATES_CTE_ALIAS = \"cte_relevance_candidates\" as const;\n","/**\n * The PILOT capability-bundle registry — DATA ONLY, sibling in spirit to\n * `backend/member-classes.ts`.\n *\n * A bundle is a named set of {@link GraphBackend} member names split into a\n * required core and a set of graduated extras, with a dialect scope, an\n * optional declaration source and cross-check mode, a port-surface refusal\n * code, a per-operation disposition table naming the sites and the extras\n * each operation requires, and one verdict resolver (`resolve.ts`) plus one\n * member accessor (`bind.ts`). It is not a re-shaping of `GraphBackend`.\n *\n * Two definition kinds, because the measurement has two shapes:\n *\n * - A GATED bundle has a non-empty required core (every member required).\n * Its resolver returns supported-with-core-member-names or\n * unsupported-with-`missing`. Pilot: `claims`, `statementExecution`,\n * `recordedRevisionOrigins`.\n * - A GRADUATED bundle has no required core: every member is an extra with\n * its own measured disposition. Its resolver returns the per-extra verdict\n * map and no `supported` field at all. Pilot: `uniqueSidecarBatch`,\n * `batchPointRead`, `contributionHealth`.\n *\n * Deliberately absent, by round-5 ruling (no pilot consumer for either):\n * `arity` on core members, `requiresBundles` edges, `AnyOfSelection`,\n * `CapabilityCoreMember`, `AllOfMembers`, `AnyOfMembers`. Both are designed\n * and seeded for WS5b in the design document's appendix, beside their first\n * real consumers.\n *\n * This is the PILOT of a larger sweep (WS5b): 15 of the 82 optional\n * `GraphBackend` members are bundled here; the other 67 are classified in\n * {@link UNBUNDLED_OPTIONAL_MEMBERS} as either `reasoned` (no bundle should\n * ever own them) or `deferred` (WS5b's seed, with a measured ceiling).\n */\nimport { type SqlDialect } from \"../../query/dialect/types\";\nimport { type Assert, type Equal } from \"../../utils/type-assert\";\nimport { type BackendCapabilities, type GraphBackend } from \"../types\";\n\n/**\n * The keys of `T` that are optional — i.e. `undefined` may stand in for the\n * member without violating the type. `object extends Pick<T, K>` is true\n * exactly when `Pick<T, K>` accepts `{}`, which is true exactly when `K` is\n * optional on `T`.\n */\nexport type OptionalKeys<T> = {\n [K in keyof T]-?: object extends Pick<T, K> ? K : never;\n}[keyof T];\n\n/**\n * Every optional `GraphBackend` member — 82 of them, verified equal to the\n * names parsed from `etc/typegraph-backend.api.md` (§Baselines). Derived,\n * never hand-written: a member added or removed from `GraphBackend` changes\n * this type automatically, and the totality proof below fails loudly if the\n * registry has not kept up.\n */\nexport type OptionalGraphBackendMember = OptionalKeys<GraphBackend>;\n\n/** How an operation degrades — or refuses — when a member it needs is absent. */\nexport type CapabilityBundleDisposition =\n /** Absence refuses, with ONE typed error per operation. */\n | Readonly<{ kind: \"refuse\"; code: string }>\n /** Absence degrades along a named, tested path. Never refuses. */\n | Readonly<{ kind: \"fallback\"; fallback: string }>;\n\n/**\n * A graduated extra: present ⇒ a better path, absent ⇒ this exact\n * disposition. `members` is a list because an extra MAY be an all-or-nothing\n * group; every pilot extra is single-membered (the measured group,\n * `indexMaterialization`'s build-claim protocol, is deferred).\n */\nexport type CapabilityBundleExtra<\n Id extends string,\n M extends OptionalGraphBackendMember,\n> = Readonly<{\n id: Id;\n members: readonly M[];\n /** REQUIRED, and typed — never a bare `fallback: string`. */\n disposition: CapabilityBundleDisposition;\n}>;\n\nexport type CapabilityCrossCheck =\n /** Presence alone. The default, and 5 of the 6 pilot bundles. */\n | \"none\"\n /**\n * Declared-but-missing refuses; implements-without-declaring resolves\n * supported. One-directional. No bundle uses this today — it exists so a\n * future cross-check has a shape to grow into, one that must carry its own\n * justification row when adopted.\n */\n | \"declared-implies-members\"\n /**\n * Disagreement in EITHER direction refuses. `claims` only — the existing\n * `CONSTRAINT_CLAIM_SURFACE_MISMATCH`, whose bidirectionality carries a\n * fence-specific justification (\"a silent fallback would unfence exactly\n * the writes the capability exists to fence\") that no other family has.\n */\n | \"bidirectional\";\n\n/** One inventory key an operation row owns. */\nexport type CapabilityBundleOperationSite = Readonly<{\n file: string;\n member: OptionalGraphBackendMember;\n /**\n * Disambiguator, required only where one `(file, member)` pair is split\n * across two or more operation rows. Three pairs need it in the pilot:\n * `node-operations.ts#checkUniqueBatch`, `guards.ts#executeStatement` and\n * `migrate-recorded-time.ts#executeStatement`.\n */\n lines?: readonly number[];\n /**\n * Set when B7's rewiring pass reclassified this site AWAY from `pilot`\n * instead of rewiring it — additive, optional, and read by nothing but the\n * inventory/report tooling. `\"deferred\"` names a site whose receiver family\n * needs plumbing this batch must not force (WS5b's input); `\"reasoned\"`\n * names one this batch decided a verdict must never gate at all. The\n * `code`/`disposition` above stay the classification data they always were;\n * this is a SEPARATE fact about the site, not a replacement for either.\n */\n rewiring?: Readonly<{ class: \"deferred\" | \"reasoned\"; reason: string }>;\n}>;\n\n/** Every caller-visible operation that consumes a bundle. */\nexport type CapabilityBundleOperation = Readonly<{\n /** The caller-visible name that lands in `details.operation`. */\n operation: string;\n disposition: CapabilityBundleDisposition;\n /** The extras this operation needs, by id. */\n requires?: readonly string[];\n /** Every inventory key this row owns, as `(file, member)` pairs. */\n sites: readonly CapabilityBundleOperationSite[];\n /**\n * Set only where the site itself reads the declaration to decide between\n * refusing and degrading. One measured instance in the pilot:\n * `probeContributions` (`store.ts:4406`).\n */\n declarationGate?: true;\n}>;\n\ntype CapabilityBundleCommon = Readonly<{\n /**\n * The registry's own id namespace is derived from `CAPABILITY_BUNDLES`\n * below (never hand-written) — but the derivation cannot be fed back into\n * THIS type: `CapabilityBundleId` is `(typeof CAPABILITY_BUNDLES)[number]\n * [\"id\"]`, and `CAPABILITY_BUNDLES` is built from values (`CLAIMS`, …)\n * whose own type is checked against `CapabilityBundleDefinition` — which\n * embeds this type. Typing this field `CapabilityBundleId` therefore makes\n * every bundle constant's type depend on its own initializer\n * (`TS2502`/`TS2456`, confirmed by compiling the literal design text).\n * `string` here is the minimal break: each bundle constant still infers\n * its literal id via `as const`, and `CapabilityBundleId` below is still\n * wholly derived from `CAPABILITY_BUNDLES`, never hand-written.\n */\n id: string;\n /** Dialects whose first-party factory implements this bundle's core. Default: both. */\n dialects?: readonly SqlDialect[];\n /** The `BackendCapabilities` field that DECLARES the bundle, when one exists. */\n declaration?: keyof BackendCapabilities;\n /** Read only when not `\"none\"` (ruling F2). */\n crossCheck: CapabilityCrossCheck;\n /** The code the MEMBER ACCESSOR throws when the port disagrees with the verdict (I20). */\n portSurfaceCode: string;\n operations: readonly CapabilityBundleOperation[];\n}>;\n\n/** A bundle with a required core. */\nexport type GatedBundleDefinition<\n MCore extends OptionalGraphBackendMember,\n XId extends string = never,\n MExtra extends OptionalGraphBackendMember = never,\n> = CapabilityBundleCommon &\n Readonly<{\n kind: \"gated\";\n /** Every name required. No arity wrapper — no pilot bundle has an `any-of` core. */\n core: readonly MCore[];\n extras?: readonly CapabilityBundleExtra<XId, MExtra>[];\n /** The bundle-wide disposition when the CORE is unsatisfied. */\n disposition: CapabilityBundleDisposition;\n }>;\n\n/** A bundle with no required core: every member is a graduated extra. */\nexport type GraduatedBundleDefinition<\n XId extends string,\n MExtra extends OptionalGraphBackendMember,\n> = CapabilityBundleCommon &\n Readonly<{\n kind: \"graduated\";\n extras: readonly CapabilityBundleExtra<XId, MExtra>[];\n /** No `disposition`: there is no bundle-level verdict to dispose of. */\n }>;\n\nexport type CapabilityBundleDefinition =\n | GatedBundleDefinition<\n OptionalGraphBackendMember,\n string,\n OptionalGraphBackendMember\n >\n | GraduatedBundleDefinition<string, OptionalGraphBackendMember>;\n\n// ---------------------------------------------------------------------------\n// The six pilot bundles — measured, per §Baselines, against this tree.\n// ---------------------------------------------------------------------------\n\n/**\n * `claimSupport` (`store/claims/backing.ts`) is the ONE bidirectional\n * cross-check consumer in the tree. Since B7 it delegates to\n * `resolveBundle`, which runs `resolve.ts`'s `assertClaimsBidirectionalAgreement`\n * — the check's only remaining owner; there is no second copy left in\n * `backing.ts` to keep byte-for-byte in sync with.\n */\nexport const CLAIMS = {\n id: \"claims\",\n kind: \"gated\",\n core: [\n \"claimEdgeCardinality\",\n \"claimEdgeCardinalityBatch\",\n \"purgeEdgeClaims\",\n \"hardDeleteUniquesByConcreteKind\",\n ],\n declaration: \"constraintClaims\",\n crossCheck: \"bidirectional\",\n portSurfaceCode: \"CONSTRAINT_CLAIM_SURFACE_MISMATCH\",\n disposition: {\n kind: \"fallback\",\n fallback: \"unclaimed writes; the caller's own supported:false branch\",\n },\n operations: [\n {\n operation: \"edge claim write\",\n disposition: {\n kind: \"fallback\",\n fallback: \"unclaimed writes; the caller's own supported:false branch\",\n },\n sites: [\n { file: \"store/claims/backing.ts\", member: \"claimEdgeCardinality\" },\n {\n file: \"store/claims/backing.ts\",\n member: \"claimEdgeCardinalityBatch\",\n },\n { file: \"store/claims/backing.ts\", member: \"purgeEdgeClaims\" },\n {\n file: \"store/claims/backing.ts\",\n member: \"hardDeleteUniquesByConcreteKind\",\n },\n ],\n },\n ],\n} as const satisfies CapabilityBundleDefinition;\n\n/**\n * Three independently-guarded extras. Measured, `hardDeleteUniquesByNodeIds`'\n * only standalone site (`node-claims.ts:732`) reaches the member through\n * `requireDefined` rather than a degrading guard, so — the round-5\n * enumeration's correction to the round-4 table — its disposition is\n * `refuse`, not the fallback round 4 assumed from the bundle's name.\n */\nexport const UNIQUE_SIDECAR_BATCH = {\n id: \"uniqueSidecarBatch\",\n kind: \"graduated\",\n crossCheck: \"none\",\n portSurfaceCode: \"BUNDLE_PORT_SURFACE_MISMATCH\",\n extras: [\n {\n id: \"insertUniqueBatch\",\n members: [\"insertUniqueBatch\"],\n disposition: { kind: \"fallback\", fallback: \"issueClaimsIndividually\" },\n },\n {\n id: \"checkUniqueBatch\",\n members: [\"checkUniqueBatch\"],\n disposition: {\n kind: \"fallback\",\n fallback: \"per-key checkUnique loop\",\n },\n },\n {\n id: \"hardDeleteUniquesByNodeIds\",\n members: [\"hardDeleteUniquesByNodeIds\"],\n disposition: {\n kind: \"refuse\",\n // Registry-assigned: the real throw is `requireDefined`'s generic\n // `TypeError`, which carries no domain code of its own.\n code: \"UNIQUE_REAP_BY_NODE_IDS_UNSUPPORTED\",\n },\n },\n ],\n operations: [\n {\n operation: \"unique batch probe\",\n disposition: { kind: \"fallback\", fallback: \"per-key checkUnique loop\" },\n requires: [\"checkUniqueBatch\"],\n sites: [\n {\n file: \"store/operations/node-operations.ts\",\n member: \"checkUniqueBatch\",\n lines: [1275, 1320],\n },\n {\n file: \"store/operations/node-operations.ts\",\n member: \"checkUniqueBatch\",\n lines: [1575, 1593],\n },\n ],\n },\n {\n operation: \"unique claim issue\",\n disposition: { kind: \"fallback\", fallback: \"issueClaimsIndividually\" },\n requires: [\"insertUniqueBatch\"],\n sites: [\n { file: \"store/claims/node-claims.ts\", member: \"insertUniqueBatch\" },\n ],\n },\n {\n operation: \"unique reap by node ids\",\n disposition: {\n kind: \"refuse\",\n code: \"UNIQUE_REAP_BY_NODE_IDS_UNSUPPORTED\",\n },\n requires: [\"hardDeleteUniquesByNodeIds\"],\n sites: [\n {\n file: \"store/claims/node-claims.ts\",\n member: \"hardDeleteUniquesByNodeIds\",\n },\n ],\n },\n {\n operation: \"set-based node update\",\n disposition: {\n kind: \"refuse\",\n code: \"SET_UPDATE_UNIQUENESS_UNSUPPORTED\",\n },\n requires: [\n \"hardDeleteUniquesByNodeIds\",\n \"insertUniqueBatch\",\n \"checkUniqueBatch\",\n ],\n sites: [\n {\n file: \"store/operations/node-write-pipeline.ts\",\n member: \"hardDeleteUniquesByNodeIds\",\n },\n {\n file: \"store/operations/node-write-pipeline.ts\",\n member: \"insertUniqueBatch\",\n },\n {\n file: \"store/operations/node-write-pipeline.ts\",\n member: \"checkUniqueBatch\",\n },\n {\n file: \"store/operations/node-operations.ts\",\n member: \"hardDeleteUniquesByNodeIds\",\n },\n {\n file: \"store/operations/node-operations.ts\",\n member: \"insertUniqueBatch\",\n },\n {\n file: \"store/operations/node-operations.ts\",\n member: \"checkUniqueBatch\",\n lines: [1993],\n },\n ],\n },\n {\n operation: \"resolved node write\",\n disposition: {\n kind: \"refuse\",\n code: \"RESOLVED_NODE_UNIQUENESS_UNSUPPORTED\",\n },\n requires: [\n \"hardDeleteUniquesByNodeIds\",\n \"insertUniqueBatch\",\n \"checkUniqueBatch\",\n ],\n sites: [\n {\n file: \"store/claims/resolved-node-claims.ts\",\n member: \"checkUniqueBatch\",\n lines: [211],\n },\n {\n file: \"store/claims/resolved-node-claims.ts\",\n member: \"checkUniqueBatch\",\n lines: [292],\n },\n {\n file: \"store/claims/resolved-node-claims.ts\",\n member: \"hardDeleteUniquesByNodeIds\",\n },\n {\n file: \"store/claims/resolved-node-claims.ts\",\n member: \"insertUniqueBatch\",\n },\n ],\n },\n ],\n} as const satisfies CapabilityBundleDefinition;\n\n/** Two independently-guarded extras, both fallback. */\nexport const BATCH_POINT_READ = {\n id: \"batchPointRead\",\n kind: \"graduated\",\n crossCheck: \"none\",\n portSurfaceCode: \"BUNDLE_PORT_SURFACE_MISMATCH\",\n extras: [\n {\n id: \"getNodes\",\n members: [\"getNodes\"],\n disposition: { kind: \"fallback\", fallback: \"per-id getNode\" },\n },\n {\n id: \"getEdges\",\n members: [\"getEdges\"],\n disposition: { kind: \"fallback\", fallback: \"per-id getEdge\" },\n },\n ],\n operations: [\n {\n operation: \"search hydration\",\n disposition: { kind: \"fallback\", fallback: \"per-id getNode\" },\n requires: [\"getNodes\"],\n sites: [{ file: \"store/search.ts\", member: \"getNodes\" }],\n },\n {\n operation: \"import reference validation\",\n disposition: {\n kind: \"fallback\",\n fallback: \"per-row getNode in the routing loop\",\n },\n requires: [\"getNodes\"],\n sites: [{ file: \"interchange/import.ts\", member: \"getNodes\" }],\n },\n {\n operation: \"import edge endpoint hydration\",\n disposition: { kind: \"fallback\", fallback: \"per-row getEdge\" },\n requires: [\"getEdges\"],\n sites: [{ file: \"interchange/import.ts\", member: \"getEdges\" }],\n },\n {\n operation: \"edge batch endpoint priming\",\n disposition: {\n kind: \"fallback\",\n fallback: \"skip the priming pass; endpoint validation reads per-row\",\n },\n requires: [\"getNodes\"],\n sites: [\n { file: \"store/operations/edge-operations.ts\", member: \"getNodes\" },\n ],\n },\n {\n operation: \"node create batch priming\",\n disposition: {\n kind: \"fallback\",\n fallback: \"skip priming; per-row probes\",\n },\n requires: [\"getNodes\"],\n sites: [\n { file: \"store/operations/node-operations.ts\", member: \"getNodes\" },\n ],\n },\n {\n operation: \"node collection batch load\",\n disposition: { kind: \"fallback\", fallback: \"per-id getNode\" },\n requires: [\"getNodes\"],\n sites: [\n { file: \"store/collections/node-collection.ts\", member: \"getNodes\" },\n ],\n },\n {\n operation: \"node batch fetch\",\n disposition: { kind: \"fallback\", fallback: \"per-id getNode\" },\n requires: [\"getNodes\"],\n sites: [{ file: \"store/node-fetch.ts\", member: \"getNodes\" }],\n },\n {\n operation: \"edge batch fetch\",\n disposition: { kind: \"fallback\", fallback: \"per-id getEdge\" },\n requires: [\"getEdges\"],\n sites: [{ file: \"store/edge-fetch.ts\", member: \"getEdges\" }],\n },\n {\n operation: \"identity member hydration\",\n disposition: { kind: \"fallback\", fallback: \"per-id getNode\" },\n requires: [\"getNodes\"],\n sites: [{ file: \"store/store.ts\", member: \"getNodes\" }],\n },\n ],\n} as const satisfies CapabilityBundleDefinition;\n\n/**\n * Core `executeStatement`. `IDENTITY_REQUIRES_STATEMENT_EXECUTION` and\n * `IDENTITY_REQUIRES_ATOMIC_BACKEND` are the existing `details.code` values\n * at `identity/sql-target.ts:101` and `store/store.ts:921`; the remaining\n * rows' underlying throws carry no domain code of their own today, so their\n * `code` here is registry-assigned classification (documented per row).\n */\nexport const STATEMENT_EXECUTION = {\n id: \"statementExecution\",\n kind: \"gated\",\n core: [\"executeStatement\"],\n crossCheck: \"none\",\n portSurfaceCode: \"BUNDLE_PORT_SURFACE_MISMATCH\",\n disposition: {\n kind: \"refuse\",\n code: \"IDENTITY_REQUIRES_STATEMENT_EXECUTION\",\n },\n operations: [\n {\n operation: \"identity statement execution\",\n disposition: {\n kind: \"refuse\",\n code: \"IDENTITY_REQUIRES_STATEMENT_EXECUTION\",\n },\n sites: [\n {\n file: \"identity/sql-target.ts\",\n member: \"executeStatement\",\n rewiring: {\n class: \"deferred\",\n reason:\n \"requires verdict threading through IdentityServiceContext / the capture session — WS5b input, measured at ~13 files/~35 signatures\",\n },\n },\n ],\n },\n {\n operation: \"recorded capture statement\",\n disposition: {\n kind: \"refuse\",\n code: \"RECORDED_CAPTURE_STATEMENT_UNSUPPORTED\",\n },\n sites: [\n {\n file: \"store/recorded-capture/guards.ts\",\n member: \"executeStatement\",\n lines: [62, 79],\n // DUAL-CLASS (file, member) pair: this same \"guards.ts#executeStatement\"\n // key also carries the \"reasoned\" rewiring below (the port-surface\n // fallback site). The live scanner (scripts/bundle-member-access-scan.ts)\n // matches rewiring annotations on (file, member) only — it cannot read\n // `lines` to split the pair — so every live executeStatement access in\n // this file classifies as `annotated-residue` once either sibling\n // annotation exists.\n rewiring: {\n class: \"deferred\",\n reason:\n \"requires verdict threading through IdentityServiceContext / the capture session — WS5b input, measured at ~13 files/~35 signatures\",\n },\n },\n ],\n },\n {\n operation: \"history construction gate\",\n disposition: {\n kind: \"refuse\",\n code: \"HISTORY_REQUIRES_STATEMENT_EXECUTION\",\n },\n sites: [\n {\n file: \"store/recorded-capture/guards.ts\",\n member: \"executeStatement\",\n lines: [251],\n },\n ],\n },\n {\n operation: \"revision tracking construction gate\",\n disposition: {\n kind: \"refuse\",\n code: \"REVISION_TRACKING_REQUIRES_STATEMENT_EXECUTION\",\n },\n sites: [\n {\n file: \"store/recorded-capture/guards.ts\",\n member: \"executeStatement\",\n lines: [299],\n },\n ],\n },\n {\n operation: \"history-unsafe raw write overlay\",\n disposition: {\n kind: \"fallback\",\n fallback: \"omit the overriding member; the port's own absence stands\",\n },\n sites: [\n {\n file: \"store/recorded-capture/guards.ts\",\n member: \"executeStatement\",\n lines: [219],\n // DUAL-CLASS (file, member) pair: this same \"guards.ts#executeStatement\"\n // key also carries the \"deferred\" rewiring above (the recorded-capture\n // statement site). The live scanner (scripts/bundle-member-access-scan.ts)\n // matches rewiring annotations on (file, member) only — it cannot read\n // `lines` to split the pair — so every live executeStatement access in\n // this file classifies as `annotated-residue` once either sibling\n // annotation exists.\n rewiring: {\n class: \"reasoned\",\n reason:\n \"genuinely a port-surface presence test; re-keying it on a verdict changes behavior in both directions (a phantom-rejecting stub one way, a raw-write escape on a history-enabled store the other — a safety regression), and adding a non-throwing gated accessor to the frozen binder surface for ONE site is the over-generalization anti-pattern\",\n },\n },\n ],\n },\n {\n operation: \"identity construction gate\",\n disposition: {\n kind: \"refuse\",\n code: \"IDENTITY_REQUIRES_ATOMIC_BACKEND\",\n },\n sites: [\n { file: \"store/store.ts\", member: \"executeStatement\", lines: [921] },\n { file: \"store/store.ts\", member: \"executeStatement\", lines: [928] },\n ],\n },\n {\n operation: \"validity window repair\",\n disposition: {\n kind: \"refuse\",\n code: \"VALIDITY_WINDOW_REPAIR_REQUIRES_STATEMENT_EXECUTION\",\n },\n sites: [\n {\n file: \"backend/repair-validity-windows.ts\",\n member: \"executeStatement\",\n },\n ],\n },\n {\n operation: \"recorded-time migration\",\n disposition: {\n kind: \"refuse\",\n code: \"RECORDED_TIME_MIGRATION_REQUIRES_STATEMENT_EXECUTION\",\n },\n sites: [\n {\n file: \"backend/migrate-recorded-time.ts\",\n member: \"executeStatement\",\n lines: [154, 161, 801],\n rewiring: {\n class: \"deferred\",\n reason:\n \"the delete path's public Pick-typed backend cannot reach resolveBundle, and the shared module-private helpers make a single-path rewire two owners\",\n },\n },\n ],\n },\n ],\n} as const satisfies CapabilityBundleDefinition;\n\n/**\n * Four extras, one per public `Store` method, each read alone. Three refuse\n * with their own existing error; `probeContributions` is the pilot's one\n * `declarationGate` row — fallback to `{ entries: [] }` when\n * `capabilities.contributions` is undeclared, refuse when it is declared.\n */\nexport const CONTRIBUTION_HEALTH = {\n id: \"contributionHealth\",\n kind: \"graduated\",\n declaration: \"contributions\",\n crossCheck: \"none\",\n portSurfaceCode: \"BUNDLE_PORT_SURFACE_MISMATCH\",\n extras: [\n {\n id: \"verifyContributions\",\n members: [\"verifyContributions\"],\n disposition: { kind: \"refuse\", code: \"CONTRIBUTION_VERIFY_UNSUPPORTED\" },\n },\n {\n id: \"repairContributions\",\n members: [\"repairContributions\"],\n disposition: { kind: \"refuse\", code: \"CONTRIBUTION_REPAIR_UNSUPPORTED\" },\n },\n {\n id: \"rebuildContribution\",\n members: [\"rebuildContribution\"],\n disposition: {\n kind: \"refuse\",\n code: \"CONTRIBUTION_REBUILD_UNSUPPORTED\",\n },\n },\n {\n id: \"probeContributions\",\n members: [\"probeContributions\"],\n disposition: { kind: \"fallback\", fallback: \"{entries: []}\" },\n },\n ],\n operations: [\n {\n operation: \"contribution verify\",\n disposition: { kind: \"refuse\", code: \"CONTRIBUTION_VERIFY_UNSUPPORTED\" },\n requires: [\"verifyContributions\"],\n sites: [{ file: \"store/store.ts\", member: \"verifyContributions\" }],\n },\n {\n operation: \"contribution repair\",\n disposition: { kind: \"refuse\", code: \"CONTRIBUTION_REPAIR_UNSUPPORTED\" },\n requires: [\"repairContributions\"],\n sites: [{ file: \"store/store.ts\", member: \"repairContributions\" }],\n },\n {\n operation: \"contribution rebuild\",\n disposition: {\n kind: \"refuse\",\n code: \"CONTRIBUTION_REBUILD_UNSUPPORTED\",\n },\n requires: [\"rebuildContribution\"],\n sites: [{ file: \"store/store.ts\", member: \"rebuildContribution\" }],\n },\n {\n operation: \"contribution probe\",\n disposition: { kind: \"fallback\", fallback: \"{entries: []}\" },\n requires: [\"probeContributions\"],\n sites: [{ file: \"store/store.ts\", member: \"probeContributions\" }],\n declarationGate: true,\n },\n ],\n} as const satisfies CapabilityBundleDefinition;\n\n/**\n * Core `ensureRevisionOriginsTable`, both refusals existing typed throws\n * (registry-assigned codes; neither underlying throw carries a domain code\n * of its own today).\n */\nexport const RECORDED_REVISION_ORIGINS = {\n id: \"recordedRevisionOrigins\",\n kind: \"gated\",\n core: [\"ensureRevisionOriginsTable\"],\n crossCheck: \"none\",\n portSurfaceCode: \"BUNDLE_PORT_SURFACE_MISMATCH\",\n disposition: {\n kind: \"refuse\",\n code: \"REVISION_TRACKING_REQUIRES_REVISION_ORIGINS\",\n },\n operations: [\n {\n operation: \"revision tracking construction gate\",\n disposition: {\n kind: \"refuse\",\n code: \"REVISION_TRACKING_REQUIRES_REVISION_ORIGINS\",\n },\n sites: [\n {\n file: \"store/recorded-capture/guards.ts\",\n member: \"ensureRevisionOriginsTable\",\n },\n ],\n },\n {\n operation: \"revision origin bootstrap\",\n disposition: {\n kind: \"refuse\",\n code: \"REVISION_ORIGIN_BOOTSTRAP_UNSUPPORTED\",\n },\n sites: [\n {\n file: \"store/recorded-capture/clock.ts\",\n member: \"ensureRevisionOriginsTable\",\n },\n ],\n },\n ],\n} as const satisfies CapabilityBundleDefinition;\n\n/** The pilot registry: six bundles, 15 members, 30 operation rows. */\nexport const CAPABILITY_BUNDLES = [\n CLAIMS,\n UNIQUE_SIDECAR_BATCH,\n BATCH_POINT_READ,\n STATEMENT_EXECUTION,\n CONTRIBUTION_HEALTH,\n RECORDED_REVISION_ORIGINS,\n] as const;\n\nexport type CapabilityBundleId = (typeof CAPABILITY_BUNDLES)[number][\"id\"];\n\n// ---------------------------------------------------------------------------\n// UNBUNDLED_OPTIONAL_MEMBERS — the other 67, both kinds classified (I5, I6).\n// ---------------------------------------------------------------------------\n\n/** No bundle should ever own this member; the reason is the fact to preserve. */\nexport type ReasonedUnbundledMember = Readonly<{\n kind: \"reasoned\";\n reason: string;\n /** Measured receiver-scoped access count (§Baselines). May be 0. */\n accesses: number;\n}>;\n\n/** The 15 WS5b bundle ids, retained from the round-4 sweep table. */\nexport type Ws5bBundleId =\n | \"batchEntityWrite\"\n | \"endpointSetRead\"\n | \"heterogeneousEndpointSetRead\"\n | \"vectorOperations\"\n | \"hybridSearch\"\n | \"vectorSlotContributions\"\n | \"fulltextOperations\"\n | \"fulltextProvisioning\"\n | \"databaseExtensions\"\n | \"contributionProvisioning\"\n | \"indexMaterialization\"\n | \"ddlExecution\"\n | \"temporaryStatements\"\n | \"rawStatementReuse\"\n | \"trustedImport\";\n\n/** WS5b's residue: this bundle owns it, and the access count may not grow. */\nexport type DeferredUnbundledMember = Readonly<{\n kind: \"deferred\";\n workstream: \"WS5b\";\n bundle: Ws5bBundleId;\n /** Measured receiver-scoped access count (§Baselines) — the ceiling. */\n ceiling: number;\n}>;\n\nexport type UnbundledOptionalMember =\n ReasonedUnbundledMember | DeferredUnbundledMember;\n\n/**\n * The 20 `reasoned` + 47 `deferred` members — 61 + 190 = 251 accesses\n * (B9's scanner corrected two `reasoned` counts: `tableNames` 22→23,\n * `ensureIdentityTables` 3→4; #520 then added `recordedTableDdl` with one\n * access), 15 + 67 = 82 members total with the pilot's 15.\n */\nexport const UNBUNDLED_OPTIONAL_MEMBERS = {\n bootstrapTables: {\n kind: \"reasoned\",\n reason:\n \"One-shot provisioning hook consulted by createStore before any capability question exists; it has no operation that could refuse or degrade.\",\n accesses: 3,\n },\n tableNames: {\n kind: \"reasoned\",\n reason:\n \"Not a capability — a name map the compiler reads on every backend. Absence is impossible in practice and meaningless as a decision.\",\n // 23, not the grep tier's 22: store/store.ts holds two `backend.tableNames`\n // accesses on one physical line, which a line-keyed grep counts once but\n // the type-aware scanner counts as two access nodes (§Baselines).\n accesses: 23,\n },\n commitSchemaVersionIfKindsEmpty: {\n kind: \"reasoned\",\n reason:\n \"Schema-version write fence, a SchemaCommitBackend role member. Its absence is dispositioned by the schema manager's own gate, which is a write-pipeline decision, not a feature-family one.\",\n accesses: 1,\n },\n commitSchemaVersionWithPreflight: {\n kind: \"reasoned\",\n reason:\n \"Same schema-version write-fence family as commitSchemaVersionIfKindsEmpty.\",\n accesses: 2,\n },\n lockSchemaVersionForWrite: {\n kind: \"reasoned\",\n reason:\n \"Same family; also the one schema member on TransactionBackend, so bundling it would re-open the accessor's B-1 port-typing question for no pilot consumer.\",\n accesses: 1,\n },\n schemaWriteTransaction: {\n kind: \"reasoned\",\n reason:\n \"Same family — and it returns a narrowed transaction backend, so it is a port constructor rather than an operation.\",\n accesses: 4,\n },\n ensureIdentityTables: {\n kind: \"reasoned\",\n reason:\n \"Identity DDL, gated by the identity construction gate (store.ts:918-935), which is the write-fence design's decision and must stay one owner there.\",\n // 4, not the grep tier's 3: identity/schema-transition.ts:228 accesses\n // `input.ensureIdentityTables` through a derived (arm-b) receiver whose\n // property name never matches the grep receiver-name filter\n // (backend|Backend|target|Target|tx|port|source). The type-aware scanner\n // resolves it via the receiver's declared type node, which textually\n // references `GraphBackend[\"ensureIdentityTables\"]` (§Baselines).\n accesses: 4,\n },\n identityTableDdl: {\n kind: \"reasoned\",\n reason: \"Same identity-DDL family as ensureIdentityTables.\",\n accesses: 2,\n },\n recordedTableDdl: {\n kind: \"reasoned\",\n reason:\n \"Recorded-time migration DDL factory; its only consumer has its own typed capability refusal, so it is a provisioning port rather than a feature-family operation.\",\n accesses: 1,\n },\n ensureKindRemovalsTable: {\n kind: \"reasoned\",\n reason:\n \"Kind-removal provisioning; the removal path's own gate is a schema-lifecycle decision with a single consumer (materialize-removals.ts) and no second theory to consolidate.\",\n accesses: 3,\n },\n getAllKindRemovals: {\n kind: \"reasoned\",\n reason: \"Same kind-removal family as ensureKindRemovalsTable.\",\n accesses: 2,\n },\n getPendingKindRemovals: {\n kind: \"reasoned\",\n reason: \"Same kind-removal family as ensureKindRemovalsTable.\",\n accesses: 4,\n },\n recordKindRemoval: {\n kind: \"reasoned\",\n reason: \"Same kind-removal family as ensureKindRemovalsTable.\",\n accesses: 4,\n },\n ensureReconciliationMarkersTable: {\n kind: \"reasoned\",\n reason:\n \"Reconciliation-marker family; single consumer, single gate, same reasoning.\",\n accesses: 2,\n },\n getReconciliationMarker: {\n kind: \"reasoned\",\n reason: \"Same reconciliation-marker family.\",\n accesses: 2,\n },\n setReconciliationMarker: {\n kind: \"reasoned\",\n reason: \"Same reconciliation-marker family.\",\n accesses: 2,\n },\n readConstraintFenceViolations: {\n kind: \"reasoned\",\n reason:\n 'Read-only fence audit with exactly one caller and a documented \"absent ⇒ the report is unavailable\" contract (history-store-backend.ts:105-108); no operation degrades or refuses on it.',\n accesses: 1,\n },\n ensureContributionMaterializationsTable: {\n kind: \"reasoned\",\n reason:\n \"Zero consumers in src/** outside the backend implementations — measured, not inferred. A member no code path consults has no measurable arity or disposition.\",\n accesses: 0,\n },\n getContributionMaterialization: {\n kind: \"reasoned\",\n reason:\n \"Same zero-consumer family as ensureContributionMaterializationsTable.\",\n accesses: 0,\n },\n recordContributionMaterialization: {\n kind: \"reasoned\",\n reason:\n \"Zero consumers outside the backend implementations; its only in-tree use is a backend implementation calling its own member (backend/drizzle/contribution-materializations.ts:1588), which the scanner excludes by scope.\",\n accesses: 0,\n },\n\n assertRuntimeContributionsInitialized: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"contributionProvisioning\",\n ceiling: 1,\n },\n assertVectorSlotInitialized: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"vectorSlotContributions\",\n ceiling: 1,\n },\n assertVectorSlotsInitialized: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"vectorSlotContributions\",\n ceiling: 1,\n },\n claimIndexMaterialization: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"indexMaterialization\",\n ceiling: 2,\n },\n compileSql: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"rawStatementReuse\",\n ceiling: 9,\n },\n createVectorIndex: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"vectorOperations\",\n ceiling: 4,\n },\n deleteEdgesBatch: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"batchEntityWrite\",\n ceiling: 5,\n },\n deleteEmbedding: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"vectorOperations\",\n ceiling: 8,\n },\n deleteEmbeddingBatch: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"vectorOperations\",\n ceiling: 4,\n },\n deleteFulltext: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"fulltextOperations\",\n ceiling: 11,\n },\n deleteFulltextBatch: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"fulltextOperations\",\n ceiling: 6,\n },\n deleteVectorSlotContribution: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"vectorSlotContributions\",\n ceiling: 0,\n },\n dropVectorIndex: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"vectorOperations\",\n ceiling: 0,\n },\n ensureExtension: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"databaseExtensions\",\n ceiling: 2,\n },\n ensureFulltextTable: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"fulltextProvisioning\",\n ceiling: 1,\n },\n ensureIndexMaterializationsTable: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"indexMaterialization\",\n ceiling: 2,\n },\n ensureRuntimeContributions: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"contributionProvisioning\",\n ceiling: 2,\n },\n ensureTrigramExtension: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"databaseExtensions\",\n ceiling: 2,\n },\n ensureVectorSlotContribution: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"vectorSlotContributions\",\n ceiling: 4,\n },\n ensureVectorSlotContributions: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"vectorSlotContributions\",\n ceiling: 1,\n },\n executeDdl: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"ddlExecution\",\n ceiling: 13,\n },\n executeRaw: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"rawStatementReuse\",\n ceiling: 7,\n },\n executeTemporaryStatement: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"temporaryStatements\",\n ceiling: 3,\n },\n findEdgesByEndpointSet: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"endpointSetRead\",\n ceiling: 1,\n },\n findEdgesByHeterogeneousEndpointSet: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"heterogeneousEndpointSetRead\",\n ceiling: 1,\n },\n fulltextSearch: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"fulltextOperations\",\n ceiling: 4,\n },\n fulltextStrategy: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"fulltextOperations\",\n ceiling: 2,\n },\n getIndexMaterialization: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"indexMaterialization\",\n ceiling: 3,\n },\n getIndexMaterializations: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"indexMaterialization\",\n ceiling: 2,\n },\n hardDeleteEdgesBatch: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"batchEntityWrite\",\n ceiling: 5,\n },\n hybridSearch: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"hybridSearch\",\n ceiling: 2,\n },\n insertEdgeNoReturn: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"batchEntityWrite\",\n ceiling: 4,\n },\n insertEdgesBatch: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"batchEntityWrite\",\n ceiling: 4,\n },\n insertEdgesBatchReturning: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"batchEntityWrite\",\n ceiling: 4,\n },\n insertNodeNoReturn: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"batchEntityWrite\",\n ceiling: 4,\n },\n insertNodesBatch: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"batchEntityWrite\",\n ceiling: 4,\n },\n insertNodesBatchReturning: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"batchEntityWrite\",\n ceiling: 4,\n },\n recordIndexMaterialization: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"indexMaterialization\",\n ceiling: 6,\n },\n releaseIndexMaterializationClaim: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"indexMaterialization\",\n ceiling: 2,\n },\n trustedImport: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"trustedImport\",\n ceiling: 1,\n },\n updateNodeSet: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"batchEntityWrite\",\n ceiling: 6,\n },\n upsertEmbedding: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"vectorOperations\",\n ceiling: 10,\n },\n upsertEmbeddingBatch: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"vectorOperations\",\n ceiling: 4,\n },\n upsertFulltext: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"fulltextOperations\",\n ceiling: 9,\n },\n upsertFulltextBatch: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"fulltextOperations\",\n ceiling: 6,\n },\n vectorSearch: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"vectorOperations\",\n ceiling: 4,\n },\n vectorStrategy: {\n kind: \"deferred\",\n workstream: \"WS5b\",\n bundle: \"vectorOperations\",\n ceiling: 9,\n },\n} as const satisfies Record<string, UnbundledOptionalMember>;\n\n/**\n * The appendix's 15 WS5b bundles, as (bundle id → member names) — written\n * INDEPENDENTLY of `UNBUNDLED_OPTIONAL_MEMBERS`'s `deferred` entries, so the\n * totality proof below is not a tautology: grouping the `deferred` entries\n * by `bundle` must reproduce this table exactly.\n */\nexport const WS5B_SEED_BUNDLES = {\n batchEntityWrite: [\n \"insertNodesBatch\",\n \"insertNodesBatchReturning\",\n \"insertEdgesBatch\",\n \"insertEdgesBatchReturning\",\n \"deleteEdgesBatch\",\n \"hardDeleteEdgesBatch\",\n \"insertNodeNoReturn\",\n \"insertEdgeNoReturn\",\n \"updateNodeSet\",\n ],\n endpointSetRead: [\"findEdgesByEndpointSet\"],\n heterogeneousEndpointSetRead: [\"findEdgesByHeterogeneousEndpointSet\"],\n vectorOperations: [\n \"upsertEmbedding\",\n \"deleteEmbedding\",\n \"upsertEmbeddingBatch\",\n \"deleteEmbeddingBatch\",\n \"vectorSearch\",\n \"vectorStrategy\",\n \"createVectorIndex\",\n \"dropVectorIndex\",\n ],\n hybridSearch: [\"hybridSearch\"],\n vectorSlotContributions: [\n \"assertVectorSlotsInitialized\",\n \"assertVectorSlotInitialized\",\n \"ensureVectorSlotContributions\",\n \"ensureVectorSlotContribution\",\n \"deleteVectorSlotContribution\",\n ],\n fulltextOperations: [\n \"upsertFulltext\",\n \"deleteFulltext\",\n \"upsertFulltextBatch\",\n \"deleteFulltextBatch\",\n \"fulltextSearch\",\n \"fulltextStrategy\",\n ],\n fulltextProvisioning: [\"ensureFulltextTable\"],\n databaseExtensions: [\"ensureExtension\", \"ensureTrigramExtension\"],\n contributionProvisioning: [\n \"ensureRuntimeContributions\",\n \"assertRuntimeContributionsInitialized\",\n ],\n indexMaterialization: [\n \"getIndexMaterialization\",\n \"recordIndexMaterialization\",\n \"getIndexMaterializations\",\n \"ensureIndexMaterializationsTable\",\n \"claimIndexMaterialization\",\n \"releaseIndexMaterializationClaim\",\n ],\n ddlExecution: [\"executeDdl\"],\n temporaryStatements: [\"executeTemporaryStatement\"],\n rawStatementReuse: [\"executeRaw\", \"compileSql\"],\n trustedImport: [\"trustedImport\"],\n} as const satisfies Record<\n Ws5bBundleId,\n readonly OptionalGraphBackendMember[]\n>;\n\n// ---------------------------------------------------------------------------\n// Compile-time proofs — written exactly as member-classes.ts:288,306-376.\n// ---------------------------------------------------------------------------\n\n// Structural, not nominal: reads `core`/`extras` off each bundle directly\n// rather than matching against `GatedBundleDefinition`/`GraduatedBundleDefinition`.\n// Measured against the compiler: matching the named definition types instead\n// (`D extends GatedBundleDefinition<infer MCore, string, infer MExtra> ? …`)\n// infers `MCore` correctly but, for a gated bundle with no `extras` field\n// (`CLAIMS`), leaves `MExtra` with NO inference candidate — and TypeScript's\n// fallback for an unmatched `infer` is the type parameter's CONSTRAINT\n// (`OptionalGraphBackendMember`, the full 82), not `never`, silently widening\n// `MCore | MExtra` to every optional member. The structural form below has no\n// such unmatched parameter: `extras` is read only when the field is actually\n// present, so a bundle without one contributes no `ExtrasMembersOf` members\n// at all.\ntype CoreMembersOf<D> = D extends { core: readonly (infer M)[] } ? M : never;\ntype ExtrasMembersOf<D> =\n D extends { extras: readonly (infer E)[] } ?\n E extends { members: readonly (infer M)[] } ?\n M\n : never\n : never;\ntype BundleMembers<D> = CoreMembersOf<D> | ExtrasMembersOf<D>;\n\ntype BundledMember = BundleMembers<(typeof CAPABILITY_BUNDLES)[number]>;\n\ntype ReasonedMember = {\n [\n K in keyof typeof UNBUNDLED_OPTIONAL_MEMBERS\n ]: (typeof UNBUNDLED_OPTIONAL_MEMBERS)[K] extends { kind: \"reasoned\" } ? K\n : never;\n}[keyof typeof UNBUNDLED_OPTIONAL_MEMBERS];\n\ntype DeferredMember = {\n [\n K in keyof typeof UNBUNDLED_OPTIONAL_MEMBERS\n ]: (typeof UNBUNDLED_OPTIONAL_MEMBERS)[K] extends { kind: \"deferred\" } ? K\n : never;\n}[keyof typeof UNBUNDLED_OPTIONAL_MEMBERS];\n\ntype Ws5bSeedMember = (typeof WS5B_SEED_BUNDLES)[Ws5bBundleId][number];\n\n/**\n * DISJOINTNESS, written to REPORT the offender — `Assert<Equal<Extract<A,\n * B>, never>>` looks like the obvious spelling and is useless here: inside a\n * generic alias `Equal` defers to `boolean`, which satisfies neither `true`\n * nor `false`, so the assertion passes whatever it is given.\n */\ntype Disjoint<A, B> =\n [Extract<A, B>] extends [never] ? true\n : [\"MEMBER CLASSIFIED TWICE\", Extract<A, B>];\n\n/* eslint-disable @typescript-eslint/no-unused-vars -- compile-time assertions */\n\n// (i) Totality: the three-way partition covers exactly the 82 optional members.\ntype _totality = Assert<\n Equal<\n BundledMember | ReasonedMember | DeferredMember,\n OptionalGraphBackendMember\n >\n>;\n\n// (ii) Pairwise disjointness, across the partition and across the six bundles.\ntype _partitionDisjoint1 = Assert<\n Disjoint<BundledMember, ReasonedMember | DeferredMember>\n>;\ntype _partitionDisjoint2 = Assert<Disjoint<ReasonedMember, DeferredMember>>;\n\ntype _bundleDisjoint1 = Assert<\n Disjoint<\n (typeof CLAIMS)[\"core\"][number],\n | (typeof UNIQUE_SIDECAR_BATCH)[\"extras\"][number][\"members\"][number]\n | (typeof BATCH_POINT_READ)[\"extras\"][number][\"members\"][number]\n | (typeof STATEMENT_EXECUTION)[\"core\"][number]\n | (typeof CONTRIBUTION_HEALTH)[\"extras\"][number][\"members\"][number]\n | (typeof RECORDED_REVISION_ORIGINS)[\"core\"][number]\n >\n>;\ntype _bundleDisjoint2 = Assert<\n Disjoint<\n (typeof UNIQUE_SIDECAR_BATCH)[\"extras\"][number][\"members\"][number],\n | (typeof BATCH_POINT_READ)[\"extras\"][number][\"members\"][number]\n | (typeof STATEMENT_EXECUTION)[\"core\"][number]\n | (typeof CONTRIBUTION_HEALTH)[\"extras\"][number][\"members\"][number]\n | (typeof RECORDED_REVISION_ORIGINS)[\"core\"][number]\n >\n>;\ntype _bundleDisjoint3 = Assert<\n Disjoint<\n (typeof BATCH_POINT_READ)[\"extras\"][number][\"members\"][number],\n | (typeof STATEMENT_EXECUTION)[\"core\"][number]\n | (typeof CONTRIBUTION_HEALTH)[\"extras\"][number][\"members\"][number]\n | (typeof RECORDED_REVISION_ORIGINS)[\"core\"][number]\n >\n>;\ntype _bundleDisjoint4 = Assert<\n Disjoint<\n (typeof STATEMENT_EXECUTION)[\"core\"][number],\n | (typeof CONTRIBUTION_HEALTH)[\"extras\"][number][\"members\"][number]\n | (typeof RECORDED_REVISION_ORIGINS)[\"core\"][number]\n >\n>;\ntype _bundleDisjoint5 = Assert<\n Disjoint<\n (typeof CONTRIBUTION_HEALTH)[\"extras\"][number][\"members\"][number],\n (typeof RECORDED_REVISION_ORIGINS)[\"core\"][number]\n >\n>;\n\n// (iii) The deferred set and the appendix's seed list name the same members.\ntype _ws5bSeedEqualsDeferred = Assert<Equal<DeferredMember, Ws5bSeedMember>>;\n\n/* eslint-enable @typescript-eslint/no-unused-vars */\n","/**\n * The bundle BINDING half (ruling B1): the actual member functions, bound at\n * the call site off whichever port the site holds. The accessor is the\n * SINGLE owner of binding — it never re-derives presence, only reads the\n * verdict's `present`/`missing` fields to decide which names to bind, then\n * binds them off the port passed to it. It throws the bundle's\n * `portSurfaceCode` when the verdict says present and the port disagrees\n * (I20) — the generalization of the check `store/claims/backing.ts:157-169`\n * performs today.\n */\nimport { ConfigurationError } from \"../../errors\";\nimport { createDataKeyedBag } from \"../../utils/object\";\nimport { type GraphBackend } from \"../types\";\nimport {\n BATCH_POINT_READ,\n CAPABILITY_BUNDLES,\n type CapabilityBundleId,\n CLAIMS,\n CONTRIBUTION_HEALTH,\n type GatedBundleDefinition,\n type OptionalGraphBackendMember,\n RECORDED_REVISION_ORIGINS,\n STATEMENT_EXECUTION,\n UNIQUE_SIDECAR_BATCH,\n} from \"./bundle-registry\";\nimport {\n type BundleVerdictOf,\n type ExtraMember,\n type ExtrasOf,\n type ExtraVerdict,\n} from \"./resolve\";\n\n/**\n * I21. The brand is what makes a BOUND member type-distinguishable from a\n * PORT member: without it, `binding.getNodes` at a rewired site still has a\n * receiver assignable to `Pick<GraphBackend, …>`, and a syntactic scanner\n * could never tell a bound value from an unbound one.\n */\ndeclare const BUNDLE_BINDING: unique symbol;\n\n/** Every named member, guaranteed present — bound off the port, never a port member itself. */\nexport type BundleBinding<M extends OptionalGraphBackendMember> = Required<\n Pick<GraphBackend, M>\n> &\n Readonly<{ [BUNDLE_BINDING]: true }>;\n\n/**\n * The graduated twin of {@link BundleBinding}: a bundle with no required\n * core cannot promise every member is present, so its bundle-wide \"members\"\n * accessor (`uniqueSidecarBatchMembers`, `batchPointReadMembers`,\n * `contributionHealthMembers`) reports whichever extras the verdict marks\n * present — never all of them by construction, and never a cast that claims\n * otherwise.\n */\nexport type PartialBundleBinding<M extends OptionalGraphBackendMember> =\n Readonly<Partial<Pick<GraphBackend, M>>> &\n Readonly<{ [BUNDLE_BINDING]: true }>;\n\nfunction portSurfaceCodeFor(bundle: CapabilityBundleId): string {\n const definition = CAPABILITY_BUNDLES.find(\n (candidate) => candidate.id === bundle,\n );\n return definition?.portSurfaceCode ?? \"BUNDLE_PORT_SURFACE_MISMATCH\";\n}\n\n/**\n * The one owner of \"does this port have every one of these names\" — used both\n * by {@link bindNames}'s REFUSE arm (`bindCore`/`bindExtra`, which keep the\n * throw) and by {@link bindExtraIfReachable}'s FALLBACK arm (which turns the\n * same answer into `undefined`). Returns the first missing name, or\n * `undefined` when the port has them all.\n */\nfunction findMissingPortMember<M extends OptionalGraphBackendMember>(\n port: Readonly<Partial<Pick<GraphBackend, M>>>,\n names: readonly M[],\n): M | undefined {\n const portRecord = port as Readonly<Record<string, unknown>>;\n return names.find((name) => portRecord[name] === undefined);\n}\n\nfunction bindNames<const M extends OptionalGraphBackendMember>(\n port: Readonly<Partial<Pick<GraphBackend, M>>>,\n names: readonly M[],\n bundle: CapabilityBundleId,\n): Record<string, unknown> {\n const missing = findMissingPortMember(port, names);\n if (missing !== undefined) {\n throw new ConfigurationError(\n `The port passed to capability bundle \"${bundle}\" is missing \"${missing}\", which the resolved verdict says is present.`,\n {\n code: portSurfaceCodeFor(bundle),\n bundle,\n member: missing,\n },\n );\n }\n const bound = createDataKeyedBag<unknown>();\n const portRecord = port as Readonly<Record<string, unknown>>;\n for (const name of names) {\n bound[name] = portRecord[name];\n }\n return bound;\n}\n\n/**\n * Bind a gated bundle's core off the port the calls execute on. The port\n * parameter is the STRUCTURAL MINIMUM over the members (ruling B-1), so\n * every one of the pilot's receiver shapes is accepted:\n * `GraphBackend`, `TransactionBackend`, `WriteTarget`, `IdentityTarget`,\n * `Pick<GraphBackend, \"dialect\" | \"executeStatement\">` and the\n * `RevisionOriginBackend`-shaped `Pick<GraphBackend, \"dialect\" |\n * \"ensureRevisionOriginsTable\" | \"execute\" | \"executeStatement\">`.\n *\n * @throws {ConfigurationError} with the bundle's `portSurfaceCode` when the\n * verdict says a core member is present and the port lacks it (I20).\n */\nexport function bindCore<\n const D extends GatedBundleDefinition<\n OptionalGraphBackendMember,\n string,\n OptionalGraphBackendMember\n >,\n M extends D[\"core\"][number],\n>(\n port: Readonly<Partial<Pick<GraphBackend, M>>>,\n verdict: Extract<BundleVerdictOf<D>, { supported: true }>,\n definition: D,\n): BundleBinding<M> {\n const bound = bindNames(\n port,\n verdict.members as readonly M[],\n definition.id as CapabilityBundleId,\n );\n return bound as BundleBinding<M>;\n}\n\n/**\n * Bind one graduated extra. Takes the EXTRA's own verdict, not the bundle's:\n * `requireExtras` (`resolve.ts`) narrows `verdict.extras.someExtra` at an\n * `if`/assertion, not `verdict` as a whole, so a signature demanding the\n * whole narrowed verdict would compile only after that call — the common\n * case is the fallback branch, which never calls `requireExtras` at all.\n *\n * @throws {ConfigurationError} with the bundle's `portSurfaceCode` when the\n * extra verdict says present and the port lacks the member (I20).\n */\nexport function bindExtra<const M extends OptionalGraphBackendMember>(\n port: Readonly<Partial<Pick<GraphBackend, M>>>,\n extraVerdict: Extract<ExtraVerdict<M>, { present: true }>,\n bundle: CapabilityBundleId,\n): BundleBinding<M> {\n const bound = bindNames(port, extraVerdict.members, bundle);\n return bound as BundleBinding<M>;\n}\n\n/**\n * The FALLBACK arm of I20's disposition-keyed port-mismatch split (ruling,\n * B8 blocker): binds an extra when the verdict says it is present AND the\n * port can reach it, otherwise returns `undefined` — collapsing \"the verdict\n * says absent\" and \"the port cannot reach it\" into the site's single declared\n * fallback, which is exactly the shape a `fallback`-dispositioned row already\n * has. Used ONLY at call sites whose registry operation row disposes\n * `fallback`; a `refuse` row keeps calling {@link bindExtra} (or\n * {@link bindCore}) so its port mismatch still throws (I20's REFUSE arm).\n *\n * Deliberately does NOT consult the row's disposition itself: an extra's own\n * disposition and its operation row's disposition can differ (`\n * checkUniqueBatch` is a `fallback` extra owned by both a `fallback` row and\n * two `refuse` rows), so only the call site — which knows which row it is —\n * can choose the arm.\n */\nexport function bindExtraIfReachable<\n const M extends OptionalGraphBackendMember,\n>(\n port: Readonly<Partial<Pick<GraphBackend, M>>>,\n extraVerdict: ExtraVerdict<M>,\n bundle: CapabilityBundleId,\n): BundleBinding<M> | undefined {\n if (!extraVerdict.present) return undefined;\n if (findMissingPortMember(port, extraVerdict.members) !== undefined) {\n return undefined;\n }\n return bindExtra(port, extraVerdict, bundle);\n}\n\n/**\n * The one owner of \"bind every extra the verdict marks present\" — the three\n * graduated bundle-wide \"members\" accessors below each call this with their\n * own bundle id rather than re-spelling the present/absent fold.\n */\nfunction bindPresentExtraVerdicts(\n port: Readonly<Partial<Pick<GraphBackend, OptionalGraphBackendMember>>>,\n extras: Readonly<Record<string, ExtraVerdict<OptionalGraphBackendMember>>>,\n bundle: CapabilityBundleId,\n): Record<string, unknown> {\n const bound = createDataKeyedBag<unknown>();\n for (const extraVerdict of Object.values(extras)) {\n if (!extraVerdict.present) continue;\n Object.assign(bound, bindExtra(port, extraVerdict, bundle));\n }\n return bound;\n}\n\nexport function claimsMembers(\n port: Readonly<Partial<Pick<GraphBackend, (typeof CLAIMS)[\"core\"][number]>>>,\n verdict: Extract<BundleVerdictOf<typeof CLAIMS>, { supported: true }>,\n): BundleBinding<(typeof CLAIMS)[\"core\"][number]> {\n return bindCore(port, verdict, CLAIMS);\n}\n\nexport function statementExecutionMembers(\n port: Readonly<\n Partial<Pick<GraphBackend, (typeof STATEMENT_EXECUTION)[\"core\"][number]>>\n >,\n verdict: Extract<\n BundleVerdictOf<typeof STATEMENT_EXECUTION>,\n { supported: true }\n >,\n): BundleBinding<(typeof STATEMENT_EXECUTION)[\"core\"][number]> {\n return bindCore(port, verdict, STATEMENT_EXECUTION);\n}\n\nexport function recordedRevisionOriginsMembers(\n port: Readonly<\n Partial<\n Pick<GraphBackend, (typeof RECORDED_REVISION_ORIGINS)[\"core\"][number]>\n >\n >,\n verdict: Extract<\n BundleVerdictOf<typeof RECORDED_REVISION_ORIGINS>,\n { supported: true }\n >,\n): BundleBinding<(typeof RECORDED_REVISION_ORIGINS)[\"core\"][number]> {\n return bindCore(port, verdict, RECORDED_REVISION_ORIGINS);\n}\n\ntype UniqueSidecarBatchExtraMember = ExtraMember<\n typeof UNIQUE_SIDECAR_BATCH,\n keyof ExtrasOf<typeof UNIQUE_SIDECAR_BATCH>\n>;\n\nexport function uniqueSidecarBatchMembers(\n port: Readonly<Partial<Pick<GraphBackend, UniqueSidecarBatchExtraMember>>>,\n verdict: BundleVerdictOf<typeof UNIQUE_SIDECAR_BATCH>,\n): PartialBundleBinding<UniqueSidecarBatchExtraMember> {\n const bound = bindPresentExtraVerdicts(\n port,\n verdict.extras,\n UNIQUE_SIDECAR_BATCH.id,\n );\n return bound as unknown as PartialBundleBinding<UniqueSidecarBatchExtraMember>;\n}\n\ntype BatchPointReadExtraMember = ExtraMember<\n typeof BATCH_POINT_READ,\n keyof ExtrasOf<typeof BATCH_POINT_READ>\n>;\n\nexport function batchPointReadMembers(\n port: Readonly<Partial<Pick<GraphBackend, BatchPointReadExtraMember>>>,\n verdict: BundleVerdictOf<typeof BATCH_POINT_READ>,\n): PartialBundleBinding<BatchPointReadExtraMember> {\n const bound = bindPresentExtraVerdicts(\n port,\n verdict.extras,\n BATCH_POINT_READ.id,\n );\n return bound as unknown as PartialBundleBinding<BatchPointReadExtraMember>;\n}\n\ntype ContributionHealthExtraMember = ExtraMember<\n typeof CONTRIBUTION_HEALTH,\n keyof ExtrasOf<typeof CONTRIBUTION_HEALTH>\n>;\n\nexport function contributionHealthMembers(\n port: Readonly<Partial<Pick<GraphBackend, ContributionHealthExtraMember>>>,\n verdict: BundleVerdictOf<typeof CONTRIBUTION_HEALTH>,\n): PartialBundleBinding<ContributionHealthExtraMember> {\n const bound = bindPresentExtraVerdicts(\n port,\n verdict.extras,\n CONTRIBUTION_HEALTH.id,\n );\n return bound as unknown as PartialBundleBinding<ContributionHealthExtraMember>;\n}\n","/**\n * The `pessimisticLocks` capability: whether this engine can serialize\n * concurrent writers, and how.\n *\n * `resolveWriteFencePlan` is THE one owner of the pessimistic-lock decision\n * every lock site used to re-derive from `dialect` inline. A lock site never\n * spells the dialect itself; it resolves a plan and consumes it.\n */\nimport { ConfigurationError } from \"../../errors\";\nimport { type SqlDialect } from \"../../query/dialect/types\";\nimport { type BackendCapabilities } from \"../types\";\n\n/**\n * The two independent facts a backend can report about concurrent-writer\n * serialization.\n */\nexport type PessimisticLockCapabilities = Readonly<{\n /** `pg_advisory_xact_lock`-style keyed locks scoped to the transaction. */\n advisoryLocks: boolean;\n /** `LOCK TABLE … IN … MODE`-style relation locks. */\n tableLocks: boolean;\n /**\n * The engine serializes concurrent writers by construction (SQLite's single\n * writer slot). This is what makes \"take no lock\" CORRECT on SQLite and\n * WRONG on an engine with neither locks nor a slot.\n */\n serializedWriters: boolean;\n}>;\n\n/**\n * The decision every lock site consumes, rather than a flag a caller would\n * have to re-derive.\n */\nexport type WriteFencePlan =\n /** Take the keyed/table lock. */\n | Readonly<{ kind: \"lock\"; advisoryLocks: true; tableLocks: boolean }>\n /** No lock needed: the engine serializes writers. */\n | Readonly<{ kind: \"engine-serialized\" }>\n /** Neither. Every non-degradable fence refuses. */\n | Readonly<{ kind: \"unfenced\" }>;\n\n/**\n * What `resolveWriteFencePlan` needs: the dialect (for the first-party\n * dialect-derivation arm and for the refusal message) and the declared\n * capabilities. Structural on purpose — see the module-private first-party\n * mark below, which is carried out-of-band rather than as a type member.\n */\nexport type WriteFenceTarget = Readonly<{\n dialect: SqlDialect;\n capabilities: BackendCapabilities;\n}>;\n\n/**\n * Marks a backend (or a small fence-target object built alongside one) as\n * produced by `createSqliteBackend` / `createPostgresBackend`, so\n * `resolveWriteFencePlan`'s dialect-derivation arm — correct only for a\n * factory backend, unsound for anything else (M-5) — is reachable only from\n * them.\n *\n * A `WeakSet<object>` keyed by object identity, not a `unique symbol`\n * property: `deriveBackend` returns a `Proxy` whose `set` trap writes\n * through to a possibly-frozen base, so a symbol property written at\n * construction is not guaranteed to survive every derivation the same way a\n * side-table entry does, and a `WeakSet` is unforgeable by a custom\n * backend in a way a plain property is not. Module-private and NOT\n * barrelled: nothing outside this module and `derive-backend.ts` may mark or\n * carry the mark.\n */\nconst FIRST_PARTY_FACTORY_BACKENDS = new WeakSet<object>();\n\n/**\n * The two first-party factories call this on the backend object they are\n * about to return (or on a small fence-target object built alongside one),\n * before it escapes the factory body.\n *\n * @internal\n */\nexport function markFirstPartyFactory<T extends object>(target: T): T {\n FIRST_PARTY_FACTORY_BACKENDS.add(target);\n return target;\n}\n\n/**\n * Carries the first-party mark from a source object onto one derived from\n * it, so a factory backend projected or decorated for a transaction still\n * resolves the SAME plan its source would — a lost mark would otherwise\n * answer \"dialect-derived\" at one call site and \"unfenced\" at another for\n * the same underlying backend.\n *\n * `src/backend/derive-backend.ts` is the only module allowed to call this,\n * alongside its call to `carryBackendResourceAudit`.\n *\n * @internal\n */\nexport function carryFirstPartyFactoryMark(\n derived: object,\n base: object,\n): void {\n if (FIRST_PARTY_FACTORY_BACKENDS.has(base)) {\n FIRST_PARTY_FACTORY_BACKENDS.add(derived);\n }\n}\n\nfunction deriveFromDialect(dialect: SqlDialect): PessimisticLockCapabilities {\n switch (dialect) {\n case \"postgres\": {\n return {\n advisoryLocks: true,\n tableLocks: true,\n serializedWriters: false,\n };\n }\n case \"sqlite\": {\n return {\n advisoryLocks: false,\n tableLocks: false,\n serializedWriters: true,\n };\n }\n default: {\n return dialect satisfies never;\n }\n }\n}\n\nfunction planFromLockCapabilities(\n declared: PessimisticLockCapabilities,\n): WriteFencePlan {\n if (declared.advisoryLocks) {\n return {\n kind: \"lock\",\n advisoryLocks: true,\n tableLocks: declared.tableLocks,\n };\n }\n // A declared table-locks-only engine (no advisoryLocks, no\n // serializedWriters) resolves `unfenced`: every TypeGraph fence needs\n // either the advisory key or the writer slot, and no lock site here takes\n // a table lock without first having taken the advisory one.\n if (declared.serializedWriters) return { kind: \"engine-serialized\" };\n return { kind: \"unfenced\" };\n}\n\n/**\n * THE one reader of `capabilities.pessimisticLocks`, and THE one constructor\n * of a {@link WriteFencePlan}.\n *\n * Resolution order:\n *\n * 1. **Declared** — use the declaration. Every first-party backend declares\n * `pessimisticLocks` (`SQLITE_CAPABILITIES` / `POSTGRES_CAPABILITIES`),\n * and a custom backend takes this path by writing one line.\n * 2. **Absent, first-party factory** — derive from `dialect`\n * (`postgres` → `{advisoryLocks:true,tableLocks:true,serializedWriters:false}`,\n * `sqlite` → `{advisoryLocks:false,tableLocks:false,serializedWriters:true}`),\n * which is exactly what every lock site used to compute inline. After\n * A1/A2 land, nothing in-tree reaches this arm — both bundled factories\n * declare `pessimisticLocks` unconditionally — so it is reachable only\n * from tests that build a backend object bypassing the factories'\n * declared capabilities while still carrying the first-party mark.\n * 3. **Absent, anything else** — `unfenced`. Conservative: an undeclared\n * custom backend is by definition uncertified, and inferring lock support\n * from `dialect` alone is the unsound inference this capability replaces\n * (a Doltgres-shaped backend reporting `dialect: \"postgres\"` need not\n * honor `pg_advisory_xact_lock`).\n */\nexport function resolveWriteFencePlan(\n target: WriteFenceTarget,\n): WriteFencePlan {\n const declared = target.capabilities.pessimisticLocks;\n if (declared !== undefined) return planFromLockCapabilities(declared);\n if (FIRST_PARTY_FACTORY_BACKENDS.has(target)) {\n return planFromLockCapabilities(deriveFromDialect(target.dialect));\n }\n return { kind: \"unfenced\" };\n}\n\n/**\n * THE one owner of the literal `pessimisticLocks` declaration line a refusal\n * recommends — printed verbatim by both unfenced refusals below, so the\n * migration guide cannot rot into a pointer (ruling OQ-B).\n */\nexport function pessimisticLockDeclarationLine(dialect: SqlDialect): string {\n switch (dialect) {\n case \"postgres\": {\n return \"pessimisticLocks: { advisoryLocks: true, tableLocks: true, serializedWriters: false }\";\n }\n case \"sqlite\": {\n return \"pessimisticLocks: { advisoryLocks: false, tableLocks: false, serializedWriters: true }\";\n }\n default: {\n return dialect satisfies never;\n }\n }\n}\n\n/**\n * The shared body of both unfenced-construction refusals below: names both\n * ways `unfenced` is reached (absent, or a present-but-all-false\n * declaration) rather than claiming absence it cannot know, then prints the\n * one line that fixes it, keyed to the dialect the backend reports.\n */\nfunction unfencedRefusalMessage(dialect: SqlDialect, resource: string): string {\n const declaredLine = pessimisticLockDeclarationLine(dialect);\n const otherDialect: SqlDialect =\n dialect === \"postgres\" ? \"sqlite\" : \"postgres\";\n const otherLine = pessimisticLockDeclarationLine(otherDialect);\n const dialectDescription =\n dialect === \"postgres\" ?\n \"an engine that honors `pg_advisory_xact_lock` and `LOCK TABLE`\"\n : \"an engine with a single writer slot\";\n const otherDescription =\n otherDialect === \"postgres\" ?\n \"an engine that honors `pg_advisory_xact_lock` and `LOCK TABLE`\"\n : \"an engine with a single writer slot\";\n return (\n \"This backend declares no usable write fence: `capabilities.pessimisticLocks` \" +\n \"is absent, or declares neither advisory/table locks nor serialized writers, \" +\n `so TypeGraph cannot know whether it fences concurrent writers, and ${resource} ` +\n \"cannot run unfenced. Add ONE line to the capabilities you pass:\\n\\n\" +\n ` ${declaredLine}\\n\\n` +\n `(that is the correct declaration for ${dialectDescription}; use\\n` +\n `\\`${otherLine}\\` for ${otherDescription}). If the engine honors ` +\n `neither, this refusal is correct and ${resource} is unavailable on it.`\n );\n}\n\n/**\n * THE refusal for Operational Identity constructed against an `unfenced`\n * backend. §5.3.1 (J9b).\n *\n * @throws {ConfigurationError} always.\n */\nexport function refuseUnfencedOperationalIdentity(dialect: SqlDialect): never {\n throw new ConfigurationError(\n unfencedRefusalMessage(dialect, \"Operational Identity\"),\n { code: \"IDENTITY_REQUIRES_WRITE_FENCE\", dialect },\n {\n suggestion:\n \"Declare `capabilities.pessimisticLocks` on this backend, or construct the store without `identity`.\",\n },\n );\n}\n\n/**\n * THE refusal for TypeGraph-owned recorded-clock allocation (`history` /\n * `revisionTracking`) constructed against an `unfenced` backend that owns\n * its own recorded-time relations. §5.3.1 (J9a).\n *\n * @throws {ConfigurationError} always.\n */\nexport function refuseUnfencedClockAllocation(dialect: SqlDialect): never {\n throw new ConfigurationError(\n unfencedRefusalMessage(\n dialect,\n \"TypeGraph's recorded-time clock allocation\",\n ),\n { code: \"RECORDED_CLOCK_REQUIRES_WRITE_FENCE\", dialect },\n {\n suggestion:\n \"Declare `capabilities.pessimisticLocks` on this backend, or construct the store without `history`/`revisionTracking`.\",\n },\n );\n}\n\n/**\n * THE refusal for a fence that cannot degrade: `unfenced` always refuses,\n * and a `lock` plan that lacks the table lock an operation requires refuses\n * too — the declared-advisory-only posture, which T15 exercises as its own\n * matrix row.\n *\n * `engine-serialized` satisfies both requirements: the writer slot is the\n * fence, whichever shape of lock the caller would otherwise have taken.\n *\n * @throws {ConfigurationError} under `unfenced`, and under\n * `kind: \"lock\" && tableLocks === false` when `requires === \"table-lock\"`.\n */\nexport function requireWriteFence(\n plan: WriteFencePlan,\n operation: string,\n requires: \"advisory-lock\" | \"table-lock\",\n): Extract<WriteFencePlan, { kind: \"lock\" | \"engine-serialized\" }> {\n switch (plan.kind) {\n case \"lock\": {\n if (requires === \"table-lock\" && !plan.tableLocks) {\n throw new ConfigurationError(\n `${operation} requires a table lock, but this backend's ` +\n \"pessimisticLocks declaration reports tableLocks: false.\",\n {\n code: \"WRITE_FENCE_UNAVAILABLE\",\n operation,\n requires,\n plan,\n },\n {\n suggestion:\n \"Declare `pessimisticLocks.tableLocks: true` on this backend, or avoid this operation.\",\n },\n );\n }\n return plan;\n }\n case \"engine-serialized\": {\n return plan;\n }\n case \"unfenced\": {\n throw new ConfigurationError(\n `${operation} requires a write fence, but this backend declares no ` +\n \"usable write fence (`capabilities.pessimisticLocks` is absent, or \" +\n \"declares neither advisory/table locks nor serialized writers).\",\n { code: \"WRITE_FENCE_UNAVAILABLE\", operation, requires },\n {\n suggestion:\n \"Declare `capabilities.pessimisticLocks` on this backend, matching the engine's real locking support.\",\n },\n );\n }\n default: {\n plan satisfies never;\n throw new ConfigurationError(\n `${operation} could not resolve a write-fence plan.`,\n { code: \"WRITE_FENCE_UNAVAILABLE\", operation, requires },\n );\n }\n }\n}\n"]}
|