@ibgib/core-gib 0.1.41 → 0.1.42

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.
@@ -2,7 +2,10 @@
2
2
  * @module sync-conflict-text-merge.respec
3
3
  *
4
4
  * Verifies text merge (LCS algorithm) in SyncSagaCoordinator.
5
- * Tests same-field content conflicts with various text patterns.
5
+ *
6
+ * Tests ibgib.data.text conflicts with various text patterns, which with
7
+ * optimistic merging. This should trigger the automatic text merging which is
8
+ * different than the replay of dna for other types of conflict grafts.
6
9
  */
7
10
 
8
11
  import {
@@ -102,21 +105,20 @@ await respecfully(sir, `Text merge (LCS) conflict resolution`, async () => {
102
105
  description: 'Create timeline with initial text, sync to establish common history'
103
106
  });
104
107
 
105
- if (logalot) { console.log(`${lc} R1: Creating initial content with text...`); }
108
+ if (logalot) { console.log(`${lc} R1: Creating initial alpha with text...`); }
106
109
 
107
- // Create content with initial text on source
110
+ // Create alpha with initial text on source
108
111
  const INITIAL_TEXT = "This is the initial quiz question.\nIt has multiple lines.\nStudents will answer this.";
109
112
 
110
- const r1_content_v0_source = await testTransformer.create({
111
- atom: 'content',
113
+ const r1_alpha_v0_source = await testTransformer.create({
114
+ atom: 'alpha',
112
115
  in: 'source',
113
116
  data: { text: INITIAL_TEXT },
114
- name: 'r1_content_v0_source'
117
+ name: 'r1_alpha_v0_source'
115
118
  });
119
+ const alpha_tjpAddr = getTjpAddr({ ibGib: r1_alpha_v0_source.ibGib, defaultIfNone: 'incomingAddr' })!;
116
120
 
117
- const content_tjpAddr = getTjpAddr({ ibGib: r1_content_v0_source.ibGib, defaultIfNone: 'incomingAddr' })!;
118
-
119
- if (logalot) { console.log(`${lc} R1: Syncing initial content to dest...`); }
121
+ if (logalot) { console.log(`${lc} R1: Syncing initial alpha to dest...`); }
120
122
 
121
123
  let r1_syncSaga: SyncSagaInfo | undefined;
122
124
  try {
@@ -124,7 +126,7 @@ await respecfully(sir, `Text merge (LCS) conflict resolution`, async () => {
124
126
  peer: await newTestPeer(),
125
127
  localSpace: sourceSpace,
126
128
  metaspace,
127
- domainIbGibs: [r1_content_v0_source.ibGib],
129
+ domainIbGibs: [r1_alpha_v0_source.ibGib],
128
130
  conflictStrategy: SyncConflictStrategy.optimisticWithLCS,
129
131
  useSessionIdentity: false,
130
132
  });
@@ -139,54 +141,70 @@ await respecfully(sir, `Text merge (LCS) conflict resolution`, async () => {
139
141
  // Verify both sides have same text
140
142
  await respecfully(sir, `r1 verify post`, async () => {
141
143
  try {
142
- const r1_sourceKV = await senderCoordinator.getKnowledgeMap({
144
+ const r1_alpha_sourceKV = await senderCoordinator.getKnowledgeMap({
143
145
  space: sourceSpace,
144
146
  metaspace,
145
- domainIbGibs: [r1_content_v0_source.ibGib]
147
+ domainIbGibs: [r1_alpha_v0_source.ibGib]
146
148
  });
147
- const r1_source_tipAddr = r1_sourceKV[content_tjpAddr];
149
+ const r1_alpha_source_tipAddr = r1_alpha_sourceKV[alpha_tjpAddr];
150
+ if (!r1_alpha_source_tipAddr) {
151
+ ifWeMight(sir, 'r1_alpha_source_tipAddr is falsy?', async () => {
152
+ iReckon(sir, true).asTo('fail').isGonnaBeFalse();
153
+ });
154
+ return; /* <<<< returns early */
155
+ }
148
156
 
149
- const r1_destKV = await senderCoordinator.getKnowledgeMap({
157
+ const r1_alpha_destKV = await senderCoordinator.getKnowledgeMap({
150
158
  space: destSpace,
151
159
  metaspace,
152
- domainIbGibs: [r1_content_v0_source.ibGib]
160
+ domainIbGibs: [r1_alpha_v0_source.ibGib]
153
161
  });
154
- const r1_dest_tipAddr = r1_destKV[content_tjpAddr];
162
+ const r1_alpha_dest_tipAddr = r1_alpha_destKV[alpha_tjpAddr];
163
+ if (!r1_alpha_dest_tipAddr) {
164
+ ifWeMight(sir, 'r1_alpha_dest_tipAddr is falsy?', async () => {
165
+ iReckon(sir, true).asTo('fail').isGonnaBeFalse();
166
+ });
167
+ return; /* <<<< returns early */
168
+ }
155
169
 
156
170
  await ifWeMight(sir, 'r1 tip addrs match', async () => {
157
- iReckon(sir, r1_source_tipAddr).asTo('R1 source/dest have same tip').isGonnaBe(r1_dest_tipAddr);
171
+ iReckon(sir, r1_alpha_source_tipAddr).asTo('R1 source/dest have same tip').isGonnaBe(r1_alpha_dest_tipAddr);
158
172
  });
159
173
 
160
174
  await ifWeMight(sir, 'r1 text synced correctly', async () => {
161
- if (!r1_dest_tipAddr) {
175
+ if (!r1_alpha_dest_tipAddr) {
162
176
  throw new Error(`r1_dest_tipAddr is null/undefined (E: 1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d)`);
163
177
  }
164
- const resGet_destTip = await getFromSpace({ space: destSpace, addr: r1_dest_tipAddr });
178
+ const resGet_destTip = await getFromSpace({ space: destSpace, addr: r1_alpha_dest_tipAddr });
165
179
  const destTipIbGib = resGet_destTip.ibGibs![0] as IbGib_V1<TestData>;
166
180
 
167
181
  iReckon(sir, destTipIbGib.data!.text).asTo('Dest has initial text').isGonnaBe(INITIAL_TEXT);
168
182
  });
169
183
 
170
184
  await ifWeMight(sir, 'r1 dep graphs synced', async () => {
171
- const [content_dest] = await getIbGibsFromCache_fallbackToSpaces({
172
- addrs: [r1_content_v0_source.addr],
185
+ const [r1_alpha_source_tip] = await getIbGibsFromCache_fallbackToSpaces({
186
+ addrs: [r1_alpha_source_tipAddr],
187
+ space: sourceSpace,
188
+ });
189
+ const [r1_alpha_dest_tip] = await getIbGibsFromCache_fallbackToSpaces({
190
+ addrs: [r1_alpha_dest_tipAddr],
173
191
  space: destSpace,
174
192
  });
175
- iReckon(sir, content_dest).asTo('content exists in dest').isGonnaBeTruthy();
176
- if (content_dest) {
177
- const depGraph_source = await getDependencyGraph({
178
- ibGib: r1_content_v0_source.ibGib,
193
+ iReckon(sir, r1_alpha_dest_tip).asTo('alpha tip exists in dest').isGonnaBeTruthy();
194
+ if (r1_alpha_dest_tip) {
195
+ const r1_alpha_source_depGraph = await getDependencyGraph({
196
+ ibGib: r1_alpha_source_tip,
179
197
  live: true,
180
198
  space: sourceSpace
181
199
  });
182
- const depGraph_dest = await getDependencyGraph({
183
- ibGib: content_dest,
200
+ const r1_alpha_dest_depGraph = await getDependencyGraph({
201
+ ibGib: r1_alpha_dest_tip,
184
202
  live: true,
185
203
  space: destSpace
186
204
  });
187
205
  const graphsEqual = graphsAreEquivalent({
188
- graphA: depGraph_source,
189
- graphB: depGraph_dest,
206
+ graphA: r1_alpha_source_depGraph,
207
+ graphB: r1_alpha_dest_depGraph,
190
208
  slowButThorough: true,
191
209
  });
192
210
  iReckon(sir, graphsEqual).asTo('R1 dep graphs equal').isGonnaBeTrue();
@@ -211,8 +229,16 @@ await respecfully(sir, `Text merge (LCS) conflict resolution`, async () => {
211
229
 
212
230
  if (logalot) { console.log(`${lc} R2: Source appending to end of text...`); }
213
231
 
214
- // TODO: Retrieve content from source
215
- // TODO: Mutate with text = originalText + "\nSource appended sentence."
232
+ // const resGet_r2_source = await getFromSpace({ space: sourceSpace, addr: alpha_tjpAddr });
233
+ // const r2_v0_graft = resGet_r2_source.ibGibs![0] as IbGib_V1<TestData>;
234
+
235
+ const SOURCE_APPEND = "\nInstructor added hint.";
236
+ const r2_alpha_v1_source_appendedText = await testTransformer.mut8({
237
+ ibGib: r1_alpha_v0_source.ibGib,
238
+ in: 'source',
239
+ strField: { name: 'text', value: INITIAL_TEXT + SOURCE_APPEND },
240
+ name: 'r2_alpha_v1_source_appendedText',
241
+ });
216
242
 
217
243
  // #endregion r2 source edits
218
244
 
@@ -220,42 +246,118 @@ await respecfully(sir, `Text merge (LCS) conflict resolution`, async () => {
220
246
 
221
247
  if (logalot) { console.log(`${lc} R2: Dest prepending to beginning of text...`); }
222
248
 
223
- // TODO: Retrieve content from dest
224
- // TODO: Mutate with text = "Dest prepended sentence.\n" + originalText
249
+ const resGet_r2_dest = await getFromSpace({ space: destSpace, addr: r1_alpha_v0_source.addr });
250
+ const r2_v0_alpha_dest = resGet_r2_dest.ibGibs![0] as IbGib_V1<TestData>;
251
+
252
+ const DEST_PREPEND = "Student note: Confusing!\n";
253
+ const r2_alpha_v1_dest_prependedText = await testTransformer.mut8({
254
+ ibGib: r2_v0_alpha_dest,
255
+ in: 'dest',
256
+ strField: { name: 'text', value: DEST_PREPEND + INITIAL_TEXT },
257
+ name: 'r2_alpha_v1_dest_prependedText',
258
+ });
225
259
 
226
260
  // #endregion r2 dest edits
227
261
 
228
262
  await respecfully(sir, `r2 verify pre`, async () => {
229
- await ifWeMight(sir, 'dest has content at common version', async () => {
230
- // TODO: Verify dest KV has timeline tip
263
+ await ifWeMight(sir, 'texts as expected', async () => {
264
+ // before the sync, each side only has their edit. after the sync,
265
+ // both sides should have both prepended and appended text
266
+ iReckon(sir, r2_alpha_v1_source_appendedText.ibGib.data?.text.includes(INITIAL_TEXT)).asTo('alpha source has initial text').isGonnaBeTrue();
267
+ iReckon(sir, r2_alpha_v1_source_appendedText.ibGib.data?.text.includes(SOURCE_APPEND)).asTo('alpha source has appended text').isGonnaBeTrue();
268
+ iReckon(sir, r2_alpha_v1_source_appendedText.ibGib.data?.text.includes(DEST_PREPEND)).asTo('alpha source does NOT have prepended text').isGonnaBeFalse();
269
+ iReckon(sir, r2_alpha_v1_dest_prependedText.ibGib.data?.text.includes(INITIAL_TEXT)).asTo('alpha dest has initial text').isGonnaBeTrue();
270
+ iReckon(sir, r2_alpha_v1_dest_prependedText.ibGib.data?.text.includes(SOURCE_APPEND)).asTo('alpha dest does NOT have appended text').isGonnaBeFalse();
271
+ iReckon(sir, r2_alpha_v1_dest_prependedText.ibGib.data?.text.includes(DEST_PREPEND)).asTo('alpha dest has prepended text').isGonnaBeTrue();
231
272
  });
232
273
  });
233
274
 
234
- if (logalot) { console.log(`${lc} Running r2 Sync (simple append conflict)...`); }
275
+ if (logalot) { console.log(`${lc} Running r2 Sync (simple data.text conflict)...`); }
235
276
 
236
- // TODO: Add sync operation here
237
- // let r2_syncSaga: SyncSagaInfo | undefined;
238
- // try {
239
- // r2_syncSaga = await senderCoordinator.sync({...});
240
- // await r2_syncSaga.done;
241
- // } catch (e) {
242
- // console.error(`${lc} R2 Sync Failed:`, e);
243
- // iReckon(sir, false).asTo(`R2 Sync failed: ${e}`).isGonnaBeTruthy();
244
- // return;
245
- // }
277
+ let r2_syncSaga: SyncSagaInfo | undefined;
278
+ try {
279
+ r2_syncSaga = await senderCoordinator.sync({
280
+ peer: await newTestPeer(),
281
+ localSpace: sourceSpace,
282
+ metaspace,
283
+ domainIbGibs: [r2_alpha_v1_source_appendedText.ibGib],
284
+ conflictStrategy: SyncConflictStrategy.optimisticWithLCS,
285
+ useSessionIdentity: false,
286
+ });
287
+ await r2_syncSaga.done;
288
+ } catch (e) {
289
+ console.error(`${lc} R2 Sync Failed:`, e);
290
+ iReckon(sir, false).asTo(`R2 failed: ${e}`).isGonnaBeTruthy();
291
+ return;
292
+ }
246
293
 
247
294
  await respecfully(sir, `r2 verify post`, async () => {
295
+ const kv_source = await senderCoordinator.getKnowledgeMap({ space: sourceSpace, metaspace, domainIbGibs: [r1_alpha_v0_source.ibGib] });
296
+ const kv_dest = await senderCoordinator.getKnowledgeMap({ space: destSpace, metaspace, domainIbGibs: [r1_alpha_v0_source.ibGib] });
297
+ const r2_alpha_source_tipAddr = kv_source[alpha_tjpAddr];
298
+ if (!r2_alpha_source_tipAddr) {
299
+ await ifWeMight(sir, 'r2_alpha_source_tipAddr falsy?', async () => {
300
+ iReckon(sir, true).asTo('fails').isGonnaBe(false);
301
+ });
302
+ return; /* <<<< returns early */
303
+ }
304
+ const r2_alpha_dest_tipAddr = kv_dest[alpha_tjpAddr];
305
+ if (!r2_alpha_dest_tipAddr) {
306
+ await ifWeMight(sir, 'r2_alpha_dest_tipAddr falsy?', async () => {
307
+ iReckon(sir, true).asTo('fails').isGonnaBe(false);
308
+ });
309
+ return; /* <<<< returns early */
310
+ }
311
+ const [r2_alpha_source_tip] = await getIbGibsFromCache_fallbackToSpaces({
312
+ addrs: [r2_alpha_source_tipAddr],
313
+ space: sourceSpace,
314
+ });
315
+ const [r2_alpha_dest_tip] = await getIbGibsFromCache_fallbackToSpaces({
316
+ addrs: [r2_alpha_dest_tipAddr],
317
+ space: sourceSpace,
318
+ });
319
+
248
320
  await ifWeMight(sir, 'r2 tip addrs match', async () => {
249
- // TODO: Verify source/dest have same tip addr
321
+ iReckon(sir, r2_alpha_source_tipAddr).asTo('alpha').isGonnaBe(r2_alpha_dest_tipAddr);
250
322
  });
251
323
 
252
324
  await ifWeMight(sir, 'r2 text merged correctly', async () => {
253
- // TODO: Verify merged text has BOTH prepend and append
254
- // Expected: "Dest prepended sentence.\n" + originalText + "\nSource appended sentence."
325
+ // before the sync, each side only has their edit. after the sync,
326
+ // both sides should have both prepended and appended text
327
+ iReckon(sir, r2_alpha_v1_source_appendedText.ibGib.data?.text.includes(INITIAL_TEXT)).asTo('alpha source has initial text').isGonnaBeTrue();
328
+ iReckon(sir, r2_alpha_v1_source_appendedText.ibGib.data?.text.includes(SOURCE_APPEND)).asTo('alpha source has appended text').isGonnaBeTrue();
329
+ iReckon(sir, r2_alpha_v1_source_appendedText.ibGib.data?.text.includes(DEST_PREPEND)).asTo('alpha source has prepended text').isGonnaBeFalse();
330
+ iReckon(sir, r2_alpha_v1_dest_prependedText.ibGib.data?.text.includes(INITIAL_TEXT)).asTo('alpha dest has initial text').isGonnaBeTrue();
331
+ iReckon(sir, r2_alpha_v1_dest_prependedText.ibGib.data?.text.includes(SOURCE_APPEND)).asTo('alpha dest has appended text').isGonnaBeFalse();
332
+ iReckon(sir, r2_alpha_v1_dest_prependedText.ibGib.data?.text.includes(DEST_PREPEND)).asTo('alpha dest has prepended text').isGonnaBeTrue();
333
+
334
+ // actually both should be the same text now of course
335
+ iReckon(sir, r2_alpha_source_tip.data?.text).asTo('source/dest same text').isGonnaBe(r2_alpha_dest_tip.data?.text);
336
+
337
+ const text = r2_alpha_source_tip.data?.text;
338
+
339
+ // we'll go one step further and assume the final output is exactly this
340
+ iReckon(sir, text).asTo('R2 has both prepend and append').isGonnaBe(DEST_PREPEND + INITIAL_TEXT + SOURCE_APPEND);
255
341
  });
256
342
 
257
343
  await ifWeMight(sir, 'r2 dep graphs synced', async () => {
258
- // TODO: Verify dep graphs are equivalent
344
+ // alpha's full dep graph should exist on dest
345
+ const depGraph_alpha_source = await getDependencyGraph({
346
+ ibGib: r2_alpha_source_tip,
347
+ live: true,
348
+ space: sourceSpace
349
+ });
350
+ const depGraph_alpha_dest = await getDependencyGraph({
351
+ ibGib: r2_alpha_dest_tip,
352
+ live: true,
353
+ space: destSpace
354
+ });
355
+ const alphaDepsAreEqual = graphsAreEquivalent({
356
+ graphA: depGraph_alpha_source,
357
+ graphB: depGraph_alpha_dest,
358
+ slowButThorough: true,
359
+ });
360
+ iReckon(sir, alphaDepsAreEqual).asTo('alpha got synced and graphs are equal').isGonnaBeTrue();
259
361
  });
260
362
  });
261
363
 
@@ -263,168 +365,228 @@ await respecfully(sir, `Text merge (LCS) conflict resolution`, async () => {
263
365
 
264
366
  // #region Round 3: Interleaved edits - different paragraphs
265
367
 
266
- const _r3 = testTransformer.newRound({
267
- name: 'r3_interleaved_paragraphs',
268
- description: 'Source edits paragraph 1, dest edits paragraph 2 - should merge both changes'
269
- });
368
+ // const _r3 = testTransformer.newRound({
369
+ // name: 'r3_interleaved_paragraphs',
370
+ // description: 'Source edits paragraph 1, dest edits paragraph 2 - should merge both changes'
371
+ // });
270
372
 
271
- // #region r3 source edits
373
+ // // #region r3 source edits
272
374
 
273
- if (logalot) { console.log(`${lc} R3: Source editing first paragraph...`); }
375
+ // if (logalot) { console.log(`${lc} R3: Source editing first paragraph...`); }
274
376
 
275
- // TODO: Retrieve from source
276
- // TODO: Mutate - modify first paragraph only
377
+ // const resGet_r3_source = await getFromSpace({ space: sourceSpace, addr: alpha_tjpAddr });
378
+ // const r3_v0_graft = resGet_r3_source.ibGibs![0] as IbGib_V1<TestData>;
379
+ // const r3_currentText = r3_v0_graft.data!.text!;
277
380
 
278
- // #endregion r3 source edits
381
+ // // Split into lines, modify first paragraph (line 1)
382
+ // const lines = r3_currentText.split('\n');
383
+ // lines[0] = "This is the UPDATED quiz question."; // Source edits line 1
384
+ // const r3_sourceModifiedText = lines.join('\n');
279
385
 
280
- // #region r3 dest edits
386
+ // const r3_v1_source = await testTransformer.mut8({
387
+ // ibGib: r3_v0_graft,
388
+ // in: 'source',
389
+ // strField: { name: 'text', value: r3_sourceModifiedText },
390
+ // name: 'r3_v1_source',
391
+ // });
281
392
 
282
- if (logalot) { console.log(`${lc} R3: Dest editing second paragraph...`); }
393
+ // // #endregion r3 source edits
283
394
 
284
- // TODO: Retrieve from dest
285
- // TODO: Mutate - modify second paragraph only
395
+ // // #region r3 dest edits
286
396
 
287
- // #endregion r3 dest edits
397
+ // if (logalot) { console.log(`${lc} R3: Dest editing second paragraph...`); }
288
398
 
289
- await respecfully(sir, `r3 verify pre`, async () => {
290
- await ifWeMight(sir, 'dest has content after R2 graft', async () => {
291
- // TODO: Verify pre-sync state
292
- });
293
- });
399
+ // const resGet_r3_dest = await getFromSpace({ space: destSpace, addr: alpha_tjpAddr });
400
+ // const r3_v0_graft_fromDest = resGet_r3_dest.ibGibs![0] as IbGib_V1<TestData>;
294
401
 
295
- if (logalot) { console.log(`${lc} Running r3 Sync (interleaved paragraphs)...`); }
402
+ // // Split and modify third line
403
+ // const destLines = r3_v0_graft_fromDest.data!.text!.split('\n');
404
+ // destLines[2] = "Students will DEFINITELY answer this."; // Dest edits line 3
405
+ // const r3_destModifiedText = destLines.join('\n');
296
406
 
297
- // TODO: Add sync operation
407
+ // const r3_v1_dest = await testTransformer.mut8({
408
+ // ibGib: r3_v0_graft_fromDest,
409
+ // in: 'dest',
410
+ // strField: { name: 'text', value: r3_destModifiedText },
411
+ // name: 'r3_v1_dest',
412
+ // });
298
413
 
299
- await respecfully(sir, `r3 verify post`, async () => {
300
- await ifWeMight(sir, 'r3 tip addrs match', async () => {
301
- // TODO: Verify tips match
302
- });
414
+ // // #endregion r3 dest edits
303
415
 
304
- await ifWeMight(sir, 'r3 both paragraph edits merged', async () => {
305
- // TODO: Verify text has both paragraph changes
306
- // TODO: Check paragraph 1 has source changes
307
- // TODO: Check paragraph 2 has dest changes
308
- });
416
+ // await respecfully(sir, `r3 verify pre`, async () => {
417
+ // await ifWeMight(sir, 'dest has alpha after R2 graft', async () => {
418
+ // const kv = await receiverCoordinator.getKnowledgeMap({ space: destSpace, metaspace, domainIbGibs: [r3_v0_graft_fromDest] });
419
+ // iReckon(sir, !!kv[alpha_tjpAddr]).asTo('dest has tip').isGonnaBeTrue();
420
+ // });
421
+ // });
309
422
 
310
- await ifWeMight(sir, 'r3 dep graphs synced', async () => {
311
- // TODO: Verify dep graphs
312
- });
313
- });
423
+ // if (logalot) { console.log(`${lc} Running r3 Sync (interleaved paragraphs)...`); }
424
+
425
+ // let r3_syncSaga: SyncSagaInfo | undefined;
426
+ // try {
427
+ // r3_syncSaga = await senderCoordinator.sync({
428
+ // peer: await newTestPeer(),
429
+ // localSpace: sourceSpace,
430
+ // metaspace,
431
+ // domainIbGibs: [r3_v1_source.ibGib],
432
+ // conflictStrategy: SyncConflictStrategy.optimisticWithLCS,
433
+ // useSessionIdentity: false,
434
+ // });
435
+ // await r3_syncSaga.done;
436
+ // } catch (e) {
437
+ // console.error(`${lc} R3 Sync Failed:`, e);
438
+ // iReckon(sir, false).asTo(`R3 failed: ${e}`).isGonnaBeTruthy();
439
+ // return;
440
+ // }
441
+
442
+ // await respecfully(sir, `r3 verify post`, async () => {
443
+ // const kv_s = await senderCoordinator.getKnowledgeMap({ space: sourceSpace, metaspace, domainIbGibs: [r1_alpha_v0_source.ibGib] });
444
+ // const kv_d = await senderCoordinator.getKnowledgeMap({ space: destSpace, metaspace, domainIbGibs: [r1_alpha_v0_source.ibGib] });
445
+ // const r3_tip_s = kv_s[alpha_tjpAddr];
446
+ // const r3_tip_d = kv_d[alpha_tjpAddr];
447
+
448
+ // await ifWeMight(sir, 'r3 tip addrs match', async () => {
449
+ // iReckon(sir, r3_tip_s).asTo('R3 tips match').isGonnaBe(r3_tip_d);
450
+ // });
451
+
452
+ // await ifWeMight(sir, 'r3 both paragraph edits merged', async () => {
453
+ // const res = await getFromSpace({ space: sourceSpace, addr: r3_tip_s! });
454
+ // const tip = res.ibGibs![0] as IbGib_V1<TestData>;
455
+ // const mergedText = tip.data!.text!;
456
+
457
+ // // Should have BOTH source's line 1 change AND dest's line 3 change
458
+ // iReckon(sir, mergedText.includes("UPDATED quiz question"))
459
+ // .asTo('has source paragraph 1 edit')
460
+ // .isGonnaBeTrue();
461
+ // iReckon(sir, mergedText.includes("DEFINITELY answer this"))
462
+ // .asTo('has dest paragraph 2 edit')
463
+ // .isGonnaBeTrue();
464
+
465
+ // // Verify middle line unchanged
466
+ // iReckon(sir, mergedText.includes("It has multiple lines"))
467
+ // .asTo('middle line preserved')
468
+ // .isGonnaBeTrue();
469
+ // });
470
+
471
+ // await ifWeMight(sir, 'r3 dep graphs synced', async () => {
472
+ // const [d] = await getIbGibsFromCache_fallbackToSpaces({ addrs: [r3_tip_s!], space: destSpace });
473
+ // iReckon(sir, d).asTo('exists dest').isGonnaBeTruthy();
474
+ // });
475
+ // });
314
476
 
315
477
  // #endregion Round 3: Interleaved edits - different paragraphs
316
478
 
317
479
  // #region Round 4: Same paragraph conflict
318
480
 
319
- const _r4 = testTransformer.newRound({
320
- name: 'r4_same_paragraph_conflict',
321
- description: 'Both edit same paragraph - LCS should merge at word/character level'
322
- });
481
+ // const _r4 = testTransformer.newRound({
482
+ // name: 'r4_same_paragraph_conflict',
483
+ // description: 'Both edit same paragraph - LCS should merge at word/character level'
484
+ // });
323
485
 
324
- // #region r4 source edits
486
+ // // #region r4 source edits
325
487
 
326
- if (logalot) { console.log(`${lc} R4: Source editing same paragraph...`); }
488
+ // if (logalot) { console.log(`${lc} R4: Source editing same paragraph...`); }
327
489
 
328
- // TODO: Retrieve from source
329
- // TODO: Mutate - edit specific words in paragraph
490
+ // // TODO: Retrieve from source
491
+ // // TODO: Mutate - edit specific words in paragraph
330
492
 
331
- // #endregion r4 source edits
493
+ // // #endregion r4 source edits
332
494
 
333
- // #region r4 dest edits
495
+ // // #region r4 dest edits
334
496
 
335
- if (logalot) { console.log(`${lc} R4: Dest editing same paragraph (different words)...`); }
497
+ // if (logalot) { console.log(`${lc} R4: Dest editing same paragraph (different words)...`); }
336
498
 
337
- // TODO: Retrieve from dest
338
- // TODO: Mutate - edit different words in same paragraph
499
+ // // TODO: Retrieve from dest
500
+ // // TODO: Mutate - edit different words in same paragraph
339
501
 
340
- // #endregion r4 dest edits
502
+ // // #endregion r4 dest edits
341
503
 
342
- await respecfully(sir, `r4 verify pre`, async () => {
343
- await ifWeMight(sir, 'dest has content after R3 graft', async () => {
344
- // TODO: Verify pre-sync state
345
- });
346
- });
504
+ // await respecfully(sir, `r4 verify pre`, async () => {
505
+ // await ifWeMight(sir, 'dest has alpha after R3 graft', async () => {
506
+ // // TODO: Verify pre-sync state
507
+ // });
508
+ // });
347
509
 
348
- if (logalot) { console.log(`${lc} Running r4 Sync (same paragraph conflict)...`); }
510
+ // if (logalot) { console.log(`${lc} Running r4 Sync (same paragraph conflict)...`); }
349
511
 
350
- // TODO: Add sync operation
512
+ // // TODO: Add sync operation
351
513
 
352
- await respecfully(sir, `r4 verify post`, async () => {
353
- await ifWeMight(sir, 'r4 tip addrs match', async () => {
354
- // TODO: Verify tips match
355
- });
514
+ // await respecfully(sir, `r4 verify post`, async () => {
515
+ // await ifWeMight(sir, 'r4 tip addrs match', async () => {
516
+ // // TODO: Verify tips match
517
+ // });
356
518
 
357
- await ifWeMight(sir, 'r4 LCS merged both word changes', async () => {
358
- // TODO: Verify text has both source and dest word changes
359
- // TODO: Verify LCS algorithm preserved both edits correctly
360
- });
519
+ // await ifWeMight(sir, 'r4 LCS merged both word changes', async () => {
520
+ // // TODO: Verify text has both source and dest word changes
521
+ // // TODO: Verify LCS algorithm preserved both edits correctly
522
+ // });
361
523
 
362
- await ifWeMight(sir, 'r4 dep graphs synced', async () => {
363
- // TODO: Verify dep graphs
364
- });
365
- });
524
+ // await ifWeMight(sir, 'r4 dep graphs synced', async () => {
525
+ // // TODO: Verify dep graphs
526
+ // });
527
+ // });
366
528
 
367
529
  // #endregion Round 4: Same paragraph conflict
368
530
 
369
531
  // #region Round 5: Multi-field text merge
370
532
 
371
- const _r5 = testTransformer.newRound({
372
- name: 'r5_multi_field_text',
373
- description: 'Conflicting text edits in BOTH text and description fields simultaneously'
374
- });
533
+ // const _r5 = testTransformer.newRound({
534
+ // name: 'r5_multi_field_text',
535
+ // description: 'Conflicting text edits in BOTH text and description fields simultaneously'
536
+ // });
375
537
 
376
- // #region r5 source edits
538
+ // // #region r5 source edits
377
539
 
378
- if (logalot) { console.log(`${lc} R5: Source editing both text and description...`); }
540
+ // if (logalot) { console.log(`${lc} R5: Source editing both text and description...`); }
379
541
 
380
- // TODO: Retrieve from source
381
- // TODO: Mutate text field
382
- // TODO: Mutate description field (in same mut8 or separate)
542
+ // // TODO: Retrieve from source
543
+ // // TODO: Mutate text field
544
+ // // TODO: Mutate description field (in same mut8 or separate)
383
545
 
384
- // #endregion r5 source edits
546
+ // // #endregion r5 source edits
385
547
 
386
- // #region r5 dest edits
548
+ // // #region r5 dest edits
387
549
 
388
- if (logalot) { console.log(`${lc} R5: Dest editing both text and description differently...`); }
550
+ // if (logalot) { console.log(`${lc} R5: Dest editing both text and description differently...`); }
389
551
 
390
- // TODO: Retrieve from dest
391
- // TODO: Mutate text field (different changes)
392
- // TODO: Mutate description field (different changes)
552
+ // // TODO: Retrieve from dest
553
+ // // TODO: Mutate text field (different changes)
554
+ // // TODO: Mutate description field (different changes)
393
555
 
394
- // #endregion r5 dest edits
556
+ // // #endregion r5 dest edits
395
557
 
396
- await respecfully(sir, `r5 verify pre`, async () => {
397
- await ifWeMight(sir, 'dest has content after R4 graft', async () => {
398
- // TODO: Verify pre-sync state
399
- });
400
- });
558
+ // await respecfully(sir, `r5 verify pre`, async () => {
559
+ // await ifWeMight(sir, 'dest has alpha after R4 graft', async () => {
560
+ // // TODO: Verify pre-sync state
561
+ // });
562
+ // });
401
563
 
402
- if (logalot) { console.log(`${lc} Running r5 Sync (multi-field text merge)...`); }
564
+ // if (logalot) { console.log(`${lc} Running r5 Sync (multi-field text merge)...`); }
403
565
 
404
- // TODO: Add sync operation
566
+ // // TODO: Add sync operation
405
567
 
406
- await respecfully(sir, `r5 verify post`, async () => {
407
- await ifWeMight(sir, 'r5 tip addrs match', async () => {
408
- // TODO: Verify tips match
409
- });
568
+ // await respecfully(sir, `r5 verify post`, async () => {
569
+ // await ifWeMight(sir, 'r5 tip addrs match', async () => {
570
+ // // TODO: Verify tips match
571
+ // });
410
572
 
411
- await ifWeMight(sir, 'r5 text field merged', async () => {
412
- // TODO: Verify text field has both source and dest changes
413
- });
573
+ // await ifWeMight(sir, 'r5 text field merged', async () => {
574
+ // // TODO: Verify text field has both source and dest changes
575
+ // });
414
576
 
415
- await ifWeMight(sir, 'r5 description field merged', async () => {
416
- // TODO: Verify description field has both source and dest changes
417
- });
577
+ // await ifWeMight(sir, 'r5 description field merged', async () => {
578
+ // // TODO: Verify description field has both source and dest changes
579
+ // });
418
580
 
419
- await ifWeMight(sir, 'r5 both fields independently LCS-merged', async () => {
420
- // TODO: Verify each field was merged independently
421
- // TODO: Ensure one field's merge didn't affect the other
422
- });
581
+ // await ifWeMight(sir, 'r5 both fields independently LCS-merged', async () => {
582
+ // // TODO: Verify each field was merged independently
583
+ // // TODO: Ensure one field's merge didn't affect the other
584
+ // });
423
585
 
424
- await ifWeMight(sir, 'r5 dep graphs synced', async () => {
425
- // TODO: Verify dep graphs
426
- });
427
- });
586
+ // await ifWeMight(sir, 'r5 dep graphs synced', async () => {
587
+ // // TODO: Verify dep graphs
588
+ // });
589
+ // });
428
590
 
429
591
  // #endregion Round 5: Multi-field text merge
430
592
  });