// maxReach — library.md §6.1, record-vocabulary.md §5.2, interaction.md §5.2
//
// ⛔ THIS IS THE ONE PLACE A DEFECT IS A PRIVACY BUG RATHER THAN A RENDERING BUG (library §6.1),
// so every case below asserts the DENY direction as well as the allow direction, and the default
// for anything unrecognised is the empty-est answer the model has: {favela}.
//
// Signature changed 2026-09-05. §6.1 signs it `maxReach(visibility)`, from when visibility was a
// frontmatter field. Visibility is now a PLACE — the room you wrote in (SOCIAL-MODEL §4) — so the
// inputs are the room's kind and the verb. The codec has no storage and cannot inspect a room, so
// the caller passes the kind; that is honest about the library boundary rather than pretending.
import test from 'brittle'
import { maxReach, NETWORKS } from '../lib/reach.js'
const set = (r) => [...r].sort().join(',')
test('a PUBLIC room reaches everywhere a verb allows', (t) => {
t.is(set(maxReach({ roomType: 'public', verb: 'post' })), 'bsky,favela,fediverse')
t.is(set(maxReach({ roomType: 'public', verb: 'like' })), 'bsky,favela,fediverse')
})
test('⛔ a FOLLOWERS room reaches the fediverse but NEVER bsky (§5.2)', (t) => {
// AP has addressing — a followers room maps onto the followers collection. atproto has NONE, so
// a projection it cannot restrict is a leak, and the only safe answer is to withhold it.
t.is(set(maxReach({ roomType: 'followers', verb: 'post' })), 'favela,fediverse')
})
test('⛔ a MEMBERS room and a DM reach nothing but favela', (t) => {
// AS2 can address actors, but an arbitrary room's membership is not expressible as an audience
// the receiving server will honour, so it fails CLOSED rather than approximating.
t.is(set(maxReach({ roomType: 'members', verb: 'post' })), 'favela')
t.is(set(maxReach({ roomType: 'dm', verb: 'post' })), 'favela')
})
test('⛔ an UNKNOWN room type reaches only favela — deny by default', (t) => {
for (const roomType of ['', null, undefined, 'PUBLIC', 'public ', 'anything', 42, {}]) {
t.is(set(maxReach({ roomType, verb: 'post' })), 'favela',
'unrecognised room type ' + JSON.stringify(roomType) + ' fails closed')
}
})
test('⛔ an UNKNOWN verb reaches only favela (interaction §5.2)', (t) => {
// "An unknown verb's maximum reach is {favela}." That IS the extension mechanism: a native-only
// verb cannot fork a signed projection because it never reaches a shared derivation.
for (const verb of ['net.example.rsvp', 'bookmark', 'pin', '', null, undefined, 99]) {
t.is(set(maxReach({ roomType: 'public', verb })), 'favela',
'unknown verb ' + JSON.stringify(verb) + ' is native-only')
}
})
test('internal verbs never leave, even from a public room', (t) => {
// alias and variant-of are how a node knows two names/byte-sets denote one thing. They have no
// projection anywhere, by design (interaction §5.5, record-vocabulary §3.5).
t.is(set(maxReach({ roomType: 'public', verb: 'alias' })), 'favela')
t.is(set(maxReach({ roomType: 'public', verb: 'variant-of' })), 'favela')
})
test('flag projects to bsky as a label, and nowhere on the fediverse', (t) => {
// AS2 `Flag` is a REPORT to the origin's moderators — a different act from a shared signal, so
// conflating them would misrepresent the moderator (SOCIAL-MODEL §6.7).
t.is(set(maxReach({ roomType: 'public', verb: 'flag' })), 'bsky,favela')
})
test('the meet is per-input: a restrictive room narrows a permissive verb', (t) => {
t.is(set(maxReach({ roomType: 'followers', verb: 'flag' })), 'favela',
'flag would reach bsky, but a followers room cannot')
})
test('maxReach is TOTAL — never throws, always returns a Set containing favela', (t) => {
const hostile = [undefined, null, {}, { roomType: 'public' }, { verb: 'post' },
{ roomType: [], verb: {} }, { roomType: 'dm', verb: 'alias' }]
for (const arg of hostile) {
try {
const r = maxReach(arg)
t.ok(r instanceof Set && r.has('favela'), 'total on ' + JSON.stringify(arg))
} catch (err) {
t.fail('threw on ' + JSON.stringify(arg) + ': ' + err.message)
}
}
})
test('favela is ALWAYS reachable — local is the substrate, not a scope (§5.4)', (t) => {
// "Every post is local. The canonical record always exists on the P2P side; that is what authoring
// one means. 'Local' is therefore not a destination you opt into, and there is no way to opt out."
for (const roomType of ['public', 'followers', 'members', 'dm', 'nonsense']) {
for (const verb of ['post', 'like', 'alias', 'net.example.unknown']) {
t.ok(maxReach({ roomType, verb }).has('favela'), roomType + '/' + verb + ' is always local')
}
}
})
test('NETWORKS is exported and favela leads it', (t) => {
t.ok(NETWORKS.includes('favela') && NETWORKS.includes('bsky') && NETWORKS.includes('fediverse'))
})