OverviewFilesCommitsIssuesDocsReleasesPeers

favela-peer commits / e325c7d

reach records the fediverse name a bridge granted
Pre-existing in the working tree, committed here because it is load-bearing for the bridge flow and because a deploy captures workspace deps live — shipping it uncommitted would mean the deployed tree matched no commit. Without it `setReach` drops the field silently, so a name a bridge just granted is recorded nowhere: favela-surface 0.0.61 already shipped the UI that writes it, and against a published favela-peer it was a no-op. A HANDLE, NOT A CREDENTIAL. identity.md §5.1's `credential` is the designated atproto one; the fediverse has no equivalent because §6 makes a bridge a RESOURCE you hold a grant on. What is recorded is the name that grant produced. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
e325c7d458a36af2ba5560be1a7b007253000f00
by plankatron <fleeky@gmail.com> · 2026-09-11T16:47:18.000Z

Changed files (1) +17 -3

lib/peer.js +17 -3
……@@ -282,7 +282,9 @@ export class Peer {
282282 networks: Array.isArray(fm.networks) ? fm.networks : [],
283283 // identity.md §5.1 — the DESIGNATED credential. With none, a projection that needs one is
284284 // withheld rather than published under a guess.
285 credential: fm.credential || null
285 credential: fm.credential || null,
286 // The name a bridge grant produced, e.g. `alice@ap.example`. Absent until one is claimed.
287 fediverse: fm.fediverse || null
286288 }
287289 }
288290
……@@ -325,10 +327,10 @@ export class Peer {
325327 }
326328
327329 /** Merges: a write naming only `networks` leaves the credential alone, and the reverse. */
328 async setReach ({ networks, credential } = {}) {
330 async setReach ({ networks, credential, fediverse } = {}) {
329331 await this.feed.update()
330332 const current = await this.reach()
331 const fm = { networks: current.networks, credential: current.credential }
333 const fm = { networks: current.networks, credential: current.credential, fediverse: current.fediverse }
332334
333335 if (networks !== undefined) {
334336 if (!Array.isArray(networks)) throw new Error('setReach: networks must be an array')
……@@ -345,7 +347,19 @@ export class Peer {
345347 if (credential !== undefined) {
346348 fm.credential = credential ? String(credential).slice(0, 256) : null
347349 }
350 // ⛔ A HANDLE, NOT A CREDENTIAL. identity.md §5.1's `credential` is the DESIGNATED ATPROTO one
351 // and says so; the fediverse has no equivalent because §6 makes a bridge a RESOURCE you hold a
352 // grant on. What is recorded here is the name that grant produced — `alice@ap.example` — so the
353 // node can say where it publishes without pretending the two networks work the same way.
354 //
355 // ⚠ The daemon never learns what a fediverse IS. `fediverse` is already one of reach.js's
356 // NETWORKS, so this names a destination it can already name and nothing more; boundary.test.js
357 // forbids the projection vocabulary, not the word.
358 if (fediverse !== undefined) {
359 fm.fediverse = fediverse ? String(fediverse).slice(0, 256) : null
360 }
348361 if (!fm.credential) delete fm.credential
362 if (!fm.fediverse) delete fm.fediverse
349363 await this.feed.put(REACH, SELF, { frontmatter: fm, body: '' })
350364 return this.reach()
351365 }