OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-social commits / 2c1c6b4

docs/social-model: mip-map levels supersede variant edges, and extend to identity
The pyramid IS the object: one manifest, N whole-file levels, each with its own oid - so sparseness by level works with the overlay's whole-file hashing rather than against it, and no variant-of edge is needed. Bridges select rather than downsample. hypernote already ships a video ladder. For identity the same shape gives progressive disclosure with one rule the analogy hands us: a lower level may OMIT, never CONTRADICT. Different personas are a different account, not a lower level. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2c1c6b48a8fee2a08282e2f6816f5703eefae51f
by plankatron <fleeky@gmail.com> · 2026-09-05T20:44:14.000Z

Changed files (1) +77 -26

docs/SOCIAL-MODEL.md +77 -26
……@@ -148,43 +148,94 @@ native record"*. That is right about *choosing what to attach* and wrong about *
148148per-target, and baking a target's ceiling into the canonical record is the shape this whole model
149149exists to refuse.
150150
151### 6.6.1 A variant is not a duplicate — it is an EDGE
151### 6.6.1 ★ The pyramid IS the object — mip-map levels, not variants
152152
153The worry is that storing a downsampled copy breaks content-addressing. It does not, and the reason
154is worth stating precisely:
153**Revised 2026-09-05 (user).** An earlier version of this section modelled a downsample as a separate
154blob joined to its original by a `variant-of` edge. **The mip-map model is better and dissolves the
155problem**, so it supersedes that.
155156
156**Dedup was never "one file per logical image." It was "identical bytes stored once."** A downsample
157has different bytes, so it is a different object by definition. What is actually lost is the
158*automatic* knowledge that two objects are the same picture at different fidelities — and that is a
159relation, which this model already has a primitive for.
157A texture in a game is not a file plus a set of related smaller files. It is **one asset containing a
158pyramid of levels**, bound and sampled as a single thing; the *consumer* picks a level by how much of
159the screen it covers. Media here should work the same way.
160160
161161```
162(variant, variant-of, original) + the parameters that produced it
162blob "sunset.jpg" → manifest (itself content-addressed)
163 level 0 4096px oid a3f…
164 level 1 2048px oid 9c1…
165 level 2 1024px oid 44b…
166 level 3 512px oid e07…
163167```
164168
165Exactly the shape of an `alias` edge (`interaction.md` §3.3): alias says *two names, one thing*;
166`variant-of` says *two byte-sets, one image at different fidelities*. Same mechanism, and it makes
167the relation explicit and inspectable instead of implicit and lost.
169**No `variant-of` edge is needed, because the levels were never separate objects.** The relation is
170not asserted and then maintained — it is the structure of the asset.
168171
169⛔ **A variant records WHO derived it.** §8's rule — *"never re-encode a record you did not author"* —
170cost two of wj62's posts. A bridge-produced downsample is a derived artifact and must never be
171attributed as the author's bytes; the `variant-of` edge carries the deriver. That keeps the wj62
172failure class out of media.
172**It sidesteps the overlay's limitation instead of fighting it.** §6.6.2 previously recorded that
173sparse fetch of one blob is impossible because hyper-overlay addresses a file by a whole-file blake2b
174hash, so a prefix cannot be authenticated. A pyramid needs no prefix: **every level is a whole file
175with its own oid**, which is exactly what the overlay already does well. Fetch the tiny manifest,
176choose a level, fetch that one oid — ordinary `ensureLocal`. We get sparseness **by level**, which is
177the property that was wanted.
173178
174### 6.6.2 Three tiers, and the one we cannot have yet
179**Bridges SELECT rather than downsample.** A bridge picks the level nearest its target's ceiling.
180Downsampling then happens **once, at authoring, deterministically** — like generating mips at asset
181build time — instead of per delivery on every bridge. That is strictly better than §6.6's
182"derive on demand", and it keeps the honesty requirement: the chosen level is reported in `loss[]`.
175183
176| | when | cost |
177|---|---|---|
178| **derive on demand** | bridges | CPU per delivery; the bridge must hold full bytes. **The default** — no storage concept at all |
179| **stored variant + `variant-of` edge** | a peer that genuinely cannot hold or fetch full fidelity (a phone) | a second blob, explicitly related. Dedup intact |
180| **sparse fetch of one blob** | *the shape we would want* | ⛔ **not expressible today** |
184**Cost is the mip cost and it is bounded:** 1 + ¼ + 1/16 + … = **4/3** of the base image. Known in
185advance, unlike an open-ended set of variants.
186
187**We already ship one.** `hypernote/lib/media/video-processor.js:7-11` defines
188`HLS_LEVELS` — 480p/720p/1080p with per-level codec profiles — and filters `l.height <= srcHeight`,
189so it never upscales. A bitrate ladder *is* a mip chain for video. It exists, in Bare, on this
190substrate; what is missing is generalising it to images and naming it as the model.
191
192**Where the analogy breaks — three places, all worth knowing:**
193
1941. **Mip levels come from a fixed filter; media ladders are target-driven.** hypernote picks
195 `baseline`/`main`/`high` profiles per level, not one filter. Levels are chosen against real
196 network ceilings, not powers of two.
1972. **Never upscale.** A level is a *floor*, not a guarantee — an asset smaller than the lowest level
198 has one level. hypernote already encodes this; the manifest must not imply levels it lacks.
1993. **Text has no pyramid.** `strip()` is lossy but not a ladder. This model covers media and identity
200 (§6.6.3), not prose.
201
202⛔ **Who derived a level still matters.** §8's *"never re-encode a record you did not author"* cost two
203of wj62's posts. Levels generated at authoring are the author's; a level a bridge generated later is
204derived, and the manifest must say so rather than presenting it as authored bytes.
205
206### 6.6.3 The same model for identity — LOD, not personas
207
208The user's observation extends past media, and the existing framing was already reaching for it:
209`SOCIAL-GRAPH-NAVIGATION.md` says *"identity is a section of the sheaf — one keypair (global
210section), but context-dependent presentation that can vary locally."*
181211
182The third is the elegant one: a progressive format lets a byte prefix decode as a lower resolution,
183so one blob serves every fidelity with no variants at all. **hyper-overlay blocks it** — it addresses
184a file by a whole-file blake2b `contentHash`, so a prefix cannot be authenticated against the
185registered oid. Getting there needs per-blob merkle verification, which the overlay does not have.
212Mip-map sharpens it: those presentations are **derived coarsenings of one canonical profile**, not
213independently maintained variants. And it is already structural, exactly as visibility is — keet
214holds member profiles **per room**, so which room you are in decides which level of you resolves.
215
216```
217level 0 full profile close contacts, DM rooms
218level 1 name + avatar rooms you are a member of
219level 2 handle only a public room
220```
221
222⛔ **The rule the analogy gives us: a lower level may OMIT, never CONTRADICT.** A mip level is a
223blurrier version of the same image, never a different picture. So your name in a public room may be
224absent; it may not be a *different* name. That is what keeps progressive disclosure from becoming
225deception, and it would not have been obvious without the analogy.
226
227**Genuinely different personas are a different ACCOUNT**, not a lower level — the SLIP-48
228`accountIndex` (§3 #1) already provides them, unlinked and unlinkable. So the two cases separate
229cleanly:
230
231| | mechanism | linkable? |
232|---|---|---|
233| less of me in this room | a lower profile level | yes — same account |
234| a different me | a different account from the same seed | no |
186235
187Worth recording as the thing to want, because it would delete tier two entirely.
236⚠ **The cost is real and should be stated:** within one account you cannot present a *different* face
237in two rooms, only less of the same one. Wanting a different face means paying for a separate account,
238which cannot be linked back. That is a deliberate product constraint, not an oversight.
188239
189240## 6.7 Moderation — rooms and edges, no new primitive
190241