@ibgib/core-gib 0.1.58 → 0.1.60

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 (96) hide show
  1. package/CHANGELOG.md +9 -1
  2. package/dist/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-v1.d.mts.map +1 -1
  3. package/dist/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-v1.mjs +6 -2
  4. package/dist/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-v1.mjs.map +1 -1
  5. package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-types.d.mts +1 -1
  6. package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.d.mts +1 -1
  7. package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.d.mts.map +1 -1
  8. package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs +7 -11
  9. package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs.map +1 -1
  10. package/dist/sync/sync-peer/sync-peer-types.d.mts +24 -1
  11. package/dist/sync/sync-peer/sync-peer-types.d.mts.map +1 -1
  12. package/dist/sync/sync-peer/sync-peer-v1.d.mts +15 -4
  13. package/dist/sync/sync-peer/sync-peer-v1.d.mts.map +1 -1
  14. package/dist/sync/sync-peer/sync-peer-v1.mjs +120 -25
  15. package/dist/sync/sync-peer/sync-peer-v1.mjs.map +1 -1
  16. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-constants.d.mts +46 -0
  17. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-constants.d.mts.map +1 -0
  18. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-constants.mjs +45 -0
  19. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-constants.mjs.map +1 -0
  20. package/dist/sync/sync-peer/{sync-peer-websocket-receiver → sync-peer-websocket/sync-peer-websocket-receiver}/sync-peer-websocket-receiver-types.d.mts +2 -2
  21. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-types.d.mts.map +1 -0
  22. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-types.mjs.map +1 -0
  23. package/dist/sync/sync-peer/{sync-peer-websocket-receiver → sync-peer-websocket/sync-peer-websocket-receiver}/sync-peer-websocket-receiver-v1.d.mts +11 -8
  24. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.d.mts.map +1 -0
  25. package/dist/sync/sync-peer/{sync-peer-websocket-receiver → sync-peer-websocket/sync-peer-websocket-receiver}/sync-peer-websocket-receiver-v1.mjs +115 -61
  26. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.mjs.map +1 -0
  27. package/dist/sync/sync-peer/{sync-peer-websocket-receiver → sync-peer-websocket/sync-peer-websocket-receiver}/sync-websocket-peer-helpers.d.mts +3 -3
  28. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.d.mts.map +1 -0
  29. package/dist/sync/sync-peer/{sync-peer-websocket-receiver → sync-peer-websocket/sync-peer-websocket-receiver}/sync-websocket-peer-helpers.mjs +6 -6
  30. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.mjs.map +1 -0
  31. package/dist/sync/sync-peer/{sync-peer-websocket-sender → sync-peer-websocket/sync-peer-websocket-sender}/sync-peer-websocket-sender-types.d.mts +1 -1
  32. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-types.d.mts.map +1 -0
  33. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-types.mjs.map +1 -0
  34. package/dist/sync/sync-peer/{sync-peer-websocket-sender → sync-peer-websocket/sync-peer-websocket-sender}/sync-peer-websocket-sender-v1.d.mts +22 -4
  35. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-v1.d.mts.map +1 -0
  36. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-v1.mjs +447 -0
  37. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-v1.mjs.map +1 -0
  38. package/dist/sync/sync-saga-context/sync-saga-context-helpers.d.mts +22 -5
  39. package/dist/sync/sync-saga-context/sync-saga-context-helpers.d.mts.map +1 -1
  40. package/dist/sync/sync-saga-context/sync-saga-context-helpers.mjs +263 -28
  41. package/dist/sync/sync-saga-context/sync-saga-context-helpers.mjs.map +1 -1
  42. package/dist/sync/sync-saga-context/sync-saga-context-types.d.mts +13 -0
  43. package/dist/sync/sync-saga-context/sync-saga-context-types.d.mts.map +1 -1
  44. package/dist/sync/sync-saga-coordinator.d.mts +12 -1
  45. package/dist/sync/sync-saga-coordinator.d.mts.map +1 -1
  46. package/dist/sync/sync-saga-coordinator.mjs +106 -12
  47. package/dist/sync/sync-saga-coordinator.mjs.map +1 -1
  48. package/dist/sync/sync-types.d.mts +24 -0
  49. package/dist/sync/sync-types.d.mts.map +1 -1
  50. package/dist/sync/sync-types.mjs +0 -1
  51. package/dist/sync/sync-types.mjs.map +1 -1
  52. package/dist/sync/sync-withid.connect.respec.mjs +3 -3
  53. package/dist/sync/sync-withid.connect.respec.mjs.map +1 -1
  54. package/dist/sync/sync-withid.pingpong.respec.d.mts +11 -0
  55. package/dist/sync/sync-withid.pingpong.respec.d.mts.map +1 -0
  56. package/dist/sync/sync-withid.pingpong.respec.mjs +199 -0
  57. package/dist/sync/sync-withid.pingpong.respec.mjs.map +1 -0
  58. package/dist/witness/space/inner-space/inner-space-v1.d.mts.map +1 -1
  59. package/dist/witness/space/inner-space/inner-space-v1.mjs +1 -1
  60. package/dist/witness/space/inner-space/inner-space-v1.mjs.map +1 -1
  61. package/package.json +1 -1
  62. package/src/sync/docs/security-3b.md +92 -0
  63. package/src/sync/docs/security.md +107 -39
  64. package/src/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-v1.mts +6 -2
  65. package/src/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-types.mts +1 -1
  66. package/src/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mts +11 -14
  67. package/src/sync/sync-peer/sync-peer-types.mts +28 -1
  68. package/src/sync/sync-peer/sync-peer-v1.mts +127 -35
  69. package/src/sync/sync-peer/sync-peer-websocket/README.md +42 -0
  70. package/src/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-constants.mts +68 -0
  71. package/src/sync/sync-peer/{sync-peer-websocket-receiver → sync-peer-websocket/sync-peer-websocket-receiver}/sync-peer-websocket-receiver-types.mts +2 -2
  72. package/src/sync/sync-peer/{sync-peer-websocket-receiver → sync-peer-websocket/sync-peer-websocket-receiver}/sync-peer-websocket-receiver-v1.mts +128 -71
  73. package/src/sync/sync-peer/{sync-peer-websocket-receiver → sync-peer-websocket/sync-peer-websocket-receiver}/sync-websocket-peer-helpers.mts +8 -8
  74. package/src/sync/sync-peer/{sync-peer-websocket-sender → sync-peer-websocket/sync-peer-websocket-sender}/sync-peer-websocket-sender-types.mts +1 -1
  75. package/src/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-v1.mts +509 -0
  76. package/src/sync/sync-saga-context/sync-saga-context-helpers.mts +267 -36
  77. package/src/sync/sync-saga-context/sync-saga-context-types.mts +14 -0
  78. package/src/sync/sync-saga-coordinator.mts +148 -8
  79. package/src/sync/sync-types.mts +28 -4
  80. package/src/sync/sync-withid.connect.respec.mts +3 -3
  81. package/src/sync/sync-withid.pingpong.respec.mts +234 -0
  82. package/src/witness/space/inner-space/inner-space-v1.mts +4 -5
  83. package/dist/sync/sync-peer/sync-peer-websocket-receiver/sync-peer-websocket-receiver-types.d.mts.map +0 -1
  84. package/dist/sync/sync-peer/sync-peer-websocket-receiver/sync-peer-websocket-receiver-types.mjs.map +0 -1
  85. package/dist/sync/sync-peer/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.d.mts.map +0 -1
  86. package/dist/sync/sync-peer/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.mjs.map +0 -1
  87. package/dist/sync/sync-peer/sync-peer-websocket-receiver/sync-websocket-peer-helpers.d.mts.map +0 -1
  88. package/dist/sync/sync-peer/sync-peer-websocket-receiver/sync-websocket-peer-helpers.mjs.map +0 -1
  89. package/dist/sync/sync-peer/sync-peer-websocket-sender/sync-peer-websocket-sender-types.d.mts.map +0 -1
  90. package/dist/sync/sync-peer/sync-peer-websocket-sender/sync-peer-websocket-sender-types.mjs.map +0 -1
  91. package/dist/sync/sync-peer/sync-peer-websocket-sender/sync-peer-websocket-sender-v1.d.mts.map +0 -1
  92. package/dist/sync/sync-peer/sync-peer-websocket-sender/sync-peer-websocket-sender-v1.mjs +0 -282
  93. package/dist/sync/sync-peer/sync-peer-websocket-sender/sync-peer-websocket-sender-v1.mjs.map +0 -1
  94. package/src/sync/sync-peer/sync-peer-websocket-sender/sync-peer-websocket-sender-v1.mts +0 -321
  95. /package/dist/sync/sync-peer/{sync-peer-websocket-receiver → sync-peer-websocket/sync-peer-websocket-receiver}/sync-peer-websocket-receiver-types.mjs +0 -0
  96. /package/dist/sync/sync-peer/{sync-peer-websocket-sender → sync-peer-websocket/sync-peer-websocket-sender}/sync-peer-websocket-sender-types.mjs +0 -0
