OverviewFilesCommitsIssuesDocsReleasesPeers

favela-markdown commits / 6a4c8c9

spec/interaction: the native URI is favela://<identity-root> (§3.4)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
6a4c8c905e82b8af3615bdbbf7f7f182aff0261c
by plankatron <fleeky@gmail.com> · 2026-09-05T19:11:24.000Z

Changed files (1) +48 -15

spec/interaction.md +48 -15
……@@ -122,21 +122,54 @@ maintain. Ours are *derived* (§3.1); foreign ones are *asserted* when observed
122122**A DID rotation therefore adds an edge; it never rewrites a record.** This is the same mechanism
123123that fixes the mention problem in `record-vocabulary.md:166,208`, rather than a special case for it.
124124
125### 3.4 ⛔ OPEN — favela has no native URI scheme
125### 3.4 The native URI — `favela://<identity-root>/<collection>/<rkey>`
126126
127`at://` is atproto's. A peer's own posts are addressed by DID, and `identity.md` §5 has just removed
128the DID from the author position precisely so it can rotate. **So there is currently no way for one
129favela peer to name another favela peer's record natively.** Every native edge would have to fall
130back to `at://<did>/...`, reintroducing exactly what was removed.
127**Decision (user, 2026-09-05).** `at://` is atproto's and `identity.md` §5 has just removed the DID
128from the author position so it can rotate, so a native scheme is required — one favela peer could
129otherwise not name another's record without reintroducing the DID.
131130
132This blocks native peer-to-peer interaction and must be settled first. It is **not** settled here.
133Options, none chosen:
131**The authority segment is the hex identity root** (`pgh/lib/identity.js:101 identityRootHex`), the
132hyperident/keet root that sits ABOVE both the DID and the device keys. Under the SLIP-48
133`accountIndex` model each user is a distinct derived key (`keet-identity-key/index.js:227`), so a
134user's identity root IS the global name of the `User` that `identity.md` §5 asks records to carry.
134135
135| | shape | problem |
136|---|---|---|
137| **a** | `favela://<userId>/<collection>/<rkey>` | `userId` is local to one registry; not globally resolvable (`identity.md` §9) |
138| **b** | `favela://<identity-root-pubkey>/...` | globally unique and rotation-stable, but names a key, not an account |
139| **c** | keep `at://<did>/...` and rely on alias edges to survive rotation | resolution becomes a graph walk; ambiguous if two aliases conflict |
136**A key in the bytes; a name only on screen.** pgh's `NameRegistry`
137(`pgh/lib/name-registry.js:74`) is the resolver for display and discovery — it already anchors
138claims to `identityRoot` with device-signed v2 ops — but it is **first-claim-wins and a released
139name is reclaimable**, so a name embedded in immutable bytes could later denote a different person.
140That is a correctness problem, not an aesthetic one.
141
142**Rejected: `punch://<serverKey>/…`.** It is a *connection* URL, not a reference: the serverKey names
143a **daemon**, so the URI dies with one node even when ten peers hold the bytes, and its petnames are
144node-local config (`git-remote-punch/lib/petnames.js:107-130`) — the same string denoting different
145things on different machines is fine for a git remote and fatal inside replicated bytes. The
146primitive it is built on — a 32-byte identity pubkey as the authority — is the part reused here.
147
148`at://` remains correct for **foreign** subjects (§3.2); that is genuinely where they live.
149
150#### 3.4.1 ⚠ Precondition — never mint a URI from the device-pubkey fallback
151
152Verified: a restore re-derives from the mnemonic (`identity-manager.js:174`,
153`IdentityKey.from({mnemonic})`) and SLIP-48 derivation is deterministic, so **a vault restore
154reproduces the same root** and previously-authored URIs keep resolving. This was the open worry from
155#48 and it is answered.
156
157⛔ But `identityRootHex` falls back to the **device pubkey** when an identity has no root at all —
158the raw/legacy identities, *"which are their own root"* (`identity.js:95-113`). A URI minted from
159that fallback would change the moment that identity gained a real root. **Minting must refuse the
160fallback and fail closed**, in the same direction as every other gate here.
161
162A linked device carries `rootPubkeyHex` in its join payload (`identity.js:116-127`), so a device
163that does not hold the seed can still name correctly.
164
165#### 3.4.2 What follows
166
167`record-vocabulary.md` §3.1's pairing extends from three names to four — canonical `favela://`,
168`at://`, the AP object URI, and a display name — all still pure functions of one rkey.
169
170⚠ **A `favela://` URI is opaque to atproto tooling.** The bsky projection rewrites subjects it can
171map, but a native link in a post *body* degrades to text there, and that is a `loss[]` entry
172(`library.md` §4), not a silence.
140173
141174---
142175
……@@ -253,8 +286,8 @@ content one shape, and an inbound edge is the same idea applied to relationships
253286
2542871. **Edge as empty-body record vs. pointer-valued log entry** (§2.1). Measure the file count for a
255288 realistic like volume before locking it.
2562. **⛔ The native URI scheme** (§3.4). Blocks native peer-to-peer interaction. Nothing else in this
257 document can be built first.
2892. ~~**The native URI scheme**~~ **CLOSED 2026-09-05** — `favela://<identity-root>/…`, §3.4. The
290 remaining work is the fail-closed minting rule (§3.4.1), not a decision.
2582913. **Inbox admission** (§6) — rate limiting, and how long an unverified claim is retained.
2592924. **Where an edge's `reach` defaults from.** A like on a public post is presumably public; a like on
260293 a followers-only post must not project. Almost certainly inherited from the subject, but the
……@@ -275,4 +308,4 @@ content one shape, and an inbound edge is the same idea applied to relationships
275308- It does not solve discovery (hyper-social #45 gap 1). That is a separate product problem and
276309 nothing here helps it.
277310- It does not specify the courier — retries, backoff, dead-letter — only that it is not a projection.
278- It does not settle the naming scheme, which is the one thing that cannot be changed later.
311- It does not make `favela://` resolvable by atproto tooling; §3.4.2.