@ibgib/space-gib 0.0.5 → 0.0.7

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 (58) hide show
  1. package/README.md +20 -0
  2. package/dist/client/bootstrap.mjs +31 -31
  3. package/dist/client/bootstrap.mjs.map +3 -3
  4. package/dist/client/chunk-RXFIBFRK.mjs +42 -0
  5. package/dist/client/chunk-RXFIBFRK.mjs.map +7 -0
  6. package/dist/client/chunk-ULFNE26Y.mjs +2216 -0
  7. package/dist/client/chunk-ULFNE26Y.mjs.map +7 -0
  8. package/dist/client/index.html +35 -14
  9. package/dist/client/index.mjs +1 -1
  10. package/dist/client/script.mjs +1 -1
  11. package/dist/client/style.css +29 -5
  12. package/dist/server/server.mjs +1447 -270
  13. package/dist/server/server.mjs.map +4 -4
  14. package/package.json +5 -5
  15. package/space-gib.localhost-1783713259760.log +45 -0
  16. package/src/client/AUTO-GENERATED-version.mts +1 -1
  17. package/src/client/bootstrap.mts +9 -0
  18. package/src/client/components/identity-header/identity-header.css +40 -2
  19. package/src/client/components/identity-header/identity-header.html +3 -2
  20. package/src/client/components/identity-header/identity-header.mts +127 -49
  21. package/src/client/components/identity-manager/identity-manager.css +57 -353
  22. package/src/client/components/identity-manager/identity-manager.html +0 -94
  23. package/src/client/components/identity-manager/identity-manager.mts +356 -484
  24. package/src/client/components/keystone-creator/keystone-creator.mts +90 -13
  25. package/src/client/components/keystone-details/keystone-details.css +472 -0
  26. package/src/client/components/keystone-details/keystone-details.html +99 -0
  27. package/src/client/components/keystone-details/keystone-details.mts +821 -0
  28. package/src/client/components/keystone-scrubber/SCRUBBER_IMPLEMENTATION.md +33 -0
  29. package/src/client/components/keystone-scrubber/keystone-scrubber.css +46 -0
  30. package/src/client/components/keystone-scrubber/keystone-scrubber.html +15 -0
  31. package/src/client/components/keystone-scrubber/keystone-scrubber.mts +356 -0
  32. package/src/client/dev-tools/common.mts +505 -10
  33. package/src/client/dev-tools/phase-4-1.mts +19 -4
  34. package/src/client/dev-tools/phase-4-10.mts +77 -305
  35. package/src/client/dev-tools/phase-4-2.mts +46 -212
  36. package/src/client/dev-tools/phase-4-3.mts +57 -198
  37. package/src/client/dev-tools/phase-4-4.mts +57 -170
  38. package/src/client/dev-tools/phase-4-5.mts +48 -204
  39. package/src/client/dev-tools/phase-4-6.mts +37 -103
  40. package/src/client/dev-tools/phase-4-7.mts +44 -228
  41. package/src/client/dev-tools/phase-4-8.mts +33 -136
  42. package/src/client/dev-tools/phase-4-9.mts +33 -137
  43. package/src/client/dev-tools/phase-4.mts +30 -6
  44. package/src/client/dev-tools.mts +18 -0
  45. package/src/client/index.html +35 -14
  46. package/src/client/style.css +29 -5
  47. package/src/client/types.mts +4 -1
  48. package/src/client/ui/shell/space-gib-shell-service.mts +4 -0
  49. package/src/server/path-constants.mts +12 -0
  50. package/src/server/serve-gib/handlers/api/keystone/sso-config.handler.mts +66 -0
  51. package/src/server/serve-gib/handlers/api/keystone/sso-link.handler.mts +119 -0
  52. package/src/server/serve-gib/handlers/api/keystone/sso-login.handler.mts +189 -0
  53. package/src/server/server.mts +6 -0
  54. package/dist/client/chunk-ANGVYAEK.mjs +0 -42
  55. package/dist/client/chunk-ANGVYAEK.mjs.map +0 -7
  56. package/dist/client/chunk-IRGFDQRD.mjs +0 -1920
  57. package/dist/client/chunk-IRGFDQRD.mjs.map +0 -7
  58. package/dist/respec-gib.node.mjs +0 -5
