OverviewFilesCommitsIssuesDocsReleasesPeers

favela-community commits / 7a2e064

README: place this in the right stack, and document 0.1.1 through 0.1.5
Two problems, and the first one matters more. favela has two room concepts and this README gave no way to tell which it is. A reader arriving from the markdown-record side would reasonably assume this is the room primitive; it is not. This is the atproto / lens-export community — a co-owned did:plc: whose roster favela-web reads keylessly, posts in each member's own signed repo. favela-peer's rooms are the other one: autobee not autobase, keet's roles, membership as the audience. They cannot converge — favela-peer may not import anything atproto-* and its boundary test enforces that. Checked rather than assumed that this is still live, because the obvious guess was that it had been superseded: loser-club is in favela-web's shipped pgh defaults, favela.7rnx.net answers 200, and favela-web, atproto-bridge and favela-node all depend on this package. So the README now says it is neither superseded nor the primitive for new work, which is the honest position. Second: the README was written at 0.1.0 and four of the six commits since added API it never mentioned. Added CommunityDiscovery (0.1.2), FeedRegistry/FeedRegistries, the {curator, params} curation contract and its three built-ins (0.1.5), communityDid (0.1.4), CommunityRooms.watch (0.1.1), and the ban/meta/mods/addIndexer methods that were there all along. create() takes { name, did, curator, params } now, so a community can be bound at genesis instead of in three follow-up writes. Test section: four files, not one. Named the DHT testnet one, and noted these are plain assertion scripts rather than brittle-bare, unlike the markdown-record repos. Added a License section, which the file lacked; the state it reports is unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
7a2e064956c6e1c1c29de5f04d3bcfc7bf131642
by plankatron <fleeky@gmail.com> · 2026-09-20T20:48:41.000Z

Changed files (1) +68 -7

README.md +68 -7
……@@ -1,8 +1,23 @@
11# favela-community
22
3Co-owned, **plaintext** community rooms for [Favela](../favela-web) — membership + moderation on a
4[hyper-rooms](../hyper-rooms) Autobase. One community protocol, shared across surfaces: **read keylessly**
5by the gateway (`favela-web`), **written** by mods (a full-node / CLI / hpp).
3Co-owned, plaintext community rooms for [favela-web](../favela-web) — membership and moderation on a
4[hyper-rooms](../hyper-rooms) Autobase. One community protocol, shared across surfaces: read keylessly
5by the gateway (`favela-web`), written by mods (a full-node / CLI / hpp).
6
7## Which stack this belongs to
8
9favela has two room concepts and they are not the same object. This one is the **atproto /
10lens-export** community: a co-owned `did:plc:` whose roster favela-web reads keylessly, with posts
11living in each member's own signed atproto repo. It is live — `loser-club` is in favela-web's shipped
12defaults and [favela.7rnx.net](https://favela.7rnx.net) serves it.
13
14The **markdown-record** stack has its own primitive: `favela-peer`'s rooms, on autobee rather than
15autobase, with keet's roles, where membership *is* the audience and a DM is a room with one other
16member. That one is not this, does not use this package, and could not — `favela-peer` may not import
17anything `atproto-*`, and its boundary test enforces it.
18
19So this is not superseded and it is not the room primitive for new work. Consumers today are
20`favela-web`, `atproto-bridge` and `favela-node`.
621
722## The model
823
……@@ -52,8 +67,42 @@ const view = await CommunityRoom.openReadonly(corestore3, roomKey)
5267await view.members() // ['did:plc:…', …] (roster minus banned)
5368```
5469
55`CommunityRooms(corestore, swarm)` is a server-side read-manager: it opens + joins a keyless replica per
56room and answers `members(roomKey)` — the `Communities.resolve` source in `favela-web`.
70`CommunityRooms(corestore, swarm)` is a server-side read-manager: it opens and joins a keyless replica
71per room and answers `members(roomKey)`, `meta`, `communityDid`, `curation`, and `watch(roomKey,
72onChange, { debounceMs })` for roster changes. It is the `Communities.resolve` source in `favela-web`.
73
74### The rest of the room
75
76| | |
77|---|---|
78| `members()` `addMember(did)` `removeMember(did)` | the roster, minus bans |
79| `ban(did)` `unban(did)` `isBanned(did)` | |
80| `mods()` `addMod(localKey, { role })` `addIndexer(localKey)` | roles are `owner`, `writer`, `mirror` |
81| `meta()` `setMeta(k, v)` | public metadata only |
82| `communityDid()` `setDid(did)` | the community's co-owned `did:plc:`, in `meta:did` |
83| `curation()` `setCuration(curator, params)` | `{ curator, params }`; built-ins `roster`, `subject`, `rules` |
84| `key` `localKey` `discoveryKey` `writable` | `key` is the public bootstrap key; `localKey` is what a mod hands the owner |
85
86`CommunityRoom.create` takes `{ name, did, curator, params }` so a community can be bound to its DID
87and its curation at genesis rather than in three follow-up writes.
88
89### `CommunityDiscovery(swarm)`
90
91Name and topic discovery over the DHT: `announce({ roomKey, name, description, topics })`,
92`discover(topic)`, `resolve(name)` (case-insensitive, `null` when unknown), `unannounce(roomKey)`.
93This is how a room key is found from a name nobody has shared out of band.
94
95### `FeedRegistry` / `FeedRegistries`
96
97A durable, co-ownable, keyless list of feeds — the same room machinery one layer over, keyed
98`feed:<did>/<rkey>`. `create`, `open`, `openReadonly`, `feeds()`, `feed(did, rkey)`,
99`addFeed({ did, rkey, name, curator, params, roomKey, handle })`, `removeFeed`, `addMod`, `removeMod`.
100`FeedRegistries` is its read-manager, with the same `watch`.
101
102### Schemas
103
104`communitySchema` and `feedRegistrySchema` are the `apply` contracts; `isDid`, `feedKey` and
105`FEED_PREFIX` are the key helpers. Import these rather than re-deriving a key format.
57106
58107## Deploy
59108
……@@ -62,5 +111,17 @@ deploy must vendor **both** `favela-community` and `hyper-rooms` (`cp -rL` into
62111
63112## Test
64113
65`npm test` → `bare test/community-room.test.mjs` — keyless read + mod admission + co-writer ops linearizing
66through the owner. Fully offline (in-process replication).
114```sh
115npm test
116```
117
118Four files under `bare`: `community-room` (keyless read, mod admission, co-writer ops linearizing
119through the owner, fully offline via in-process replication), `feed-registry`, `cli`, and `discovery`
120— the last one over a testnet DHT, covering announce, resolve-by-name and discover-by-topic.
121
122Not `brittle-bare`, unlike the markdown-record repos: these are plain assertion scripts that print
123their own summary line.
124
125## License
126
127Not yet declared — `package.json` carries no `license` field and there is no LICENSE file.