OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-proto-peer commits / d231238

README: the Modules section described a layout that was refactored away
Five of the nine documented modules are not in this repo. lib/state-base.js, lib/lease.js, lib/membership.js, lib/signer.js and lib/serve-membrane.js all moved to the sibling package atproto-room (package.json has depended on it as file:../atproto-room throughout). Modules is now split into "in this repo" and "in atproto-room" and every path resolves. Worse than stale paths, the architecture was wrong. The diagram said "lease-holder materializes intents" and the intro said "a lease elects one signer at a time". It does not. swarm-device.js:739 marks the __lease__ ts-heartbeat LEGACY in as many words, and :745 names the presence election as "the field that ACTUALLY gates signing". SignerPresence elects the lowest-keyed device among currently-CONNECTED co-owners, in RAM, appending nothing -- the lease wrote a wall-clock ts to an append-only log every ~8s forever, ~20MB/day unreclaimable, which is why it went. Documented the graceMs blip window and the currency filter, since without the latter a behind co-owner wins the election, the forward-only sign gate blocks it, and the chain freezes. Lease is kept in the docs, marked legacy, because claimLease/renewLease/ holdsLease are still on SwarmDevice and diag still reports holdsLease -- a reader who finds those needs to know the field does not gate signing. Test suite is 62 files, not 59. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
d231238bc560737f6b613e33136cd35e336d025b
by plankatron <fleeky@gmail.com> · 2026-09-10T14:59:05.000Z

Changed files (1) +44 -18

README.md +44 -18
……@@ -3,8 +3,8 @@
33The **self-custody, P2P-native atproto peer** — the source of truth in the peer/bridge
44split (Model B). It holds the user's signing key and content as Hypercores, authors and
55**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
7time. [`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
7signer at a time. [`atproto-bridge`](../atproto-bridge) then projects it to Bluesky **without ever
88holding the key**.
99
1010Part of the **atproto-base** self-custody stack:
……@@ -24,7 +24,7 @@ atproto-bridge keyless membrane → Bluesky
2424 │ each writes repo INTENTS into…
2525 ▼
2626 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
2828 │ across hand-offs), written back into the shared log under __commit__/<rev>
2929 ▼
3030 serve-device (device↔device RPC: get-state, apply-write, gated by writer allowlist)
……@@ -34,24 +34,46 @@ atproto-bridge keyless membrane → Bluesky
3434
3535## Modules
3636
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) +
37The room engine — the shared Autobase, admission, election and signing — lives in the sibling
38package [`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
5048 mints/verifies JWTs. The peer is the **auth authority**; the bridge only relays.
5149- **device-node** (`lib/device-node.js`) — `bootSwarmDevice`, `provisionDevice`,
5250 `provisionAdoptedDevice`, `readAdoptRepo` (onboarding + adopt-existing-repo).
5351- **peer** (`lib/peer.js`, main) — the single-tenant `Peer` (serve one repo).
5452
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
5577## Onboarding — the proper setup
5678
5779An 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
112134## Test
113135
114136```
115bare test/all.js # 59-file suite (repo, signer, lease, membership, sessions, service-auth,
116 # membrane, adopt, multi-device, …)
137bare test/all.js # 62-file suite (repo, signer, presence, membership, sessions,
138 # service-auth, membrane, adopt, multi-device, …)
117139```
140
141## License
142
143Not yet declared.