// Model B PURE MEMBRANE: createPdsServer({peers}) + startControl({peers}). No local Pds,
// no key, no account. Every fronted-DID read still routes to the remote hyper-proto-peer
// (keyless); describeServer/listRepos synthesize from opts+fronted set; every custodial /
// authed endpoint 404s; a non-fronted DID 404s; the UDS status reports a membrane.
// This is the artifact that restores wj62 on :3399 without re-custodying its key.
import test from 'brittle'
import { mkdtempSync, rmSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import b4a from 'b4a'
import c from 'compact-encoding'
import Hyperswarm from 'hyperswarm'
import createTestnet from '@hyperswarm/testnet'
import ProtomuxRPC from 'protomux-rpc'
import { pushAnnounce } from './serve-announce.js'
import { Client } from 'hyper-svc'
import { openCorestore } from 'atproto-store/lib/corestore.js'
import { RepoStore } from 'atproto-store/lib/repo-store.js'
import { RepoManager } from 'atproto-store/lib/repo-manager.js'
import { FirehoseSequencer } from 'atproto-store/lib/sequencer.js'
import { keyFromPrivate } from 'atproto-identity'
import { discoveryTopic } from 'atproto-identity/lib/discovery.js'
import { createPdsServer } from '../lib/server.js'
import { startControl } from '../lib/control.js'
import { DidPeerRouter } from 'atproto-did-peer'
process.env.PGH_SIDECAR_SOCK = join(tmpdir(), `no-sidecar-${process.pid}.sock`) // no registration
const DID = 'did:plc:membraneonly'
const HANDLE = 'membraneonly.7rnx.net'
const PRIV = new Uint8Array(32).fill(7)
const NOW = '2026-07-04T00:00:00.000Z'
const SERVER_DID = 'did:web:pds.7rnx.net'
const DOMAINS = ['.7rnx.net']
test('pure membrane (pds=null) fronts a peer, synthesizes describeServer/listRepos, 404s custodial endpoints', async (t) => {
const testnet = await createTestnet(3)
// a discoverable self-custody peer: signed repo + firehose + get-coords / create-session
const peerDir = mkdtempSync(join(tmpdir(), 'monly-peer-'))
const peerStore = openCorestore(peerDir)
const repo = await new RepoStore(peerStore, { name: `atproto-repo:${DID}` }).ready()
let micros = 1_700_000_000_000_000n
const mgr = await new RepoManager(repo, { did: DID, privateKey: PRIV, clock: () => (micros += 1_000_000n) }).init()
const seq = await new FirehoseSequencer(peerStore.get({ name: 'firehose' })).ready()
const w = await mgr.applyWrite({ action: 'create', collection: 'app.bsky.feed.post', rkey: '3a', record: { $type: 'app.bsky.feed.post', text: 'self-custody', createdAt: NOW } })
await seq.sequenceCommit(w, { time: NOW })
const peerSwarm = new Hyperswarm({ bootstrap: testnet.bootstrap })
peerSwarm.on('connection', (conn) => {
peerStore.replicate(conn)
const rpc = new ProtomuxRPC(conn, { protocol: 'hyper-proto-peer/rpc/v1', valueEncoding: c.json })
pushAnnounce(conn, { did: DID, handle: HANDLE, repo, seq })
rpc.respond('create-session', async ({ identifier }) => ({ did: DID, handle: HANDLE, accessJwt: `access-${identifier}`, refreshJwt: 'refresh' }))
})
await peerSwarm.join(discoveryTopic(DID), { server: true, client: false }).flushed()
// THE MEMBRANE: no Pds at all — the shared DidPeerRouter fronting DID + the HTTP server with pds=null.
// Constructed EXACTLY as pds-serve.js does (owns-swarm + join + rpc) — verifies the prod repoint.
const routerStore = openCorestore(mkdtempSync(join(tmpdir(), 'monly-router-')))
const routerSwarm = new Hyperswarm({ bootstrap: testnet.bootstrap })
const router = new DidPeerRouter(routerStore, {
swarm: routerSwarm,
join: (did) => { try { routerSwarm.join(discoveryTopic(did), { server: true, client: true }); routerSwarm.flush().catch(() => {}) } catch {} },
fronted: [DID],
resolveVerifyKey: async () => keyFromPrivate(PRIV).publicKey,
rpc: true
})
const server = createPdsServer({ peers: router, serverDid: SERVER_DID, availableUserDomains: DOMAINS })
await new Promise((r) => server.listen(0, '127.0.0.1', r))
const base = `http://127.0.0.1:${server.address().port}`
const xrpc = (m) => `${base}/xrpc/${m}`
const udsDir = mkdtempSync(join(tmpdir(), 'monly-uds-'))
const uds = join(udsDir, 'svc.sock')
const control = await startControl({ uds, name: 'atproto-bridge-membrane-test', peers: router })
t.teardown(async () => {
await control.close(); server.close(); await router.close()
await peerSwarm.destroy(); await routerSwarm.destroy()
await seq.close(); await repo.close(); await peerStore.close(); await routerStore.close()
await testnet.destroy()
rmSync(peerDir, { recursive: true, force: true }); rmSync(udsDir, { recursive: true, force: true })
})
// --- fronted-DID reads route to the peer, keyless ---
const carBuf = new Uint8Array(await (await fetch(xrpc('com.atproto.sync.getRepo') + '?did=' + DID)).arrayBuffer())
t.ok(carBuf.length > 0, 'membrane getRepo returns the fronted peer CAR (keyless, pds=null)')
const rec = await (await fetch(xrpc('com.atproto.repo.getRecord') + '?repo=' + DID + '&collection=app.bsky.feed.post&rkey=3a')).json()
t.is(rec.value.text, 'self-custody', 'membrane getRecord routed to the peer (pds=null)')
const status = await (await fetch(xrpc('com.atproto.sync.getRepoStatus') + '?did=' + DID)).json()
t.is(status.active, true, 'membrane getRepoStatus routed to the peer (pds=null)')
const latest = await (await fetch(xrpc('com.atproto.sync.getLatestCommit') + '?did=' + DID)).json()
t.ok(latest.cid && latest.rev, 'membrane getLatestCommit routed to the peer (pds=null)')
const sess = await (await fetch(xrpc('com.atproto.server.createSession'), { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ identifier: DID, password: 'x' }) })).json()
t.is(sess.accessJwt, `access-${DID}`, 'membrane createSession routed to the peer (pds=null)')
// --- synthesized server metadata (no Pds to answer these) ---
const desc = await (await fetch(xrpc('com.atproto.server.describeServer'))).json()
t.is(desc.did, SERVER_DID, 'describeServer.did synthesized from serverDid opt')
t.alike(desc.availableUserDomains, DOMAINS, 'describeServer.availableUserDomains synthesized')
const repos = await (await fetch(xrpc('com.atproto.sync.listRepos'))).json()
t.ok(repos.repos.length === 1 && repos.repos[0].did === DID && repos.repos[0].active === true, 'listRepos advertises the fronted DID as active')
const resolved = await (await fetch(xrpc('com.atproto.identity.resolveHandle') + '?handle=' + HANDLE)).json()
t.is(resolved.did, DID, 'resolveHandle maps the fronted handle to its DID')
// --- non-fronted DID + custodial/authed endpoints all 404 (nothing to serve locally) ---
const missing = await fetch(xrpc('com.atproto.sync.getRepo') + '?did=did:plc:notfronted')
t.is(missing.status, 404, 'non-fronted DID getRepo → 404')
const gsess = await fetch(xrpc('com.atproto.server.getSession'), { headers: { authorization: 'Bearer whatever' } })
t.is(gsess.status, 404, 'authed getSession on a keyless membrane → 404')
const blob = await fetch(xrpc('com.atproto.sync.getBlob') + '?cid=bafyreiabc')
t.is(blob.status, 404, 'getBlob on a keyless membrane → 404')
const acct = await fetch(xrpc('com.atproto.server.createAccount'), { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ handle: 'x.7rnx.net' }) })
t.is(acct.status, 404, 'createAccount on a keyless membrane → 404')
// --- UDS control status reports a membrane ---
const cli = await Client.connectUds(uds)
const st = await cli.call('status')
await cli.close()
t.ok(st.ok && st.membrane === true && Array.isArray(st.fronted) && st.fronted[0] === DID, 'UDS status reports membrane:true + fronted=[DID]')
})