Tempest Navigator 4.0 - Reference Documentation

Reference file: migration-lifecycle.md

Migration and Account Lifecycle

Account migration lets a DID move between PDS hosts without changing the account identifier. Tempest keeps this flow explicit: an imported account is present in local storage, but it is not publicly served until activation proves the account belongs on this PDS.

Concepts

Atproto account identity is the DID. Handles may change, but clients and relays follow the DID document's #atproto_pds service to find the authoritative PDS. A migration therefore has two parts:

  1. Move repository and blob data to the new PDS.
  2. Update identity so the DID document points at the new PDS.

active=false means Tempest must not redistribute repo content. Sync repo reads, record reads, blob reads, and commit events are suppressed while the account is inactive. Account status and identity metadata may still be visible.

XRPC Methods

Account lifecycle:

  • com.atproto.server.checkAccountStatus
  • com.atproto.server.getServiceAuth
  • com.atproto.server.reserveSigningKey
  • com.atproto.server.activateAccount
  • com.atproto.server.deactivateAccount
  • com.atproto.server.requestAccountDelete
  • com.atproto.server.deleteAccount

Migration data:

  • com.atproto.repo.importRepo
  • com.atproto.repo.listMissingBlobs

createAccount also accepts an existing did when accompanied by a valid service-auth proof for com.atproto.server.createAccount.

Create and import flow

When createAccount receives an existing DID, Tempest validates the service-auth proof and creates the account as:

active=false
status=deactivated

The account receives stable signing-key material and an empty repo, but public sync reads remain disabled. importRepo then replaces the repo with the imported CAR after verification.

The import boundary checks:

  • valid CAR container and commit root
  • commit block is present and matches its CID
  • commit DID matches the authenticated account
  • complete MST graph and all referenced record blocks are present
  • commit signature verifies against the DID document
  • replacement is atomic, so failed imports leave the prior repo intact

Post-import writes use the normal repo write path. Revisions are monotonic: if the clock would produce a lower or equal TID, Tempest increments from the imported current revision.

Blob readiness

listMissingBlobs compares blob references indexed from current records with local blob metadata. It returns referenced CIDs that still need to be uploaded.

checkAccountStatus reports repo, record, public blob, and missing blob counts, plus migrationReady. Missing blobs keep migrationReady=false.

Activation and lifecycle events

activateAccount verifies local DID-document consistency before changing state. The DID document must match the account and expose #atproto_pds for this Tempest public URL.

Activation emits events in migration-safe order:

#identity
#account active=true
#commit repo.activate

The commit event contains a CAR slice for the latest imported state. After this, public sync reads and future commit events are enabled.

deactivateAccount sets active=false, status=deactivated, and emits an account event before public content can be redistributed again. deleteAccount sets status=deleted, revokes active sessions, and emits #account active=false.

Recovery notes

A missing or bad service-auth proof fails closed before account creation for an existing DID. This covers the unavailable-old-PDS path until fuller PLC and external DID resolution flows are implemented.

Self-controlled did:web accounts can be created with service auth and activated when their local DID document points at this PDS. This is the current tested path for bring-your-own identity migration.

Verification

hurl --test --jobs 1 \
  --variable base_url=http://localhost:4000 \
  test/smoke/migration-lifecycle.hurl

The smoke test covers status, service auth, exported-CAR fixture reads, bad CAR atomicity, missing blobs, deactivation suppression, activation, and deletion.

Start tempest docs / tempest.desertthunder.dev 2026-06-24 18:46:05Z