/**
 * @module sync-conflict.respec
 *
 * Verifies Conflict Resolution strategies in SyncSagaCoordinator.
 * Reproduces divergence scenarios and asserts resolution behavior.
 */
import { respecfully, ifWe, iReckon } from '@ibgib/helper-gib/dist/respec-gib/respec-gib.mjs';
const maam = `[${import.meta.url}]`, sir = maam;
import { clone, delay, extractErrorMsg, pretty } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
import { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';
import { GLOBAL_LOG_A_LOT } from '../core-constants.mjs';
import { TestTransformer, } from '../test-helpers.mjs';
import { SyncSagaCoordinator } from './sync-saga-coordinator.mjs';
import { getFromSpace } from '../witness/space/space-helper.mjs';
import { Metaspace_Innerspace } from '../witness/space/metaspace/metaspace-innerspace/metaspace-innerspace.mjs';
import { InnerSpace_V1 } from '../witness/space/inner-space/inner-space-v1.mjs';
import { SyncPeerInnerspace_V1 } from './sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs';
import { DEFAULT_INNER_SPACE_DATA_V1 } from '../witness/space/inner-space/inner-space-types.mjs';
import { getIbGibsFromCache_fallbackToSpaces, getTjpAddr, } from '../common/other/ibgib-helper.mjs';
import { getDependencyGraph, graphsAreEquivalent } from '../common/other/graph-helper.mjs';
import { SYNC_PEER_INNERSPACE_DEFAULT_DATA_V1 } from './sync-peer/sync-peer-innerspace/sync-peer-innerspace-constants.mjs';
import { SyncConflictStrategy } from './sync-constants.mjs';
import { getHistory } from '../timeline/timeline-api.mjs';
const logalot = GLOBAL_LOG_A_LOT;
const lc = sir;
const TEST_REL8N_NAME = 'testrel8n';
await respecfully(sir, `Multi-round/timeline permutations`, async () => {
    // #region Init/Setup
    const metaspace = new Metaspace_Innerspace(undefined);
    await metaspace.initialize({
        getFnAlert: () => async ({ title, msg }) => { console.log(`[Alert] ${title}: ${msg}`); },
        getFnPrompt: () => async ({ title, msg }) => { console.log(`[Prompt] ${title}: ${msg}`); return ''; },
        getFnPromptPassword: () => async (title, msg) => { console.log(`[PromptPwd] ${title}: ${msg}`); return null; },
    });
    while (!metaspace.initialized) {
        await delay(10);
    }
    const defaultLocalUserSpace = await metaspace.getLocalUserSpace({ lock: false });
    await defaultLocalUserSpace.initialized;
    const sourceSpace = new InnerSpace_V1({
        ...DEFAULT_INNER_SPACE_DATA_V1,
        name: 'source',
        uuid: 'source_uuid',
        description: 'source test space',
    });
    await sourceSpace.initialized;
    const destSpace = new InnerSpace_V1({
        ...DEFAULT_INNER_SPACE_DATA_V1,
        name: 'dest',
        uuid: 'dest_uuid',
        description: 'dest test space',
    });
    await destSpace.initialized;
    const testTransformer = new TestTransformer(metaspace, sourceSpace, destSpace);
    if (logalot) {
        console.log(`${lc} Setting up Coordinators...`);
    }
    const senderCoordinator = new SyncSagaCoordinator();
    const receiverCoordinator = new SyncSagaCoordinator();
    async function newTestPeer() {
        const peer = new SyncPeerInnerspace_V1(clone(SYNC_PEER_INNERSPACE_DEFAULT_DATA_V1));
        await peer.initialized;
        await peer.initializeOpts({
            localMetaspace: metaspace,
            localSpace: sourceSpace,
            receiverSpace: destSpace,
            receiverCoordinator: receiverCoordinator,
            receiverMetaspace: metaspace,
        });
        return peer;
    }
    // #endregion Init/Setup
    // #region Round 1: Seed common history
    /**
     * not sure if we're going to do anything with the round info itself
     */
    const _r1 = testTransformer.newRound({
        name: 'r1_seedCommonHistory',
        description: 'Create alpha v0 and v1 on source, sync to dest so both v0 and v1 are established as synced.',
    });
    // #region r1 setup
    if (logalot) {
        console.log(`${lc} Creating common History...`);
    }
    const r1_alpha_v0_source = await testTransformer.create({
        atom: 'alpha',
        in: 'source',
        name: 'r1_alpha_v0_source', // should be auto-calculated?
    });
    const alpha_tjpAddr = getTjpAddr({ ibGib: r1_alpha_v0_source.ibGib, defaultIfNone: 'incomingAddr' });
    // Create v1 (common) - will be synced to dest
    const r1_alpha_v1_source_common = await testTransformer.mut8({
        stepInfo: r1_alpha_v0_source,
        strField: 'commonField',
        name: 'r1_alpha_v1_source_common'
    });
    // #endregion r1 setup
    await respecfully(sir, `r1 verify pre`, async () => {
        await ifWe(sir, 'dest should NOT have alpha', async () => {
            const resGet = await getFromSpace({
                space: destSpace,
                addr: alpha_tjpAddr,
            });
            // When timeline doesn't exist, getFromSpace returns success:false
            iReckon(sir, resGet.success).asTo('getFromSpace should return false for missing timeline').isGonnaBeFalse();
            iReckon(sir, resGet.ibGibs?.length ?? 0).asTo('Dest should NOT have alpha timeline yet').isGonnaBe(0);
        });
    });
    const r1_syncSaga = await senderCoordinator.sync({
        peer: await newTestPeer(),
        localSpace: sourceSpace,
        metaspace,
        domainIbGibs: [r1_alpha_v1_source_common.ibGib],
        conflictStrategy: SyncConflictStrategy.optimisticWithLCS,
    });
    await r1_syncSaga.done;
    if (logalot) {
        console.log(`${lc} r1_syncSaga Complete.`);
    }
    await respecfully(sir, `r1 verify post`, async () => {
        await ifWe(sir, 'dest should have alpha', async () => {
            // alpha's full dep graph should exist on dest
            const [alpha_dest] = await getIbGibsFromCache_fallbackToSpaces({
                addrs: [r1_alpha_v0_source.addr],
                space: destSpace,
            });
            iReckon(sir, alpha_dest).asTo('alpha exists in dest').isGonnaBeTruthy();
            if (alpha_dest) {
                const depGraph_alpha_source = await getDependencyGraph({ ibGib: r1_alpha_v0_source.ibGib, space: sourceSpace });
                const depGraph_alpha_dest = await getDependencyGraph({ ibGib: alpha_dest, space: destSpace });
                const alphaDepsAreEqual = graphsAreEquivalent({
                    graphA: depGraph_alpha_source, graphB: depGraph_alpha_dest
                });
                iReckon(sir, alphaDepsAreEqual).asTo('alpha got synced and graphs are equal').isGonnaBeTrue();
            }
        });
    });
    // Get alpha_v1_common from destSpace for Round 2
    const resGetDest = await getFromSpace({ space: destSpace, addr: r1_alpha_v1_source_common.addr });
    if (!resGetDest.success || !resGetDest.ibGibs || resGetDest.ibGibs.length === 0) {
        throw new Error(`Failed to retrieve alpha from destSpace after sync. (E: 40c67811eba14f729880a46dcbb65126)`);
    }
    const alpha_v1_common_onDest = resGetDest.ibGibs[0];
    // #endregion Round 1: Seed common history
    // #region Round 2: Create Divergence (v2source vs v2dest) - "simultaneous" parallel edits
    const _r2 = testTransformer.newRound({
        name: 'r2_divergent_edits',
        description: 'Create conflicts on alpha, add beta relation on source, separate edit on dest'
    });
    // #region r2 source edits
    if (logalot) {
        console.log(`${lc} Creating Divergence...`);
    }
    // Source: Create beta, mutate alpha fieldA, add beta relation
    const r2_beta_v0_source = await testTransformer.create({
        atom: 'beta',
        in: 'source',
        data: { fieldA: 'beta field A created on source' },
        name: 'r2_beta_v0_source'
    });
    const r2_alpha_v2_source_arbitraryMut8 = await testTransformer.mut8({
        ibGib: r1_alpha_v1_source_common.ibGib,
        in: 'source',
        strField: 'fieldA',
        name: 'r2_alpha_v2_source_arbitraryMut8',
        comments_snake_plus_CamelCase: 'editedOnSource',
    });
    const r2_alpha_v3_source_rel8dBeta = await testTransformer.rel8({
        stepInfo: r2_alpha_v2_source_arbitraryMut8,
        in: 'source',
        targetIbGibs: [r2_beta_v0_source.ibGib],
        rel8nName: TEST_REL8N_NAME,
        name: 'r2_alpha_v3_source_rel8dBeta'
    });
    // #endregion r2 source edits
    // #region r2 dest edits
    // Dest: Mutate alpha fieldB (different field than source)
    const r2_alpha_v2_dest_mut8FieldB = await testTransformer.mut8({
        ibGib: alpha_v1_common_onDest,
        in: 'dest',
        strField: 'fieldB',
        name: 'r2_alpha_v2_dest_mut8FieldB',
        comments_snake_plus_CamelCase: 'editedOnDest',
    });
    if (logalot) {
        console.log(`${lc} Divergence created.`);
    }
    // #endregion r2 dest edits
    // Verify Receiver has correct KV (Pre-Sync Check)
    // This ensures the conflict precondition exists.
    await respecfully(sir, `r2 verify pre`, async () => {
        await ifWe(sir, 'dest has alpha v1 common', async () => {
            try {
                const destKV = await receiverCoordinator.getKnowledgeMap({
                    space: destSpace,
                    metaspace,
                    domainIbGibs: [alpha_v1_common_onDest]
                });
                const alpha_v1_common_tjpAddr_onDest = getTjpAddr({ ibGib: alpha_v1_common_onDest, defaultIfNone: 'incomingAddr' });
                const destTip = destKV[alpha_v1_common_tjpAddr_onDest];
                iReckon(sir, !!destTip).asTo(`Dest KV has timeline tip for ${alpha_v1_common_tjpAddr_onDest}`).isGonnaBeTruthy();
                if (!destTip) {
                    throw new Error(`Test Setup Fail: Dest Space does not have index for timeline ${alpha_v1_common_tjpAddr_onDest}. Seeding failed. (E: c194a80b4e4877b77826c37a1753b826)`);
                }
            }
            catch (error) {
                console.error(`${lc} ${extractErrorMsg(error)}`);
                iReckon(sir, true).asTo('getKnowledgeMap errored out').isGonnaBeFalse();
            }
        });
    });
    if (logalot) {
        console.log(`${lc} Running Sync (ConflictStrategy: optimistic)...`);
    }
    let r2_syncSaga;
    try {
        if (logalot) {
            console.dir(sourceSpace);
        }
        if (logalot) {
            console.dir(destSpace);
        }
        r2_syncSaga = await senderCoordinator.sync({
            peer: await newTestPeer(),
            localSpace: sourceSpace,
            metaspace,
            domainIbGibs: [r2_alpha_v3_source_rel8dBeta.ibGib],
            conflictStrategy: SyncConflictStrategy.optimisticWithLCS,
        });
        if (logalot) {
            console.log(`${lc} awaiting r2_syncSaga.done`);
        }
        await r2_syncSaga.done;
        if (logalot) {
            console.log(`${lc} r2_syncSaga Complete.`);
        }
    }
    catch (e) {
        console.error(`${lc} Sync Failed with Error:`, e);
        iReckon(sir, false).asTo(`Sync failed with error: ${e}`).isGonnaBeTruthy();
        return; // Exit test early
    }
    // Expectation: Both Spaces should now have a NEW tip (V3) that merges v2source and v2dest.
    await respecfully(sir, `r2 verify post`, async () => {
        // Retrieve updated KV from Source (or check what happened to v2source)
        // Ideally, we just check the source space for the timeline tip
        // The timeline tip for alpha/v0 should now be NEW.
        try {
            // Get the KV for the Source Space
            const alpha_sourceKV_afterSync = await senderCoordinator.getKnowledgeMap({
                space: sourceSpace,
                metaspace,
                domainIbGibs: [r1_alpha_v0_source.ibGib] // We want to know the tip of this timeline
            });
            if (logalot) {
                console.log(`${lc} getKnowledgeMap returned. sourceKV_afterSync: ${pretty(alpha_sourceKV_afterSync)} (I: e8780cda37c8b2a46eeb85786874e926)`);
            }
            const alpha_source_tipAddr = alpha_sourceKV_afterSync[alpha_tjpAddr];
            if (logalot) {
                console.log(`${lc} alpha_source_tipAddr: ${alpha_source_tipAddr} (I: 34590f29c9b706ba04a54b0f633a6426)`);
            }
            if (!alpha_source_tipAddr) {
                throw new Error(`Source Space missing timeline tip for ${alpha_tjpAddr} (E: ec95980b9c980c5c5870812e15e43826)`);
            }
            const alpha_destKV_afterSync = await senderCoordinator.getKnowledgeMap({
                space: destSpace,
                metaspace,
                domainIbGibs: [r1_alpha_v0_source.ibGib] // We want to know the tip of this timeline
            });
            if (logalot) {
                console.log(`${lc} getKnowledgeMap returned. destKV_afterSync: ${pretty(alpha_destKV_afterSync)} (I: e8780cda37c8b2a46eeb85786874e926)`);
            }
            const alpha_dest_tipAddr = alpha_destKV_afterSync[alpha_tjpAddr];
            if (logalot) {
                console.log(`${lc} alpha_dest_tipAddr: ${alpha_dest_tipAddr} (I: afac71eba4e6d3f3c47952680ad8b826)`);
            }
            if (!alpha_dest_tipAddr) {
                throw new Error(`dest Space missing timeline tip for ${alpha_tjpAddr} (E: 30b018c6349917aa28c9f538fa567826)`);
            }
            await ifWe(sir, 'tip addrs', async () => {
                iReckon(sir, alpha_source_tipAddr).asTo('source/dest have same tip addrs').isGonnaBe(alpha_dest_tipAddr);
            });
            // Fetch the new tip
            const resGet_alpha_source_tipAddr = await getFromSpace({ space: sourceSpace, addr: alpha_source_tipAddr });
            const gotten_alpha_source_tipIbGib = resGet_alpha_source_tipAddr.ibGibs[0];
            if (logalot || true) {
                console.log(`${lc} gotten_alpha_source_tipIbGib:\n${pretty(gotten_alpha_source_tipIbGib)} (I: e9c608c1fcb85f08d17d4af319d62726)`);
            }
            // #region DEBUG SANITY CHECK
            const resGetTjp = await getFromSpace({ space: sourceSpace, addr: alpha_tjpAddr });
            const gottenTjp = resGetTjp.ibGibs[0];
            debugger;
            const history = await getHistory({
                timeline: gotten_alpha_source_tipIbGib,
                space: sourceSpace,
                metaspace,
                includeDna: true,
            });
            debugger;
            // #endregion DEBUG SANITY CHECK
            await ifWe(sir, 'r2 basics of alpha merge', async () => {
                iReckon(sir, alpha_source_tipAddr)
                    .asTo(`Source Tip (${alpha_source_tipAddr}) should NOT be r2_alpha_v3_source_rel8dBeta`)
                    .not.isGonnaBe(r2_alpha_v3_source_rel8dBeta.addr);
                iReckon(sir, alpha_source_tipAddr)
                    .asTo(`Source Tip (${alpha_source_tipAddr}) should NOT be r2_alpha_v2_dest_mut8FieldB`)
                    .not.isGonnaBe(r2_alpha_v2_dest_mut8FieldB.addr);
                // Check Data: Should have BOTH edits (using testTransformer-generated values)
                const r2_source_mut8Info = r2_alpha_v2_source_arbitraryMut8.infos[0];
                const r2_dest_mut8Info = r2_alpha_v2_dest_mut8FieldB.infos[0];
                const a = gotten_alpha_source_tipIbGib.data[r2_source_mut8Info.key];
                const a2 = r2_source_mut8Info.value;
                console.log(`${a} should be ${a2}`);
                iReckon(sir, gotten_alpha_source_tipIbGib.data[r2_source_mut8Info.key]).asTo(`New Tip has source field ${r2_source_mut8Info.key}`).isGonnaBe(r2_source_mut8Info.value);
                const b = gotten_alpha_source_tipIbGib.data[r2_dest_mut8Info.key];
                const b2 = r2_dest_mut8Info.value;
                console.log(`${b} should be ${b2}`);
                iReckon(sir, gotten_alpha_source_tipIbGib.data[r2_dest_mut8Info.key]).asTo(`New Tip has dest field ${r2_dest_mut8Info.key}`).isGonnaBe(r2_dest_mut8Info.value);
            });
            await ifWe(sir, 'r2 alpha and deps synced', async () => {
                // alpha's full dep graph should exist on dest, even though its
                // timeline was grafted
                const [alpha_dest] = await getIbGibsFromCache_fallbackToSpaces({
                    addrs: [r1_alpha_v0_source.addr],
                    space: destSpace,
                });
                iReckon(sir, alpha_dest).asTo('alpha exists in dest').isGonnaBeTruthy();
                if (alpha_dest) {
                    try {
                        const depGraph_alpha_source = await getDependencyGraph({
                            ibGib: r1_alpha_v0_source.ibGib,
                            live: true,
                            space: sourceSpace
                        });
                        const depGraph_alpha_dest = await getDependencyGraph({
                            ibGib: alpha_dest,
                            live: true,
                            space: destSpace
                        });
                        const alphaDepsAreEqual = graphsAreEquivalent({
                            graphA: depGraph_alpha_source,
                            graphB: depGraph_alpha_dest,
                            slowButThorough: true,
                        });
                        iReckon(sir, alphaDepsAreEqual).asTo('alpha got synced and graphs are equal').isGonnaBeTrue();
                    }
                    catch (error) {
                        console.error(`${lc} ${extractErrorMsg(error)}`);
                        iReckon(sir, true).asTo('ERROR: alpha exists in dest').isGonnaBeFalse(); // fails
                    }
                }
            });
            await ifWe(sir, 'r2 beta and deps synced', async () => {
                // beta's full dep graph should exist on dest
                const [beta_dest] = await getIbGibsFromCache_fallbackToSpaces({
                    addrs: [r2_beta_v0_source.addr],
                    space: destSpace,
                });
                iReckon(sir, beta_dest).asTo('beta exists in dest').isGonnaBeTruthy();
                if (beta_dest) {
                    const depGraph_beta_source = await getDependencyGraph({
                        ibGib: r2_beta_v0_source.ibGib,
                        live: true,
                        space: sourceSpace
                    });
                    const depGraph_beta_dest = await getDependencyGraph({
                        ibGib: beta_dest,
                        live: true,
                        space: destSpace
                    });
                    const betaDepsAreEqual = graphsAreEquivalent({
                        graphA: depGraph_beta_source,
                        graphB: depGraph_beta_dest,
                        slowButThorough: true,
                    });
                    iReckon(sir, betaDepsAreEqual).asTo('beta got synced and graphs are equal').isGonnaBeTrue();
                }
            });
        }
        catch (error) {
            console.error(`${lc} ${extractErrorMsg(error)}`);
            iReckon(sir, true).asTo('getKnowledgeMap errored out').isGonnaBeFalse();
        }
    });
    // #endregion Round 2: Create Divergence (v2source vs v2dest) - "simultaneous" parallel edits
    // #region Round 3: Multiple Timeline Conflicts
    const _r3 = testTransformer.newRound({
        name: 'r3_multiple_timeline_conflicts',
        description: 'Both alpha AND beta have divergent edits on source vs dest - tests multiple simultaneous grafts'
    });
    // #region r3 source edits
    if (logalot) {
        console.log(`${lc} Creating r3 divergent edits on source...`);
    }
    // Source: Get latest alpha and beta from source, then mutate both
    // After R2, alpha has graft point on source. We'll mutate from that.
    const resGet_r3_alpha_source = await getFromSpace({ space: sourceSpace, addr: alpha_tjpAddr });
    if (!resGet_r3_alpha_source.success || !resGet_r3_alpha_source.ibGibs || resGet_r3_alpha_source.ibGibs.length === 0) {
        throw new Error(`Failed to retrieve alpha from sourceSpace for R3. (E: 8e3a4f7c9b2d1a5e6f8c3d9e2b4a7c1f)`);
    }
    const r3_alpha_v3_graftPoint = resGet_r3_alpha_source.ibGibs[0];
    const beta_tjpAddr = getTjpAddr({ ibGib: r2_beta_v0_source.ibGib, defaultIfNone: 'incomingAddr' });
    const resGet_r3_beta_source = await getFromSpace({ space: sourceSpace, addr: beta_tjpAddr });
    if (!resGet_r3_beta_source.success || !resGet_r3_beta_source.ibGibs || resGet_r3_beta_source.ibGibs.length === 0) {
        throw new Error(`Failed to retrieve beta from sourceSpace for R3. (E: 3f9e2c8a7d5b1c4e9f6a2d8c5b7e1a3f)`);
    }
    const r3_beta_v0_graftPoint = resGet_r3_beta_source.ibGibs[0];
    // Mutate alpha fieldC on source
    const r3_alpha_v4_source_mut8fieldC = await testTransformer.mut8({
        ibGib: r3_alpha_v3_graftPoint,
        in: 'source',
        strField: 'fieldC',
        name: 'r3_alpha_v4_source_mut8fieldC',
        comments_snake_plus_CamelCase: 'postGraft',
    });
    // Mutate beta betaFieldA on source
    const r3_beta_v1_source = await testTransformer.mut8({
        ibGib: r3_beta_v0_graftPoint,
        in: 'source',
        strField: 'betaFieldA',
        name: 'r3_beta_v1_source',
    });
    // #endregion r3 source edits
    // #region r3 dest edits
    if (logalot) {
        console.log(`${lc} Creating r3 divergent edits on dest...`);
    }
    // Dest: Get latest alpha and beta from dest, then mutate both
    const resGet_r3_alpha_dest = await getFromSpace({ space: destSpace, addr: alpha_tjpAddr });
    if (!resGet_r3_alpha_dest.success || !resGet_r3_alpha_dest.ibGibs || resGet_r3_alpha_dest.ibGibs.length === 0) {
        throw new Error(`Failed to retrieve alpha from destSpace for R3. (E: 2c7e9f1a4b8d3e5c7a9f2d4e6b8c1a5e)`);
    }
    const r3_alpha_v3_graftPoint_fromDest = resGet_r3_alpha_dest.ibGibs[0];
    const resGet_r3_beta_dest = await getFromSpace({ space: destSpace, addr: beta_tjpAddr });
    if (!resGet_r3_beta_dest.success || !resGet_r3_beta_dest.ibGibs || resGet_r3_beta_dest.ibGibs.length === 0) {
        throw new Error(`Failed to retrieve beta from destSpace for R3. (E: 5d8c2e9a1f4b7e3c6d9a2f5e8b1c4a7e)`);
    }
    const r3_beta_v0_graftPoint_fromDest = resGet_r3_beta_dest.ibGibs[0];
    // Mutate alpha fieldD on dest
    const r3_alpha_v4_dest_mut8fieldD = await testTransformer.mut8({
        ibGib: r3_alpha_v3_graftPoint_fromDest,
        in: 'dest',
        strField: 'fieldD',
        name: 'r3_alpha_v4_dest_mut8fieldD',
        comments_snake_plus_CamelCase: 'postGraft',
    });
    // Mutate beta betaFieldB on dest
    const r3_beta_v1_dest = await testTransformer.mut8({
        ibGib: r3_beta_v0_graftPoint_fromDest,
        in: 'dest',
        strField: 'betaFieldB',
        name: 'r3_beta_v1_dest',
    });
    if (logalot) {
        console.log(`${lc} R3 Divergence created (both alpha and beta conflicted).`);
    }
    // #endregion r3 dest edits
    await respecfully(sir, `r3 verify pre`, async () => {
        await ifWe(sir, 'dest has both alpha and beta tips (pre-conflict)', async () => {
            try {
                const destKV = await receiverCoordinator.getKnowledgeMap({
                    space: destSpace,
                    metaspace,
                    domainIbGibs: [r3_alpha_v3_graftPoint_fromDest, r3_beta_v0_graftPoint_fromDest]
                });
                // Verify alpha tip exists on dest
                const destAlphaTip = destKV[alpha_tjpAddr];
                iReckon(sir, !!destAlphaTip).asTo(`Dest KV has alpha timeline tip`).isGonnaBeTruthy();
                // Verify beta tip exists on dest
                const destBetaTip = destKV[beta_tjpAddr];
                iReckon(sir, !!destBetaTip).asTo(`Dest KV has beta timeline tip`).isGonnaBeTruthy();
            }
            catch (error) {
                console.error(`${lc} ${extractErrorMsg(error)}`);
                iReckon(sir, true).asTo('getKnowledgeMap errored out').isGonnaBeFalse();
            }
        });
    });
    if (logalot) {
        console.log(`${lc} Running r3 Sync (both alpha and beta conflict)...`);
    }
    let r3_syncSaga;
    try {
        r3_syncSaga = await senderCoordinator.sync({
            peer: await newTestPeer(),
            localSpace: sourceSpace,
            metaspace,
            domainIbGibs: [r3_alpha_v4_source_mut8fieldC.ibGib, r3_beta_v1_source.ibGib],
            conflictStrategy: SyncConflictStrategy.optimisticWithLCS,
        });
        if (logalot) {
            console.log(`${lc} awaiting r3_syncSaga.done`);
        }
        await r3_syncSaga.done;
        if (logalot) {
            console.log(`${lc} r3_syncSaga Complete.`);
        }
    }
    catch (e) {
        console.error(`${lc} R3 Sync Failed with Error:`, e);
        iReckon(sir, false).asTo(`R3 Sync failed with error: ${e}`).isGonnaBeTruthy();
        return; // Exit test early
    }
    await respecfully(sir, `r3 verify post`, async () => {
        try {
            // Get KVs for both timelines after sync
            const alpha_sourceKV_afterR3 = await senderCoordinator.getKnowledgeMap({
                space: sourceSpace,
                metaspace,
                domainIbGibs: [r1_alpha_v0_source.ibGib]
            });
            const r3_alpha_source_tipAddr = alpha_sourceKV_afterR3[alpha_tjpAddr];
            const alpha_destKV_afterR3 = await senderCoordinator.getKnowledgeMap({
                space: destSpace,
                metaspace,
                domainIbGibs: [r1_alpha_v0_source.ibGib]
            });
            const r3_alpha_dest_tipAddr = alpha_destKV_afterR3[alpha_tjpAddr];
            const beta_sourceKV_afterR3 = await senderCoordinator.getKnowledgeMap({
                space: sourceSpace,
                metaspace,
                domainIbGibs: [r2_beta_v0_source.ibGib]
            });
            const r3_beta_source_tipAddr = beta_sourceKV_afterR3[beta_tjpAddr];
            const beta_destKV_afterR3 = await senderCoordinator.getKnowledgeMap({
                space: destSpace,
                metaspace,
                domainIbGibs: [r2_beta_v0_source.ibGib]
            });
            const r3_beta_dest_tipAddr = beta_destKV_afterR3[beta_tjpAddr];
            if (!r3_beta_dest_tipAddr) {
                await ifWe(sir, 'r3_beta_dest_tipAddr is falsy?', async () => {
                    iReckon(sir, true).asTo('fail').isGonnaBeFalse();
                });
                return; /* <<<< returns early */
            }
            await ifWe(sir, 'r3 tip addrs match (both timelines)', async () => {
                iReckon(sir, r3_alpha_source_tipAddr).asTo('alpha source/dest have same tip addrs').isGonnaBe(r3_alpha_dest_tipAddr);
                iReckon(sir, r3_beta_source_tipAddr).asTo('beta source/dest have same tip addrs').isGonnaBe(r3_beta_dest_tipAddr);
            });
            // Fetch alpha tip ibgib
            if (!r3_alpha_source_tipAddr) {
                throw new Error(`r3_alpha_source_tipAddr is null/undefined (E: 746f32e97387ce2e1401ea6e1c1b4826)`);
            }
            const resGet_r3_alpha_tip = await getFromSpace({ space: sourceSpace, addr: r3_alpha_source_tipAddr });
            const r3_alpha_tipIbGib = resGet_r3_alpha_tip.ibGibs[0];
            // Fetch beta tip ibgib
            if (!r3_beta_source_tipAddr) {
                throw new Error(`r3_beta_source_tipAddr is null/undefined (E: 9212c9e87248017d08a243682462ba26)`);
            }
            const resGet_r3_beta_tip = await getFromSpace({ space: sourceSpace, addr: r3_beta_source_tipAddr });
            const r3_beta_tipIbGib = resGet_r3_beta_tip.ibGibs[0];
            await ifWe(sir, 'r3 alpha merge has all four fields (commonField, fieldA, fieldB, fieldC, fieldD)', async () => {
                // Should have new graft point  with different addr than before
                iReckon(sir, r3_alpha_source_tipAddr)
                    .asTo(`Alpha R3 tip should NOT be r3_alpha_v4_source_mut8fieldC`)
                    .not.isGonnaBe(r3_alpha_v4_source_mut8fieldC.addr);
                iReckon(sir, r3_alpha_source_tipAddr)
                    .asTo(`Alpha R3 tip should NOT be r3_alpha_v4_dest_mut8fieldD`)
                    .not.isGonnaBe(r3_alpha_v4_dest_mut8fieldD.addr);
                // Check alpha has ALL fields: commonField (R1), fieldA (R2 source), fieldB (R2 dest), fieldC (R3 source), fieldD (R3 dest)
                const r3_alpha_v4_source_mut8Info = r3_alpha_v4_source_mut8fieldC.infos[0];
                const r3_alpha_v4_dest_mut8Info = r3_alpha_v4_dest_mut8fieldD.infos[0];
                iReckon(sir, r3_alpha_tipIbGib.data[r3_alpha_v4_source_mut8Info.key])
                    .asTo(`Alpha R3 tip has source field ${r3_alpha_v4_source_mut8Info.key}`)
                    .isGonnaBe(r3_alpha_v4_source_mut8Info.value);
                iReckon(sir, r3_alpha_tipIbGib.data[r3_alpha_v4_dest_mut8Info.key])
                    .asTo(`Alpha R3 tip has dest field ${r3_alpha_v4_dest_mut8Info.key}`)
                    .isGonnaBe(r3_alpha_v4_dest_mut8Info.value);
            });
            await ifWe(sir, 'r3 beta merge has both fields (betaFieldA, betaFieldB)', async () => {
                // Should have new graft point with different addr than before
                iReckon(sir, r3_beta_source_tipAddr)
                    .asTo(`Beta R3 tip should NOT be r3_beta_v1_source`)
                    .not.isGonnaBe(r3_beta_v1_source.addr);
                iReckon(sir, r3_beta_source_tipAddr)
                    .asTo(`Beta R3 tip should NOT be r3_beta_v1_dest`)
                    .not.isGonnaBe(r3_beta_v1_dest.addr);
                // Check beta has BOTH fields: betaFieldA (R3 source), betaFieldB (R3 dest)
                const r3_source_beta_mut8Info = r3_beta_v1_source.infos[0];
                const r3_dest_beta_mut8Info = r3_beta_v1_dest.infos[0];
                iReckon(sir, r3_beta_tipIbGib.data[r3_source_beta_mut8Info.key])
                    .asTo(`Beta R3 tip has source field ${r3_source_beta_mut8Info.key}`)
                    .isGonnaBe(r3_source_beta_mut8Info.value);
                iReckon(sir, r3_beta_tipIbGib.data[r3_dest_beta_mut8Info.key])
                    .asTo(`Beta R3 tip has dest field ${r3_dest_beta_mut8Info.key}`)
                    .isGonnaBe(r3_dest_beta_mut8Info.value);
            });
            await ifWe(sir, 'r3 alpha and deps synced', async () => {
                const [alpha_dest] = await getIbGibsFromCache_fallbackToSpaces({
                    // addrs: [r1_alpha_v0_source.addr],
                    addrs: [r3_alpha_source_tipAddr],
                    space: destSpace,
                });
                iReckon(sir, alpha_dest).asTo('alpha exists in dest').isGonnaBeTruthy();
                if (alpha_dest) {
                    try {
                        const depGraph_alpha_source = await getDependencyGraph({
                            ibGib: r1_alpha_v0_source.ibGib,
                            live: true,
                            space: sourceSpace
                        });
                        const depGraph_alpha_dest = await getDependencyGraph({
                            ibGib: alpha_dest,
                            live: true,
                            space: destSpace
                        });
                        const alphaDepsAreEqual = graphsAreEquivalent({
                            graphA: depGraph_alpha_source,
                            graphB: depGraph_alpha_dest,
                            slowButThorough: true,
                        });
                        iReckon(sir, alphaDepsAreEqual).asTo('alpha dep graph equal after R3 graft').isGonnaBeTrue();
                    }
                    catch (error) {
                        console.error(`${lc} ${extractErrorMsg(error)}`);
                        iReckon(sir, true).asTo('ERROR: alpha dep graph check failed').isGonnaBeFalse();
                    }
                }
            });
            await ifWe(sir, 'r3 beta and deps synced', async () => {
                const [beta_dest] = await getIbGibsFromCache_fallbackToSpaces({
                    // addrs: [r2_beta_v0_source.addr],
                    addrs: [r3_beta_dest_tipAddr],
                    space: destSpace,
                });
                iReckon(sir, beta_dest).asTo('beta exists in dest').isGonnaBeTruthy();
                if (beta_dest) {
                    try {
                        const depGraph_beta_source = await getDependencyGraph({
                            ibGib: r2_beta_v0_source.ibGib,
                            live: true,
                            space: sourceSpace
                        });
                        const depGraph_beta_dest = await getDependencyGraph({
                            ibGib: beta_dest,
                            live: true,
                            space: destSpace
                        });
                        const betaDepsAreEqual = graphsAreEquivalent({
                            graphA: depGraph_beta_source,
                            graphB: depGraph_beta_dest,
                            slowButThorough: true,
                        });
                        iReckon(sir, betaDepsAreEqual).asTo('beta dep graph equal after R3 graft').isGonnaBeTrue();
                    }
                    catch (error) {
                        console.error(`${lc} ${extractErrorMsg(error)}`);
                        iReckon(sir, true).asTo('ERROR: beta dep graph check failed').isGonnaBeFalse();
                    }
                }
            });
        }
        catch (error) {
            console.error(`${lc} ${extractErrorMsg(error)}`);
            iReckon(sir, true).asTo('R3 verify post errored out').isGonnaBeFalse();
        }
    });
    // #endregion Round 3: Multiple Timeline Conflicts
    // #region Round 4: Chain Edits After Graft
    const _r4 = testTransformer.newRound({
        name: 'r4_chain_edits_after_graft',
        description: 'Post-graft chain edits: mut8 → create gamma → rel8 gamma → mut8 again, tests continued editing on grafted timelines'
    });
    // #region r4 source edits
    if (logalot) {
        console.log(`${lc} Creating r4 chain edits on source (post-graft)...`);
    }
    // Source: Build chain on alpha post-graft
    // 1. Retrieve alpha R3 graft point from source
    const resGet_r4_alpha_source = await getFromSpace({ space: sourceSpace, addr: alpha_tjpAddr });
    if (!resGet_r4_alpha_source.success || !resGet_r4_alpha_source.ibGibs || resGet_r4_alpha_source.ibGibs.length === 0) {
        throw new Error(`Failed to retrieve alpha from sourceSpace for R4. (E: 1f2e3d4c5b6a7e8f9d0c1b2a3e4f5d6c)`);
    }
    const r4_alpha_v4_graftPoint = resGet_r4_alpha_source.ibGibs[0];
    // 2. Mutate alpha v5 (fieldE) from R3 graft point
    const r4_alpha_v5_source = await testTransformer.mut8({
        ibGib: r4_alpha_v4_graftPoint,
        in: 'source',
        strField: 'fieldE',
        name: 'r4_alpha_v5_source',
        comments_snake_plus_CamelCase: 'postGraft2',
    });
    // 3. Create new gamma timeline
    const r4_gamma_v0_source = await testTransformer.create({
        atom: 'gamma',
        in: 'source',
        data: { gammaField: 'gamma created on source' },
        name: 'r4_gamma_v0_source'
    });
    // 4. Relate alpha to gamma (creates v6)
    const r4_alpha_v6_source_rel8dGamma = await testTransformer.rel8({
        stepInfo: r4_alpha_v5_source,
        in: 'source',
        targetIbGibs: [r4_gamma_v0_source.ibGib],
        rel8nName: TEST_REL8N_NAME,
        name: 'r4_alpha_v6_source_rel8dGamma'
    });
    // 5. Mutate alpha again v7 (fieldF)
    const r4_alpha_v7_source = await testTransformer.mut8({
        ibGib: r4_alpha_v6_source_rel8dGamma.ibGib,
        in: 'source',
        strField: 'fieldF',
        name: 'r4_alpha_v7_source',
        comments_snake_plus_CamelCase: 'chainEnd',
    });
    // 6. Retrieve beta R3 graft point from source
    const resGet_r4_beta_source = await getFromSpace({ space: sourceSpace, addr: beta_tjpAddr });
    if (!resGet_r4_beta_source.success || !resGet_r4_beta_source.ibGibs || resGet_r4_beta_source.ibGibs.length === 0) {
        throw new Error(`Failed to retrieve beta from sourceSpace for R4. (E: 4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b)`);
    }
    const r4_beta_v1_graftPoint = resGet_r4_beta_source.ibGibs[0];
    // 7. Mutate beta v2 (betaFieldD) on source - creates divergence with dest
    const r4_beta_v2_source = await testTransformer.mut8({
        ibGib: r4_beta_v1_graftPoint,
        in: 'source',
        strField: 'betaFieldD',
        name: 'r4_beta_v2_source',
    });
    // #endregion r4 source edits
    // #region r4 dest edits
    if (logalot) {
        console.log(`${lc} Creating r4 edits on dest (post-graft)...`);
    }
    // Dest: Mutate both alpha and beta from their R3 graft points
    // 1. Retrieve alpha R3 graft point from dest
    const resGet_r4_alpha_dest = await getFromSpace({ space: destSpace, addr: alpha_tjpAddr });
    if (!resGet_r4_alpha_dest.success || !resGet_r4_alpha_dest.ibGibs || resGet_r4_alpha_dest.ibGibs.length === 0) {
        throw new Error(`Failed to retrieve alpha from destSpace for R4. (E: 9e8d7c6b5a4f3e2d1c0b9a8e7f6d5c4b)`);
    }
    const r4_alpha_v4_graftPoint_fromDest = resGet_r4_alpha_dest.ibGibs[0];
    // 2. Mutate alpha v5 (fieldG) from R3 graft point
    const r4_alpha_v5_dest = await testTransformer.mut8({
        ibGib: r4_alpha_v4_graftPoint_fromDest,
        in: 'dest',
        strField: 'fieldG',
        name: 'r4_alpha_v5_dest',
        comments_snake_plus_CamelCase: 'postGraft2',
    });
    // 3. Retrieve beta R3 graft point from dest (reuse beta_tjpAddr from R3)
    const resGet_r4_beta_dest = await getFromSpace({ space: destSpace, addr: beta_tjpAddr });
    if (!resGet_r4_beta_dest.success || !resGet_r4_beta_dest.ibGibs || resGet_r4_beta_dest.ibGibs.length === 0) {
        throw new Error(`Failed to retrieve beta from destSpace for R4. (E: 3b2a1f0e9d8c7b6a5e4f3d2c1b0a9e8f)`);
    }
    const r4_beta_v1_graftPoint_fromDest = resGet_r4_beta_dest.ibGibs[0];
    // 4. Mutate beta v2 (betaFieldC)
    const r4_beta_v2_dest = await testTransformer.mut8({
        ibGib: r4_beta_v1_graftPoint_fromDest,
        in: 'dest',
        strField: 'betaFieldC',
        name: 'r4_beta_v2_dest',
    });
    if (logalot) {
        console.log(`${lc} R4 Divergence created (post-graft chain edits).`);
    }
    // #endregion r4 dest edits
    await respecfully(sir, `r4 verify pre`, async () => {
        await ifWe(sir, 'dest has alpha and beta post-R3 tips', async () => {
            try {
                const destKV = await receiverCoordinator.getKnowledgeMap({
                    space: destSpace,
                    metaspace,
                    domainIbGibs: [r4_alpha_v4_graftPoint_fromDest, r4_beta_v1_graftPoint_fromDest]
                });
                // Verify alpha tip exists on dest (should be R3 graft point)
                const destAlphaTip = destKV[alpha_tjpAddr];
                iReckon(sir, !!destAlphaTip).asTo(`Dest KV has alpha timeline tip`).isGonnaBeTruthy();
                // Verify beta tip exists on dest (should be R3 graft point)
                const destBetaTip = destKV[beta_tjpAddr];
                iReckon(sir, !!destBetaTip).asTo(`Dest KV has beta timeline tip`).isGonnaBeTruthy();
            }
            catch (error) {
                console.error(`${lc} ${extractErrorMsg(error)}`);
                iReckon(sir, true).asTo('getKnowledgeMap errored out').isGonnaBeFalse();
            }
        });
    });
    if (logalot) {
        console.log(`${lc} Running r4 Sync (chain edits after graft)...`);
    }
    let r4_syncSaga;
    try {
        r4_syncSaga = await senderCoordinator.sync({
            peer: await newTestPeer(),
            localSpace: sourceSpace,
            metaspace,
            domainIbGibs: [r4_alpha_v7_source.ibGib, r4_gamma_v0_source.ibGib, r4_beta_v2_source.ibGib],
            conflictStrategy: SyncConflictStrategy.optimisticWithLCS,
        });
        if (logalot) {
            console.log(`${lc} awaiting r4_syncSaga.done`);
        }
        await r4_syncSaga.done;
        if (logalot) {
            console.log(`${lc} r4_syncSaga Complete.`);
        }
    }
    catch (e) {
        console.error(`${lc} R4 Sync Failed with Error:`, e);
        iReckon(sir, false).asTo(`R4 Sync failed with error: ${e}`).isGonnaBeTruthy();
        return; // Exit test early
    }
    await respecfully(sir, `r4 verify post`, async () => {
        try {
            // Get KVs for all three timelines after sync
            const gamma_tjpAddr = getTjpAddr({ ibGib: r4_gamma_v0_source.ibGib, defaultIfNone: 'incomingAddr' });
            const r4_alpha_sourceKV = await senderCoordinator.getKnowledgeMap({
                space: sourceSpace,
                metaspace,
                domainIbGibs: [r1_alpha_v0_source.ibGib]
            });
            const r4_alpha_source_tipAddr = r4_alpha_sourceKV[alpha_tjpAddr];
            const r4_alpha_destKV = await senderCoordinator.getKnowledgeMap({
                space: destSpace,
                metaspace,
                domainIbGibs: [r1_alpha_v0_source.ibGib]
            });
            const r4_alpha_dest_tipAddr = r4_alpha_destKV[alpha_tjpAddr];
            const r4_beta_sourceKV = await senderCoordinator.getKnowledgeMap({
                space: sourceSpace,
                metaspace,
                domainIbGibs: [r2_beta_v0_source.ibGib]
            });
            const r4_beta_source_tipAddr = r4_beta_sourceKV[beta_tjpAddr];
            const r4_beta_destKV = await senderCoordinator.getKnowledgeMap({
                space: destSpace,
                metaspace,
                domainIbGibs: [r2_beta_v0_source.ibGib]
            });
            const r4_beta_dest_tipAddr = r4_beta_destKV[beta_tjpAddr];
            if (!r4_beta_dest_tipAddr) {
                await ifWe(sir, 'r4_beta_dest_tipAddr is falsy?', async () => {
                    iReckon(sir, true).asTo('fail').isGonnaBeFalse();
                });
                return; /* <<<< returns early */
            }
            const r4_gamma_sourceKV = await senderCoordinator.getKnowledgeMap({
                space: sourceSpace,
                metaspace,
                domainIbGibs: [r4_gamma_v0_source.ibGib]
            });
            const r4_gamma_source_tipAddr = r4_gamma_sourceKV[gamma_tjpAddr];
            const r4_gamma_destKV = await senderCoordinator.getKnowledgeMap({
                space: destSpace,
                metaspace,
                domainIbGibs: [r4_gamma_v0_source.ibGib]
            });
            const r4_gamma_dest_tipAddr = r4_gamma_destKV[gamma_tjpAddr];
            await ifWe(sir, 'r4 tip addrs match (alpha, beta, gamma)', async () => {
                iReckon(sir, r4_alpha_source_tipAddr).asTo('alpha source/dest have same tip addrs').isGonnaBe(r4_alpha_dest_tipAddr);
                iReckon(sir, r4_beta_source_tipAddr).asTo('beta source/dest have same tip addrs').isGonnaBe(r4_beta_dest_tipAddr);
                iReckon(sir, r4_gamma_source_tipAddr).asTo('gamma source/dest have same tip addrs').isGonnaBe(r4_gamma_dest_tipAddr);
            });
            // Fetch tips
            if (!r4_alpha_source_tipAddr) {
                throw new Error(`r4_alpha_source_tipAddr is null/undefined (E: 5e4d3c2b1a0f9e8d7c6b5a4e3f2d1c0b)`);
            }
            const resGet_r4_alpha_tip = await getFromSpace({ space: sourceSpace, addr: r4_alpha_source_tipAddr });
            const r4_alpha_tipIbGib = resGet_r4_alpha_tip.ibGibs[0];
            if (!r4_beta_source_tipAddr) {
                throw new Error(`r4_beta_source_tipAddr is null/undefined (E: 2a1b0c9d8e7f6a5b4c3d2e1f0a9b8c7d)`);
            }
            const resGet_r4_beta_tip = await getFromSpace({ space: sourceSpace, addr: r4_beta_source_tipAddr });
            const r4_beta_tipIbGib = resGet_r4_beta_tip.ibGibs[0];
            if (!r4_gamma_source_tipAddr) {
                throw new Error(`r4_gamma_source_tipAddr is null/undefined (E: 7f6e5d4c3b2a1e0f9d8c7b6a5e4f3d2c)`);
            }
            const resGet_r4_gamma_tip = await getFromSpace({ space: sourceSpace, addr: r4_gamma_source_tipAddr });
            const r4_gamma_tipIbGib = resGet_r4_gamma_tip.ibGibs[0];
            await ifWe(sir, 'r4 alpha has complete chain of edits and gamma relation', async () => {
                // Should have new graft point with different addr than either pre-graft version
                iReckon(sir, r4_alpha_source_tipAddr)
                    .asTo(`Alpha R4 tip should NOT be r4_alpha_v7_source`)
                    .not.isGonnaBe(r4_alpha_v7_source.addr);
                iReckon(sir, r4_alpha_source_tipAddr)
                    .asTo(`Alpha R4 tip should NOT be r4_alpha_v5_dest`)
                    .not.isGonnaBe(r4_alpha_v5_dest.addr);
                // Check alpha has ALL fields from R1-R4
                // R1: commonField
                // R2 source: fieldA, R2 dest: fieldB
                // R3 source: fieldC (in graft), R3 dest: fieldD (in graft)
                // R4 source: fieldE, fieldF (in chain), R4 dest: fieldG (in graft)
                const r4_source_alpha_v5_mut8Info = r4_alpha_v5_source.infos[0];
                const r4_source_alpha_v7_mut8Info = r4_alpha_v7_source.infos[0];
                const r4_dest_alpha_mut8Info = r4_alpha_v5_dest.infos[0];
                iReckon(sir, r4_alpha_tipIbGib.data[r4_source_alpha_v5_mut8Info.key])
                    .asTo(`Alpha R4 tip has source fieldE`)
                    .isGonnaBe(r4_source_alpha_v5_mut8Info.value);
                iReckon(sir, r4_alpha_tipIbGib.data[r4_source_alpha_v7_mut8Info.key])
                    .asTo(`Alpha R4 tip has source fieldF`)
                    .isGonnaBe(r4_source_alpha_v7_mut8Info.value);
                iReckon(sir, r4_alpha_tipIbGib.data[r4_dest_alpha_mut8Info.key])
                    .asTo(`Alpha R4 tip has dest fieldG`)
                    .isGonnaBe(r4_dest_alpha_mut8Info.value);
                // Verify alpha has gamma in relations
                const gammaAddr = getIbGibAddr({ ibGib: r4_gamma_v0_source.ibGib });
                const alphaRel8ns = r4_alpha_tipIbGib.rel8ns?.[TEST_REL8N_NAME] || [];
                iReckon(sir, alphaRel8ns.includes(gammaAddr))
                    .asTo('Alpha has gamma in testrel8n')
                    .isGonnaBeTrue();
            });
            await ifWe(sir, 'r4 beta has all edits', async () => {
                // Beta should have new graft from R4
                iReckon(sir, r4_beta_source_tipAddr)
                    .asTo(`Beta R4 tip should NOT be r4_beta_v2_source (source version pre-graft)`)
                    .not.isGonnaBe(r4_beta_v2_source.addr);
                iReckon(sir, r4_beta_source_tipAddr)
                    .asTo(`Beta R4 tip should NOT be r4_beta_v2_dest (dest version pre-graft)`)
                    .not.isGonnaBe(r4_beta_v2_dest.addr);
                // Check beta has ALL fields: betaFieldA (R3 source), betaFieldB (R3 dest), betaFieldC (R4 dest), betaFieldD (R4 source)
                const r4_source_beta_mut8Info = r4_beta_v2_source.infos[0];
                const r4_dest_beta_mut8Info = r4_beta_v2_dest.infos[0];
                iReckon(sir, r4_beta_tipIbGib.data[r4_source_beta_mut8Info.key])
                    .asTo(`Beta R4 tip has source betaFieldD`)
                    .isGonnaBe(r4_source_beta_mut8Info.value);
                iReckon(sir, r4_beta_tipIbGib.data[r4_dest_beta_mut8Info.key])
                    .asTo(`Beta R4 tip has dest betaFieldC`)
                    .isGonnaBe(r4_dest_beta_mut8Info.value);
            });
            await ifWe(sir, 'r4 gamma synced with deps', async () => {
                const [gamma_dest] = await getIbGibsFromCache_fallbackToSpaces({
                    addrs: [r4_gamma_v0_source.addr],
                    space: destSpace,
                });
                iReckon(sir, gamma_dest).asTo('gamma exists in dest').isGonnaBeTruthy();
                if (gamma_dest) {
                    try {
                        const depGraph_gamma_source = await getDependencyGraph({
                            ibGib: r4_gamma_v0_source.ibGib,
                            live: true,
                            space: sourceSpace
                        });
                        const depGraph_gamma_dest = await getDependencyGraph({
                            ibGib: gamma_dest,
                            live: true,
                            space: destSpace
                        });
                        const gammaDepsAreEqual = graphsAreEquivalent({
                            graphA: depGraph_gamma_source,
                            graphB: depGraph_gamma_dest,
                            slowButThorough: true,
                        });
                        iReckon(sir, gammaDepsAreEqual).asTo('gamma dep graph equal').isGonnaBeTrue();
                    }
                    catch (error) {
                        console.error(`${lc} ${extractErrorMsg(error)}`);
                        iReckon(sir, true).asTo('ERROR: gamma dep graph check failed').isGonnaBeFalse();
                    }
                }
            });
            await ifWe(sir, 'r4 all timelines dep graphs synced', async () => {
                // Verify alpha dep graphs
                const [alpha_dest] = await getIbGibsFromCache_fallbackToSpaces({
                    addrs: [r4_alpha_source_tipAddr],
                    space: destSpace,
                });
                iReckon(sir, alpha_dest).asTo('alpha exists in dest').isGonnaBeTruthy();
                if (alpha_dest) {
                    try {
                        const depGraph_alpha_source = await getDependencyGraph({
                            ibGib: r1_alpha_v0_source.ibGib,
                            live: true,
                            space: sourceSpace
                        });
                        const depGraph_alpha_dest = await getDependencyGraph({
                            ibGib: alpha_dest,
                            live: true,
                            space: destSpace
                        });
                        const alphaDepsAreEqual = graphsAreEquivalent({
                            graphA: depGraph_alpha_source,
                            graphB: depGraph_alpha_dest,
                            slowButThorough: true,
                        });
                        iReckon(sir, alphaDepsAreEqual).asTo('alpha dep graph equal after R4').isGonnaBeTrue();
                    }
                    catch (error) {
                        console.error(`${lc} ${extractErrorMsg(error)}`);
                        iReckon(sir, true).asTo('ERROR: alpha dep graph check failed').isGonnaBeFalse();
                    }
                }
                // Verify beta dep graphs
                const [beta_dest] = await getIbGibsFromCache_fallbackToSpaces({
                    addrs: [r4_beta_dest_tipAddr],
                    space: destSpace,
                });
                iReckon(sir, beta_dest).asTo('beta exists in dest').isGonnaBeTruthy();
                if (beta_dest) {
                    try {
                        const depGraph_beta_source = await getDependencyGraph({
                            ibGib: r2_beta_v0_source.ibGib,
                            live: true,
                            space: sourceSpace
                        });
                        const depGraph_beta_dest = await getDependencyGraph({
                            ibGib: beta_dest,
                            live: true,
                            space: destSpace
                        });
                        const betaDepsAreEqual = graphsAreEquivalent({
                            graphA: depGraph_beta_source,
                            graphB: depGraph_beta_dest,
                            slowButThorough: true,
                        });
                        iReckon(sir, betaDepsAreEqual).asTo('beta dep graph equal after R4').isGonnaBeTrue();
                    }
                    catch (error) {
                        console.error(`${lc} ${extractErrorMsg(error)}`);
                        iReckon(sir, true).asTo('ERROR: beta dep graph check failed').isGonnaBeFalse();
                    }
                }
            });
        }
        catch (error) {
            console.error(`${lc} ${extractErrorMsg(error)}`);
            iReckon(sir, true).asTo('R4 verify post errored out').isGonnaBeFalse();
        }
    });
    // #endregion Round 4: Chain Edits After Graft
});
//# sourceMappingURL=sync-conflict-adv-multitimelines.respec.mjs.map