Everything a joining device needs, sealed to the pending identity named by
its signed pairing request. The transport bundle is public kickoff data; the member
admission inside sealed_invitation carries provider credentials and can
be opened only by that joining device.
A listener behind the one QR code shown by the existing device. It accepts
one exact signed identity, survives client reconnects, and returns the same
sealed invitation on every retry.
The one code an existing device displays. Possession of this code grants
access only to this pairing session; Store credentials remain sealed to the
joining identity the existing device approves.
The joining device’s retained side of a pairing attempt. It owns no secret
key bytes; the pending identity stays in the configured key custody and is
addressed by the signed request’s public key until the join commits.
Why joining or restoring a store failed. Both are the same operation —
bootstrap a store from the cloud — differing only in their entry data (an
admission that wraps the store key vs a restore code that carries the bucket
credentials), so they share one error shape rather than two that duplicate
most of their variants and then have to map between each other.
The durable user-visible phase of one joining-device enrollment.
Invitation bytes remain private because they contain the sealed Store
admission; callers only need the operation they can resume.
Complete the joining side after scanning the existing device’s one pairing
code. The local session returns the invitation sealed to this attempt; the
existing Store transport then performs registration and bootstrap. The
caller’s Coven migration policy controls every writer open during bootstrap.
Submit the same signed request until the owner approves, cancels, or the
caller’s deadline expires. Each retry may use another endpoint from the QR;
the host accepts the exact request idempotently and refuses a competing one.