@@ -1,19 +1,17 @@
1
- import { extractErrorMsg, getUUID, getTimestamp } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
1
+ import { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
2
2
  import { Factory_V1 as factory } from '@ibgib/ts-gib/dist/V1/factory.mjs';
3
3
  import { ROOT } from '@ibgib/ts-gib/dist/V1/constants.mjs';
4
4
  import { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';
5
5
  import { KeystoneIbGib_V1 } from '@ibgib/core-gib/dist/keystone/keystone-types.mjs';
6
- import { KeystoneService_V1 } from '@ibgib/core-gib/dist/keystone/keystone-service-v1.mjs';
7
6
  import { getGlobalMetaspace_waitIfNeeded } from "@ibgib/web-gib/dist/helpers.mjs";
8
7
  import { mut8Timeline } from '@ibgib/core-gib/dist/timeline/timeline-api.mjs';
9
8
  import { graphsAreEquivalent } from '@ibgib/core-gib/dist/common/other/graph-helper.mjs';
10
- import { SyncPeerWebSocketSender_V1 } from '@ibgib/core-gib/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-v1.mjs';
11
- import { SyncSagaCoordinator } from '@ibgib/core-gib/dist/sync/sync-saga-coordinator.mjs';
12
- import { SyncConflictStrategy } from '@ibgib/core-gib/dist/sync/sync-constants.mjs';
13
- import { SESSION_KEYSTONE_POLICY, getSpaceGibPoolConfig } from "../../common/keystone-policies.mjs";
14
9
  import { SpaceGibApiBridge } from '../api/space-gib-api-bridge.mjs';
15
10
 
16
- import { debugState, devLog, lc } from './common.mjs';
11
+ import {
12
+ debugState, devLog, lc,
13
+ setupDomainAndDelegateIdentities, runSyncPass, verifyIdentitiesOnServer
14
+ } from './common.mjs';
17
15
 
18
16
  export function init4_4bSetupButton(): void {
19
17
  const btn = document.getElementById('btn-4-4b-setup') as HTMLButtonElement | null;
@@ -27,33 +25,18 @@ export function init4_4bSetupButton(): void {
27
25
  const space = await metaspace.getLocalUserSpace({});
28
26
  if (!space) { throw new Error("No default space."); }
29
27
 
30
- const keystoneService = new KeystoneService_V1();
28
+ const apiBridge = new SpaceGibApiBridge();
31
29
 
32
- const domainI = await keystoneService.genesis({
30
+ // Create domain + delegate identities (DRY helper)
31
+ await setupDomainAndDelegateIdentities({
33
32
  masterSecret: 'test-sender-secret-phase4-4',
34
- configs: [
35
- getSpaceGibPoolConfig('sync', 'senderidentitysyncsaltphase4-4'),
36
- getSpaceGibPoolConfig('manage', 'senderidentitymanagesaltphase4-4'),
37
- ],
38
- metaspace,
39
- space,
40
- frameDetails: { client: 'space-gib-web-dev', timestamp: getTimestamp() }
33
+ syncSalt: 'senderidentitysyncsaltphase4-4',
34
+ manageSalt: 'senderidentitymanagesaltphase4-4',
35
+ metaspace, space, apiBridge,
36
+ phaseText: '4.4B'
41
37
  });
42
38
 
43
- debugState.domainI = domainI;
44
- debugState.domainIMasterSecret = 'test-sender-secret-phase4-4';
45
-
46
- devLog(`4.4B Setup: ✓ Domain Keystone (I) created locally: ${getIbGibAddr({ ibGib: domainI })}`);
47
-
48
- const apiBridge = new SpaceGibApiBridge();
49
- const resGenesis = await apiBridge.postGenesisKeystone(domainI);
50
- if (resGenesis.success) {
51
- devLog(`4.4B Setup: ✓ Domain Keystone registered on server.`);
52
- } else {
53
- throw new Error(`Server rejected genesis domain keystone: ${resGenesis.message}`);
54
- }
55
-
56
- // Create V0 (Root)
39
+ // Create V0
57
40
  const resV0 = await factory.firstGen({
58
41
  parentIbGib: ROOT,
59
42
  ib: 'timeline_root_deep_4_4b',
@@ -65,25 +48,23 @@ export function init4_4bSetupButton(): void {
65
48
  const r1_v0 = resV0.newIbGib;
66
49
  await metaspace.persistTransformResult({ resTransform: resV0, space });
67
50
  await metaspace.registerNewIbGib({ ibGib: r1_v0 });
68
- debugState.targetC1 = r1_v0; // V0
51
+ debugState.targetC1 = r1_v0;
69
52
 
70
53
  // Create V1
71
54
  const r1_v1 = await mut8Timeline({
72
55
  timeline: r1_v0,
73
56
  mut8Opts: { dataToAddOrPatch: { type: 'comment', label: 'V1_4_4b' } },
74
- metaspace,
75
- space,
57
+ metaspace, space,
76
58
  });
77
- debugState.targetC2 = r1_v1; // V1
59
+ debugState.targetC2 = r1_v1;
78
60
 
79
61
  // Create V2
80
62
  const r1_v2 = await mut8Timeline({
81
63
  timeline: r1_v1,
82
64
  mut8Opts: { dataToAddOrPatch: { type: 'comment', label: 'V2_4_4b' } },
83
- metaspace,
84
- space,
65
+ metaspace, space,
85
66
  });
86
- debugState.targetX = r1_v2; // V2 (Tip)
67
+ debugState.targetX = r1_v2;
87
68
 
88
69
  devLog(`4.4B Setup: ✓ Timeline V0 -> V1 -> V2 created locally. V2 Tip: ${getIbGibAddr({ ibGib: r1_v2 })}`);
89
70
 
@@ -110,53 +91,18 @@ async function performPhaseSync4_4b(): Promise<void> {
110
91
  btn.disabled = true;
111
92
  devLog(`4.4B Sync: Initiating WebSocket Sync of V2 Tip...`);
112
93
 
113
- const domainI = debugState.domainI;
114
94
  const targetV2 = debugState.targetX;
115
- if (!domainI || !targetV2) {
95
+ if (!debugState.domainI || !targetV2) {
116
96
  devLog(`⚠ 4.4B Sync: Missing setup state. Please run Setup first.`);
117
97
  btn.disabled = false;
118
98
  return;
119
99
  }
120
100
 
121
- const domainAddr = getIbGibAddr({ ibGib: domainI });
122
101
  const metaspace = await getGlobalMetaspace_waitIfNeeded();
123
102
  const space = await metaspace.getLocalUserSpace({});
124
103
  if (!space) { throw new Error("No default space."); }
125
104
 
126
- const protocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
127
-
128
- const senderPeer = new SyncPeerWebSocketSender_V1({
129
- classname: 'SyncPeerWebSocketSender_V1',
130
- httpEvolveUrl: `${location.protocol}//${location.host}/api/keystone/evolve/${encodeURIComponent(domainAddr)}`,
131
- wsUrl: `${protocol}//${location.host}/api/sync/ws/${encodeURIComponent(domainAddr)}`
132
- });
133
-
134
- const coordinator = new SyncSagaCoordinator();
135
- const sagaId = await getUUID();
136
- debugState.sagaId = sagaId;
137
- debugState.senderPeer = senderPeer;
138
-
139
- await senderPeer.initializeOpts({
140
- localMetaspace: metaspace,
141
- localSpace: space,
142
- senderIdentity: domainI,
143
- fnSenderSecret: async () => debugState.domainIMasterSecret!,
144
- sagaId,
145
- sessionConnectPoolConfig: SESSION_KEYSTONE_POLICY.CONNECT_POOL as any,
146
- sessionSyncPoolConfig: SESSION_KEYSTONE_POLICY.DEFAULT_POOL as any,
147
- targetAddrs: [domainAddr]
148
- });
149
-
150
- const syncSaga = await coordinator.sync({
151
- domainIbGibs: [targetV2],
152
- senderIdentity: domainI,
153
- fnSenderSecret: async () => debugState.domainIMasterSecret!,
154
- peer: senderPeer,
155
- localSpace: space,
156
- metaspace,
157
- conflictStrategy: SyncConflictStrategy.optimisticWithLCS,
158
- });
159
- await syncSaga.done;
105
+ await runSyncPass({ domainIbGibs: [targetV2], passLabel: 'Pass 1 (Sync V2 tip)', metaspace, space });
160
106
  devLog(`4.4B Sync: ✓ WebSocket Sync completed.`);
161
107
 
162
108
  devLog(`✓ 4.4B Sync Sequence Complete! Ready for State Checks.`);
@@ -175,9 +121,7 @@ async function performPhaseSync4_4b(): Promise<void> {
175
121
  export function init4_4bSyncButton(): void {
176
122
  const btn = document.getElementById('btn-4-4b-sync') as HTMLButtonElement | null;
177
123
  if (!btn) { return; }
178
- btn.addEventListener('click', () => {
179
- performPhaseSync4_4b();
180
- });
124
+ btn.addEventListener('click', () => { performPhaseSync4_4b(); });
181
125
  }
182
126
 
183
127
  export function init4_4bCheckButton(): void {
@@ -201,167 +145,110 @@ export function init4_4bCheckButton(): void {
201
145
  const v1Addr = getIbGibAddr({ ibGib: targetV1 });
202
146
  const v2Addr = getIbGibAddr({ ibGib: targetV2 });
203
147
  const domainAddr = getIbGibAddr({ ibGib: domainI });
148
+ const apiBridge = new SpaceGibApiBridge();
204
149
 
205
- // 1. Verify V0, V1, and V2 exist locally
150
+ // 1. Verify V0, V1, V2 exist locally
206
151
  const localV0Res = await metaspace.get({ addrs: [v0Addr], space });
207
152
  const localV1Res = await metaspace.get({ addrs: [v1Addr], space });
208
153
  const localV2Res = await metaspace.get({ addrs: [v2Addr], space });
209
154
  if (!localV0Res.success || !localV0Res.ibGibs?.[0]) {
210
- devLog('✗ Check: Timeline frame V0 NOT found locally.');
211
- return;
155
+ devLog('✗ Check: Timeline frame V0 NOT found locally.'); return;
212
156
  }
213
157
  if (!localV1Res.success || !localV1Res.ibGibs?.[0]) {
214
- devLog('✗ Check: Timeline frame V1 NOT found locally.');
215
- return;
158
+ devLog('✗ Check: Timeline frame V1 NOT found locally.'); return;
216
159
  }
217
160
  if (!localV2Res.success || !localV2Res.ibGibs?.[0]) {
218
- devLog('✗ Check: Timeline frame V2 NOT found locally.');
219
- return;
161
+ devLog('✗ Check: Timeline frame V2 NOT found locally.'); return;
220
162
  }
221
163
  devLog(`✓ Check: Timeline frames V0, V1, and V2 exist locally.`);
222
164
 
223
- // 2. Fetch server's V2, V1, and V0
224
- const apiBridge = new SpaceGibApiBridge();
165
+ // 2. Verify V2, V1 exist on server with correct past refs, and V2 graph matches
225
166
  const serverV2Res = await apiBridge.getIbGib(domainAddr, v2Addr);
226
167
  if (!serverV2Res.success || !serverV2Res.ibGib) {
227
- devLog(`✗ Check: Timeline frame V2 NOT found on server: ${serverV2Res.message}`);
228
- return;
168
+ devLog(`✗ Check: Timeline frame V2 NOT found on server: ${serverV2Res.message}`); return;
229
169
  }
230
170
  devLog(`✓ Check: Timeline frame V2 exists on server.`);
231
171
 
232
- const serverV2IbGib = serverV2Res.ibGib;
233
- const pastAddrV2 = serverV2IbGib.rel8ns?.past?.at(-1);
172
+ const pastAddrV2 = serverV2Res.ibGib.rel8ns?.past?.at(-1);
234
173
  if (pastAddrV2 === v1Addr) {
235
174
  devLog('✓ Check: Server V2 correctly references V1 in its past relation.');
236
175
  } else {
237
- devLog(`✗ Check: Server V2 does not reference V1 in past relation! got: ${pastAddrV2}`);
238
- return;
176
+ devLog(`✗ Check: Server V2 does not reference V1 in past relation! got: ${pastAddrV2}`); return;
239
177
  }
240
178
 
241
179
  const serverV1Res = await apiBridge.getIbGib(domainAddr, v1Addr);
242
180
  if (!serverV1Res.success || !serverV1Res.ibGib) {
243
- devLog(`✗ Check: Timeline frame V1 NOT found on server: ${serverV1Res.message}`);
244
- return;
181
+ devLog(`✗ Check: Timeline frame V1 NOT found on server: ${serverV1Res.message}`); return;
245
182
  }
246
183
  devLog(`✓ Check: Timeline frame V1 exists on server.`);
247
184
 
248
- const serverV1IbGib = serverV1Res.ibGib;
249
- const pastAddrV1 = serverV1IbGib.rel8ns?.past?.at(-1);
185
+ const pastAddrV1 = serverV1Res.ibGib.rel8ns?.past?.at(-1);
250
186
  if (pastAddrV1 === v0Addr) {
251
187
  devLog('✓ Check: Server V1 correctly references V0 in its past relation.');
252
188
  } else {
253
- devLog(`✗ Check: Server V1 does not reference V0 in past relation! got: ${pastAddrV1}`);
254
- return;
189
+ devLog(`✗ Check: Server V1 does not reference V0 in past relation! got: ${pastAddrV1}`); return;
255
190
  }
256
191
 
257
- const localV2Graph = await metaspace.getDependencyGraph({
258
- ibGibAddr: v2Addr,
259
- space
260
- });
192
+ const localV2Graph = await metaspace.getDependencyGraph({ ibGibAddr: v2Addr, space });
261
193
  const serverV2GetGraphRes = await apiBridge.getIbGibGraph(domainAddr, v2Addr, true);
262
194
  if (!serverV2GetGraphRes.success || !serverV2GetGraphRes.graph) {
263
- devLog(`✗ Check: Failed to fetch V2 graph from server: ${serverV2GetGraphRes.message}`);
264
- return;
195
+ devLog(`✗ Check: Failed to fetch V2 graph from server: ${serverV2GetGraphRes.message}`); return;
265
196
  }
266
- const serverV2Graph = serverV2GetGraphRes.graph;
267
-
268
- const v2GraphsEqual = graphsAreEquivalent({ graphA: localV2Graph, graphB: serverV2Graph });
269
- if (v2GraphsEqual) {
270
- devLog('✓ Check: V2 timeline dependency graphs are equivalent on client and server.');
271
- } else {
272
- devLog('✗ Check: V2 timeline dependency graphs mismatch between client and server!');
273
- return;
197
+ if (!graphsAreEquivalent({ graphA: localV2Graph, graphB: serverV2GetGraphRes.graph })) {
198
+ devLog('✗ Check: V2 timeline dependency graphs mismatch between client and server!'); return;
274
199
  }
200
+ devLog('✓ Check: V2 timeline dependency graphs are equivalent on client and server.');
275
201
 
276
- // 3. Verify evolved sender identity I exists locally and on server, n = 1 (1 connect/sync handshake)
277
- const latestLocalIAddr = await metaspace.getLatestAddr({
278
- addr: domainAddr,
279
- space
280
- });
281
- if (!latestLocalIAddr) {
282
- devLog('✗ Check: Evolved domain keystone tip NOT found in local space!');
283
- return;
284
- }
202
+ // 3. Verify domain keystone n=1, then verify domain/delegate/session on server
203
+ const latestLocalIAddr = await metaspace.getLatestAddr({ addr: domainAddr, space });
204
+ if (!latestLocalIAddr) { devLog('✗ Check: Domain keystone tip not found locally!'); return; }
285
205
  const localIRes = await metaspace.get({ addrs: [latestLocalIAddr], space });
286
206
  const localI = localIRes.ibGibs?.[0] as KeystoneIbGib_V1 | undefined;
287
- if (!localI) {
288
- devLog('✗ Check: Failed to load evolved I from local space.');
289
- return;
290
- }
207
+ if (!localI) { devLog('✗ Check: Failed to load domain keystone!'); return; }
291
208
  devLog(`✓ Check: Evolved Domain Keystone exists locally: ${latestLocalIAddr}`);
292
209
 
293
210
  const nI = localI.data?.n;
294
211
  devLog(`✓ Check: Evolved I tip is at n = ${nI}.`);
295
212
  if (nI !== 1) {
296
- devLog(`✗ Check: Expected I to evolve to n = 1, got n = ${nI}.`);
297
- return;
298
- }
299
-
300
- const serverIGetRes = await apiBridge.getIbGib(domainAddr, latestLocalIAddr);
301
- if (!serverIGetRes.success || !serverIGetRes.ibGib) {
302
- devLog(`✗ Check: Evolved Domain Keystone tip NOT found on server!`);
303
- return;
304
- }
305
- devLog(`✓ Check: Evolved Domain Keystone tip exists on server.`);
306
-
307
- // 4. Verify session identity S tip exists locally and on server, n = 3
308
- const syncProof = localI.data?.proofs?.find(p => p.claim?.verb === 'sync');
309
- const sessionIdentityTjpAddr = syncProof?.claim?.target;
310
- if (!sessionIdentityTjpAddr) {
311
- devLog('✗ Check: Evolved I sync claim does not target a session keystone.');
312
- return;
213
+ devLog(`✗ Check: Expected I to evolve to n = 1, got n = ${nI}.`); return;
313
214
  }
314
215
 
315
- const latestLocalSAddr = await metaspace.getLatestAddr({
316
- addr: sessionIdentityTjpAddr,
317
- space
216
+ const { sessionIdentityTjpAddr } = await verifyIdentitiesOnServer({
217
+ localI, metaspace, space, apiBridge, domainAddr
318
218
  });
219
+
220
+ // 4. Verify session keystone S n=3 and graph matches
221
+ const latestLocalSAddr = await metaspace.getLatestAddr({ addr: sessionIdentityTjpAddr, space });
319
222
  if (!latestLocalSAddr) {
320
- devLog('✗ Check: Latest Session Keystone (S) NOT found in local space.');
321
- return;
223
+ devLog('✗ Check: Latest Session Keystone (S) NOT found in local space.'); return;
322
224
  }
323
225
  devLog(`✓ Check: Found latest session keystone (S) locally: ${latestLocalSAddr}`);
324
226
 
325
227
  const localSRes = await metaspace.get({ addrs: [latestLocalSAddr], space });
326
228
  const sessionS = localSRes.ibGibs?.[0] as KeystoneIbGib_V1 | undefined;
327
- if (!sessionS) {
328
- devLog('✗ Check: Failed to load latest Session Keystone (S) locally.');
329
- return;
330
- }
229
+ if (!sessionS) { devLog('✗ Check: Failed to load Session Keystone (S) locally.'); return; }
331
230
 
332
231
  const nS = sessionS.data?.n;
333
232
  devLog(`✓ Check: Latest session S tip evolved to n = ${nS}.`);
334
233
  if (nS !== 3) {
335
- devLog(`✗ Check: Expected latest session S to evolve to n = 3, got n = ${nS}.`);
336
- return;
234
+ devLog(`✗ Check: Expected latest session S to evolve to n = 3, got n = ${nS}.`); return;
337
235
  }
338
236
 
339
237
  const serverSGetRes = await apiBridge.getIbGib(domainAddr, latestLocalSAddr);
340
238
  if (!serverSGetRes.success || !serverSGetRes.ibGib) {
341
- devLog(`✗ Check: Latest Session Keystone (S) NOT found on server!`);
342
- return;
239
+ devLog(`✗ Check: Latest Session Keystone (S) NOT found on server!`); return;
343
240
  }
344
241
  devLog(`✓ Check: Latest Session Keystone (S) exists on server.`);
345
242
 
346
- // 5. Assert S graph is identical on client and server
347
- const localSGraph = await metaspace.getDependencyGraph({
348
- ibGibAddr: latestLocalSAddr,
349
- space
350
- });
243
+ const localSGraph = await metaspace.getDependencyGraph({ ibGibAddr: latestLocalSAddr, space });
351
244
  const serverSGetGraphRes = await apiBridge.getIbGibGraph(domainAddr, sessionIdentityTjpAddr, true);
352
245
  if (!serverSGetGraphRes.success || !serverSGetGraphRes.graph) {
353
- devLog(`✗ Check: Failed to fetch session S graph from server: ${serverSGetGraphRes.message}`);
354
- return;
246
+ devLog(`✗ Check: Failed to fetch session S graph from server: ${serverSGetGraphRes.message}`); return;
355
247
  }
356
- const serverSGraph = serverSGetGraphRes.graph;
357
-
358
- const sGraphsEqual = graphsAreEquivalent({ graphA: localSGraph, graphB: serverSGraph });
359
- if (sGraphsEqual) {
360
- devLog('✓ Check: Session Keystone (S) dependency graphs are equivalent on client and server.');
361
- } else {
362
- devLog('✗ Check: Session Keystone (S) dependency graphs mismatch between client and server!');
363
- return;
248
+ if (!graphsAreEquivalent({ graphA: localSGraph, graphB: serverSGetGraphRes.graph })) {
249
+ devLog('✗ Check: Session Keystone (S) dependency graphs mismatch between client and server!'); return;
364
250
  }
251
+ devLog('✓ Check: Session Keystone (S) dependency graphs are equivalent on client and server.');
365
252
 
366
253
  devLog('🎉 ALL PHASE 4.4B TRANSACTION SYNC CHECKS PASSED FLAWLESSLY! ✓');
367
254
  btn.textContent = '✓ 4.4B All Passed';