@nicia-ai/typegraph 0.55.0 → 0.56.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/backend/index.cjs +86 -86
  3. package/dist/backend/index.js +7 -7
  4. package/dist/backend/postgres/index.cjs +22 -22
  5. package/dist/backend/postgres/index.js +8 -8
  6. package/dist/backend/postgres/pglite-store.cjs +1 -1
  7. package/dist/backend/postgres/pglite-store.d.cts +2 -2
  8. package/dist/backend/postgres/pglite-store.d.ts +2 -2
  9. package/dist/backend/postgres/pglite-store.js +1 -1
  10. package/dist/backend/postgres/pglite.cjs +10 -10
  11. package/dist/backend/postgres/pglite.js +9 -9
  12. package/dist/backend/sqlite/index.cjs +21 -21
  13. package/dist/backend/sqlite/index.js +8 -8
  14. package/dist/backend/sqlite/libsql.cjs +12 -12
  15. package/dist/backend/sqlite/libsql.js +8 -8
  16. package/dist/backend/sqlite/local-store.cjs +1 -1
  17. package/dist/backend/sqlite/local-store.d.cts +2 -2
  18. package/dist/backend/sqlite/local-store.d.ts +2 -2
  19. package/dist/backend/sqlite/local-store.js +1 -1
  20. package/dist/backend/sqlite/local.cjs +10 -10
  21. package/dist/backend/sqlite/local.js +9 -9
  22. package/dist/{chunk-S5WG5AFG.cjs → chunk-2XUAUSMI.cjs} +12 -12
  23. package/dist/{chunk-S5WG5AFG.cjs.map → chunk-2XUAUSMI.cjs.map} +1 -1
  24. package/dist/{chunk-MTE255N3.cjs → chunk-36XLQHZA.cjs} +4 -4
  25. package/dist/{chunk-MTE255N3.cjs.map → chunk-36XLQHZA.cjs.map} +1 -1
  26. package/dist/{chunk-FWSGKOBN.js → chunk-6LTRZOUU.js} +6 -6
  27. package/dist/{chunk-FWSGKOBN.js.map → chunk-6LTRZOUU.js.map} +1 -1
  28. package/dist/{chunk-YVKPUSHS.js → chunk-75KH6Y2W.js} +16 -7
  29. package/dist/chunk-75KH6Y2W.js.map +1 -0
  30. package/dist/{chunk-MJXEO7YA.js → chunk-762VPGHN.js} +5 -5
  31. package/dist/{chunk-MJXEO7YA.js.map → chunk-762VPGHN.js.map} +1 -1
  32. package/dist/{chunk-GGDTMBNA.cjs → chunk-7CCVR2QF.cjs} +54 -54
  33. package/dist/{chunk-GGDTMBNA.cjs.map → chunk-7CCVR2QF.cjs.map} +1 -1
  34. package/dist/{chunk-7EOJO6QB.js → chunk-7MHENVRG.js} +3 -3
  35. package/dist/{chunk-7EOJO6QB.js.map → chunk-7MHENVRG.js.map} +1 -1
  36. package/dist/{chunk-7B3DSFX3.cjs → chunk-AUTRK6WM.cjs} +4 -4
  37. package/dist/{chunk-7B3DSFX3.cjs.map → chunk-AUTRK6WM.cjs.map} +1 -1
  38. package/dist/{chunk-SIQ4BFL5.js → chunk-AZP5CCHL.js} +4 -4
  39. package/dist/{chunk-SIQ4BFL5.js.map → chunk-AZP5CCHL.js.map} +1 -1
  40. package/dist/{chunk-WTW7RWAG.cjs → chunk-BYUIOM4L.cjs} +6 -6
  41. package/dist/{chunk-WTW7RWAG.cjs.map → chunk-BYUIOM4L.cjs.map} +1 -1
  42. package/dist/{chunk-74FNI3PT.js → chunk-C3TJU4KQ.js} +6 -6
  43. package/dist/chunk-C3TJU4KQ.js.map +1 -0
  44. package/dist/{chunk-7V2R4MH6.js → chunk-CEQOTZGB.js} +5 -5
  45. package/dist/{chunk-7V2R4MH6.js.map → chunk-CEQOTZGB.js.map} +1 -1
  46. package/dist/{chunk-TKFQLKH2.cjs → chunk-CYKHSH5O.cjs} +36 -36
  47. package/dist/{chunk-TKFQLKH2.cjs.map → chunk-CYKHSH5O.cjs.map} +1 -1
  48. package/dist/{chunk-D5TCKAQT.cjs → chunk-DGIA64DM.cjs} +4 -4
  49. package/dist/{chunk-D5TCKAQT.cjs.map → chunk-DGIA64DM.cjs.map} +1 -1
  50. package/dist/{chunk-FFR3YUY2.js → chunk-E4QYEWVH.js} +5 -5
  51. package/dist/{chunk-FFR3YUY2.js.map → chunk-E4QYEWVH.js.map} +1 -1
  52. package/dist/{chunk-467YITD4.cjs → chunk-ETU5IILQ.cjs} +13 -13
  53. package/dist/{chunk-467YITD4.cjs.map → chunk-ETU5IILQ.cjs.map} +1 -1
  54. package/dist/{chunk-HW3IX2RF.js → chunk-EWRLWI7W.js} +4 -4
  55. package/dist/{chunk-HW3IX2RF.js.map → chunk-EWRLWI7W.js.map} +1 -1
  56. package/dist/{chunk-KZ6OHFDV.js → chunk-F2S5JWCT.js} +3 -3
  57. package/dist/{chunk-KZ6OHFDV.js.map → chunk-F2S5JWCT.js.map} +1 -1
  58. package/dist/{chunk-45WPPI64.js → chunk-FMCPKMQI.js} +3 -3
  59. package/dist/{chunk-45WPPI64.js.map → chunk-FMCPKMQI.js.map} +1 -1
  60. package/dist/{chunk-QM6IQW7B.js → chunk-ILHVYKXJ.js} +7 -7
  61. package/dist/{chunk-QM6IQW7B.js.map → chunk-ILHVYKXJ.js.map} +1 -1
  62. package/dist/{chunk-ECYEWFEH.cjs → chunk-J34FSPSC.cjs} +16 -6
  63. package/dist/chunk-J34FSPSC.cjs.map +1 -0
  64. package/dist/{chunk-GFYCLCGU.cjs → chunk-KM3CLHDB.cjs} +9 -9
  65. package/dist/{chunk-GFYCLCGU.cjs.map → chunk-KM3CLHDB.cjs.map} +1 -1
  66. package/dist/{chunk-SLNH62T3.js → chunk-KQYUKOGX.js} +3 -3
  67. package/dist/{chunk-SLNH62T3.js.map → chunk-KQYUKOGX.js.map} +1 -1
  68. package/dist/{chunk-7I2PYI4U.cjs → chunk-KR3N6Y7O.cjs} +67 -67
  69. package/dist/{chunk-7I2PYI4U.cjs.map → chunk-KR3N6Y7O.cjs.map} +1 -1
  70. package/dist/{chunk-HZCOCNIX.cjs → chunk-L2REUAJB.cjs} +24 -24
  71. package/dist/{chunk-HZCOCNIX.cjs.map → chunk-L2REUAJB.cjs.map} +1 -1
  72. package/dist/{chunk-VU65FXEG.js → chunk-LFXBFPI2.js} +66 -29
  73. package/dist/chunk-LFXBFPI2.js.map +1 -0
  74. package/dist/{chunk-NXRSR6QG.js → chunk-MHM6OGZR.js} +9 -9
  75. package/dist/{chunk-NXRSR6QG.js.map → chunk-MHM6OGZR.js.map} +1 -1
  76. package/dist/{chunk-FCUSVSYX.js → chunk-MRGWM5LE.js} +10 -10
  77. package/dist/{chunk-FCUSVSYX.js.map → chunk-MRGWM5LE.js.map} +1 -1
  78. package/dist/{chunk-WXGMDROJ.js → chunk-QDNEXTON.js} +7 -7
  79. package/dist/{chunk-WXGMDROJ.js.map → chunk-QDNEXTON.js.map} +1 -1
  80. package/dist/{chunk-VYU5H4FO.js → chunk-RXA2D3UR.js} +3 -3
  81. package/dist/{chunk-VYU5H4FO.js.map → chunk-RXA2D3UR.js.map} +1 -1
  82. package/dist/{chunk-XODNY4QI.js → chunk-TIBSLFHR.js} +6 -6
  83. package/dist/{chunk-XODNY4QI.js.map → chunk-TIBSLFHR.js.map} +1 -1
  84. package/dist/{chunk-KZG7HQSN.cjs → chunk-UVMSWO6X.cjs} +173 -173
  85. package/dist/{chunk-KZG7HQSN.cjs.map → chunk-UVMSWO6X.cjs.map} +1 -1
  86. package/dist/{chunk-ORPT5EQW.cjs → chunk-UZ6CJUC5.cjs} +27 -27
  87. package/dist/chunk-UZ6CJUC5.cjs.map +1 -0
  88. package/dist/{chunk-GNF3PHEQ.cjs → chunk-VF2IMMZT.cjs} +17 -17
  89. package/dist/{chunk-GNF3PHEQ.cjs.map → chunk-VF2IMMZT.cjs.map} +1 -1
  90. package/dist/{chunk-PGZV3E3I.cjs → chunk-VXEHEPC4.cjs} +4 -4
  91. package/dist/{chunk-PGZV3E3I.cjs.map → chunk-VXEHEPC4.cjs.map} +1 -1
  92. package/dist/{chunk-OJ47LMOB.cjs → chunk-WIUHN6SZ.cjs} +669 -628
  93. package/dist/chunk-WIUHN6SZ.cjs.map +1 -0
  94. package/dist/{chunk-HNW5IDB3.js → chunk-WIZB5U6N.js} +7 -7
  95. package/dist/{chunk-HNW5IDB3.js.map → chunk-WIZB5U6N.js.map} +1 -1
  96. package/dist/{chunk-IDQZI6GL.js → chunk-XH75W3O5.js} +3 -3
  97. package/dist/{chunk-IDQZI6GL.js.map → chunk-XH75W3O5.js.map} +1 -1
  98. package/dist/{chunk-T7LSSV7J.cjs → chunk-XXEFDJHY.cjs} +45 -45
  99. package/dist/{chunk-T7LSSV7J.cjs.map → chunk-XXEFDJHY.cjs.map} +1 -1
  100. package/dist/{chunk-GORCU2GR.cjs → chunk-Z4NU4MYB.cjs} +123 -123
  101. package/dist/{chunk-GORCU2GR.cjs.map → chunk-Z4NU4MYB.cjs.map} +1 -1
  102. package/dist/{chunk-KFC3OUV4.cjs → chunk-ZHK3HEZ2.cjs} +130 -130
  103. package/dist/{chunk-KFC3OUV4.cjs.map → chunk-ZHK3HEZ2.cjs.map} +1 -1
  104. package/dist/{chunk-FYMYLZGX.cjs → chunk-ZXXGMQC3.cjs} +10 -10
  105. package/dist/{chunk-FYMYLZGX.cjs.map → chunk-ZXXGMQC3.cjs.map} +1 -1
  106. package/dist/graph-merge/index.cjs +577 -99
  107. package/dist/graph-merge/index.cjs.map +1 -1
  108. package/dist/graph-merge/index.d.cts +108 -4
  109. package/dist/graph-merge/index.d.ts +108 -4
  110. package/dist/graph-merge/index.js +495 -21
  111. package/dist/graph-merge/index.js.map +1 -1
  112. package/dist/{graph-templates-qraW63Ry.d.ts → graph-templates-BSA9VU_O.d.ts} +1 -1
  113. package/dist/{graph-templates--hp2U4kn.d.cts → graph-templates-Cg7DpEOF.d.cts} +1 -1
  114. package/dist/index.cjs +95 -95
  115. package/dist/index.d.cts +3 -3
  116. package/dist/index.d.ts +3 -3
  117. package/dist/index.js +16 -16
  118. package/dist/interchange/index.cjs +33 -33
  119. package/dist/interchange/index.d.cts +1 -1
  120. package/dist/interchange/index.d.ts +1 -1
  121. package/dist/interchange/index.js +10 -10
  122. package/dist/{local-store-impl-HXBO3VF4.js → local-store-impl-77DCLAAY.js} +18 -18
  123. package/dist/{local-store-impl-HXBO3VF4.js.map → local-store-impl-77DCLAAY.js.map} +1 -1
  124. package/dist/{local-store-impl-CUQKHHOZ.cjs → local-store-impl-NJCWM3KR.cjs} +22 -22
  125. package/dist/{local-store-impl-CUQKHHOZ.cjs.map → local-store-impl-NJCWM3KR.cjs.map} +1 -1
  126. package/dist/{pglite-store-impl-BD3AVOUH.js → pglite-store-impl-3VFSYLAJ.js} +18 -18
  127. package/dist/{pglite-store-impl-BD3AVOUH.js.map → pglite-store-impl-3VFSYLAJ.js.map} +1 -1
  128. package/dist/{pglite-store-impl-C3MQ72LT.cjs → pglite-store-impl-LHLJ3GBQ.cjs} +22 -22
  129. package/dist/{pglite-store-impl-C3MQ72LT.cjs.map → pglite-store-impl-LHLJ3GBQ.cjs.map} +1 -1
  130. package/dist/profiler/index.d.cts +1 -1
  131. package/dist/profiler/index.d.ts +1 -1
  132. package/dist/provenance/index.cjs +21 -21
  133. package/dist/provenance/index.d.cts +1 -1
  134. package/dist/provenance/index.d.ts +1 -1
  135. package/dist/provenance/index.js +5 -5
  136. package/dist/schema/index.cjs +36 -36
  137. package/dist/schema/index.d.cts +3 -3
  138. package/dist/schema/index.d.ts +3 -3
  139. package/dist/schema/index.js +6 -6
  140. package/dist/{store-stw2AEB4.d.ts → store-CQ3uzXla.d.ts} +58 -27
  141. package/dist/{store-DTEkUQ0k.d.cts → store-DbHAgVMH.d.cts} +58 -27
  142. package/package.json +1 -1
  143. package/dist/chunk-74FNI3PT.js.map +0 -1
  144. package/dist/chunk-ECYEWFEH.cjs.map +0 -1
  145. package/dist/chunk-OJ47LMOB.cjs.map +0 -1
  146. package/dist/chunk-ORPT5EQW.cjs.map +0 -1
  147. package/dist/chunk-VU65FXEG.js.map +0 -1
  148. package/dist/chunk-YVKPUSHS.js.map +0 -1
