// Mirror mode (issue #35): a sister daemon replicates the WHOLE forge by
// following the primary's org-key list and mounting EVERY org. Contrast
// with peer mode (join specific orgs via invite). Both mount per-org
// autobases — mirror just grabs them all.
//
// (This proves the read-replica path: mirror sees all orgs. HA write
// enrollment for mirrors — making the sister a writer too — reuses
// enrollWriter and is a follow-up.)
import test from 'brittle'
import Corestore from 'corestore'
import { mkdtempSync } from 'fs'
import { join } from 'path'
import { tmpdir } from 'os'
import { replicateAndSync } from 'autobase-test-helpers'
import { HyperOrgs } from '../index.js'
function tmpStore () {
return new Corestore(mkdtempSync(join(tmpdir(), 'hyper-orgs-mirror-')))
}
test('#35 mirror mode: mount ALL orgs from the primary key-list', async (t) => {
const storeP = tmpStore()
const storeM = tmpStore()
const primary = new HyperOrgs(storeP, { namespace: 'mir-primary' })
await primary.ready()
await primary.create('alpha', 'group', { displayName: 'Alpha' })
await primary.create('beta', 'group')
await primary.create('gamma', 'group')
await primary.addResource('alpha', 'repo-1')
await primary.sync()
// Primary exposes its org keys (over RPC in the daemon; here directly).
const keys = primary.listOrgKeys()
t.is(keys.length, 3, 'primary lists all 3 org keys')
// Mirror mounts EVERY org by key (no invite — mirror mode).
const mirror = new HyperOrgs(storeM, { namespace: 'mir-mirror' })
await mirror.ready()
for (const k of keys) await mirror.mountOrg(k.name, k.bootstrapKey, 'reader')
for (const k of keys) {
await replicateAndSync([primary.getOrgBase(k.name), mirror.getOrgBase(k.name)])
}
// Full replica: mirror sees every org + its data.
for (const n of ['alpha', 'beta', 'gamma']) t.ok(await mirror.get(n), `mirror has ${n}`)
t.is((await mirror.list()).length, 3, 'mirror replicates all orgs')
t.alike((await mirror.get('alpha')).resources, ['repo-1'], 'mirror has alpha data')
t.teardown(async () => {
try { await primary.close() } catch {}
try { await mirror.close() } catch {}
try { await storeP.close() } catch {}
try { await storeM.close() } catch {}
})
})