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