@@ -1,22 +1,22 @@
1
1
  'use strict';
2
2
 
3
- var chunkOJ47LMOB_cjs = require('../chunk-OJ47LMOB.cjs');
4
- require('../chunk-WTW7RWAG.cjs');
5
- var chunk7I2PYI4U_cjs = require('../chunk-7I2PYI4U.cjs');
6
- require('../chunk-KZG7HQSN.cjs');
7
- var chunkORPT5EQW_cjs = require('../chunk-ORPT5EQW.cjs');
8
- require('../chunk-PGZV3E3I.cjs');
9
- require('../chunk-MTE255N3.cjs');
10
- require('../chunk-D5TCKAQT.cjs');
11
- var chunkHZCOCNIX_cjs = require('../chunk-HZCOCNIX.cjs');
3
+ var chunkWIUHN6SZ_cjs = require('../chunk-WIUHN6SZ.cjs');
4
+ require('../chunk-BYUIOM4L.cjs');
5
+ var chunkKR3N6Y7O_cjs = require('../chunk-KR3N6Y7O.cjs');
6
+ require('../chunk-UVMSWO6X.cjs');
7
+ var chunkUZ6CJUC5_cjs = require('../chunk-UZ6CJUC5.cjs');
8
+ require('../chunk-VXEHEPC4.cjs');
9
+ require('../chunk-36XLQHZA.cjs');
10
+ require('../chunk-DGIA64DM.cjs');
11
+ var chunkL2REUAJB_cjs = require('../chunk-L2REUAJB.cjs');
12
12
  require('../chunk-6YKISECL.cjs');
13
13
  var chunkOGZA7IS4_cjs = require('../chunk-OGZA7IS4.cjs');
14
- var chunkT7LSSV7J_cjs = require('../chunk-T7LSSV7J.cjs');
15
- var chunkTKFQLKH2_cjs = require('../chunk-TKFQLKH2.cjs');
14
+ var chunkXXEFDJHY_cjs = require('../chunk-XXEFDJHY.cjs');
15
+ var chunkCYKHSH5O_cjs = require('../chunk-CYKHSH5O.cjs');
16
16
  require('../chunk-6OWTUEUL.cjs');
17
17
  var chunk5X46XWNH_cjs = require('../chunk-5X46XWNH.cjs');
18
- require('../chunk-FYMYLZGX.cjs');
19
- var chunkECYEWFEH_cjs = require('../chunk-ECYEWFEH.cjs');
18
+ require('../chunk-ZXXGMQC3.cjs');
19
+ var chunkJ34FSPSC_cjs = require('../chunk-J34FSPSC.cjs');
20
20
  var chunkV32ES2Q2_cjs = require('../chunk-V32ES2Q2.cjs');
21
21
  var chunkOJHFXL7Y_cjs = require('../chunk-OJHFXL7Y.cjs');
22
22
  require('../chunk-F2HGOZJR.cjs');
@@ -129,7 +129,8 @@ var MERGE_ERROR_CODES = {
129
129
  planningStale: "GRAPH_MERGE_PLANNING_STALE",
130
130
  candidateSource: "GRAPH_MERGE_CANDIDATE_SOURCE",
131
131
  evidence: "GRAPH_MERGE_EVIDENCE",
132
- candidateWriteSet: "GRAPH_MERGE_CANDIDATE_WRITE_SET"
132
+ candidateWriteSet: "GRAPH_MERGE_CANDIDATE_WRITE_SET",
133
+ review: "GRAPH_MERGE_REVIEW"
133
134
  };
