feat: invite and accept, the CLI from docs/scenarios.md - #11
Merged
Conversation
cablehead
force-pushed
the
feat/invite-accept-cli
branch
from
August 18, 2026 16:04
48101ef to
644c3c8
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements the CLI worked out in
docs/scenarios.md. Breaking: every commandthat names a peer has changed.
The shape
An invitation and its acceptance are two halves of one handshake. One side
says hi, be friends; the other says yeah, be friends. The old names hid that:
grant-token,pin, andadd-peerwere three commands doing two things, andwhich one you reached for depended on who happened to dial.
An invitation is one value
invitenow prints<key>.<code>: who to dial, and the code that admits you.They were always used together and always sent together.
This is what
ticketshould have been.Daemon::ticket()wasendpoint.id().to_string()with aTODO: proper ticket serializationabove it.The TODO is gone and so is the word: a bare key is just a key.
accepttakes either form. A bare key covers the host-attested case in ADR0003, where nothing secret can travel to the peer.
A running daemon can now take up an invitation
--enrollonly existed onpai-sho daemon, so a laptop already running adaemon had no way to use a code it was handed. Its options were to restart, or
to give up on codes and have both sides pin each other by key.
acceptworksat any time.
Naming is local
Both
inviteandaccepttake--as, and both are optional. Each side namesthe other for its own use. The old
--labelwas mandatory and sat on theinviter, which is backwards when the inviter is the one serving the port: it
had to pick a name it would never type.
An invitation can carry its grant
invite --expose 8080attaches the grant to the invitation that justifies it.Still default deny and still directed at one key: the key is filled in when the
invitation is claimed, instead of being typed twice.
For the build box, that is the whole setup in one command per machine:
surfaces folded into list
listandsurfacesboth walked the peer table and printed overlapping JSON.Now one row per peer carries its name, how it was admitted, what it exposes to
us, and where those ports are bound.
SurfaceInfoandBindingInfoare gone.Every peer has a name
If neither side passes
--as, a peer is named after the first 8 characters ofits key. Surfaces answer by name, so an unnamed peer had nothing to answer to.
project --asrenames it.Tests
72 passing, 0.55s, 5 consecutive runs with no flakes.
The live tests drive
Request::InviteandRequest::Accept, so they exercisethe operator's path rather than reaching past it into
PeerManager. Three arenew: an invitation carrying its own grant reaches the port with no
exposestep, an unnamed peer still resolves by its short key, and a grant carried by an
invitation names only the claimer.
src/core/invite.rsis pure, with 7 tests on the parse. One parse test assertsthat
ticket,grant-token,pin,add-peer,remove-peer, andsurfacesno longer exist.
Docs
docs/scenarios.mdis rewritten as what shipped rather than what was proposed.The build box section keeps the old flow under "The flow before this", because
the reason for the change is the thing worth recording.
ADR 0003 gets a note reconciling its
--slugwith the--asthat shipped. Itsdecision is unchanged. It was also the one file in the repo with non-ASCII
punctuation, which is now fixed.
Version
Breaking, so this wants 0.5.0 rather than the current 0.4.2-dev. Not bumped
here, since the release flow owns that.