OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-social commits / af2b294

docs/notes: note to self from the 2026-09-06 design session
Why the room noun was misleading us, the lego/typing thing with the Quake numbers, the test-5 mistake, and a short do-not-forget list. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
af2b2940355413634b161974d97a2a97c82267d4
by plankatron <fleeky@gmail.com> · 2026-09-06T16:03:40.000Z

Changed files (1) +89 -0

docs/notes/NOTE-TO-SELF.md +89 -0
……@@ -0,0 +1,89 @@
1# note to self — 2026-09-06
2
3ok so this started as "settle the three decisions in #60" and turned into taking the whole
4thing apart. writing it down because i'll forget why.
5
6## what actually happened
7
8i asked to settle three things. one got settled and shipped (the facet shape, fine, small).
9the other two turned out to be built on a claim that isn't true in the code — the spec says a
10personal room's key comes from the identity root, but it's `hash(ns + did)`. from the DID. the
11thing we spent #58 demoting *because* it rotates. so rotating a DID would change every address
12in the room, which is the exact thing the favela:// scheme was invented to stop.
13
14and position. i'd been treating it as an address. it isn't, it's a view coordinate — keet
15resolves everything by oplog and uses index only for where a message sits in a thread. a
16counter assigned inside apply() is a function of the linearization and apply gets replayed on
17reorg. so a "permalink" that can change afterwards. embedded in other people's bytes.
18
19both of those are things i'd have found by reading the source instead of reading our own docs
20back to myself. that's the lesson, again.
21
22## the bigger thing
23
24the room model was doing two jobs and only one of them worked.
25
26audience: doesn't work. adding someone gives them the whole history, leaving revokes nothing,
27and to like a post you have to become a writer in someone's autobase — which means a popular
28post turns every liker into a hypercore. that's a wall not a slope.
29
30container: fine, but a feed already does that.
31
32the tell was that all three failures are *obvious* if you call it a shared document and
33*surprising* if you call it a room. we were being misled by our own noun. everyone who has it
34has all of it. you don't walk in, you get a copy.
35
36so: feed and document are primitives. a room isn't one. a room is what you call it after
37enough stuff has clustered and someone names it — same as a community, just one scale down.
38which is neat because it means the same mechanism handles both and we stop having a special
39case.
40
41and removing it *fixes* the scaling wall by accident rather than by design work. no room to
42write into means your like lives in your own feed. writer sets stay at your own devices.
43counts go per-observer, which we'd already committed to anyway.
44
45## the lego thing
46
47the bit i keep coming back to. every join, follow, listing, bridge is two things fitting
48together. the connection isn't an object, it's the event. we'd been modelling the receipt and
49calling it the primitive.
50
51and then type comes from what a thing fits with, not from what it declares. two feeds are the
52same kind if they click the same way — even with nobody in common. our current MI does
53membership overlap, which can only ever find things that already overlap. that's the whole
54difference and it's why this is worth doing.
55
56quake is the reason i believe it. nine tries stuck at 1.0 because we typed the connector by
57geometry. changed it to what the thing *is* and it went to 1.78 with a third of pieces reusing.
58the statistics never changed. only what the stud meant.
59
60## what i got wrong today
61
62said test 5 could run against wj62 and loser-club. it can't. two rooms, three members and two
63members, zero overlap. they're not a social network, they're two co-owned DIDs with device
64rosters — of course the members don't overlap, roomKey is per-DID.
65
66which means the entire emergent layer is unfalsifiable until there's a network. can't be
67cleverness'd around. build the thing first, but instrument every mating event from day one
68with its type, because reconstructing types from state later is exactly the quake mistake.
69
70## where it is now
71
72clean break from atproto and AP. not "atproto with markdown bolted on" — i caught myself
73building the double-write codec into atproto-store today and that was the old thinking. bridges
74come after, and they read us, we never read them.
75
76favela-peer exists. record store works — markdown files, content addressed, and i kept the four
77invariants we paid for (never re-encode, verify local bytes against the pointer, return null
78rather than a stale copy, del drops bytes not the record). boundary is a test not a promise.
79
80next: the log. feed = one identity's log, writers are its devices. then follow, then timeline
81as a local projection. keet already has the identity and reaction machinery so most of it is
82using what's there rather than writing it.
83
84## don't forget
85
86- private means encrypted. unlisted just means harder to find. never let the ui blur those.
87- the system detects, a person names. auto-naming a cluster is a political act.
88- counts are per-observer. never sum them.
89- if independent peers don't converge on the same clusters, emergence is a story and we drop it.