134
135
  function toTypeGraphErrorOptions(category, options) {
135
136
  return {
@@ -159,6 +160,14 @@ var InvalidMergeOptionsError = class extends MergeError {
159
160
  this.name = "InvalidMergeOptionsError";
160
161
  }
161
162
  };
163
+ var MergeReviewError = class extends MergeError {
164
+ static errorCategory = "user";
165
+ code = MERGE_ERROR_CODES.review;
166
+ constructor(message, options = {}) {
167
+ super(message, options);
168
+ this.name = "MergeReviewError";
169
+ }
170
+ };
162
171
  var BranchError = class extends chunkASKXTVK5_cjs.TypeGraphError {
163
172
  constructor(message, options = {}) {
164
173
  super(
@@ -735,7 +744,7 @@ function identityEndpointKey(assertion) {
735
744
  return chunkOJHFXL7Y_cjs.encodeTupleKey(endpointTuple(assertion));
736
745
  }
737
746
  function identitySemanticKey(assertion) {
738
- return chunkT7LSSV7J_cjs.identityAssertionSemanticKey(
747
+ return chunkXXEFDJHY_cjs.identityAssertionSemanticKey(
739
748
  assertion.relation,
740
749
  assertion.a,
741
750
  assertion.b
@@ -799,7 +808,7 @@ function assertNoOpposingIdentityRelations(assertions) {
799
808
  );
800
809
  for (const sameAssertion of same) {
801
810
  for (const differentAssertion of different) {
802
- if (!chunkT7LSSV7J_cjs.identityValidityWindowsOverlap(sameAssertion, differentAssertion)) {
811
+ if (!chunkXXEFDJHY_cjs.identityValidityWindowsOverlap(sameAssertion, differentAssertion)) {
803
812
  continue;
804
813
  }
805
814
  throw new IdentityMergeConflictError(
@@ -959,7 +968,7 @@ function remapIdentityAssertionEndpoints(assertions, canonicalOf, retypeMap, sto
959
968
  );
960
969
  continue;
961
970
  }
962
- const [a, b] = chunkT7LSSV7J_cjs.normalizeIdentityPair(remappedA, remappedB);
971
+ const [a, b] = chunkXXEFDJHY_cjs.normalizeIdentityPair(remappedA, remappedB);
963
972
  const endpointWindowA = endpointWindows.get(mergeKeyOf(a));
964
973
  const endpointWindowB = endpointWindows.get(mergeKeyOf(b));
965
974
  const validFrom = [
@@ -1114,7 +1123,7 @@ async function buildIdentityPeerProbe(target, probedIds, targetPeers, plan, prof
1114
1123
  (group) => group.map((member) => mergeKey(member.kind, member.id))
1115
1124
  )
1116
1125
  ]);
1117
- const ledger = (await relevantLedgerAssertions(target, memberKeys, chunkORPT5EQW_cjs.storeBackend(target))).filter(
1126
+ const ledger = (await relevantLedgerAssertions(target, memberKeys, chunkUZ6CJUC5_cjs.storeBackend(target))).filter(
1118
1127
  (assertion) => !plannedDeletions.has(mergeKey(assertion.a.kind, assertion.a.id)) && !plannedDeletions.has(mergeKey(assertion.b.kind, assertion.b.id))
1119
1128
  );
1120
1129
  return {
@@ -1135,7 +1144,7 @@ async function buildIdentityPeerProbe(target, probedIds, targetPeers, plan, prof
1135
1144
  };
1136
1145
  }
1137
1146
  async function snapshotIdentityClasses(target, seeds, liveKeys, plannedDeletions, txBackend) {
1138
- const classes = await chunkORPT5EQW_cjs.storeRuntime(target).structuralIdentityClasses(
1147
+ const classes = await chunkUZ6CJUC5_cjs.storeRuntime(target).structuralIdentityClasses(
1139
1148
  seeds,
1140
1149
  txBackend
1141
1150
  );
@@ -1143,7 +1152,7 @@ async function snapshotIdentityClasses(target, seeds, liveKeys, plannedDeletions
1143
1152
  const groups = [];
1144
1153
  for (const seed of seeds) {
1145
1154
  const key = mergeKey(seed.kind, seed.id);
1146
- const members = (classes.get(chunkT7LSSV7J_cjs.identityReferenceKey(seed)) ?? [seed]).filter(
1155
+ const members = (classes.get(chunkXXEFDJHY_cjs.identityReferenceKey(seed)) ?? [seed]).filter(
1147
1156
  (member) => !plannedDeletions.has(mergeKey(member.kind, member.id))
1148
1157
  );
1149
1158
  groups.push(members);
@@ -1152,7 +1161,7 @@ async function snapshotIdentityClasses(target, seeds, liveKeys, plannedDeletions
1152
1161
  return { fingerprints, groups };
1153
1162
  }
1154
1163
  async function relevantLedgerAssertions(target, memberKeys, backend) {
1155
- const current = await chunkORPT5EQW_cjs.storeRuntime(target).identityAssertionsAtTarget(
1164
+ const current = await chunkUZ6CJUC5_cjs.storeRuntime(target).identityAssertionsAtTarget(
1156
1165
  backend,
1157
1166
  "state"
1158
1167
  );
@@ -1225,7 +1234,7 @@ async function assertPlannedIdentityIdsFresh(target, txBackend, plan) {
1225
1234
  ...plan.identityRetractions.map((retraction) => retraction.id)
1226
1235
  ];
1227
1236
  if (plannedIds.length === 0) return;
1228
- const storedById = await chunkORPT5EQW_cjs.storeRuntime(target).identityAssertionRowsByIds(
1237
+ const storedById = await chunkUZ6CJUC5_cjs.storeRuntime(target).identityAssertionRowsByIds(
1229
1238
  plannedIds,
1230
1239
  txBackend
1231
1240
  );
@@ -1278,7 +1287,7 @@ function affectedIdentityClassSeeds(plan, profile) {
1278
1287
  return [...seedsByKey.values()];
1279
1288
  }
1280
1289
  async function assertMergedIdentityClassesConsistent(target, txBackend, plan) {
1281
- await chunkORPT5EQW_cjs.storeRuntime(target).assertIdentityClassesConsistentAtTarget(
1290
+ await chunkUZ6CJUC5_cjs.storeRuntime(target).assertIdentityClassesConsistentAtTarget(
1282
1291
  txBackend,
1283
1292
  affectedIdentityClassSeeds(plan, target.graph.identity?.sameIdAcrossKinds)
1284
1293
  );
@@ -1332,7 +1341,7 @@ function translateIdentityCommitError(error) {
1332
1341
  }
1333
1342
  async function assertIdentityPeersStable(target, txBackend, probe, plan) {
1334
1343
  if (probe === void 0) return;
1335
- const live = (await chunkORPT5EQW_cjs.storeRuntime(target).liveNodesSharingIds(probe.ids, txBackend)).filter((peer) => !probe.plannedDeletions.has(mergeKey(peer.kind, peer.id)));
1344
+ const live = (await chunkUZ6CJUC5_cjs.storeRuntime(target).liveNodesSharingIds(probe.ids, txBackend)).filter((peer) => !probe.plannedDeletions.has(mergeKey(peer.kind, peer.id)));
1336
1345
  const seedKindsById = /* @__PURE__ */ new Map();
1337
1346
  for (const seed of probe.seeds) {
1338
1347
  const kinds = seedKindsById.get(seed.id) ?? /* @__PURE__ */ new Set();
@@ -1632,8 +1641,8 @@ async function diffAgainstBase(baseStore, forkStore, captureForkState = true) {
1632
1641
  const nodeKinds = chunkV32ES2Q2_cjs.getNodeKinds(graph);
1633
1642
  const edgeKinds = chunkV32ES2Q2_cjs.getEdgeKinds(graph);
1634
1643
  const [baseIdentity, forkIdentity] = await Promise.all([
1635
- chunkORPT5EQW_cjs.storeRuntime(baseStore).readCurrentIdentityAssertions("archival"),
1636
- chunkORPT5EQW_cjs.storeRuntime(forkStore).readCurrentIdentityAssertions("archival")
1644
+ chunkUZ6CJUC5_cjs.storeRuntime(baseStore).readCurrentIdentityAssertions("archival"),
1645
+ chunkUZ6CJUC5_cjs.storeRuntime(forkStore).readCurrentIdentityAssertions("archival")
1637
1646
  ]);
1638
1647
  const baseIdentityById = new Map(
1639
1648
  baseIdentity.map((assertion) => [assertion.id, assertion])
@@ -1648,12 +1657,12 @@ async function diffAgainstBase(baseStore, forkStore, captureForkState = true) {
1648
1657
  const forkNodeVersions = /* @__PURE__ */ new Map();
1649
1658
  for (const kind of nodeKinds) {
1650
1659
  const baseRows = await enumerateAllNodes(
1651
- chunkORPT5EQW_cjs.storeBackend(baseStore),
1660
+ chunkUZ6CJUC5_cjs.storeBackend(baseStore),
1652
1661
  baseStore.graphId,
1653
1662
  kind
1654
1663
  );
1655
1664
  const forkRows = await enumerateAllNodes(
1656
- chunkORPT5EQW_cjs.storeBackend(forkStore),
1665
+ chunkUZ6CJUC5_cjs.storeBackend(forkStore),
1657
1666
  forkStore.graphId,
1658
1667
  kind
1659
1668
  );
@@ -1683,12 +1692,12 @@ async function diffAgainstBase(baseStore, forkStore, captureForkState = true) {
1683
1692
  const forkEdgeSignatures = /* @__PURE__ */ new Map();
1684
1693
  for (const kind of edgeKinds) {
1685
1694
  const baseRows = await enumerateAllEdges(
1686
- chunkORPT5EQW_cjs.storeBackend(baseStore),
1695
+ chunkUZ6CJUC5_cjs.storeBackend(baseStore),
1687
1696
  baseStore.graphId,
1688
1697
  kind
1689
1698
  );
1690
1699
  const forkRows = await enumerateAllEdges(
1691
- chunkORPT5EQW_cjs.storeBackend(forkStore),
1700
+ chunkUZ6CJUC5_cjs.storeBackend(forkStore),
1692
1701
  forkStore.graphId,
1693
1702
  kind
1694
1703
  );
@@ -1785,10 +1794,10 @@ async function readActiveSchemaVersion(backend, graphId) {
1785
1794
  }
1786
1795
  async function computeSchemaComponent(store) {
1787
1796
  const version = await readActiveSchemaVersion(
1788
- chunkORPT5EQW_cjs.storeBackend(store),
1797
+ chunkUZ6CJUC5_cjs.storeBackend(store),
1789
1798
  store.graphId
1790
1799
  );
1791
- return chunkHZCOCNIX_cjs.computeSchemaHash(chunkHZCOCNIX_cjs.serializeSchema(store.graph, version));
1800
+ return chunkL2REUAJB_cjs.computeSchemaHash(chunkL2REUAJB_cjs.serializeSchema(store.graph, version));
1792
1801
  }
1793
1802
  function byDigestEntry(left, right) {
1794
1803
  const byKind = chunkNYWU6CBZ_cjs.compareStrings(left.kind, right.kind);
@@ -1847,7 +1856,7 @@ async function computeBaseVersion(store) {
1847
1856
  computeSchemaComponent(store),
1848
1857
  store.revisionOriginNow(),
1849
1858
  store.revisionNow(),
1850
- readActiveSchemaVersion(chunkORPT5EQW_cjs.storeBackend(store), store.graphId)
1859
+ readActiveSchemaVersion(chunkUZ6CJUC5_cjs.storeBackend(store), store.graphId)
1851
1860
  ]);
1852
1861
  return asBaseVersion(
1853
1862
  `${schemaComponent2}${SCHEMA_VERSION_TAG}${activeVersion}${TOKEN_SEPARATOR}${revisionComponent(origin, revision)}`
@@ -1862,9 +1871,9 @@ async function computeBaseVersion(store) {
1862
1871
  );
1863
1872
  }
1864
1873
  async function computeStoreContentComponent(store) {
1865
- const identityAssertions = await chunkORPT5EQW_cjs.storeRuntime(store).readCurrentIdentityAssertions("state");
1874
+ const identityAssertions = await chunkUZ6CJUC5_cjs.storeRuntime(store).readCurrentIdentityAssertions("state");
1866
1875
  return computeContentComponent(
1867
- chunkORPT5EQW_cjs.storeBackend(store),
1876
+ chunkUZ6CJUC5_cjs.storeBackend(store),
1868
1877
  store.graphId,
1869
1878
  store.graph,
1870
1879
  identityAssertions
@@ -1918,7 +1927,7 @@ function cloneWorkingCopyWithGraphStrategy(makeBackend, graphForClone) {
1918
1927
  create: async (baseStore) => {
1919
1928
  const backend = await makeBackend();
1920
1929
  try {
1921
- const [freshStore] = await chunkOJ47LMOB_cjs.createStoreWithSchema(
1930
+ const [freshStore] = await chunkWIUHN6SZ_cjs.createStoreWithSchema(
1922
1931
  graphForClone(baseStore),
1923
1932
  backend,
1924
1933
  {
@@ -1939,16 +1948,16 @@ function cloneWorkingCopyWithGraphStrategy(makeBackend, graphForClone) {
1939
1948
  validateReferences: true,
1940
1949
  batchSize: CLONE_IMPORT_BATCH_SIZE
1941
1950
  };
1942
- const result = chunkECYEWFEH_cjs.snapshotExportContention(
1943
- chunkORPT5EQW_cjs.storeBackend(baseStore),
1944
- chunkORPT5EQW_cjs.storeBackend(freshStore)
1945
- ) === void 0 ? await chunk7I2PYI4U_cjs.importGraphStream(
1951
+ const result = chunkJ34FSPSC_cjs.snapshotExportContention(
1952
+ chunkUZ6CJUC5_cjs.storeBackend(baseStore),
1953
+ chunkUZ6CJUC5_cjs.storeBackend(freshStore)
1954
+ ) === void 0 ? await chunkKR3N6Y7O_cjs.importGraphStream(
1946
1955
  freshStore,
1947
- chunk7I2PYI4U_cjs.exportGraphStream(baseStore, exportOptions),
1956
+ chunkKR3N6Y7O_cjs.exportGraphStream(baseStore, exportOptions),
1948
1957
  importOptions
1949
- ) : await chunk7I2PYI4U_cjs.importGraph(
1958
+ ) : await chunkKR3N6Y7O_cjs.importGraph(
1950
1959
  freshStore,
1951
- await chunk7I2PYI4U_cjs.exportGraph(baseStore, exportOptions),
1960
+ await chunkKR3N6Y7O_cjs.exportGraph(baseStore, exportOptions),
1952
1961
  importOptions
1953
1962
  );
1954
1963
  if (!result.success) {
@@ -1997,7 +2006,7 @@ function graphWithoutNodeUniqueness(graph) {
1997
2006
  async function branch(baseStore, makeBackend, options, strategy) {
1998
2007
  try {
1999
2008
  const base = await computeBaseVersion(baseStore);
2000
- const id = options?.id ?? asBranchId(chunkTKFQLKH2_cjs.generateId());
2009
+ const id = options?.id ?? asBranchId(chunkCYKHSH5O_cjs.generateId());
2001
2010
  const workingCopyStrategy = strategy ?? cloneWorkingCopyStrategy(makeBackend);
2002
2011
  const store = await workingCopyStrategy.create(baseStore);
2003
2012
  const schemaAnchor = await captureBranchSchemaAnchor(store);
@@ -2017,11 +2026,11 @@ async function branch(baseStore, makeBackend, options, strategy) {
2017
2026
  }
2018
2027
  async function captureBranchSchemaAnchor(store) {
2019
2028
  try {
2020
- const schemaRow = await chunkORPT5EQW_cjs.storeBackend(store).getActiveSchema(store.graphId);
2029
+ const schemaRow = await chunkUZ6CJUC5_cjs.storeBackend(store).getActiveSchema(store.graphId);
2021
2030
  return schemaRow === void 0 ? void 0 : { version: schemaRow.version, hash: schemaRow.schema_hash };
2022
2031
  } catch (error) {
2023
2032
  try {
2024
- await chunkORPT5EQW_cjs.storeBackend(store).close();
2033
+ await chunkUZ6CJUC5_cjs.storeBackend(store).close();
2025
2034
  } catch {
2026
2035
  }
2027
2036
  throw error;
@@ -2074,10 +2083,10 @@ async function ingestionBranch(baseStore, makeBackend, options) {
2074
2083
  nodes: store.nodes,
2075
2084
  edges: store.edges,
2076
2085
  ...identityAccess,
2077
- close: async () => chunkORPT5EQW_cjs.storeBackend(store).close()
2086
+ close: async () => chunkUZ6CJUC5_cjs.storeBackend(store).close()
2078
2087
  });
2079
2088
  PRIVATE_BRANCHES.set(handle, privateBranch);
2080
- chunk7I2PYI4U_cjs.registerIngestionImportTarget(handle, store);
2089
+ chunkKR3N6Y7O_cjs.registerIngestionImportTarget(handle, store);
2081
2090
  return chunkNXJRIRWE_cjs.ok(handle);
2082
2091
  } catch (error) {
2083
2092
  return chunkNXJRIRWE_cjs.err(
@@ -2098,6 +2107,45 @@ function unwrapMergeBranches(inputs) {
2098
2107
  return inputs.map((input) => unwrapMergeBranch(input));
2099
2108
  }
2100
2109
 
2110
+ // src/graph-merge/apply-callbacks.ts
2111
+ var NODE_READ_NAMES = [
2112
+ ...chunkWIUHN6SZ_cjs.NODE_TEMPORAL_READ_NAMES,
2113
+ ...chunkWIUHN6SZ_cjs.CURRENT_ONLY_READ_NAMES
2114
+ ];
2115
+ function pickReadMethods(source, names) {
2116
+ return Object.fromEntries(names.map((name) => [name, source[name]]));
2117
+ }
2118
+ function mergePlanReadContext(tx, graph) {
2119
+ return {
2120
+ nodes: Object.fromEntries(
2121
+ Object.keys(graph.nodes).map((kind) => [
2122
+ kind,
2123
+ pickReadMethods(chunkBXHAPCQG_cjs.requireDefined(tx.nodes[kind]), NODE_READ_NAMES)
2124
+ ])
2125
+ ),
2126
+ edges: Object.fromEntries(
2127
+ Object.keys(graph.edges).map((kind) => [
2128
+ kind,
2129
+ pickReadMethods(
2130
+ chunkBXHAPCQG_cjs.requireDefined(tx.edges[kind]),
2131
+ chunkWIUHN6SZ_cjs.EDGE_TEMPORAL_READ_NAMES
2132
+ )
2133
+ ])
2134
+ ),
2135
+ ..."identity" in tx ? {
2136
+ identity: pickReadMethods(tx.identity, chunkWIUHN6SZ_cjs.IDENTITY_READ_NAMES)
2137
+ } : {}
2138
+ };
2139
+ }
2140
+ function assertMergeCallbackResult(result, callback) {
2141
+ if (result !== void 0) {
2142
+ throw new InvalidMergeOptionsError(
2143
+ `${callback} must resolve without a return value; throw or reject to abort merge application.`,
2144
+ { cause: result, details: { callback } }
2145
+ );
2146
+ }
2147
+ }
2148
+
2101
2149
  // src/graph-merge/blocking.ts
2102
2150
  var UNBLOCKED_BUCKET_KEY = "unblocked";
2103
2151
  var KEY_PART_SEPARATOR = "\0";
@@ -4903,7 +4951,7 @@ function buildProvenanceGraph(targetGraphId) {
4903
4951
  });
4904
4952
  }
4905
4953
  async function openProvenanceStore(...args) {
4906
- const [backend, targetGraphId] = args.length === 1 ? [chunkORPT5EQW_cjs.storeBackend(args[0]), args[0].graphId] : args;
4954
+ const [backend, targetGraphId] = args.length === 1 ? [chunkUZ6CJUC5_cjs.storeBackend(args[0]), args[0].graphId] : args;
4907
4955
  const graph = buildOwnedProvenanceGraph(targetGraphId);
4908
4956
  const preflight = await inspectSidecarGraphId(backend, graph, targetGraphId);
4909
4957
  if (preflight.state === "refuse") {
@@ -4915,7 +4963,7 @@ async function openProvenanceStore(...args) {
4915
4963
  throw provenanceGraphIdCollision(graph.id, targetGraphId, claim.reason);
4916
4964
  }
4917
4965
  }
4918
- const [store] = await chunkOJ47LMOB_cjs.createStoreWithSchema(graph, backend);
4966
+ const [store] = await chunkWIUHN6SZ_cjs.createStoreWithSchema(graph, backend);
4919
4967
  return store;
4920
4968
  }
4921
4969
  async function claimSidecarOwnership(backend, graph, targetGraphId) {
@@ -4941,15 +4989,15 @@ async function claimSidecarOwnership(backend, graph, targetGraphId) {
4941
4989
  });
4942
4990
  }
4943
4991
  async function drainUnfencedRowWriters(tx) {
4944
- const plan = chunkECYEWFEH_cjs.resolveWriteFencePlan(tx);
4945
- const fence = chunkECYEWFEH_cjs.requireWriteFence(
4992
+ const plan = chunkJ34FSPSC_cjs.resolveWriteFencePlan(tx);
4993
+ const fence = chunkJ34FSPSC_cjs.requireWriteFence(
4946
4994
  plan,
4947
4995
  "graph-merge provenance fence",
4948
4996
  "table-lock"
4949
4997
  );
4950
4998
  switch (fence.kind) {
4951
4999
  case "lock": {
4952
- const schema = chunkECYEWFEH_cjs.createSqlSchema(tx.tableNames);
5000
+ const schema = chunkJ34FSPSC_cjs.createSqlSchema(tx.tableNames);
4953
5001
  await tx.executeStatement(
4954
5002
  chunkAYQBEVQY_cjs.asCompiledStatementSql(
4955
5003
  chunkAYQBEVQY_cjs.sql`LOCK TABLE ${schema.nodesTable}, ${schema.edgesTable} IN SHARE ROW EXCLUSIVE MODE`
@@ -4977,14 +5025,14 @@ async function inspectSidecarGraphId(port, graph, targetGraphId) {
4977
5025
  if (activeSchema === void 0) {
4978
5026
  return { state: "refuse", reason: "application-graph" };
4979
5027
  }
4980
- const ownedHash = await chunkHZCOCNIX_cjs.computeSchemaHash(
4981
- chunkHZCOCNIX_cjs.serializeSchema(graph, activeSchema.version)
5028
+ const ownedHash = await chunkL2REUAJB_cjs.computeSchemaHash(
5029
+ chunkL2REUAJB_cjs.serializeSchema(graph, activeSchema.version)
4982
5030
  );
4983
5031
  if (activeSchema.schema_hash === ownedHash) {
4984
5032
  return { state: "refuse", reason: "unowned-exact-schema-graph" };
4985
5033
  }
4986
- const legacyHash = await chunkHZCOCNIX_cjs.computeSchemaHash(
4987
- chunkHZCOCNIX_cjs.serializeSchema(buildProvenanceGraph(targetGraphId), activeSchema.version)
5034
+ const legacyHash = await chunkL2REUAJB_cjs.computeSchemaHash(
5035
+ chunkL2REUAJB_cjs.serializeSchema(buildProvenanceGraph(targetGraphId), activeSchema.version)
4988
5036
  );
4989
5037
  if (activeSchema.schema_hash !== legacyHash) {
4990
5038
  return { state: "refuse", reason: "application-graph" };
@@ -5088,7 +5136,7 @@ async function* readRowsOfKind(port, graphId, kind) {
5088
5136
  }
5089
5137
  }
5090
5138
  async function hasRowsUnderGraphId(port, graphId, scope) {
5091
- const schema = chunkECYEWFEH_cjs.createSqlSchema(port.tableNames);
5139
+ const schema = chunkJ34FSPSC_cjs.createSqlSchema(port.tableNames);
5092
5140
  const kindFilter = scope === "any" ? chunkAYQBEVQY_cjs.sql.empty() : chunkAYQBEVQY_cjs.sql` AND kind <> ${PROVENANCE_KIND}`;
5093
5141
  if (await hasRowsInTable(port, schema.tables.nodes, graphId, kindFilter)) {
5094
5142
  return true;
@@ -5685,7 +5733,7 @@ async function stageBranches(baseStore, branches, captureTargetStateFor) {
5685
5733
  const windowedEdges = [];
5686
5734
  const newIdentityAssertions = [];
5687
5735
  const retractedIdentityAssertions = [];
5688
- const baseIdentityAssertions = await chunkORPT5EQW_cjs.storeRuntime(baseStore).readCurrentIdentityAssertions("state");
5736
+ const baseIdentityAssertions = await chunkUZ6CJUC5_cjs.storeRuntime(baseStore).readCurrentIdentityAssertions("state");
5689
5737
  let targetNodeVersions = /* @__PURE__ */ new Map();
5690
5738
  let targetEdgeSignatures = /* @__PURE__ */ new Map();
5691
5739
  for (const branch2 of branches) {
@@ -5885,7 +5933,7 @@ function reconcileTypes(clusters, closure, mode) {
5885
5933
  // src/graph-merge/write-fence.ts
5886
5934
  async function lockMergeTargetWrite(txBackend, input) {
5887
5935
  try {
5888
- await chunkTKFQLKH2_cjs.lockSchemaVersionForStoreWrite(
5936
+ await chunkCYKHSH5O_cjs.lockSchemaVersionForStoreWrite(
5889
5937
  { graphId: input.graphId, schemaVersion: input.schemaVersion },
5890
5938
  txBackend
5891
5939
  );
@@ -5896,7 +5944,20 @@ async function lockMergeTargetWrite(txBackend, input) {
5896
5944
  throw input.staleSchemaError(error);
5897
5945
  }
5898
5946
  if (input.graphLock === "required") {
5899
- await chunkTKFQLKH2_cjs.lockRecordedGraphWrite(txBackend, input.graphId);
5947
+ const lock = await chunkCYKHSH5O_cjs.lockRecordedGraphWrite(txBackend, input.graphId);
5948
+ if (input.requireFreshSnapshot && lock.coordination !== void 0) {
5949
+ const isolation = chunkJ34FSPSC_cjs.graphCommandCoordinationIsolation(
5950
+ txBackend.commands,
5951
+ input.graphId,
5952
+ lock.coordination
5953
+ );
5954
+ if (isolation !== "read_committed") {
5955
+ throw new MergePlanCapabilityError(
5956
+ "Merge callbacks require read-committed isolation so their reads observe the target after acquiring its graph lock.",
5957
+ { details: { capability: "mergeCallbackIsolation", isolation } }
5958
+ );
5959
+ }
5960
+ }
5900
5961
  }
5901
5962
  }
5902
5963
 
@@ -6846,7 +6907,7 @@ async function applyNodeRows(target, txBackend, nodesApi, deletions, upserts) {
6846
6907
  afterImages.set(mergeKey(kind, item.id), props);
6847
6908
  }
6848
6909
  }
6849
- return chunkORPT5EQW_cjs.storeRuntime(target).applyResolvedNodeUniqueness(
6910
+ return chunkUZ6CJUC5_cjs.storeRuntime(target).applyResolvedNodeUniqueness(
6850
6911
  txBackend,
6851
6912
  {
6852
6913
  upserts: upserts.map((upsert) => ({
@@ -6894,7 +6955,7 @@ async function applyEdgeRows(edgesApi, deletions, upserts) {
6894
6955
  }
6895
6956
  async function applyIdentityRows(target, txBackend, assertions, retractions, assertConsistent) {
6896
6957
  try {
6897
- const applied = await chunkORPT5EQW_cjs.storeRuntime(target).applyIdentityMergeAtTarget(
6958
+ const applied = await chunkUZ6CJUC5_cjs.storeRuntime(target).applyIdentityMergeAtTarget(
6898
6959
  txBackend,
6899
6960
  retractions,
6900
6961
  assertions
@@ -6992,7 +7053,7 @@ async function applyInternalMergePlan(plan, nodesApi, edgesApi, target, txBacken
6992
7053
  };
6993
7054
  }
6994
7055
  async function commitPlan(target, plan, expectedBaseVersion) {
6995
- if (!chunkORPT5EQW_cjs.storeBackend(target).capabilities.execution.interactiveTransactions) {
7056
+ if (!chunkUZ6CJUC5_cjs.storeBackend(target).capabilities.execution.interactiveTransactions) {
6996
7057
  throw new MergeError(
6997
7058
  "merge() requires a transaction-capable target backend. The merged plan (canonical upserts, soft-deletes, edge upserts) must commit atomically; a non-transactional fallback would leave a partially-merged graph on a mid-commit failure. (mergeIncremental() enforces the same requirement.)",
6998
7059
  { details: { capability: "execution.interactiveTransactions" } }
@@ -7003,14 +7064,14 @@ async function commitPlan(target, plan, expectedBaseVersion) {
7003
7064
  () => target.transaction(async (tx) => {
7004
7065
  if (expectedBaseVersion !== void 0) {
7005
7066
  await assertTargetUnchanged(
7006
- chunkORPT5EQW_cjs.transactionBackend(tx),
7067
+ chunkUZ6CJUC5_cjs.transactionBackend(tx),
7007
7068
  target,
7008
7069
  expectedBaseVersion
7009
7070
  );
7010
7071
  }
7011
7072
  await assertPlannedIdentityIdsFresh(
7012
7073
  target,
7013
- chunkORPT5EQW_cjs.transactionBackend(tx),
7074
+ chunkUZ6CJUC5_cjs.transactionBackend(tx),
7014
7075
  plan
7015
7076
  );
7016
7077
  return applyInternalMergePlan(
@@ -7018,7 +7079,7 @@ async function commitPlan(target, plan, expectedBaseVersion) {
7018
7079
  tx.nodes,
7019
7080
  tx.edges,
7020
7081
  target,
7021
- chunkORPT5EQW_cjs.transactionBackend(tx)
7082
+ chunkUZ6CJUC5_cjs.transactionBackend(tx)
7022
7083
  );
7023
7084
  }, mergeCommitTransactionOptions(target))
7024
7085
  )
@@ -7049,7 +7110,7 @@ async function assertTargetUnchanged(txBackend, target, expectedBaseVersion) {
7049
7110
  )
7050
7111
  });
7051
7112
  const expectedOrigin = revisionOriginOf(expectedBaseVersion);
7052
- const liveOrigin = await chunkTKFQLKH2_cjs.readRevisionOrigin(
7113
+ const liveOrigin = await chunkCYKHSH5O_cjs.readRevisionOrigin(
7053
7114
  txBackend,
7054
7115
  target.revisionSchema,
7055
7116
  target.graphId
@@ -7063,7 +7124,7 @@ async function assertTargetUnchanged(txBackend, target, expectedBaseVersion) {
7063
7124
  }
7064
7125
  );
7065
7126
  }
7066
- const liveRevision = await chunkTKFQLKH2_cjs.readRecordedClock(
7127
+ const liveRevision = await chunkCYKHSH5O_cjs.readRecordedClock(
7067
7128
  txBackend,
7068
7129
  target.revisionSchema,
7069
7130
  target.graphId
@@ -7084,7 +7145,7 @@ async function assertTargetUnchanged(txBackend, target, expectedBaseVersion) {
7084
7145
  txBackend,
7085
7146
  target.graphId,
7086
7147
  target.graph,
7087
- await chunkORPT5EQW_cjs.storeRuntime(target).identityAssertionsAtTarget(txBackend, "state")
7148
+ await chunkUZ6CJUC5_cjs.storeRuntime(target).identityAssertionsAtTarget(txBackend, "state")
7088
7149
  );
7089
7150
  const expectedContent = contentComponentOf(expectedBaseVersion);
7090
7151
  if (liveContent !== expectedContent) {
@@ -7176,7 +7237,7 @@ async function tryOpenProvenanceStore(target) {
7176
7237
  }
7177
7238
  }
7178
7239
  function assertPublicPlanCapability(target) {
7179
- if (!chunkORPT5EQW_cjs.storeBackend(target).capabilities.execution.interactiveTransactions) {
7240
+ if (!chunkUZ6CJUC5_cjs.storeBackend(target).capabilities.execution.interactiveTransactions) {
7180
7241
  throw new MergePlanCapabilityError(
7181
7242
  "Public merge plans require a transaction-capable target backend.",
7182
7243
  { details: { capability: "execution.interactiveTransactions" } }
@@ -7195,7 +7256,7 @@ function assertPublicPlanCapability(target) {
7195
7256
  async function captureMergePlanTargetFence(target) {
7196
7257
  assertPublicPlanCapability(target);
7197
7258
  const [activeSchema, schemaHash, origin, revision] = await Promise.all([
7198
- chunkORPT5EQW_cjs.storeBackend(target).getActiveSchema(target.graphId),
7259
+ chunkUZ6CJUC5_cjs.storeBackend(target).getActiveSchema(target.graphId),
7199
7260
  computeSchemaComponent(target),
7200
7261
  target.revisionOriginNow(),
7201
7262
  target.revisionNow()
@@ -7361,7 +7422,7 @@ async function resolveMerge(store, target, branches, options, useBaseSources, in
7361
7422
  }
7362
7423
  }
7363
7424
  for (const branch2 of branches) {
7364
- const branchSchemaRow = await chunkORPT5EQW_cjs.storeBackend(branch2.store).getActiveSchema(
7425
+ const branchSchemaRow = await chunkUZ6CJUC5_cjs.storeBackend(branch2.store).getActiveSchema(
7365
7426
  branch2.store.graphId
7366
7427
  );
7367
7428
  let drifted;
@@ -7369,7 +7430,7 @@ async function resolveMerge(store, target, branches, options, useBaseSources, in
7369
7430
  const anchor = branch2.schemaAnchor;
7370
7431
  drifted = anchor === void 0 ? branchSchemaRow !== void 0 : branchSchemaRow?.version !== anchor.version || branchSchemaRow.schema_hash !== anchor.hash;
7371
7432
  } else {
7372
- const sourceSchemaRow = await chunkORPT5EQW_cjs.storeBackend(store).getActiveSchema(
7433
+ const sourceSchemaRow = await chunkUZ6CJUC5_cjs.storeBackend(store).getActiveSchema(
7373
7434
  store.graphId
7374
7435
  );
7375
7436
  drifted = branchSchemaRow?.schema_hash !== sourceSchemaRow?.schema_hash;
@@ -7414,7 +7475,7 @@ async function resolveMerge(store, target, branches, options, useBaseSources, in
7414
7475
  options.embedder
7415
7476
  );
7416
7477
  const ctx = {
7417
- backend: chunkORPT5EQW_cjs.storeBackend(store),
7478
+ backend: chunkUZ6CJUC5_cjs.storeBackend(store),
7418
7479
  ...embeddings === void 0 ? {} : { embeddings }
7419
7480
  };
7420
7481
  const candidates = await generateAllCandidates(
@@ -7442,7 +7503,7 @@ async function resolveMerge(store, target, branches, options, useBaseSources, in
7442
7503
  ])
7443
7504
  ])
7444
7505
  ];
7445
- const targetPeers = identityProbeIds === void 0 ? [] : await chunkORPT5EQW_cjs.storeRuntime(target).liveNodesSharingIds(identityProbeIds);
7506
+ const targetPeers = identityProbeIds === void 0 ? [] : await chunkUZ6CJUC5_cjs.storeRuntime(target).liveNodesSharingIds(identityProbeIds);
7446
7507
  const stagedIdentityIds = [
7447
7508
  .../* @__PURE__ */ new Set([
7448
7509
  ...staging.newIdentityAssertions.map((staged) => staged.assertion.id),
@@ -7451,7 +7512,7 @@ async function resolveMerge(store, target, branches, options, useBaseSources, in
7451
7512
  )
7452
7513
  ])
7453
7514
  ];
7454
- const storedIdentityRowsById = stagedIdentityIds.length === 0 || target.graph.identity === void 0 ? NO_STORED_ASSERTIONS : await chunkORPT5EQW_cjs.storeRuntime(target).identityAssertionRowsByIds(
7515
+ const storedIdentityRowsById = stagedIdentityIds.length === 0 || target.graph.identity === void 0 ? NO_STORED_ASSERTIONS : await chunkUZ6CJUC5_cjs.storeRuntime(target).identityAssertionRowsByIds(
7455
7516
  stagedIdentityIds
7456
7517
  );
7457
7518
  const identityContext = {
@@ -7476,14 +7537,14 @@ async function resolveMerge(store, target, branches, options, useBaseSources, in
7476
7537
  if (plan.identityAssertions.length > 0) {
7477
7538
  assertOneIdOneTruth(
7478
7539
  plan.identityAssertions,
7479
- await chunkORPT5EQW_cjs.storeRuntime(target).identityAssertionRowsByIds(
7540
+ await chunkUZ6CJUC5_cjs.storeRuntime(target).identityAssertionRowsByIds(
7480
7541
  plan.identityAssertions.map((assertion) => assertion.id)
7481
7542
  )
7482
7543
  );
7483
7544
  }
7484
7545
  let identityGuard;
7485
7546
  if (identityProbeIds !== void 0 && incremental !== void 0) {
7486
- const freshPeers = await chunkORPT5EQW_cjs.storeRuntime(target).liveNodesSharingIds(identityProbeIds);
7547
+ const freshPeers = await chunkUZ6CJUC5_cjs.storeRuntime(target).liveNodesSharingIds(identityProbeIds);
7487
7548
  const built = await buildIdentityPeerProbe(
7488
7549
  target,
7489
7550
  identityProbeIds,
@@ -7681,7 +7742,7 @@ async function planMergeIncremental(args) {
7681
7742
  computeSchemaComponent(target)
7682
7743
  ]);
7683
7744
  if (forkSchema !== targetSchema) return chunkNXJRIRWE_cjs.err(incrementalSchemaError());
7684
- const forkActiveSchema = await chunkORPT5EQW_cjs.storeBackend(forkPoint).getActiveSchema(
7745
+ const forkActiveSchema = await chunkUZ6CJUC5_cjs.storeBackend(forkPoint).getActiveSchema(
7685
7746
  forkPoint.graphId
7686
7747
  );
7687
7748
  const targetBranch = {
@@ -8024,11 +8085,12 @@ async function preflightWireMergeWrites(target, nodesApi, edgesApi, artifact) {
8024
8085
  }
8025
8086
  }
8026
8087
  }
8027
- async function assertMergePlanFenceInsideTransaction(target, txBackend, artifact) {
8088
+ async function assertMergePlanFenceInsideTransaction(target, txBackend, artifact, requireFreshSnapshot) {
8028
8089
  await lockMergeTargetWrite(txBackend, {
8029
8090
  graphId: target.graphId,
8030
8091
  schemaVersion: artifact.target.schema.managed ? artifact.target.schema.version : void 0,
8031
8092
  graphLock: "required",
8093
+ requireFreshSnapshot,
8032
8094
  staleSchemaError: (cause) => new MergePlanSchemaMismatchError(
8033
8095
  "The target's active schema no longer matches the merge plan.",
8034
8096
  { cause, details: { expected: artifact.target.schema } }
@@ -8046,7 +8108,7 @@ async function assertMergePlanFenceInsideTransaction(target, txBackend, artifact
8046
8108
  { details: { expected: artifact.target.schema, live: liveSchema } }
8047
8109
  );
8048
8110
  }
8049
- const liveOrigin = await chunkTKFQLKH2_cjs.readRevisionOrigin(
8111
+ const liveOrigin = await chunkCYKHSH5O_cjs.readRevisionOrigin(
8050
8112
  txBackend,
8051
8113
  target.revisionSchema,
8052
8114
  target.graphId
@@ -8062,7 +8124,7 @@ async function assertMergePlanFenceInsideTransaction(target, txBackend, artifact
8062
8124
  }
8063
8125
  );
8064
8126
  }
8065
- const liveRevision = await chunkTKFQLKH2_cjs.readRecordedClock(
8127
+ const liveRevision = await chunkCYKHSH5O_cjs.readRecordedClock(
8066
8128
  txBackend,
8067
8129
  target.revisionSchema,
8068
8130
  target.graphId
@@ -8138,7 +8200,7 @@ async function applyWireMergeWrites(target, nodesApi, edgesApi, txBackend, artif
8138
8200
  txBackend,
8139
8201
  identityAssertions,
8140
8202
  identityRetractions,
8141
- () => chunkORPT5EQW_cjs.storeRuntime(target).assertIdentityClassesConsistentAtTarget(
8203
+ () => chunkUZ6CJUC5_cjs.storeRuntime(target).assertIdentityClassesConsistentAtTarget(
8142
8204
  txBackend,
8143
8205
  identityConsistencySeeds(
8144
8206
  artifact,
@@ -8146,8 +8208,8 @@ async function applyWireMergeWrites(target, nodesApi, edgesApi, txBackend, artif
8146
8208
  )
8147
8209
  )
8148
8210
  );
8149
- if (!chunkTKFQLKH2_cjs.forceRecordedGraphRevision(txBackend, target.graphId) && !chunkTKFQLKH2_cjs.forceWriteTransactionRevision(txBackend)) {
8150
- await chunkTKFQLKH2_cjs.advanceRevisionClock(
8211
+ if (!chunkCYKHSH5O_cjs.forceRecordedGraphRevision(txBackend, target.graphId) && !chunkCYKHSH5O_cjs.forceWriteTransactionRevision(txBackend)) {
8212
+ await chunkCYKHSH5O_cjs.advanceRevisionClock(
8151
8213
  txBackend,
8152
8214
  target.revisionSchema,
8153
8215
  target.graphId,
@@ -8182,7 +8244,7 @@ function reportFromArtifact(artifact, merged, warnings, provenancePersisted) {
8182
8244
  ...provenancePersisted === void 0 ? {} : { provenancePersisted }
8183
8245
  };
8184
8246
  }
8185
- async function applyMergePlan(target, input) {
8247
+ async function applyMergePlan(target, input, options = {}) {
8186
8248
  let validation;
8187
8249
  try {
8188
8250
  validation = await validateMergePlanArtifact(input);
@@ -8211,6 +8273,9 @@ async function applyMergePlan(target, input) {
8211
8273
  );
8212
8274
  }
8213
8275
  try {
8276
+ const { beforeApply, afterApply } = options;
8277
+ const composed = beforeApply !== void 0 || afterApply !== void 0;
8278
+ const transactionOptions = composed ? { isolationLevel: "read_committed" } : mergeCommitTransactionOptions(target);
8214
8279
  assertPublicPlanCapability(target);
8215
8280
  const provenanceStore = artifact.provenance.persist ? await tryOpenProvenanceStore(target) : void 0;
8216
8281
  if (provenanceStore !== void 0 && chunkNXJRIRWE_cjs.isErr(provenanceStore)) {
@@ -8218,12 +8283,19 @@ async function applyMergePlan(target, input) {
8218
8283
  }
8219
8284
  const merged = await withTxConflictRetry(
8220
8285
  () => target.transaction(async (tx) => {
8221
- const txBackend = chunkORPT5EQW_cjs.transactionBackend(tx);
8286
+ const txBackend = chunkUZ6CJUC5_cjs.transactionBackend(tx);
8222
8287
  await assertMergePlanFenceInsideTransaction(
8223
8288
  target,
8224
8289
  txBackend,
8225
- artifact
8290
+ artifact,
8291
+ composed
8226
8292
  );
8293
+ if (beforeApply !== void 0) {
8294
+ assertMergeCallbackResult(
8295
+ await beforeApply(mergePlanReadContext(tx, target.graph)),
8296
+ "beforeApply"
8297
+ );
8298
+ }
8227
8299
  await preflightWireMergeWrites(
8228
8300
  target,
8229
8301
  tx.nodes,
@@ -8234,14 +8306,21 @@ async function applyMergePlan(target, input) {
8234
8306
  identityAssertions: artifact.writes.identityAssertions,
8235
8307
  identityRetractions: artifact.writes.identityRetractions
8236
8308
  });
8237
- return applyWireMergeWrites(
8309
+ const applied = await applyWireMergeWrites(
8238
8310
  target,
8239
8311
  tx.nodes,
8240
8312
  tx.edges,
8241
8313
  txBackend,
8242
8314
  artifact
8243
8315
  );
8244
- }, mergeCommitTransactionOptions(target))
8316
+ if (afterApply !== void 0) {
8317
+ assertMergeCallbackResult(
8318
+ await afterApply(tx, { merged: structuredClone(applied) }),
8319
+ "afterApply"
8320
+ );
8321
+ }
8322
+ return applied;
8323
+ }, transactionOptions)
8245
8324
  );
8246
8325
  const warnings = [...artifact.review.warnings];
8247
8326
  let provenancePersisted;
@@ -8711,7 +8790,7 @@ async function assertForkPointUnchanged(precondition) {
8711
8790
  );
8712
8791
  }
8713
8792
  async function commitIncrementalPlan(target, plan, guard) {
8714
- if (!chunkORPT5EQW_cjs.storeBackend(target).capabilities.execution.interactiveTransactions) {
8793
+ if (!chunkUZ6CJUC5_cjs.storeBackend(target).capabilities.execution.interactiveTransactions) {
8715
8794
  throw new MergeError(
8716
8795
  "mergeIncremental() requires a transaction-capable target backend. Incremental writes must preflight existing rows and commit atomically; non-transactional fallback would allow partial graph writes.",
8717
8796
  { details: { capability: "execution.interactiveTransactions" } }
@@ -8720,7 +8799,7 @@ async function commitIncrementalPlan(target, plan, guard) {
8720
8799
  return runMergeCommit(
8721
8800
  () => withTxConflictRetry(
8722
8801
  () => target.transaction(async (tx) => {
8723
- await lockMergeTargetWrite(chunkORPT5EQW_cjs.transactionBackend(tx), {
8802
+ await lockMergeTargetWrite(chunkUZ6CJUC5_cjs.transactionBackend(tx), {
8724
8803
  graphId: target.graphId,
8725
8804
  schemaVersion: target.introspect().schemaVersion,
8726
8805
  graphLock: target.revisionTrackingEnabled ? "required" : "not-required",
@@ -8738,12 +8817,12 @@ async function commitIncrementalPlan(target, plan, guard) {
8738
8817
  );
8739
8818
  await assertPlannedIdentityIdsFresh(
8740
8819
  target,
8741
- chunkORPT5EQW_cjs.transactionBackend(tx),
8820
+ chunkUZ6CJUC5_cjs.transactionBackend(tx),
8742
8821
  plan
8743
8822
  );
8744
8823
  await assertIdentityPeersStable(
8745
8824
  target,
8746
- chunkORPT5EQW_cjs.transactionBackend(tx),
8825
+ chunkUZ6CJUC5_cjs.transactionBackend(tx),
8747
8826
  guard.identityPeerProbe,
8748
8827
  plan
8749
8828
  );
@@ -8755,7 +8834,7 @@ async function commitIncrementalPlan(target, plan, guard) {
8755
8834
  nodesApi,
8756
8835
  edgesApi,
8757
8836
  target,
8758
- chunkORPT5EQW_cjs.transactionBackend(tx)
8837
+ chunkUZ6CJUC5_cjs.transactionBackend(tx)
8759
8838
  );
8760
8839
  }, mergeCommitTransactionOptions(target))
8761
8840
  )
@@ -8845,10 +8924,10 @@ var CandidateWriteSetSchema = zod.z.object({
8845
8924
  target: CandidateWriteSetTargetSchema,
8846
8925
  nodes: zod.z.array(candidateNodeSchema),
8847
8926
  edges: zod.z.array(candidateEdgeSchema),
8848
- identity: chunk7I2PYI4U_cjs.InterchangeIdentitySchema.optional()
8927
+ identity: chunkKR3N6Y7O_cjs.InterchangeIdentitySchema.optional()
8849
8928
  });
8850
8929
  async function captureCandidateWriteSetTarget(target) {
8851
- const activeSchema = await chunkORPT5EQW_cjs.storeBackend(target).getActiveSchema(
8930
+ const activeSchema = await chunkUZ6CJUC5_cjs.storeBackend(target).getActiveSchema(
8852
8931
  target.graphId
8853
8932
  );
8854
8933
  return {
@@ -8927,7 +9006,7 @@ async function planCandidateWriteSet(args) {
8927
9006
  }
8928
9007
  const candidate = created.data;
8929
9008
  try {
8930
- const imported = await chunk7I2PYI4U_cjs.importGraph(
9009
+ const imported = await chunkKR3N6Y7O_cjs.importGraph(
8931
9010
  candidate,
8932
9011
  interchangeDocument(writeSet),
8933
9012
  {
@@ -8966,6 +9045,401 @@ async function planCandidateWriteSet(args) {
8966
9045
  }
8967
9046
  }
8968
9047
 
9048
+ // src/graph-merge/review-evidence.ts
9049
+ function reviewJson(value) {
9050
+ if (value === void 0) return "undefined";
9051
+ return JSON.stringify(value, chunk5X46XWNH_cjs.sortedReplacer);
9052
+ }
9053
+ async function reviewDigest(value) {
9054
+ return chunkZY4GXIVN_cjs.sha256Hex(reviewJson(value), 32);
9055
+ }
9056
+ function reviewOptionEvidence(options) {
9057
+ return encodeOption(normalizeMergeOptions(options), /* @__PURE__ */ new Set());
9058
+ }
9059
+ function encodeOption(value, ancestors) {
9060
+ if (value === void 0) return ["undefined"];
9061
+ if (typeof value === "function") return ["callback"];
9062
+ if (value === null || typeof value === "string" || typeof value === "boolean") {
9063
+ return ["literal", value];
9064
+ }
9065
+ if (typeof value === "number" && Number.isFinite(value))
9066
+ return ["number", value];
9067
+ if (typeof value !== "object" || ancestors.has(value)) {
9068
+ throw new MergeReviewError(
9069
+ "Merge options contain unsupported or cyclic review evidence."
9070
+ );
9071
+ }
9072
+ const nextAncestors = /* @__PURE__ */ new Set([...ancestors, value]);
9073
+ if (Array.isArray(value)) {
9074
+ return [
9075
+ "array",
9076
+ value.map((item) => encodeOption(item, nextAncestors))
9077
+ ];
9078
+ }
9079
+ if (value instanceof Map) {
9080
+ const entries = [...value].map(
9081
+ ([key, entry]) => [
9082
+ encodeOption(key, nextAncestors),
9083
+ encodeOption(entry, nextAncestors)
9084
+ ]
9085
+ );
9086
+ entries.sort(
9087
+ (left, right) => chunkNYWU6CBZ_cjs.compareStrings(reviewJson(left), reviewJson(right))
9088
+ );
9089
+ return ["map", entries];
9090
+ }
9091
+ if (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) {
9092
+ throw new MergeReviewError(
9093
+ "Merge options contain a non-JSON object without a review representation."
9094
+ );
9095
+ }
9096
+ return [
9097
+ "object",
9098
+ Object.entries(value).sort(([left], [right]) => chunkNYWU6CBZ_cjs.compareStrings(left, right)).map(([key, entry]) => [key, encodeOption(entry, nextAncestors)])
9099
+ ];
9100
+ }
9101
+
9102
+ // src/graph-merge/review-baseline.ts
9103
+ function reviewRowKey(row) {
9104
+ return JSON.stringify([row.role, row.kind, row.id]);
9105
+ }
9106
+ async function captureReviewBaseline(target) {
9107
+ const backend = chunkUZ6CJUC5_cjs.storeBackend(target);
9108
+ const rows = [];
9109
+ for (const kind of chunkV32ES2Q2_cjs.getNodeKinds(target.graph)) {
9110
+ for (const row of await enumerateAllNodes(backend, target.graphId, kind)) {
9111
+ rows.push({
9112
+ role: "node",
9113
+ kind,
9114
+ id: row.id,
9115
+ digest: await reviewDigest({ ...row, props: parseRowProps(row.props) })
9116
+ });
9117
+ }
9118
+ }
9119
+ for (const kind of chunkV32ES2Q2_cjs.getEdgeKinds(target.graph)) {
9120
+ for (const row of await enumerateAllEdges(backend, target.graphId, kind)) {
9121
+ rows.push({
9122
+ role: "edge",
9123
+ kind,
9124
+ id: row.id,
9125
+ digest: await reviewDigest({ ...row, props: parseRowProps(row.props) })
9126
+ });
9127
+ }
9128
+ }
9129
+ const identity = await chunkUZ6CJUC5_cjs.storeRuntime(target).readCurrentIdentityAssertions(
9130
+ "archival",
9131
+ {
9132
+ includeDeleted: true
9133
+ }
9134
+ );
9135
+ return {
9136
+ rows: rows.sort(
9137
+ (left, right) => chunkNYWU6CBZ_cjs.compareStrings(reviewRowKey(left), reviewRowKey(right))
9138
+ ),
9139
+ identityDigest: await reviewDigest(
9140
+ [...identity].sort((left, right) => chunkNYWU6CBZ_cjs.compareStrings(left.id, right.id))
9141
+ )
9142
+ };
9143
+ }
9144
+ function withReviewAbsences(baseline, writeSet, plan, graph) {
9145
+ const rows = new Map(baseline.rows.map((row) => [reviewRowKey(row), row]));
9146
+ function addNode(entity) {
9147
+ for (const kind of chunkV32ES2Q2_cjs.getNodeKinds(graph)) {
9148
+ const row = { role: "node", kind, id: entity.id };
9149
+ if (!rows.has(reviewRowKey(row))) rows.set(reviewRowKey(row), row);
9150
+ }
9151
+ }
9152
+ for (const row of baseline.rows) if (row.role === "node") addNode(row);
9153
+ function addEdge(entity) {
9154
+ for (const kind of chunkV32ES2Q2_cjs.getEdgeKinds(graph)) {
9155
+ const row = { role: "edge", kind, id: entity.id };
9156
+ if (!rows.has(reviewRowKey(row))) rows.set(reviewRowKey(row), row);
9157
+ }
9158
+ }
9159
+ for (const node of [
9160
+ ...writeSet.nodes,
9161
+ ...plan.writes.nodeUpserts,
9162
+ ...plan.writes.nodeDeletes,
9163
+ ...plan.guards.deletedNodes
9164
+ ])
9165
+ addNode(node);
9166
+ for (const edge of [...writeSet.edges, ...plan.writes.edgeUpserts]) {
9167
+ addEdge(edge);
9168
+ addNode(edge.from);
9169
+ addNode(edge.to);
9170
+ }
9171
+ for (const edge of plan.writes.edgeDeletes) addEdge(edge);
9172
+ for (const assertion of [
9173
+ ...writeSet.identity?.assertions ?? [],
9174
+ ...plan.writes.identityAssertions,
9175
+ ...plan.writes.identityRetractions
9176
+ ]) {
9177
+ addNode(assertion.a);
9178
+ addNode(assertion.b);
9179
+ if (assertion.endedBy !== void 0) addNode(assertion.endedBy);
9180
+ }
9181
+ for (const mapping of plan.guards.canonicalMappings) {
9182
+ addNode(mapping.member);
9183
+ addNode(mapping.canonical);
9184
+ }
9185
+ for (const retype of plan.guards.retypes) {
9186
+ addNode(retype.entity);
9187
+ addNode({ kind: retype.toKind, id: retype.entity.id });
9188
+ }
9189
+ return {
9190
+ ...baseline,
9191
+ rows: [...rows.values()].sort(
9192
+ (left, right) => chunkNYWU6CBZ_cjs.compareStrings(reviewRowKey(left), reviewRowKey(right))
9193
+ )
9194
+ };
9195
+ }
9196
+ function compareReviewBaseline(reviewed, current) {
9197
+ const currentRows = new Map(
9198
+ current.rows.map((row) => [reviewRowKey(row), row])
9199
+ );
9200
+ const differences = [];
9201
+ for (const row of reviewed.rows) {
9202
+ if (row.digest !== currentRows.get(reviewRowKey(row))?.digest) {
9203
+ differences.push({
9204
+ category: "baseline",
9205
+ path: "baseline.rows",
9206
+ entity: { role: row.role, kind: row.kind, id: row.id }
9207
+ });
9208
+ }
9209
+ }
9210
+ if (reviewed.identityDigest !== current.identityDigest) {
9211
+ differences.push({ category: "baseline", path: "baseline.identityDigest" });
9212
+ }
9213
+ return differences;
9214
+ }
9215
+ var MERGE_REVIEW_FORMAT_VERSION = 1;
9216
+ var digestSchema = zod.z.string().regex(/^[\da-f]{64}$/u);
9217
+ var mergeReviewPolicySchema = zod.z.object({
9218
+ id: zod.z.string().min(1),
9219
+ context: zod.z.json()
9220
+ }).strict();
9221
+ var mergeReviewArtifactSchema = zod.z.object({
9222
+ formatVersion: zod.z.literal(MERGE_REVIEW_FORMAT_VERSION),
9223
+ kind: zod.z.literal("candidate-write-set"),
9224
+ digest: zod.z.object({ algorithm: zod.z.literal("sha256"), value: digestSchema }).strict(),
9225
+ writeSet: CandidateWriteSetSchema,
9226
+ policy: mergeReviewPolicySchema,
9227
+ options: zod.z.json(),
9228
+ plan: mergePlanArtifactV1Schema,
9229
+ baseline: zod.z.object({
9230
+ rows: zod.z.array(
9231
+ zod.z.object({
9232
+ role: zod.z.enum(["node", "edge"]),
9233
+ kind: zod.z.string().min(1),
9234
+ id: zod.z.string().min(1),
9235
+ digest: digestSchema.optional()
9236
+ }).strict()
9237
+ ),
9238
+ identityDigest: digestSchema
9239
+ }).strict()
9240
+ }).strict();
9241
+
9242
+ // src/graph-merge/candidate-review.ts
9243
+ async function planCandidateWriteSetReview(args) {
9244
+ try {
9245
+ const writeSet = CandidateWriteSetSchema.parse(args.writeSet);
9246
+ const policy = mergeReviewPolicySchema.parse(args.policy);
9247
+ const options = reviewOptionEvidence(args.options);
9248
+ const startingFence = await captureMergePlanTargetFence(args.target);
9249
+ const baseline = await captureReviewBaseline(args.target);
9250
+ const planned = await planCandidateWriteSet({ ...args, writeSet });
9251
+ if (chunkNXJRIRWE_cjs.isErr(planned)) return planned;
9252
+ assertReviewPlanFence(startingFence, planned.data);
9253
+ await assertPlanningFenceUnchanged(args.target, startingFence);
9254
+ assertOptionsUnchanged(options, reviewOptionEvidence(args.options));
9255
+ const input = {
9256
+ formatVersion: MERGE_REVIEW_FORMAT_VERSION,
9257
+ kind: "candidate-write-set",
9258
+ writeSet,
9259
+ policy,
9260
+ options,
9261
+ plan: planned.data,
9262
+ baseline: withReviewAbsences(
9263
+ baseline,
9264
+ writeSet,
9265
+ planned.data,
9266
+ args.target.graph
9267
+ )
9268
+ };
9269
+ const review = {
9270
+ ...input,
9271
+ digest: { algorithm: "sha256", value: await reviewDigest(input) }
9272
+ };
9273
+ mergeReviewArtifactSchema.parse(review);
9274
+ return chunkNXJRIRWE_cjs.ok(review);
9275
+ } catch (error) {
9276
+ return chunkNXJRIRWE_cjs.err(asReviewError(error));
9277
+ }
9278
+ }
9279
+ async function revalidateCandidateWriteSetReview(args) {
9280
+ try {
9281
+ const review = await validateReview(args.review);
9282
+ const policy = mergeReviewPolicySchema.parse(args.policy);
9283
+ const options = reviewOptionEvidence(args.options);
9284
+ const startingFence = await captureMergePlanTargetFence(args.target);
9285
+ const targetDifferences = compareReviewTarget(
9286
+ review.plan.target,
9287
+ startingFence
9288
+ );
9289
+ if (targetDifferences.length > 0)
9290
+ return chunkNXJRIRWE_cjs.ok({
9291
+ status: "incompatible",
9292
+ reviewDigest: review.digest,
9293
+ differences: targetDifferences
9294
+ });
9295
+ if (withReviewAbsences(
9296
+ review.baseline,
9297
+ review.writeSet,
9298
+ review.plan,
9299
+ args.target.graph
9300
+ ).rows.length !== review.baseline.rows.length) {
9301
+ throw new MergeReviewError(
9302
+ "The merge review is missing required baseline evidence.",
9303
+ { details: { reason: "incomplete-baseline" } }
9304
+ );
9305
+ }
9306
+ const policyDifferences = compareFields(
9307
+ "policy",
9308
+ { policy: review.policy, options: review.options },
9309
+ { policy, options }
9310
+ );
9311
+ if (policyDifferences.length > 0)
9312
+ return chunkNXJRIRWE_cjs.ok({
9313
+ status: "changed",
9314
+ reviewDigest: review.digest,
9315
+ differences: policyDifferences
9316
+ });
9317
+ const baseline = await captureReviewBaseline(args.target);
9318
+ const baselineDifferences = compareReviewBaseline(
9319
+ review.baseline,
9320
+ baseline
9321
+ );
9322
+ if (baselineDifferences.length > 0) {
9323
+ await assertPlanningFenceUnchanged(args.target, startingFence);
9324
+ return chunkNXJRIRWE_cjs.ok({
9325
+ status: "changed",
9326
+ reviewDigest: review.digest,
9327
+ differences: baselineDifferences
9328
+ });
9329
+ }
9330
+ const planned = await planCandidateWriteSet({
9331
+ ...args,
9332
+ writeSet: review.writeSet
9333
+ });
9334
+ if (chunkNXJRIRWE_cjs.isErr(planned)) return planned;
9335
+ assertReviewPlanFence(startingFence, planned.data);
9336
+ await assertPlanningFenceUnchanged(args.target, startingFence);
9337
+ assertOptionsUnchanged(options, reviewOptionEvidence(args.options));
9338
+ const differences = compareFields(
9339
+ "plan",
9340
+ reviewPlanContent(review.plan),
9341
+ reviewPlanContent(planned.data)
9342
+ );
9343
+ return chunkNXJRIRWE_cjs.ok(
9344
+ differences.length === 0 ? {
9345
+ status: "compatible",
9346
+ reviewDigest: review.digest,
9347
+ plan: planned.data
9348
+ } : {
9349
+ status: "changed",
9350
+ reviewDigest: review.digest,
9351
+ differences,
9352
+ plan: planned.data
9353
+ }
9354
+ );
9355
+ } catch (error) {
9356
+ return chunkNXJRIRWE_cjs.err(asReviewError(error));
9357
+ }
9358
+ }
9359
+ async function validateReview(input) {
9360
+ const review = mergeReviewArtifactSchema.parse(input);
9361
+ if (reviewJson(input) !== reviewJson(review)) {
9362
+ throw new MergeReviewError(
9363
+ "Stored merge review evidence must not require normalization.",
9364
+ {
9365
+ details: { reason: "noncanonical-shape" }
9366
+ }
9367
+ );
9368
+ }
9369
+ const { digest, ...content } = review;
9370
+ if (digest.value !== await reviewDigest(content)) {
9371
+ throw new MergeReviewError(
9372
+ "The merge review digest does not match its content.",
9373
+ { details: { reason: "digest-mismatch" } }
9374
+ );
9375
+ }
9376
+ const plan = await validateMergePlanArtifact(review.plan);
9377
+ if (!plan.success)
9378
+ throw new MergeReviewError("The reviewed execution plan is invalid.", {
9379
+ details: { reason: "invalid-plan", error: plan.error }
9380
+ });
9381
+ const anchors = plan.artifact.anchors;
9382
+ if (plan.artifact.mode !== "incremental" || anchors.kind !== "incremental" || anchors.forkPoint.graphId !== review.writeSet.target.graphId || plan.artifact.target.graphId !== review.writeSet.target.graphId || plan.artifact.target.schema.version !== review.writeSet.target.schemaVersion || plan.artifact.target.schema.hash !== review.writeSet.target.schemaHash || reviewJson(anchors.forkPoint.schema) !== reviewJson(plan.artifact.target.schema) || anchors.branches.length !== 1 || anchors.branches[0]?.branchId !== review.writeSet.sourceId || anchors.branches[0].baseVersion !== anchors.forkPoint.baseVersion) {
9383
+ throw new MergeReviewError(
9384
+ "The reviewed plan does not describe the retained candidate source and target.",
9385
+ { details: { reason: "incompatible-plan" } }
9386
+ );
9387
+ }
9388
+ if (new Set(review.baseline.rows.map((row) => reviewRowKey(row))).size !== review.baseline.rows.length) {
9389
+ throw new MergeReviewError(
9390
+ "The merge review contains duplicate baseline references.",
9391
+ { details: { reason: "duplicate-baseline" } }
9392
+ );
9393
+ }
9394
+ return { ...review, plan: plan.artifact };
9395
+ }
9396
+ function assertReviewPlanFence(fence, plan) {
9397
+ if (!sameMergePlanTargetFence(fence, plan.target)) {
9398
+ throw new MergePlanningStaleError(
9399
+ "The target changed between review evidence capture and planning."
9400
+ );
9401
+ }
9402
+ }
9403
+ function assertOptionsUnchanged(before, after) {
9404
+ if (reviewJson(before) !== reviewJson(after))
9405
+ throw new MergeReviewError(
9406
+ "Merge options changed while review evidence was being captured."
9407
+ );
9408
+ }
9409
+ function compareReviewTarget(reviewed, current) {
9410
+ return compareFields(
9411
+ "target",
9412
+ {
9413
+ graphId: reviewed.graphId,
9414
+ schema: reviewed.schema,
9415
+ origin: reviewed.revision.origin
9416
+ },
9417
+ {
9418
+ graphId: current.graphId,
9419
+ schema: current.schema,
9420
+ origin: current.revision.origin
9421
+ }
9422
+ );
9423
+ }
9424
+ function reviewPlanContent(plan) {
9425
+ const {
9426
+ digest: _digest,
9427
+ target: _target,
9428
+ anchors: _anchors,
9429
+ ...content
9430
+ } = plan;
9431
+ return content;
9432
+ }
9433
+ function compareFields(category, reviewed, current) {
9434
+ return [.../* @__PURE__ */ new Set([...Object.keys(reviewed), ...Object.keys(current)])].sort().filter((key) => reviewJson(reviewed[key]) !== reviewJson(current[key])).map((key) => ({ category, path: `${category}.${key}` }));
9435
+ }
9436
+ function asReviewError(error) {
9437
+ return error instanceof MergeError ? error : new MergeReviewError(
9438
+ "Unable to validate or capture merge review evidence.",
9439
+ { cause: error }
9440
+ );
9441
+ }
9442
+
8969
9443
  Object.defineProperty(exports, "isErr", {
8970
9444
  enumerable: true,
8971
9445
  get: function () { return chunkNXJRIRWE_cjs.isErr; }
@@ -8992,6 +9466,7 @@ exports.MERGE_ERROR_CODES = MERGE_ERROR_CODES;
8992
9466
  exports.MERGE_OPTION_DEFAULTS = MERGE_OPTION_DEFAULTS;
8993
9467
  exports.MERGE_PLAN_DIGEST_ALGORITHM = MERGE_PLAN_DIGEST_ALGORITHM;
8994
9468
  exports.MERGE_PLAN_FORMAT_VERSION = MERGE_PLAN_FORMAT_VERSION;
9469
+ exports.MERGE_REVIEW_FORMAT_VERSION = MERGE_REVIEW_FORMAT_VERSION;
8995
9470
  exports.MatchEvidenceError = MatchEvidenceError;
8996
9471
  exports.MergeConflictError = MergeConflictError;
8997
9472
  exports.MergeConstraintConflictError = MergeConstraintConflictError;
@@ -9002,6 +9477,7 @@ exports.MergePlanOriginMismatchError = MergePlanOriginMismatchError;
9002
9477
  exports.MergePlanSchemaMismatchError = MergePlanSchemaMismatchError;
9003
9478
  exports.MergePlanTargetMismatchError = MergePlanTargetMismatchError;
9004
9479
  exports.MergePlanningStaleError = MergePlanningStaleError;
9480
+ exports.MergeReviewError = MergeReviewError;
9005
9481
  exports.SimilarityUnavailableError = SimilarityUnavailableError;
9006
9482
  exports.StaleMergePlanError = StaleMergePlanError;
9007
9483
  exports.UnsupportedMergePlanVersionError = UnsupportedMergePlanVersionError;
@@ -9020,9 +9496,11 @@ exports.normalizeMergeOptions = normalizeMergeOptions;
9020
9496
  exports.openProvenanceStore = openProvenanceStore;
9021
9497
  exports.persistProvenanceRecords = persistProvenanceRecords;
9022
9498
  exports.planCandidateWriteSet = planCandidateWriteSet;
9499
+ exports.planCandidateWriteSetReview = planCandidateWriteSetReview;
9023
9500
  exports.planMerge = planMerge;
9024
9501
  exports.planMergeIncremental = planMergeIncremental;
9025
9502
  exports.provenanceGraphId = provenanceGraphId;
9026
9503
  exports.readProvenance = readProvenance;
9504
+ exports.revalidateCandidateWriteSetReview = revalidateCandidateWriteSetReview;
9027
9505
  //# sourceMappingURL=index.cjs.map
9028
9506
  //# sourceMappingURL=index.cjs.map