@@ -285,29 +285,29 @@ We still call `senderCoordinator.sync(...)` — the phase focus is on what `peer
285
285
 
286
286
  **Goal**: With identity fully established and transport connected, sync a single ibgib `X` from source to dest. Verify S evolves correctly per turn (`sync` pool), and X's full dependency graph arrives on dest. After commit, both sender and receiver durable spaces must contain: the same evolved I, the full S dependency graph, and the full X dependency graph.
287
287
 
288
- #### Phase 3A — Innerspace unit test (`sync-withid.fullsync.respec.mts`)
289
-
290
- - [ ] Create `sync-withid.fullsync.respec.mts`
291
- - [ ] Create `r1_alpha_v0_source` via `TestTransformer`
292
- - [ ] Call `senderCoordinator.sync({ domainIbGibs: [alpha], senderIdentity, senderSecret, ... })`
293
- - [ ] `ifWeMight` — `"alpha dep graph matches on source and dest"`: use `getDependencyGraph` + `graphsAreEquivalent`
294
- - [ ] `ifWeMight` — `"sessionIdentity evolved the expected number of times"`: assert `S.data.n` equals the known deterministic turn count
295
- - [ ] 🔲 **TODO**: Manually inspect the full session keystone graph after a first run and count the exact number of outgoing turns (Init + Delta(s) + Commit), then hard-code that number into this assertion
296
- - [ ] `ifWeMight` — `"sender durable space has I (evolved frame)"`: assert I1 addr is in `sourceSpace`
297
- - [ ] `ifWeMight` — `"receiver durable space has I (evolved frame)"`: assert I1 addr is in `destSpace`
298
- - [ ] `ifWeMight` — `"sender durable space has full S dep graph"`: use `getDependencyGraph` on S in `sourceSpace`
299
- - [ ] `ifWeMight` — `"receiver durable space has full S dep graph"`: use `getDependencyGraph` on S in `destSpace`
288
+ #### Phase 3A — Innerspace unit test (`sync-withid.pingpong.respec.mts`)
289
+
290
+ - [x] Create `sync-withid.pingpong.respec.mts`
291
+ - [x] Create `r1_alpha_v0_source` (represented by `xStone` test domain ibgib)
292
+ - [x] Call `senderCoordinator.sync({ domainIbGibs: [alpha], senderIdentity, senderSecret, ... })`
293
+ - [x] `ifWeMight` — `"alpha dep graph matches on source and dest"`: use `getDependencyGraph` + `graphsAreEquivalent`
294
+ - [x] `ifWeMight` — `"sessionIdentity evolved the expected number of times"`: assert `S.data.n` equals the known deterministic turn count
295
+ - [x] **TODO**: Manually inspect the full session keystone graph after a first run and count the exact number of outgoing turns (Init + Delta(s) + Commit), then hard-code that number into this assertion
296
+ - [x] `ifWeMight` — `"sender durable space has I (evolved frame)"`: assert I1 addr is in `sourceSpace`
297
+ - [x] `ifWeMight` — `"receiver durable space has I (evolved frame)"`: assert I1 addr is in `destSpace`
298
+ - [x] `ifWeMight` — `"sender durable space has full S dep graph"`: use `getDependencyGraph` on S in `sourceSpace`
299
+ - [x] `ifWeMight` — `"receiver durable space has full S dep graph"`: use `getDependencyGraph` on S in `destSpace`
300
300
 
301
301
  #### Phase 3B — Space-Gib integrated (manual)
302
302
 
303
- - [ ] Trigger a sync of a known test ibgib via `dev-tools.mts` (add "sync - fullsync" button to a new row)
304
- - [ ] Confirm S evolves on each outgoing turn (inspect frame `data.n` in debugger)
305
- - [ ] Confirm X's full dependency graph is present on the client after commit
306
- - [ ] Confirm X's full dependency graph is present on the server after commit
307
- - [ ] Confirm S's full dependency graph is present on the client after commit
308
- - [ ] Confirm S's full dependency graph is present on the server after commit
309
- - [ ] Confirm I's evolved frame (I1) is present on the client after commit
310
- - [ ] Confirm I's evolved frame (I1) is present on the server after commit
303
+ - [x] Trigger a sync of a known test ibgib via `dev-tools.mts` (add "sync - fullsync" button to a new row)
304
+ - [x] Confirm S evolves on each outgoing turn (inspect frame `data.n` in debugger)
305
+ - [x] Confirm X's full dependency graph is present on the client after commit
306
+ - [x] Confirm X's full dependency graph is present on the server after commit
307
+ - [x] Confirm S's full dependency graph is present on the client after commit
308
+ - [x] Confirm S's full dependency graph is present on the server after commit
309
+ - [x] Confirm I's evolved frame (I1) is present on the client after commit
310
+ - [x] Confirm I's evolved frame (I1) is present on the server after commit
311
311
 
312
312
 
313
313
  ---
@@ -320,14 +320,14 @@ The sync proper will not be called. The test only cares that the pre-connect ide
320
320
 
321
321
  #### Phase 1A — Innerspace unit test
322
322
 
323
- - [ ] Create `sync-with-identity-basic.respec.mts` with scaffold:
323
+ - [x] Create `sync-withid.establish.respec.mts` with scaffold:
324
324
  - `Metaspace_Innerspace` + two `InnerSpace_V1` (source/dest) + `SyncSagaCoordinator` pair + `newTestPeer()` factory
325
325
  - A `senderSecret` constant (test-only plaintext)
326
326
  - A `KeystoneService_V1` instance (new'd inline)
327
- - [ ] Add `respecfully` block: `"Phase 1: establishSessionIdentity"`
328
- - [ ] `ifWeMight` — `"creates sessionIdentity genesis (S) locally"`: assert `S^Stjp` was generated and exists in `sourceSpace`
329
- - [ ] `ifWeMight` — `"evolves senderIdentity (I → I1) with sync claim"`: assert `I1` frame has a proof whose `claim.verb === 'sync'` and `claim.target === S^Stjp`
330
- - [ ] `ifWeMight` — `"posts I1 and S to destSpace (receiver)"`: assert both addrs are retrievable from `destSpace`
327
+ - [x] Add `respecfully` block: `"Phase 1: establishSessionIdentity"`
328
+ - [x] `ifWeMight` — `"creates sessionIdentity genesis (S) locally"`: assert `S^Stjp` was generated and exists in `sourceSpace`
329
+ - [x] `ifWeMight` — `"evolves senderIdentity (I → I1) with sync claim"`: assert `I1` frame has a proof whose `claim.verb === 'sync'` and `claim.target === S^Stjp`
330
+ - [x] `ifWeMight` — `"posts I1 and S to destSpace (receiver)"`: assert both addrs are retrievable from `destSpace`
331
331
 
332
332
  #### Phase 1B — Space-Gib integrated (manual)
333
333
 
@@ -344,7 +344,7 @@ The sync proper will not be called. The test only cares that the pre-connect ide
344
344
 
345
345
  #### Phase 2A — Innerspace unit test
346
346
 
347
- - [x] Extend `sync-with-identity-basic.respec.mts` with a `respecfully` block: `"Phase 2: connect"` (Note: implemented in separate file `sync-withid.connect.respec.mts`)
347
+ - [x] Create `sync-withid.connect.respec.mts` with a `respecfully` block: `"Phase 2: connect"`
348
348
  - [x] `ifWeMight` — `"connect completes without error"`: call `peer.connect()` and assert no exception
349
349
  - [x] `ifWeMight` — `"connect pool is depleted by exactly one challenge"`: assert `S.data.pools['connect'].used` increased by the expected count
350
350
 
@@ -362,19 +362,87 @@ The sync proper will not be called. The test only cares that the pre-connect ide
362
362
 
363
363
  #### Phase 3A — Innerspace unit test
364
364
 
365
- - [ ] Extend `sync-with-identity-basic.respec.mts` or create `sync-with-identity-singletimeline.respec.mts`
366
- - [ ] Create `r1_alpha_v0_source` via `TestTransformer`
367
- - [ ] Call `senderCoordinator.sync({ domainIbGibs: [alpha], senderIdentity, senderSecret, ... })`
368
- - [ ] `ifWeMight` — `"alpha dep graph matches on source and dest"`: use `getDependencyGraph` + `graphsAreEquivalent`
369
- - [ ] `ifWeMight` — `"sessionIdentity evolved once per sync turn"`: assert `S.data.n` equals number of outgoing turns
365
+ - [x] Create `sync-withid.pingpong.respec.mts`
366
+ - [x] Create `r1_alpha_v0_source` via `TestTransformer` (represented by `xStone` test domain ibgib)
367
+ - [x] Call `senderCoordinator.sync({ domainIbGibs: [alpha], senderIdentity, senderSecret, ... })`
368
+ - [x] `ifWeMight` — `"alpha dep graph matches on source and dest"`: use `getDependencyGraph` + `graphsAreEquivalent`
369
+ - [x] `ifWeMight` — `"sessionIdentity evolved once per sync turn"`: assert `S.data.n` equals number of outgoing turns
370
370
 
371
371
  #### Phase 3B — Space-Gib integrated (manual)
372
372
 
373
- - [ ] Trigger a sync of a known test ibgib via `dev-tools.mts` or equivalent UI
374
- - [ ] Confirm S evolves on each outgoing turn (inspect frame `data.n` in debugger)
375
- - [ ] Confirm X's full dependency graph is present on the client after commit
376
- - [ ] Confirm X's full dependency graph is present on the server after commit
377
- - [ ] Confirm S's full dependency graph is present on the client after commit
378
- - [ ] Confirm S's full dependency graph is present on the server after commit
379
- - [ ] Confirm I's full dependency graph is present on the client after commit
380
- - [ ] Confirm I's full dependency graph is present on the server after commit
373
+ - [x] Trigger a sync of a known test ibgib via `dev-tools.mts` or equivalent UI
374
+ - [x] Confirm S evolves on each outgoing turn (inspect frame `data.n` in debugger)
375
+ - [x] Confirm X's full dependency graph is present on the client after commit
376
+ - [x] Confirm X's full dependency graph is present on the server after commit
377
+ - [x] Confirm S's full dependency graph is present on the client after commit
378
+ - [x] Confirm S's full dependency graph is present on the server after commit
379
+ - [x] Confirm I's full dependency graph is present on the client after commit
380
+ - [x] Confirm I's full dependency graph is present on the server after commit
381
+
382
+ ---
383
+
384
+ ### Phase 4 — Advanced Data and Conflict Scenarios
385
+
386
+ **Goal**: Extend the WebSocket peer and Space-Gib interface to manually execute and verify all advanced data and conflict scenarios currently covered by the InnerSpace unit tests.
387
+
388
+ For each scenario, verify automated innerspace tests (A) are fully functional, and create manual websocket peer tests (B) with corresponding buttons/UI elements.
389
+
390
+ #### 1. Sync InnerSpace (Basic Push Sync)
391
+ - [ ] Phase 4.1A — Automated InnerSpace Verification (`sync-innerspace.respec.mts`)
392
+ - [ ] Phase 4.1B — WebSocket Peer Manual Verification (integrated via Dev Tools)
393
+ * Tests basic push sync of a single timeline and its mutations from Source to Destination.
394
+ * Verifies that the target timeline tip and its dependency graph successfully arrive at the destination.
395
+
396
+ #### 2. Sync Constants (No TJP)
397
+ - [ ] Phase 4.2A — Automated InnerSpace Verification (`sync-innerspace-constants.respec.mts`)
398
+ - [ ] Phase 4.2B — WebSocket Peer Manual Verification (integrated via Dev Tools)
399
+ * Tests syncing "constants" (ibGibs without timelines/TJPs) and verifies that dependencies (linked constants) are resolved.
400
+ * Ensures idempotency/smart diffing (payloads are not re-sent if they already exist in the destination space).
401
+
402
+ #### 3. Sync Destination with Partial History
403
+ - [ ] Phase 4.3A — Automated InnerSpace Verification (`sync-innerspace-partial-update.respec.mts`)
404
+ - [ ] Phase 4.3B — WebSocket Peer Manual Verification (integrated via Dev Tools)
405
+ * Tests push synchronization when the destination already contains a partial timeline history (e.g., up to V1), but the sender has newer frames (V2).
406
+ * Verifies that only the delta is transmitted and correctly linked to the existing history at the destination.
407
+
408
+ #### 4. Sync Deep History Updates
409
+ - [ ] Phase 4.4A — Automated InnerSpace Verification (`sync-innerspace-deep-updates.respec.mts`)
410
+ - [ ] Phase 4.4B — WebSocket Peer Manual Verification (integrated via Dev Tools)
411
+ * Tests push synchronization of a timeline tip with a deep mutation history (multiple updates).
412
+ * Verifies that the destination receives all intermediate frames, preserving the full timeline history and graph integrity.
413
+
414
+ #### 5. Sync Destination Ahead (Remote Newer)
415
+ - [ ] Phase 4.5A — Automated InnerSpace Verification (`sync-innerspace-dest-ahead.respec.mts`)
416
+ - [ ] Phase 4.5B — WebSocket Peer Manual Verification (integrated via Dev Tools)
417
+ * Tests synchronization when the destination (remote) actually has a newer frame (V2) than the sender's local tip (V1).
418
+ * Verifies that the sender learns of the remote tip and pulls it down so both client and server converge to the dest-ahead tip.
419
+
420
+ #### 6. Sync Multiple Independent Timelines
421
+ - [ ] Phase 4.6A — Automated InnerSpace Verification (`sync-innerspace-multiple-timelines.respec.mts`)
422
+ - [ ] Phase 4.6B — WebSocket Peer Manual Verification (integrated via Dev Tools)
423
+ * Tests synchronization of multiple independent timelines (e.g., Timeline A and Timeline B) in a single sync coordinator call.
424
+ * Verifies that both timeline tips and their respective dependency graphs are transferred and updated correctly.
425
+
426
+ #### 7. Basic Divergence Conflict Resolution
427
+ - [ ] Phase 4.7A — Automated InnerSpace Verification (`sync-conflict-basic-divergence.respec.mts`)
428
+ - [ ] Phase 4.7B — WebSocket Peer Manual Verification (integrated via Dev Tools)
429
+ * Tests divergence when source and destination edit different fields on a shared base timeline simultaneously.
430
+ * Verifies that optimistic merge automatically produces a merged tip (V3) containing both edits and records the graft metadata (`graftbase`, `graftorphan`).
431
+
432
+ #### 8. Divergence with Related Timelines
433
+ - [ ] Phase 4.8A — Automated InnerSpace Verification (`sync-conflict-basic-multitimelines.respec.mts`)
434
+ - [ ] Phase 4.8B — WebSocket Peer Manual Verification (integrated via Dev Tools)
435
+ * Tests advanced divergence where one of the divergent updates also references/relates a new independent timeline (Beta).
436
+ * Verifies that during optimistic merge, the dependent timeline is synced automatically alongside the merged tip.
437
+
438
+ #### 9. Text Field Merge (LCS) Conflict Resolution
439
+ - [ ] Phase 4.9A — Automated InnerSpace Verification (`sync-conflict-text-merge.respec.mts`)
440
+ - [ ] Phase 4.9B — WebSocket Peer Manual Verification (integrated via Dev Tools)
441
+ * Tests automatic merging of conflicting string edits within the `ibgib.data.text` field using the LCS (Longest Common Subsequence) merge algorithm.
442
+ * Verifies merging of simple appends (beginning vs. end) and interleaved edits in different paragraphs.
443
+
444
+ #### 10. Advanced Multi-Round/Timeline Permutations
445
+ - [ ] Phase 4.10A — Automated InnerSpace Verification (`sync-conflict-adv-multitimelines.respec.mts`)
446
+ - [ ] Phase 4.10B — WebSocket Peer Manual Verification (integrated via Dev Tools)
447
+ * Tests complex multi-round/timeline permutations with parallel divergent edits across multiple rounds.
448
+ * Verifies that nested or sequential merges resolve correctly using the optimistic graft strategy.
@@ -8,7 +8,7 @@ import { IbGib_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';
8
8
  import { GLOBAL_LOG_A_LOT } from '../../../core-constants.mjs';
9
9
  import { SyncPeer_V1 } from '../sync-peer-v1.mjs';
10
10
  import { SyncSagaContextIbGib_V1 } from '../../sync-saga-context/sync-saga-context-types.mjs';
11
- import { authenticateContext } from '../../sync-saga-context/sync-saga-context-helpers.mjs';
11
+ import { authenticateContextIntrinsically } from '../../sync-saga-context/sync-saga-context-helpers.mjs';
12
12
  import { IbGibSpaceAny } from '../../../witness/space/space-base-v1.mjs';
13
13
  import {
14
14
  InitializeSyncPeerHttpReceiverOpts,
@@ -160,13 +160,16 @@ export class SyncPeerHttpReceiver_V1
160
160
 
161
161
  // Put control ibgibs into durable space
162
162
  const allControlIbGibs = [context, ...payloadIbGibsControl];
163
+ if (context.signedSessionIdentity) {
164
+ allControlIbGibs.push(context.signedSessionIdentity);
165
+ }
163
166
  for (const ibGib of allControlIbGibs) {
164
167
  await putInSpace({ space: localSpace, ibGibs: [ibGib] });
165
168
  await registerNewIbGib({ space: localSpace, ibGib });
166
169
  }
167
170
 
168
171
  // Auth verification (Bill architecture: turn-based context signing)
169
- const authErrors = await authenticateContext({
172
+ const authErrors = await authenticateContextIntrinsically({
170
173
  context,
171
174
  space: localSpace,
172
175
  });
@@ -186,6 +189,7 @@ export class SyncPeerHttpReceiver_V1
186
189
  metaspace: localMetaspace,
187
190
  mySpace: localSpace,
188
191
  myTempSpace: localTempSpace,
192
+ peer: this,
189
193
  });
190
194
 
191
195
  return responseCtx || undefined;
@@ -45,7 +45,7 @@ export interface SyncPeerInnerspaceOptions {
45
45
  */
46
46
  receiverTempSpace?: IbGibSpaceAny;
47
47
  /**
48
- * The sender coordinator, used for authentication-related (k eystones).
48
+ * The sender coordinator, used for authentication-related (keystones).
49
49
  */
50
50
  senderCoordinator?: SyncSagaCoordinator;
51
51
  }
@@ -12,14 +12,14 @@ import { SyncPeer_V1 } from '../sync-peer-v1.mjs';
12
12
  import { putInSpace, registerNewIbGib } from '../../../witness/space/space-helper.mjs';
13
13
  import { SyncSagaContextIbGib_V1, } from '../../sync-saga-context/sync-saga-context-types.mjs';
14
14
  import { SyncPeerInnerspaceData_V1, SyncPeerInnerspaceIbGib_V1, SyncPeerInnerspaceOptions, SyncPeerInnerspaceRel8ns_V1 } from './sync-peer-innerspace-types.mjs';
15
- import { authenticateContext } from '../../sync-saga-context/sync-saga-context-helpers.mjs';
15
+ import { authenticateContextIntrinsically } from '../../sync-saga-context/sync-saga-context-helpers.mjs';
16
16
  import { MetaspaceService } from '../../../witness/space/metaspace/metaspace-types.mjs';
17
17
  import { SyncSagaCoordinator } from '../../sync-saga-coordinator.mjs';
18
18
  import { ConnectSyncPeerOpts, InitializeSyncPeerOpts } from '../sync-peer-types.mjs';
19
19
  import { getSyncSagaFrameDependencyGraph, putInSpace_dnasThenNonDnas } from '../../sync-helpers.mjs';
20
20
  import { getDependencyGraph } from '../../../common/other/graph-helper.mjs';
21
21
  import { SyncStage } from '../../sync-constants.mjs';
22
- import { toDto } from '../../../common/other/ibgib-helper.mjs';import { KeystoneIbGib_V1 } from '../../../keystone/keystone-types.mjs';
22
+ import { toDto } from '../../../common/other/ibgib-helper.mjs'; import { KeystoneIbGib_V1 } from '../../../keystone/keystone-types.mjs';
23
23
 
24
24
 
25
25
  const logalot = GLOBAL_LOG_A_LOT;
@@ -52,7 +52,7 @@ export interface InitializeSyncPeerInnerspaceOpts extends InitializeSyncPeerOpts
52
52
  */
53
53
  receiverTempSpace?: IbGibSpaceAny;
54
54
  /**
55
- * The sender coordinator, used for authentication-related (k eystones).
55
+ * The sender coordinator, used for authentication-related (keystones).
56
56
  */
57
57
  senderCoordinator?: SyncSagaCoordinator;
58
58
  }
@@ -205,6 +205,7 @@ export class SyncPeerInnerspace_V1 extends SyncPeer_V1<ConnectSyncPeerInnerspace
205
205
 
206
206
  const { sagaFrame } = context;
207
207
 
208
+
208
209
  // The context has already been validated, authenticated and authorized at this point.
209
210
 
210
211
  // #region sanity validation assertions
@@ -242,8 +243,7 @@ export class SyncPeerInnerspace_V1 extends SyncPeer_V1<ConnectSyncPeerInnerspace
242
243
  const msg = msgStones[0];
243
244
  if (!msg.data) { throw new Error(`(UNEXPECTED) sync saga message ibgib.data falsy? (E: 61ec18743988ad3cbab2072d1dd69826)`); }
244
245
 
245
-
246
- // this is where we did the i dentityIbGibs
246
+ // this is where we did the identityIbGibs
247
247
 
248
248
  // send the context itself, then send the payload ibgibs separately.
249
249
  // in this innerspace, this just means putting the control ibgibs
@@ -257,6 +257,9 @@ export class SyncPeerInnerspace_V1 extends SyncPeer_V1<ConnectSyncPeerInnerspace
257
257
  const payloadIbGibsControl = [
258
258
  msg, sagaFrame, context
259
259
  ].map(x => toDto({ ibGib: x }));
260
+ if (context.signedSessionIdentity) {
261
+ payloadIbGibsControl.push(toDto({ ibGib: context.signedSessionIdentity }));
262
+ }
260
263
  if (logalot) { console.log(`${lc} putting into receiverSpace: ${receiverSpace.ib} (I: 1ba18b14a26bdd0e7800da4812898826)`); }
261
264
  await putInSpace({
262
265
  ibGibs: payloadIbGibsControl,
@@ -288,20 +291,14 @@ export class SyncPeerInnerspace_V1 extends SyncPeer_V1<ConnectSyncPeerInnerspace
288
291
  // the payload ibgibs. so the receiver coordinator should be ready
289
292
  // to do its thing.
290
293
 
291
- // Auth verification (Bill architecture: turn-based context signing)
292
- const authErrors = await authenticateContext({
293
- context,
294
- space: receiverSpace,
295
- });
296
- if (authErrors.length > 0) {
297
- throw new Error(`Context authentication failed: ${authErrors.join(', ')} (E: d34b8ad98d84e1ba8d8f7facd288826)`);
298
- }
294
+ // NOTE: We have already validated/authenticated/authorized context at this point, as we called it before invoking this method (sendContextRequest)
299
295
 
300
296
  const responseCtx = await receiverCoordinator.continueSync({
301
297
  sagaContext: context,
302
298
  metaspace: receiverMetaspace,
303
299
  mySpace: receiverSpace,
304
300
  myTempSpace: receiverTempSpace,
301
+ peer: this,
305
302
  });
306
303
 
307
304
  if (logalot) { console.log(`${lc} receiverCoordinator.continueSync responseCtx: ${responseCtx ? pretty(responseCtx) : 'undefined'} (I: fb2831decde1f2b3589021f85ab19126)`); }
@@ -328,7 +325,7 @@ export class SyncPeerInnerspace_V1 extends SyncPeer_V1<ConnectSyncPeerInnerspace
328
325
  if (!msgResponse.data) { throw new Error(`(UNEXPECTED) sync saga message ibgib.data falsy? (E: 61ec18743988ad3cbab2072d1dd69826)`); }
329
326
 
330
327
  const responsePayloadIbGibsControl = [
331
- msgResponse, responseCtx.sagaFrame, context
328
+ msgResponse, responseCtx.sagaFrame, responseCtx
332
329
  ].map(x => toDto({ ibGib: x }));
333
330
  // ...put into sender's durable space
334
331
  await putInSpace({
@@ -3,6 +3,7 @@
3
3
  */
4
4
 
5
5
  import { IbGibData_V1, IbGibRel8ns_V1, IbGib_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';
6
+ import { IbGibAddr } from '@ibgib/ts-gib/dist/types.mjs';
6
7
 
7
8
  import { SubjectWitness } from '../../common/pubsub/subject/subject-types.mjs';
8
9
  import { SyncSagaContextData_V1, SyncSagaContextIbGib_V1, SyncSagaContextRel8ns_V1 } from '../sync-saga-context/sync-saga-context-types.mjs';
@@ -162,6 +163,12 @@ export interface SyncPeerWitness<TInitializeOpts extends InitializeSyncPeerOpts
162
163
  */
163
164
  payloadIbGibsDomainReceived$: SubjectWitness<IbGib_V1>;
164
165
 
166
+ currentSessionIdentity: KeystoneIbGib_V1 | undefined;
167
+ /**
168
+ * convenience getter for {@link currentSessionIdentity}
169
+ */
170
+ get currentSessionIdentityAddr(): IbGibAddr | undefined;
171
+
165
172
  /**
166
173
  * Pre-connect phase: creates the session keystone (S) locally, evolves
167
174
  * `senderIdentity` (I → I1) with a `sync` claim targeting S, and posts
@@ -174,7 +181,7 @@ export interface SyncPeerWitness<TInitializeOpts extends InitializeSyncPeerOpts
174
181
  * this reference for the remainder of the saga. The name `newSenderIdentity`
175
182
  * (I1) is intentionally scoped only within this method to avoid confusion.
176
183
  */
177
- establishSessionIdentity(): Promise<KeystoneIbGib_V1 | undefined>;
184
+ establishSessionIdentity(): Promise<void>;
178
185
 
179
186
  /**
180
187
  * Establishes the connection context.
@@ -184,4 +191,24 @@ export interface SyncPeerWitness<TInitializeOpts extends InitializeSyncPeerOpts
184
191
  * @param opts Connection options, including the sagaId for the upcoming sync saga.
185
192
  */
186
193
  connect(opts?: { sagaId?: string }): Promise<void>;
194
+
195
+ // /**
196
+ // * Returns the sender's long-lived primary/domain identity.
197
+ // */
198
+ // getSenderIdentity(): KeystoneIbGib_V1 | undefined;
199
+
200
+ /**
201
+ * Evolves the session identity (S_n -> S_n+1) and signs targeting
202
+ * contextAddr for the **sync** verb. This is in contrast to signing for
203
+ * the "connect" verb, for which you use {@link signContextConnect}
204
+ */
205
+ signContext(opts: { contextAddr: IbGibAddr }): Promise<KeystoneIbGib_V1 | undefined>;
206
+
207
+ /**
208
+ * Evolves the session identity (S_n -> S_n+1) solving the demanded connect
209
+ * challenges. This is NOT for signing session when doing the ping pong of
210
+ * sync protocol. For that, you use {@link signContext}
211
+ */
212
+ signContextConnect(opts: { challengeUuid: string, demandedIds: string[] }): Promise<KeystoneIbGib_V1 | undefined>;
213
+
187
214
  }
@@ -7,11 +7,8 @@
7
7
  import { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
8
8
  import { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';
9
9
  import { IbGib_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';
10
- import { IbGibAddr } from '@ibgib/ts-gib/dist/types.mjs';
11
- import { validateIbGibIntrinsically } from '@ibgib/ts-gib/dist/V1/validate-helper.mjs';
12
10
 
13
11
  import { GLOBAL_LOG_A_LOT } from '../../core-constants.mjs';
14
- import { SYNC_MSG_REL8N_NAME, SYNC_SAGA_PAYLOAD_ADDRS_DOMAIN } from '../sync-constants.mjs';
15
12
  import { SubjectWitness } from '../../common/pubsub/subject/subject-types.mjs';
16
13
  import { SyncSagaContextIbGib_V1 } from '../sync-saga-context/sync-saga-context-types.mjs';
17
14
  import {
@@ -19,19 +16,18 @@ import {
19
16
  SyncPeerRel8ns_V1, SyncPeerWitness
20
17
  } from './sync-peer-types.mjs';
21
18
  import { LightWitnessBase_V1 } from '../../witness/light-witness-base-v1.mjs';
22
- import { IbGibSpaceAny } from '../../witness/space/space-base-v1.mjs';
23
19
  import { newupSubject } from '../../common/pubsub/subject/subject-helper.mjs';
24
- import { authenticateContext, authorizeContext, validateContextAndSagaFrame } from '../sync-saga-context/sync-saga-context-helpers.mjs';
20
+ import { authenticateContextIntrinsically, validateContextAndSagaFrame } from '../sync-saga-context/sync-saga-context-helpers.mjs';
25
21
  import { getFromSpace } from '../../witness/space/space-helper.mjs';
26
22
  import { getFullSyncSagaHistory, deriveSessionSecret } from '../sync-helpers.mjs';
27
- import { SyncSagaFrameDependencyGraph } from '../sync-types.mjs';
23
+ import { SessionGenesisFrameDetails, SyncSagaFrameDependencyGraph } from '../sync-types.mjs';
28
24
  import { KeystoneService_V1 } from '../../keystone/keystone-service-v1.mjs';
29
25
  import { KeystoneIbGib_V1 } from '../../keystone/keystone-types.mjs';
30
- import { KEYSTONE_VERB_SYNC } from '../../keystone/keystone-constants.mjs';
26
+ import { KEYSTONE_VERB_CONNECT, KEYSTONE_VERB_SYNC, POOL_ID_CONNECT, } from '../../keystone/keystone-constants.mjs';
27
+ import { getTjpAddr } from '../../common/other/ibgib-helper.mjs';
28
+ import { IbGibAddr } from '@ibgib/ts-gib/dist/types.mjs';
31
29
 
32
30
  const logalot = GLOBAL_LOG_A_LOT;
33
- const logalotControlDomain = false;
34
- const lcControlDomain = '[ControlDomain]';
35
31
 
36
32
 
37
33
  /**
@@ -54,6 +50,100 @@ export abstract class SyncPeer_V1<
54
50
 
55
51
  public opts: TInitializeOpts | undefined;
56
52
  public payloadIbGibsDomainReceived$!: SubjectWitness<IbGib_V1>;
53
+ public currentSessionIdentity: KeystoneIbGib_V1 | undefined;
54
+ public get currentSessionIdentityAddr(): IbGibAddr | undefined {
55
+ return this.currentSessionIdentity ?
56
+ getIbGibAddr({ ibGib: this.currentSessionIdentity }) :
57
+ undefined;
58
+ }
59
+
60
+ // public getSenderIdentity(): KeystoneIbGib_V1 | undefined {
61
+ // return this.opts?.senderIdentity;
62
+ // }
63
+
64
+ public async signContext({
65
+ contextAddr,
66
+ }: {
67
+ contextAddr: IbGibAddr;
68
+ }): Promise<KeystoneIbGib_V1 | undefined> {
69
+ const lc = `${this.lc}[${this.signContext.name}]`;
70
+ try {
71
+ if (!this.currentSessionIdentity) {
72
+ return undefined;
73
+ }
74
+ if (!this.opts) { throw new Error(`opts not initialized. (E: bcf5978aed789b0ebcbdc51971ebe826)`); }
75
+ const { fnSenderSecret, sagaId, localMetaspace, localSpace } = this.opts;
76
+ if (!fnSenderSecret) { throw new Error(`fnSenderSecret not initialized. (E: 207fd292a2e8c53c05fd0a74a4ae6d26)`); }
77
+ if (!sagaId) { throw new Error(`sagaId not initialized. (E: f2e35cc13ed873b638116188119d1826)`); }
78
+
79
+ const senderSecret = await fnSenderSecret();
80
+ const sessionSecret = await deriveSessionSecret({ senderSecret, sagaId });
81
+
82
+ const keystoneSvc = new KeystoneService_V1();
83
+ const evolved = await keystoneSvc.sign({
84
+ latestKeystone: this.currentSessionIdentity,
85
+ masterSecret: sessionSecret,
86
+ claim: {
87
+ verb: KEYSTONE_VERB_SYNC,
88
+ target: contextAddr,
89
+ },
90
+ metaspace: localMetaspace,
91
+ space: localSpace,
92
+ });
93
+
94
+ this.currentSessionIdentity = evolved;
95
+ return evolved;
96
+ } catch (error) {
97
+ console.error(`${lc} ${extractErrorMsg(error)}`);
98
+ throw error;
99
+ }
100
+ }
101
+
102
+ /**
103
+ * Evolves the session identity (S_n -> S_n+1) solving the demanded connect challenges.
104
+ */
105
+ public async signContextConnect({
106
+ challengeUuid,
107
+ demandedIds,
108
+ }: {
109
+ challengeUuid: string;
110
+ demandedIds: string[];
111
+ }): Promise<KeystoneIbGib_V1 | undefined> {
112
+ const lc = `${this.lc}[${this.signContextConnect.name}]`;
113
+ try {
114
+ if (!this.currentSessionIdentity) {
115
+ return undefined;
116
+ }
117
+ if (!this.opts) { throw new Error(`opts not initialized. (E: bcf5978aed789b0ebcbdc51971ebe826)`); }
118
+ const { fnSenderSecret, sagaId, localMetaspace, localSpace } = this.opts;
119
+ if (!fnSenderSecret) { throw new Error(`fnSenderSecret not initialized. (E: 207fd292a2e8c53c05fd0a74a4ae6d26)`); }
120
+ if (!sagaId) { throw new Error(`sagaId not initialized. (E: f2e35cc13ed873b638116188119d1826)`); }
121
+
122
+ const senderSecret = await fnSenderSecret();
123
+ const sessionSecret = await deriveSessionSecret({ senderSecret, sagaId });
124
+
125
+ const keystoneSvc = new KeystoneService_V1();
126
+ const evolved = await keystoneSvc.sign({
127
+ latestKeystone: this.currentSessionIdentity,
128
+ masterSecret: sessionSecret,
129
+ poolId: POOL_ID_CONNECT,
130
+ requiredChallengeIds: demandedIds,
131
+ claim: {
132
+ verb: KEYSTONE_VERB_CONNECT,
133
+ target: challengeUuid,
134
+ },
135
+ metaspace: localMetaspace,
136
+ space: localSpace,
137
+ });
138
+
139
+ this.currentSessionIdentity = evolved;
140
+ return evolved;
141
+ } catch (error) {
142
+ console.error(`${lc} ${extractErrorMsg(error)}`);
143
+ throw error;
144
+ }
145
+ }
146
+
57
147
 
58
148
  get classname(): string {
59
149
  if (!this.data) { throw new Error(`(UNEXPECTED) this.data falsy? (E: 1ab1841e9338b54f3aa615fa37024826)`); }
@@ -127,7 +217,7 @@ export abstract class SyncPeer_V1<
127
217
  * hold a reference for subsequent per-turn signing. The name
128
218
  * `newSenderIdentity` (I1) is scoped only within this method.
129
219
  */
130
- public async establishSessionIdentity(): Promise<KeystoneIbGib_V1 | undefined> {
220
+ public async establishSessionIdentity(): Promise<void> {
131
221
  const lc = `${this.lc}[${this.establishSessionIdentity.name}]`;
132
222
  try {
133
223
  if (logalot) { console.log(`${lc} starting... (I: f2a1b3c4d5e6f7a8b9c0d1e2f3a4b526)`); }
@@ -141,6 +231,9 @@ export abstract class SyncPeer_V1<
141
231
  if (logalot) { console.log(`${lc} no senderIdentity/fnSenderSecret — skipping establish (I: f29348a77d1542326d14043ea4b69126)`); }
142
232
  return undefined;
143
233
  }
234
+ const senderIdentityAddr = getIbGibAddr({ ibGib: senderIdentity });
235
+ const senderIdentityTjpAddr = getTjpAddr({ ibGib: senderIdentity });
236
+ if (!senderIdentityTjpAddr) { throw new Error(`(UNEXPECTED) senderIdentityTjpAddr falsy? (E: d5d8c3ab25a83a2c127904fe96de1526)`); }
144
237
 
145
238
  if (!sagaId) { throw new Error(`(UNEXPECTED) sagaId falsy? Must be set in initializeOpts before calling establishSessionIdentity. (E: c6ba389d51b8af07d82458f875cf9826)`); }
146
239
 
@@ -155,10 +248,19 @@ export abstract class SyncPeer_V1<
155
248
  if (!this.opts.sessionConnectPoolConfig) { throw new Error(`(UNEXPECTED) opts.sessionConnectPoolConfig falsy? (E: 3351fd566eb8bbd2f821bb08c4419826)`); }
156
249
  if (!this.opts.sessionSyncPoolConfig) { throw new Error(`(UNEXPECTED) opts.sessionSyncPoolConfig falsy? (E: dbffa810d9e7ff6079088deb5b8e7826)`); }
157
250
 
251
+ // session genesis keystone should have soft links to both
252
+ // targetAddrs and the sender identity that spawned it.
253
+ const frameDetails: SessionGenesisFrameDetails = {
254
+ senderIdentityAddr,
255
+ senderIdentityTjpAddr,
256
+ }
257
+ if (this.opts.targetAddrs) {
258
+ frameDetails.targetAddrs = this.opts.targetAddrs
259
+ }
158
260
  const sessionIdentity = await keystoneSvc.genesis({
159
261
  masterSecret: sessionSecret,
160
262
  configs: [this.opts.sessionConnectPoolConfig, this.opts.sessionSyncPoolConfig],
161
- frameDetails: this.opts.targetAddrs ? { targetAddrs: this.opts.targetAddrs } : undefined,
263
+ frameDetails,
162
264
  metaspace: localMetaspace,
163
265
  space: localSpace,
164
266
  });
@@ -179,7 +281,7 @@ export abstract class SyncPeer_V1<
179
281
  // Step 3: Post both to the receiver (peer-specific).
180
282
  await this.postEstablishToReceiver({ newSenderIdentity, sessionIdentity });
181
283
 
182
- return sessionIdentity;
284
+ this.currentSessionIdentity = sessionIdentity;
183
285
  } catch (error) {
184
286
  console.error(`${lc} ${extractErrorMsg(error)}`);
185
287
  throw error;
@@ -257,16 +359,12 @@ export abstract class SyncPeer_V1<
257
359
  // }
258
360
  // }
259
361
 
260
-
261
-
262
- protected async authenticateValidateAuthorize({
362
+ protected async authenticateAndValidate({
263
363
  context,
264
- fullSagaHistory,
265
364
  }: {
266
365
  context: SyncSagaContextIbGib_V1,
267
- fullSagaHistory: SyncSagaFrameDependencyGraph[],
268
366
  }): Promise<void> {
269
- const lc = `${this.lc}[${this.authenticateValidateAuthorize.name}]`;
367
+ const lc = `${this.lc}[${this.authenticateAndValidate.name}]`;
270
368
  try {
271
369
  if (logalot) { console.log(`${lc} starting... (I: add238055cd84a222c5b8c89913af526)`); }
272
370
 
@@ -274,7 +372,8 @@ export abstract class SyncPeer_V1<
274
372
  const { localSpace } = this.opts;
275
373
 
276
374
  // first authenticate, because invalid authn is a non-starter
277
- const authenticationErrors = await authenticateContext({
375
+ // (already validated intrinsically)
376
+ const authenticationErrors = await authenticateContextIntrinsically({
278
377
  context,
279
378
  space: localSpace,
280
379
  });
@@ -288,12 +387,6 @@ export abstract class SyncPeer_V1<
288
387
  if (validationErrors.length > 0) {
289
388
  throw new Error(`invalid context received. validationErrors: ${validationErrors} (E: 8b34c875c968af29bc433138e57a7826)`);
290
389
  }
291
- // we have a valid authentication that points to a valid context,
292
- // but what exactly is authorized ?
293
- const authorizationErrors = await authorizeContext({ context, fullSagaHistory });
294
- if (authorizationErrors.length > 0) {
295
- throw new Error(`invalid context authorization. authorizationErrors: ${authorizationErrors} (E: 8ddc284a758cf10ba829334c1babb826)`);
296
- }
297
390
  } catch (error) {
298
391
  console.error(`${lc} ${extractErrorMsg(error)}`);
299
392
  throw error;
@@ -361,14 +454,12 @@ export abstract class SyncPeer_V1<
361
454
  // this is not just happening on the client, but this peer may be
362
455
  // the one receiving the context as well.
363
456
 
364
- const sagaHistory_beforeSend = await getFullSyncSagaHistory({
365
- sagaIbGib: context.sagaFrame,
366
- space: this.opts.localSpace
367
- });
457
+ // const sagaHistory_beforeSend = await getFullSyncSagaHistory({
458
+ // sagaIbGib: context.sagaFrame,
459
+ // space: this.opts.localSpace
460
+ // });
368
461
 
369
- await this.authenticateValidateAuthorize({
370
- context, fullSagaHistory: sagaHistory_beforeSend,
371
- });
462
+ await this.authenticateAndValidate({ context });
372
463
 
373
464
  // at this point, we have a valid, authenticated, authorized context
374
465
 
@@ -389,9 +480,10 @@ export abstract class SyncPeer_V1<
389
480
  space: this.opts.localSpace
390
481
  });
391
482
 
392
- await this.authenticateValidateAuthorize({
393
- context, fullSagaHistory: sagaHistory_afterSend,
394
- });
483
+ // NOTE: I think this is the wrong place for this, as we must do this in the peer **before** storing any control ibgibs. This needs to be done in the continueSync I _think_ (not sure yet)
484
+ // await this.authenticateValidateAuthorize({
485
+ // context, fullSagaHistory: sagaHistory_afterSend,
486
+ // });
395
487
 
396
488
  return response;
397
489
  } else {