import assert from 'node:assert/strict' import { describe, it } from 'node:test' import { materialize } from '../dist/materializer.js' import { MemoryRecordStore } from '../dist/store.js' import { privateScenario, goldenScenario } from '../dist/test/scenario.js' import { COLLECTIONS } from '../dist/generated/records.js' import { indexDigest, digestDifferences } from '../dist/digest.js' import { readDeviceDirectory } from '../dist/devices.js' import { connectablePeers } from '../dist/private/peers.js' const AS_OF = '2026-04-01T00:00:00Z' function build(records, spaceUri) { const store = new MemoryRecordStore() records.forEach((record) => store.put(record)) return materialize(store, { spaceUri, asOf: AS_OF }) } function shuffled(records, seed) { const result = [...records] let state = seed >>> 0 const random = () => { state ^= state << 13 state ^= state >>> 17 state ^= state << 5 return state >>> 0 } for (let index = result.length - 1; index > 0; index -= 1) { const target = random() % (index + 1) ;[result[index], result[target]] = [result[target], result[index]] } return result } const reasonsFor = (index, uri) => index.ignored.filter((entry) => entry.uri === uri).map((entry) => entry.reason) describe('the device fold', () => { it('keeps rotated-key history and exposes every published key as bound', () => { const scenario = privateScenario() const index = build(scenario.records, scenario.spaceUri) assert.equal(index.private, true) assert.ok(index.goals[0].messages.some((entry) => entry.uri === scenario.rotatedHistoryUri)) assert.ok(index.devices.some((device) => device.deviceKeyId === scenario.rootDeviceKeyId)) assert.ok(index.devices.some((device) => device.deviceKeyId === scenario.rotatedRootDeviceKeyId)) }) it('refuses signatures from unpublished keys and directory records from envelopes', () => { const scenario = privateScenario() const index = build(scenario.records, scenario.spaceUri) assert.deepEqual(reasonsFor(index, scenario.unpublishedSignerUri), [ 'signing device is not published by its author', ]) assert.deepEqual(reasonsFor(index, scenario.envelopeDeviceUri), [ 'device directory records are only read from the public path', ]) }) it('refuses unsigned private-space work, including a forged membership grant', () => { const scenario = privateScenario() const index = build(scenario.records, scenario.spaceUri) assert.deepEqual(reasonsFor(index, scenario.injectedGrantUri), [ 'record did not arrive in a signed envelope', ]) assert.deepEqual(reasonsFor(index, scenario.injectedMessageUri), [ 'record did not arrive in a signed envelope', ]) assert.equal(index.members.some((member) => member.did === scenario.injectedAdminDid), false) }) it('counts an agent profile only from an envelope, never from its author\'s PDS', () => { const scenario = privateScenario() const index = build(scenario.records, scenario.spaceUri) // The enveloped profile is the whole of `index.agents` here: an assignee list a private space // has at all is one the daemon sealed into the replica. assert.deepEqual(index.agents.map((agent) => agent.uri), [scenario.envelopeAgentUri]) assert.deepEqual(index.agents[0].value.artifactTypes, ['implementation', 'review']) // A private replica is per-space, so effective types are resolved before sealing and the // scoping vocabulary never travels in an envelope. assert.equal(index.agents[0].value.scopes, undefined) // The same profile written to the agent's own repo — what `radiald init` publishes — is refused // for the ordinary reason. `agent` is not on the public path, so custody of a repo is not a // capability grant. assert.deepEqual(reasonsFor(index, scenario.injectedAgentUri), [ 'record did not arrive in a signed envelope', ]) }) it('uses earliest creation and URI order for a contested device key id', () => { const scenario = privateScenario() const original = scenario.records.find( (record) => record.collection === COLLECTIONS.device && record.rkey === scenario.rootDeviceKeyId, ) const contested = { ...original, rkey: 'contested-root-key', uri: `at://${scenario.rootDid}/${COLLECTIONS.device}/contested-root-key`, cid: 'cid-contested-root-key', value: { ...original.value, publicKey: 'z'.repeat(43), createdAt: '2026-03-02T00:00:00Z' }, } const index = build([...scenario.records, contested], scenario.spaceUri) const binding = index.devices.find((device) => device.deviceKeyId === scenario.rootDeviceKeyId) assert.equal(binding.publicKey, original.value.publicKey) assert.deepEqual(reasonsFor(index, contested.uri), [ 'device key id is already published by this author', ]) }) it('adopts the latest address without changing the digest', () => { const scenario = privateScenario() const index = build(scenario.records, scenario.spaceUri) const device = index.devices.find((entry) => entry.deviceKeyId === scenario.rootDeviceKeyId) assert.equal(device.endpointId, scenario.addressEndpointId) const stale = scenario.records.filter( (record) => !(record.collection === COLLECTIONS.deviceAddress && record.cid === 'cid-address-v2'), ) assert.deepEqual( digestDifferences(indexDigest(build(stale, scenario.spaceUri)), indexDigest(index)), [], ) }) it('changes nothing at all when a device is retired', () => { // ADR §29: retiring a device is a statement about CONNECTIONS, and the fold is where that claim // has to be false or true. It is asserted against the whole index rather than against the // records the retired key happens to have signed, because the interesting failure is not "some // of its history vanished" — it is any difference whatsoever. const scenario = privateScenario() const index = build(scenario.records, scenario.spaceUri) const withdrawn = scenario.records.map((record) => record.collection === COLLECTIONS.deviceAddress && record.cid === 'cid-address-v2' ? { ...record, value: { ...record.value, retiredAt: '2026-03-02T00:00:00Z' } } : record, ) const after = build(withdrawn, scenario.spaceUri) assert.deepEqual(after.records, index.records) assert.deepEqual(after.ignored, index.ignored) assert.deepEqual(digestDifferences(indexDigest(after), indexDigest(index)), []) // The device is still bound and still listed — the binding is untouched, which is the whole // difference between this and a revocation. What changed is only where it can be reached. const device = after.devices.find((entry) => entry.deviceKeyId === scenario.rootDeviceKeyId) assert.equal(device.retiredAt, '2026-03-02T00:00:00Z') assert.equal(device.endpointId, undefined) assert.deepEqual( connectablePeers(readDeviceDirectory(withdrawn, [])).map((peer) => peer.endpointId), connectablePeers(readDeviceDirectory(scenario.records, [])) .map((peer) => peer.endpointId) .filter((endpointId) => endpointId !== scenario.addressEndpointId), ) }) it('is invariant under 200 deterministic arrival permutations', () => { const scenario = privateScenario() const expected = build(scenario.records, scenario.spaceUri) for (let seed = 1; seed <= 200; seed += 1) { assert.deepEqual(build(shuffled(scenario.records, seed), scenario.spaceUri), expected, `seed ${seed}`) } }) it('leaves public spaces untouched', () => { const golden = goldenScenario() const index = build(golden.records, golden.spaceUri) assert.equal(index.private, false) assert.deepEqual(index.devices, []) }) })