| … | … | @@ -3,8 +3,8 @@ |
| 3 | 3 | The **self-custody, P2P-native atproto peer** — the source of truth in the peer/bridge |
| 4 | 4 | split (Model B). It holds the user's signing key and content as Hypercores, authors and |
| 5 | 5 | **signs its own atproto repo**, and serves it over Hyperswarm. N attested devices of one |
| 6 | | `did:plc` share a single repo via an Autobase (StateBaseV3); a lease elects one signer at a |
| 7 | | time. [`atproto-bridge`](../atproto-bridge) then projects it to Bluesky **without ever |
| 6 | `did:plc` share a single repo via an Autobase (StateBaseV3); a presence election picks one |
| 7 | signer at a time. [`atproto-bridge`](../atproto-bridge) then projects it to Bluesky **without ever |
| 8 | 8 | holding the key**. |
| 9 | 9 | |
| 10 | 10 | Part of the **atproto-base** self-custody stack: |
| … | … | @@ -24,7 +24,7 @@ atproto-bridge keyless membrane → Bluesky |
| 24 | 24 | │ each writes repo INTENTS into… |
| 25 | 25 | ▼ |
| 26 | 26 | StateBaseV3 ── shared Autobase intent-log (members-only, admission-gated) |
| 27 | | │ lease-holder materializes intents → ONE signed commit chain (continuous |
| 27 | │ the elected signer materializes intents → ONE signed commit chain (continuous |
| 28 | 28 | │ across hand-offs), written back into the shared log under __commit__/<rev> |
| 29 | 29 | ▼ |
| 30 | 30 | serve-device (device↔device RPC: get-state, apply-write, gated by writer allowlist) |
| … | … | @@ -34,24 +34,46 @@ atproto-bridge keyless membrane → Bluesky |
| 34 | 34 | |
| 35 | 35 | ## Modules |
| 36 | 36 | |
| 37 | | - **SwarmDevice** (`lib/swarm-device.js`) — one device: wraps the shared StateBaseV3 with |
| 38 | | the repo-op layer, the single-signer `Lease`, and the shared-key signer. `applyWrite`, |
| 39 | | `sign`, `getServiceAuth` (ES256K, for the bridge's AppView proxy), `get/putPreferences`. |
| 40 | | - **StateBaseV3** (`lib/state-base.js`) — the admission-gated shared Autobase (keet-pattern |
| 41 | | `optimistic + ackInterval + ackThreshold`); durable banned-set + epoch receipts. |
| 42 | | - **Lease** (`lib/lease.js`) — elects the current signer; only the holder materializes. |
| 43 | | - **membership** (`lib/membership.js`) — attested-device admission (getMembers / attest / |
| 44 | | verifyAttest), members-only roomSeed/encryptionKey, receipts. |
| 45 | | - **signer** (`lib/signer.js`) — `materialize` / `buildCommitWrite`: linearized record set → |
| 46 | | signed commit continuing from the last head (via [`atproto-repo`](../atproto-repo)). |
| 47 | | - **serve-device** / **serve-membrane** (`lib/serve-*.js`) — the two RPC surfaces (device |
| 48 | | peers vs. the keyless membrane). |
| 49 | | - **sessions** (`lib/sessions.js`) — bsky-login auth: verifies the app-password (scrypt) + |
| 37 | The room engine — the shared Autobase, admission, election and signing — lives in the sibling |
| 38 | package [`atproto-room`](../atproto-room), not here. This package is the **daemon** around it. |
| 39 | |
| 40 | ### In this repo |
| 41 | |
| 42 | - **SwarmDevice** (`lib/swarm-device.js`) — one device: wraps the shared StateBaseV3 with the |
| 43 | repo-op layer and the shared-key signer. `applyWrite`, `sign`, `getServiceAuth` (ES256K, for |
| 44 | the bridge's AppView proxy), `get/putPreferences`. |
| 45 | - **serve-device** (`lib/serve-device.js`, `lib/serve-device-uds.js`) — the device↔device RPC |
| 46 | surface (get-state, apply-write), gated by the writer allowlist. |
| 47 | - **sessions** (`lib/sessions.js`) — bsky-login auth: verifies the app-password (scrypt) and |
| 50 | 48 | mints/verifies JWTs. The peer is the **auth authority**; the bridge only relays. |
| 51 | 49 | - **device-node** (`lib/device-node.js`) — `bootSwarmDevice`, `provisionDevice`, |
| 52 | 50 | `provisionAdoptedDevice`, `readAdoptRepo` (onboarding + adopt-existing-repo). |
| 53 | 51 | - **peer** (`lib/peer.js`, main) — the single-tenant `Peer` (serve one repo). |
| 54 | 52 | |
| 53 | ### In `atproto-room` |
| 54 | |
| 55 | - **StateBaseV3** (`atproto-room/lib/state-base.js`) — the admission-gated shared Autobase |
| 56 | (keet-pattern `optimistic + ackInterval + ackThreshold`); durable banned-set + epoch receipts. |
| 57 | - **SignerPresence** (`atproto-room/lib/signer-presence.js`) — **what actually elects the |
| 58 | signer.** The election is the lowest-keyed device among currently-connected co-owners, |
| 59 | computed in RAM from live connection presence and appending nothing. A `graceMs` window |
| 60 | (15 s, matching the old lease TTL) absorbs blips so a brief disconnect does not thrash the |
| 61 | signer, and a *currency* filter keeps a behind co-owner from winning — otherwise it would |
| 62 | hold the election while the forward-only sign gate blocked it, and the chain would freeze. |
| 63 | - **Lease** (`atproto-room/lib/lease.js`) — **legacy.** The `__lease__` ts-heartbeat wrote a |
| 64 | wall-clock timestamp to the append-only log every ~8 s forever (~20 MB/day, unreclaimable), |
| 65 | which is why it was replaced. `claimLease` / `renewLease` / `holdsLease` still exist on |
| 66 | `SwarmDevice` and the diag surface still reports `holdsLease`, but that field does **not** |
| 67 | gate signing — `holdsSigner` does. |
| 68 | - **membership** (`atproto-room/lib/membership.js`) — attested-device admission (getMembers / |
| 69 | attest / verifyAttest), members-only roomSeed/encryptionKey, receipts. |
| 70 | - **signer** (`atproto-room/lib/signer.js`) — `materialize` / `buildCommitWrite`: linearized |
| 71 | record set → signed commit continuing from the last head (via |
| 72 | [`atproto-repo`](../atproto-repo)). |
| 73 | - **serve-membrane** (`atproto-room/lib/serve-membrane.js`) — the bridge's RPC surface |
| 74 | (get-coords, create/refresh-session, apply-write, apply-writes, get-service-auth, |
| 75 | get/put-preferences) + repo/firehose cores. |
| 76 | |
| 55 | 77 | ## Onboarding — the proper setup |
| 56 | 78 | |
| 57 | 79 | An hpp account is **rooted on a hyperident**: one BIP39 mnemonic (the hyperident root) |
| … | … | @@ -112,6 +134,10 @@ bundle; it boots as a co-equal swarm writer. **This is why hpp is a swarm even a |
| 112 | 134 | ## Test |
| 113 | 135 | |
| 114 | 136 | ``` |
| 115 | | bare test/all.js # 59-file suite (repo, signer, lease, membership, sessions, service-auth, |
| 116 | | # membrane, adopt, multi-device, …) |
| 137 | bare test/all.js # 62-file suite (repo, signer, presence, membership, sessions, |
| 138 | # service-auth, membrane, adopt, multi-device, …) |
| 117 | 139 | ``` |
| 140 | |
| 141 | ## License |
| 142 | |
| 143 | Not yet declared. |