OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-social commits / 7b2025c

docs: retention per tier — a mirror is a cache, not a log
Settles §9 item 2. The question looked hard because two different things were being conflated. ⛔ EVICTING A MIRRORED BYTE IS NOT A DELETION. SOCIAL-MODEL §6.5 requires retention to tombstone rather than silently drop — but that is about an author retaining their OWN records, where absence in a replicated log is ambiguous and the signer's forward-only gate stalls on a pointer whose bytes vanished. A mirror holds someone else's record: the pointer is not ours to tombstone, and dropping the bytes returns that record to UNRESOLVED, which is a state the system already reports honestly and already recovers from. It is reversible. ⇒ Retention of your own records is a LOG question. Retention of a mirror is a CACHE question. That distinction is the whole answer. browse held until the peek ends, evicted with it — including at restart follow held until you unfollow, evicted only under budget, oldest first interaction held while the subject exists, evicted last, and it is smallest browse answers the question node.js leaves open beside peek(): "the BYTES stay on disk until something collects them; that is a separate question." follow gets no clock — following IS the decision to keep, so only a budget evicts. Order: browse, then followed oldest-first, then interactions. Never a record you authored; that is your log, not a mirror. ★ The budget is the ONE number that differs per device, which is why this had to be settled before packaging an APK: a handset cannot hold what an always-on box can, and the mirror fetches eagerly on every append with no reader. One number, not a separate architecture for phones. ⚠ Eviction costs availability and nothing measures it: drop the only second copy of a record whose author is offline and it is unreadable for everyone. The right policy would prefer records with many known holders; we do not track holders. Stated, not solved. evictContent(hash) and compactIndex(opts) already exist. Nothing calls either. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
7b2025cd4dad0eee34fc6820ec09ae9eab49cb8c
by plankatron <fleeky@gmail.com> · 2026-09-08T19:39:28.000Z

Changed files (1) +44 -2

docs/HOLDING-AND-TELLING.md +44 -2
……@@ -144,14 +144,56 @@ activity currently has nowhere to go in the peer, because its author has no feed
144144at the view layer as a second source. The doorbell is that place. With it, a reply from Mastodon and
145145a reply from a favela stranger stop being two mechanisms.
146146
147## 8.5 Retention, per tier
148
149⛔ **Evicting a mirrored byte is NOT a deletion, and needs no tombstone.** `SOCIAL-MODEL.md` §6.5
150requires retention to tombstone rather than silently drop — but that is about an author retaining
151their OWN records, where absence in a replicated log is ambiguous and the signer's forward-only gate
152stalls on a pointer whose bytes vanished. A mirror holds someone ELSE's record: the pointer is not
153ours to tombstone, and dropping the bytes returns that record to **UNRESOLVED** on this node, which
154is an honest state the system already reports and already recovers from. It is reversible — the next
155fetch brings it back if any holder is online.
156
157⇒ **Retention of your own records is a LOG question. Retention of a mirror is a CACHE question.**
158Conflating them is what made this look hard.
159
160| tier | held until | evicted |
161|---|---|---|
162| **browse** | the peek ends | with the peek — including at restart, where peeks already evaporate |
163| **follow** | you unfollow | only under budget pressure, oldest first |
164| **interaction** | the subject is gone | last, and it is the smallest |
165
166**browse** answers the question `favela-peer/lib/node.js` leaves open beside `peek()`: *"a peek lasts
167for the life of the daemon and then evaporates… The BYTES stay on disk until something collects them;
168that is a separate question."* This is that answer — the bytes are a cache whose lifetime is the
169peek's, and a restart that forgets the peek must collect them.
170
171**follow** has no clock. Following is the decision to keep, so the only thing that evicts a followed
172feed's bytes is a **budget**, and the eviction order is: browse first (already ephemeral), then
173followed records oldest-first, then interactions. ⛔ **Never a record you authored** — that is your
174log, not a mirror of anyone.
175
176★ **The budget is the ONE number that differs per device**, and that is the whole reason this
177matters now. An always-on box can hold everything; a handset cannot, and the mirror fetches eagerly
178on every append without a reader. One number, not a different design — which is what keeps a phone
179from needing its own architecture.
180
181⚠ **Eviction costs availability, and nothing measures it.** Drop the only second copy of a record
182whose author is offline and it becomes unreadable for everyone. The right policy would prefer
183evicting records with many known holders; we do not track holders, so a first cut cannot. Stated
184rather than solved.
185
186`evictContent(hash)` and `compactIndex(opts)` already exist on the overlay. Nothing calls either.
187
147188## 9. Open
148189
1491901. **Bounding the doorbell.** `knock` gets away with one row per feed because it is a single
150191 yes/no. Likes and replies are per-post and per-person, so "one row" does not hold, and unbounded
151192 means anyone may write into your feed for ever. Bounding by *relationship* is the likely shape —
152193 whose ring is accepted is a choice, as following is.
1532. **Retention per tier.** §3 names three lifetimes and nothing implements any of them. Mirror mode
154 without retention is a disk-filler; `evictContent` and `compact` exist and nothing calls them.
1942. ~~**Retention per tier.**~~ **RESOLVED — §8.5.** A mirror is a cache, not a log, so eviction
195 needs no tombstone; browse evicts with the peek, follow only under budget, and the budget is the
196 one number that differs per device. Unimplemented, but decided.
1551973. **Which feeds mirror.** All followed, or own-devices-only? Own-devices is bounded by construction
156198 and fixes §0 on its own.
1571994. **Does browsing spool or scratch?** A peek that spools becomes a durable mirror by accident.