atproto pds in zig
zds docs references.md
8.2 kB
Markdown
at main

pds ecosystem references #

ZDS is built with a small set of PDS implementations and adjacent projects in mind. This file records what each one is useful for so future work can start from known prior art instead of rediscovering it.

primary references #

official Bluesky PDS #

Links: legacy repo, atproto package

Use it as the compatibility floor. If an endpoint, repo write, sync frame, invite-code rule, app-password route, account status field, or OAuth behavior is implemented by the official PDS, ZDS should usually match it unless there is a documented reason not to.

Strengths:

  • broad client compatibility with bsky.app and ecosystem OAuth clients
  • SQLite-backed account, invite, token, repo, blob, and identity state
  • record preparation behavior for known and unknown lexicons
  • sync and firehose frame shape, including inductive Sync 1.1 fields
  • operational conventions around crawlers, email, app passwords, and admin APIs

Use it especially for:

  • XRPC response shape and error codes
  • app-password and invite-code behavior
  • DID/PLC migration and recommended credentials
  • repo import/export and block storage expectations
  • conformance tests and bug triage

Tranquil #

Link: tranquil.farm/tranquil-pds

Use it as the maturity reference. Tranquil is more ambitious than the official PDS in places, but it tends to separate concerns cleanly and has already solved many problems ZDS wants to grow into.

Strengths:

  • clean store boundaries and storage-specific benchmark targets
  • strong validation and conformance posture
  • passkey/WebAuthn login support
  • richer account security model: sessions, app passwords, token lifecycle, and audit-friendly account state
  • delegation-oriented subject/actor/controller distinctions
  • good instinct for keeping appview behavior outside the PDS

Use it especially for:

  • account-plane hardening
  • passkey UX and credential storage semantics
  • OAuth refresh/revocation edge cases
  • benchmark design and metastore comparisons
  • delegation groundwork

webauthn #

Link: zzstoatzz.io/webauthn

ZDS uses this local Zig WebAuthn library for passkey ceremony parsing and verification. Keep PDS policy in ZDS, but prefer moving general WebAuthn encoding, challenge, and signature-verification fixes into this library.

Pegasus #

Link: futur.blue/pegasus

Use it as a compact architecture reference. Pegasus is useful when ZDS needs a smaller codebase to compare module boundaries, protocol routing, and generic PDS shape without inheriting the full complexity of the official implementation.

Strengths:

  • readable PDS organization
  • clear protocol module boundaries
  • useful contrast against both Tranquil's broader architecture and the official PDS's production-oriented codebase

Use it especially for:

  • sanity-checking whether a ZDS module boundary is understandable
  • comparing minimal PDS surface area
  • avoiding overfitting to bsky-specific client pressure

secondary and adjacent references #

Cocoon #

Link: haileyok/cocoon

Cocoon is useful additional PDS context, especially for seeing a different implementation's tradeoffs around repo/account organization. Treat it as informative rather than normative.

distributed-pds #

Link: willdot.net/distributed-pds

This is useful for thinking about future account delegation and distributed PDS shape. It should influence abstractions only after the official PDS and Tranquil have been checked, because it is more experimental.

pds.js #

Link: chadtmiller.com/pds.js

Useful as a compact endpoint reference and a quick way to compare how a smaller implementation handles basic routing and PDS behaviors.

pds-message-poc #

Link: zzstoatzz.io/pds-message-poc

Useful for custom records and PDS-to-PDS behavior. This is app-adjacent context, not a substitute for PDS conformance.

PDS Gatekeeper #

Link: pds.dad/pds-gatekeeper

Useful operational policy prior art for captcha-gated account creation, 2FA, and migration-only account creation. It can inform boundary policy, but it does not replace invite-code accounting inside the PDS.

PDS Moover #

Link: pds.dad/pds-moover

Useful for migration behavior and PLC rotation-key handling as observed by real PDS moves. When migration behavior is confusing, check this alongside the official PDS before assuming what key material should be stored or exposed.

test and workload references #

  • alice.mosphere.at/atproto-smoke: browser-oriented PDS compatibility tests.
  • zzstoatzz.io/atproto-bench: benchmark rigor and methodology reference.
  • pollz: Zig + SvelteKit ATProto app using OAuth, SQLite, Jetstream, and PDS writes.
  • plyr.fm, streamplace, pds.ls, and bsky.app are useful live client probes because they exercise OAuth, scope handling, repo writes, blobs, appview proxy routes, and client expectations differently.

reference hierarchy #

When references disagree, use this order:

  1. atproto specs and lexicons
  2. official Bluesky PDS behavior
  3. Tranquil for richer mature behavior and implementation shape
  4. Pegasus or other compact implementations for readability checks
  5. experimental or app-adjacent references for ideas only

Any intentional ZDS divergence from the first three should be documented near the code or in the relevant docs page.

lessons kept in code #

  • Empty upstream proxy bodies must stay empty; returning JSON content type with an empty body breaks clients that call JSON.parse.
  • createSession and related session responses need DID document and account status fields for client compatibility.
  • Repo writes must not claim validationStatus: "valid" for unknown lexicons. The official PDS returns validationStatus: "unknown" for unknown schemas unless validation was explicitly requested; see packages/pds/src/repo/prepare.ts.
  • Generic valid rkeys are not enough for known records; key schemas matter.
  • Blob metadata belongs in SQLite, while blob bytes belong in the blobstore.
  • Crawl requests are part of making repo activity visible to relays.
  • Invite codes are core PDS state. Captcha, 2FA, and migration-only policies can live at the PDS boundary or a reverse proxy boundary; pds-gatekeeper is useful prior art for that layer, not a substitute for invite-code accounting.
  • Passkeys are Tranquil-derived, not reference-PDS-derived: store credential IDs, public keys, counters, names, and timestamps, and verify WebAuthN assertions before authorizing OAuth requests.
  • Account-plane security should be storage-backed. Sessions, refresh rotation, app passwords, OAuth grants, passkeys, and revocation are durable account state, not merely JWT formatting concerns.
  • Delegation-ready code should keep subject, actor, and controller identities distinct even before user-facing account delegation exists.
  • Account-status actions are local hosting decisions. For operator action, distinguish temporary deactivation from host takedown, deletion, and physical purge; see account takedown runbook.

active comparison work #

ZDS should stay close to Tranquil's design where it has already solved a PDS problem cleanly:

  • use storage-specific benchmarks, not only HTTP smoke tests
  • separate blob bytes from metadata
  • keep appview behavior behind atproto-proxy
  • validate known records before writes are accepted
  • report latency percentiles for storage operations
  • keep account security surfaces durable and inspectable

See benchmarks for the active performance comparison work.