// Peer-level BYTE convergence — the regression guard for "co-owned on paper, single-homed in practice".
//
// The autobase guarantees POINTER convergence: every co-owner agrees on WHICH records exist. Byte
// convergence had no equivalent. The only path that resolves record bytes is sign()'s
// listRecords({now:true}), and sign() returns at the ELECTION GATE (holdsSigner) BEFORE reaching it:
//
// sign() ... if (!force && !this.sb.holdsSigner(...)) return null <-- non-signer exits here
// const records = await this.repo.listRecords(null, {now:true}) <-- bytes resolved HERE
//
// So a co-owner that is not the current signer never fetched a single record byte. Its byte set grew
// only from what it authored locally while its pointer set stayed correct and agreeing — both nodes
// report a healthy, identical record set while silently diverging. Measured on the live wj62 pair:
// 125 vs 124 posts, each holding one the other lacked, and a record unresolved for 75+ hours that
// appeared the instant anything called a byte-resolving read.
//
// Test 1 is the load-bearing one: it asserts the NON-SIGNER converges. It fails without
// reconcileBytes, because sign() is the only thing that would have pulled and it returns early.
//
// Run: bare test/reconcile-bytes.test.mjs
import '../lib/bare-globals.js'
import test from 'brittle'
import fs from 'bare-fs'
import b4a from 'b4a'
import crypto from 'hypercore-crypto'
import { OverlayRepoStore } from 'atproto-store/lib/overlay-repo-store.js'
import { SwarmDevice } from '../lib/swarm-device.js'
const DID = 'did:plc:reconcilebytes00000000'
const tmp = () => { const d = '/tmp/hpp-recon-' + Math.floor(Math.random() * 1e9); fs.mkdirSync(d, { recursive: true }); return d }
// A substrate holding POINTERS only — exactly what replication delivers to a co-owner: it converges
// which records exist, and nothing about their bytes.
function memKV (holdsSigner) {
const m = new Map()
return {
_m: m,
async set (k, v) { m.set(k, v) },
async del (k) { m.delete(k) },
async get (k) { return m.has(k) ? m.get(k) : null },
async list (prefix = '') { const o = {}; for (const [k, v] of m) if (k.startsWith(prefix)) o[k] = v; return o },
async listNow (prefix = '') { return this.list(prefix) },
async getNow (k) { return this.get(k) },
holdsSigner: () => holdsSigner
}
}
// A content-addressed transport shared by the "peers": bytes are fetchable by oid from anywhere,
// which is the one property a real overlay provides and the one this feature depends on.
function mkOverlay (net) {
return {
async registerFile (overlayPath, diskPath) {
const bytes = fs.readFileSync(diskPath)
const oid = crypto.data(bytes).toString('hex')
net.set(oid, bytes)
return { contentHash: oid }
},
async fetchFile (oid, { destPath } = {}) {
const bytes = net.get(oid)
if (!bytes) return null
fs.writeFileSync(destPath, bytes)
return { path: destPath }
},
get peerCount () { return net.size ? 1 : 0 }
}
}
const REC = { $type: 'app.bsky.feed.post', text: 'a co-owner must be able to hold this', createdAt: '2026-07-26T00:00:00.000Z' }
// Seed `net` with a record's bytes (as the authoring peer would) and return its pointer.
async function authorElsewhere (net, collection, rkey, record) {
const store = await new OverlayRepoStore(tmp(), { overlay: mkOverlay(net) }).ready()
const { oid, size } = await store.put(collection, rkey, record)
return { $oid: oid, size }
}
test('a NON-SIGNER converges record bytes (it never reaches the code path that pulls)', async (t) => {
const net = new Map()
const ptr = await authorElsewhere(net, 'app.bsky.feed.post', '3kaaa', REC)
const root = tmp()
const store = await new OverlayRepoStore(root, { overlay: mkOverlay(net), did: DID }).ready()
const sb = memKV(false) // <- NOT the elected signer
const device = new SwarmDevice(sb, { did: DID, privateKey: crypto.randomBytes(32), self: 'peerB', recordStore: store })
// Replication delivered the POINTER; the bytes are not here.
await sb.set('app.bsky.feed.post/3kaaa', ptr)
t.absent(fs.existsSync(root + '/records/app.bsky.feed.post/3kaaa.dagcbor'), 'precondition: pointer converged, bytes absent')
// CONTROL: sign() is the only thing that would have pulled, and it bails at the election gate.
t.is(await device.sign(), null, 'CONTROL: a non-signer signs nothing — so it never resolves bytes')
t.absent(fs.existsSync(root + '/records/app.bsky.feed.post/3kaaa.dagcbor'), 'and the bytes are STILL absent after a full sign pass')
const r = await device.reconcileBytes()
t.is(r.missing, 1, 'reconcile saw one pointer without local bytes')
t.is(r.fetched, 1, 'and pulled it')
t.ok(fs.existsSync(root + '/records/app.bsky.feed.post/3kaaa.dagcbor'), 'the NON-SIGNER now holds the bytes')
t.alike(await store.get('app.bsky.feed.post', '3kaaa'), REC, 'byte-exact record')
await store.close()
})
test('reconcile is idempotent and quiet once converged', async (t) => {
const net = new Map()
const ptr = await authorElsewhere(net, 'app.bsky.feed.post', '3kbbb', REC)
const store = await new OverlayRepoStore(tmp(), { overlay: mkOverlay(net), did: DID }).ready()
const sb = memKV(false)
const device = new SwarmDevice(sb, { did: DID, privateKey: crypto.randomBytes(32), self: 'peerB', recordStore: store })
await sb.set('app.bsky.feed.post/3kbbb', ptr)
t.is((await device.reconcileBytes()).fetched, 1, 'first pass pulls')
const second = await device.reconcileBytes()
t.is(second.fetched, 0, 'second pass pulls nothing')
t.is(second.missing, 0, 'nothing is missing')
t.is(second.checked, 1, 'but it still checked the record')
await store.close()
})
test('reconcile ignores reserved keys and tombstones (never chases bytes that cannot exist)', async (t) => {
const net = new Map()
const store = await new OverlayRepoStore(tmp(), { overlay: mkOverlay(net), did: DID }).ready()
const sb = memKV(false)
const device = new SwarmDevice(sb, { did: DID, privateKey: crypto.randomBytes(32), self: 'peerB', recordStore: store })
await sb.set('__commit__/3kzzz', { rev: '3kzzz', ops: [] }) // firehose frame — not a record
await sb.set('__members__', { a: 1 }) // control key
await sb.set('app.bsky.feed.post/3kdel', { $deleted: true }) // tombstone — deliberately no bytes
const r = await device.reconcileBytes()
t.is(r.checked, 0, 'no reserved key or tombstone was treated as a record')
t.is(r.missing, 0, 'so nothing was reported missing')
t.is(r.failed, 0, 'and nothing was uselessly fetched')
await store.close()
})
test('a pass is BOUNDED and reports `more`, so a backlog cannot block signing', async (t) => {
const net = new Map()
const store = await new OverlayRepoStore(tmp(), { overlay: mkOverlay(net), did: DID }).ready()
const sb = memKV(false)
const device = new SwarmDevice(sb, { did: DID, privateKey: crypto.randomBytes(32), self: 'peerB', recordStore: store })
for (let i = 0; i < 10; i++) {
const ptr = await authorElsewhere(net, 'app.bsky.feed.post', 'r' + i, { ...REC, text: 'post ' + i })
await sb.set('app.bsky.feed.post/r' + i, ptr)
}
const first = await device.reconcileBytes({ limit: 4 })
t.is(first.fetched, 4, 'a bounded pass pulls at most `limit`')
t.ok(first.more, 'and says there is more to do')
let guard = 0
while ((await device.reconcileBytes({ limit: 4 })).more && guard++ < 10) { /* drain */ }
const done = await device.reconcileBytes({ limit: 4 })
t.is(done.missing, 0, 'successive passes converge the whole backlog')
t.is(done.checked, 10, 'all ten records accounted for')
await store.close()
})
test('an unfetchable pointer fails without wedging the pass (no peer has the bytes)', async (t) => {
const net = new Map()
const store = await new OverlayRepoStore(tmp(), { overlay: mkOverlay(net), did: DID }).ready()
const sb = memKV(false)
const device = new SwarmDevice(sb, { did: DID, privateKey: crypto.randomBytes(32), self: 'peerB', recordStore: store })
const good = await authorElsewhere(net, 'app.bsky.feed.post', 'ok', REC)
await sb.set('app.bsky.feed.post/ok', good)
await sb.set('app.bsky.feed.post/gone', { $oid: b4a.toString(crypto.randomBytes(32), 'hex'), size: 9 }) // nobody has it
const r = await device.reconcileBytes()
t.is(r.fetched, 1, 'the resolvable record was pulled')
t.is(r.failed, 1, 'the unresolvable one was counted, not thrown')
t.ok(await store.get('app.bsky.feed.post', 'ok'), 'and the good record is present')
await store.close()
})