OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-social commits / 9e622d4

docs/social-model: retention, media variants, and moderation
Retention is a room property and must tombstone. Downsampling is a BRIDGE concern - to media what strip() is to text - and a variant is not a duplicate, it is a variant-of edge. Moderation needs no new primitive. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
9e622d48e7ec6e47da960cf3d11099090070e9dd
by plankatron <fleeky@gmail.com> · 2026-09-05T20:24:47.000Z

Changed files (1) +100 -4

docs/SOCIAL-MODEL.md +100 -4
……@@ -118,6 +118,101 @@ discovery key — the topology is proven, not hypothetical.
118118That makes retention a **room property**, and it must be in the model rather than discovered later.
119119This is the one place §3's "six primitives and no more" takes on a modifier.
120120
121## 6.5 Retention — the one room property beyond membership
122
123Tempo (§6) makes retention a room setting: chat wants a bounded window, posts want durability. It
124belongs in the room's custom metadata (`ROOMS-ARE-THE-COMPUTER.md`'s `_hs:room-meta` convention) and
125is set by admins, like any other room config.
126
127⛔ **Retention must TOMBSTONE, never silently drop.** Dropping a record's bytes while its pointer is
128still converged produces exactly the state the signer's forward-only gate treats as *"pointer
129present, bytes unreplicated — behind — SKIP"*: the chain stalls rather than advancing. A retention
130policy that deletes without a tombstone would freeze signing for the whole room, and the freeze would
131look like a replication problem.
132
133Absence is ambiguous in a replicated log; expiry has to be **positive evidence** for the same reason
134deletion is.
135
136## 6.6 Media — bytes are already solved; VARIANTS are the open question
137
138**Peer-to-peer media needs nothing new.** Blobs live in hyper-overlay, content-addressed, and any
139peer holding the bytes can serve them. No downsampling, no negotiation, full fidelity.
140
141**Downsampling is a BRIDGE concern.** It exists because other networks have ceilings we do not. That
142places it exactly where `strip()` is: **downsampling is to media what the strip is to text** — a
143lossy, pure, boundary-time projection that must report what it lost (`library.md` §4). Not an
144authoring decision, and not stored.
145
146⚠ **This refines `design.md` §8 #1**, which says media policy *"is an AUTHORING-time decision of the
147native record"*. That is right about *choosing what to attach* and wrong about *fidelity*: fidelity is
148per-target, and baking a target's ceiling into the canonical record is the shape this whole model
149exists to refuse.
150
151### 6.6.1 A variant is not a duplicate — it is an EDGE
152
153The worry is that storing a downsampled copy breaks content-addressing. It does not, and the reason
154is worth stating precisely:
155
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.
160
161```
162(variant, variant-of, original) + the parameters that produced it
163```
164
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.
168
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.
173
174### 6.6.2 Three tiers, and the one we cannot have yet
175
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** |
181
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.
186
187Worth recording as the thing to want, because it would delete tier two entirely.
188
189## 6.7 Moderation — rooms and edges, no new primitive
190
191`COMMUNITY-MODERATION.md` already answers this, and it lands on the room model exactly.
192
193- **Roles are keet-core roles.** admin / moderator / member / read-only. No new permission system.
194- **Listings, not content.** A community moderator delists a room from the community; they **cannot**
195 moderate inside it. Two rooms, two scopes — which is what the room model gives for free.
196- **The accountability gap is deliberate.** *"The room admin is a bartender… the community admin is a
197 neighborhood association — they decide which bars are listed in the directory, they don't enter the
198 bars."* This is what stops governance becoming surveillance.
199- **A room in two communities has two governance contexts.** Federation, not hierarchy.
200- **Signals, not enforcement.** A flag is information; each community applies its own context.
201 *"What's spam in a dev community might be on-topic in a crypto community."*
202
203**In this model a moderation signal is an EDGE** — `(moderator, flag, room)` with a reason — written
204in the moderation room, so **its audience is that room's subscribers by construction**. Subscribing to
205another community's signals is joining their room. Delisting is a tombstone on a listing record.
206
207Nothing here needs a mechanism the six primitives do not already have, which is the strongest
208evidence so far that the primitive set is the right size.
209
210⚠ **`flag` projects asymmetrically**, and the asymmetry is semantic rather than technical: atproto has
211a real equivalent — a signed `com.atproto.label`, which we already emit
212(`atproto-room/lib/label-room.js`, `label-signer.js`) — while AS2's `Flag` is a *report to the origin
213server's moderators*, which means something different and must not be conflated with a shared signal.
214So `flag` → atproto label; `flag` → fediverse **nothing**, with a `loss[]` entry.
215
121216## 7. Translating outward
122217
123218Bridges map *our* model onto theirs. The mapping quality is not uniform, and the asymmetry is
……@@ -171,14 +266,15 @@ imitating a system that cannot do them.
171266 `record-vocabulary.md` §3/§5 (hyper-social #57 B1–B3) is now a room-model rewrite as well as a
172267 `visibility`/`reach` rename, and the store layout is still a flat `records/<collection>/<rkey>`
173268 per DID with no room segment.
1742. **Retention as a room property** (§6) — what the vocabulary is, and who may set it.
2692. ~~**Retention as a room property**~~ **RESOLVED 2026-09-05** — §6.5. Room metadata, set by admins,
270 and it must tombstone rather than drop.
1752713. **Cross-room identity of one record.** A post quoted into another room: one record with two
176272 addresses, or two records with an alias edge? The alias mechanism exists (`interaction.md` §3.3).
1772734. **Room-per-audience proliferation.** Does every follower subset become a room, and if so who
178274 manages them? This is the model's ergonomic risk and it is not addressed.
1795. **Moderation** — `COMMUNITY-MODERATION.md` is 30KB and has not been read into this model. Room
180 roles are the mechanism; *"moderation is shared context, not rules"* is the principle; the
181 connection between them is unwritten.
2755. ~~**Moderation**~~ **RESOLVED 2026-09-05** — §6.7. It needs no new primitive: roles are keet roles,
276 a signal is an edge, delisting is a tombstone. What remains open is the *frustum* view model
277 (`COMMUNITY-MODERATION.md` §"view frustum", 350 lines) which has not been read into this model.
1822786. **Where governance of a public room lives** when its membership is "anyone".
183279
184280## 11. What this does not claim