| … | … | @@ -0,0 +1,32 @@ |
| 1 | # atproto-room |
| 2 | |
| 3 | The **shared room engine** for co-owned atproto identities — the substrate behind a multi-device |
| 4 | [hyper-proto-peer](../hyper-proto-peer) and a co-owned Favela community |
| 5 | ([favela-node](../favela-node)). This is the **multiswarm-PDS pattern**: N attested writers co-own one |
| 6 | autobase; a single lease-elected signer produces byte-identical signed output, so authority is shared with |
| 7 | no single point of key custody and no fork on failover. |
| 8 | |
| 9 | ## Pieces (`lib/`) |
| 10 | |
| 11 | | Module | Role | |
| 12 | |---|---| |
| 13 | | `state-base.js` (`StateBaseV3`) | attestation-gated, **encrypted** multi-writer room (Autobase + HyperDB view). Admission is cryptographic + in-apply: a joiner proves it's a device attested to the room's root identity, then is `addWriter`ed. | |
| 14 | | `membership.js` | binary attestation admission (keet-identity-key root→device chains) — the N devices of ONE DID, all role-equal. | |
| 15 | | `lease.js` (`Lease`) | one active signer at a time; TTL failover-safe. | |
| 16 | | `signer.js` | the lease-holder materializes the linearized record view into ONE canonical signed atproto commit under the shared `#atproto` key (RFC6979-deterministic → byte-identical across holders). | |
| 17 | | `repo-base.js` (`RepoBase`) | the atproto repo op layer over the shared state (put/del/list records). | |
| 18 | | `label-base.js` / `label-room.js` / `label-signer.js` | the **co-authored labeler**: N mods append label intents; the lease-holder signs them into a shared `__label__` log; `projectTo` serves a byte-identical `com.atproto.label` feed from any node. | |
| 19 | | `serve-membrane.js` | project the shared `__commit__` log + records into served cores (what the keyless membrane fronts). | |
| 20 | |
| 21 | ## Design invariants |
| 22 | |
| 23 | - **Deterministic apply** — apply reads only fields carried in the op (never `Date.now()`/randomness); |
| 24 | Autobase replays it on every boot + reorg. |
| 25 | - **Quorum (2f+1)** — grow the indexer set only to an odd count ≥3 on independent boxes, or use one |
| 26 | always-on anchor. **Never N=2** (deadlocks on one loss; autobase forbids 2→1). |
| 27 | - **Encrypted, members-only** — the base key derives from a members-only `encryptionKey`; non-members can |
| 28 | neither derive nor read it. (A keyless *reader* needs [atproto-did-peer](../atproto-did-peer) against the |
| 29 | served membrane, not this room.) |
| 30 | |
| 31 | Lineage: reskinned from keet-daemon / hyper-tps per-room `StateBaseV3`; extracted here as the engine |
| 32 | consumed by hyper-proto-peer (repo devices) and the co-authored labeler. |