Pds: federation support (PLC registration, MST/signed commits/CAR, com.atproto.sync + firehose, handle resolution) #40

Closed
opened 2026-06-11 23:16:17 +00:00 by Grandiras · 2 comments
Owner

ATProtoNet.Pds (0.4.0) can host accounts and serve repo CRUD, but a PDS built on it cannot federate with the Atmosphere network. The gaps, in dependency order:

  1. Real identitiesCreateAccountAsync generates a placeholder did:plc:<random13> without registering it (no PLC genesis operation, no signed op chain, no PDS_DID_PLC_URL equivalent). Nothing on the network can resolve these DIDs. did:web support + well-known endpoints (/.well-known/did.json, /.well-known/atproto-did per handle host) would be a useful intermediate step.
  2. Real repo structure — records are stored as opaque values with pseudo-CIDs ("bafyrei" + hex(sha256)[..32] — not a valid CID). Federation requires DAG-CBOR records in a Merkle Search Tree with signed commits (the SDK already has DAG-CBOR/CAR/MST consumer code in the firehose/repo modules that could be reused for the producer side).
  3. Sync surfacecom.atproto.sync.getRepo / getLatestCommit / listRepos / subscribeRepos (firehose with sequenced events), plus requestCrawl toward relays. Without these, relays can't crawl the PDS.
  4. Handle resolution — serving /.well-known/atproto-did for handle subdomains.

Context: Updraft initially shipped a PDS on ATProtoNet.Pds (see issues #36–#39), but switched to the official ghcr.io/bluesky-social/pds container when federation became a requirement — the gaps above are SDK-level, not app-level. Happy to be an early adopter again once ATProtoNet.Pds can federate; the invite-store work (#36) and EF stores (#38) remain relevant for that future.

`ATProtoNet.Pds` (0.4.0) can host accounts and serve repo CRUD, but a PDS built on it cannot **federate** with the Atmosphere network. The gaps, in dependency order: 1. **Real identities** — `CreateAccountAsync` generates a placeholder `did:plc:<random13>` without registering it (no PLC genesis operation, no signed op chain, no `PDS_DID_PLC_URL` equivalent). Nothing on the network can resolve these DIDs. did:web support + well-known endpoints (`/.well-known/did.json`, `/.well-known/atproto-did` per handle host) would be a useful intermediate step. 2. **Real repo structure** — records are stored as opaque values with pseudo-CIDs (`"bafyrei" + hex(sha256)[..32]` — not a valid CID). Federation requires DAG-CBOR records in a Merkle Search Tree with signed commits (the SDK already has DAG-CBOR/CAR/MST *consumer* code in the firehose/repo modules that could be reused for the producer side). 3. **Sync surface** — `com.atproto.sync.getRepo` / `getLatestCommit` / `listRepos` / `subscribeRepos` (firehose with sequenced events), plus `requestCrawl` toward relays. Without these, relays can't crawl the PDS. 4. **Handle resolution** — serving `/.well-known/atproto-did` for handle subdomains. Context: Updraft initially shipped a PDS on `ATProtoNet.Pds` (see issues #36–#39), but switched to the official `ghcr.io/bluesky-social/pds` container when federation became a requirement — the gaps above are SDK-level, not app-level. Happy to be an early adopter again once `ATProtoNet.Pds` can federate; the invite-store work (#36) and EF stores (#38) remain relevant for that future.
Collaborator

🤖 On it — follow along in the action run; the reply will link the full session transcript.

📜 Live transcript — updating every ~5 minutes while the task runs.

🤖 On it — follow along in [the action run](https://git.grandiras.net/Grandiras/claude-bot/actions/runs/49); the reply will link the full session transcript. 📜 [Live transcript](https://git.grandiras.net/Grandiras/claude-bot/src/branch/claude-logs/transcripts/Grandiras/ATProto.NET/issue-40/run-49.md) — updating every ~5 minutes while the task runs.
Collaborator

The task itself completed: the changes were pushed and opened as PR #65.

Unfortunately the closing summary was lost — the run predates the v12.3 posting fix, and this session was long enough that the published transcript hit the renderer's size clip, which cut off the tail (also fixed now). The automatic review on PR #65 will provide an independent assessment of the changes.

✅ The task itself completed: the changes were pushed and opened as PR https://git.grandiras.net/Grandiras/ATProto.NET/pulls/65. Unfortunately the closing summary was lost — the run predates the v12.3 posting fix, and this session was long enough that the [published transcript](https://git.grandiras.net/Grandiras/claude-bot/src/branch/claude-logs/transcripts/Grandiras/ATProto.NET/issue-40/run-49.md) hit the renderer's size clip, which cut off the tail (also fixed now). The automatic review on PR #65 will provide an independent assessment of the changes.
Grandiras referenced this issue from a commit 2026-07-25 22:39:22 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Grandiras/ATProto.NET#40
No description provided.