docs(arch): rewrite hub README for multi-transport + channels substrate; add OQ-58 (worker registration)
The hub README predates channels (2026-07-09) and was built on the call-protocol-directly-over-QUIC model: 'One QUIC connection per peer carrying the call protocol,' CallClient::connect as the dial path, QUIC as the only transport. The channels crate replaced that substrate (ADR-071/079/080), and the hub's primary use case (worker provisioning on docker/vast.ai/runpod) requires TCP+TLS for registration and QUIC or TCP+TLS for the ongoing session — coexisting on one hub, not as alternatives. Rewrite: - Multi-transport stated as decided: 'A hub MUST support TCP+TLS and QUIC endpoints simultaneously.' TCP+TLS accept loop (ADR-010 Am. 1) lives in the hub, shares the HandlerRegistry with the quinn endpoint. - Channels substrate: the hub uses ChannelsAdapter/ChannelClient (from_connection primary, connect_quic convenience — ADR-080), not CallClient/CallAdapter directly. One channels connection per peer; CallAdapter runs on channel 0 (ADR-072). - Transport-agnostic dial/accept: dial_worker_connection takes a Connection (one-way door); connect_quic_worker is a two-way-door convenience. supervise_worker takes a dial closure, not a SocketAddr. - Identity over transports: fingerprint path (QUIC+raw-key, X.509 client cert) via resolve_from_fingerprint; bearer-token path (TCP+TLS no client cert, WebTransport, WebSocket) via resolve_from_token on the call first frame. Both resolve to the same PeerEntry (ADR-030/034). - Worker registration flow (6 steps): provision → token → download → key gen → HTTP POST over TCP+TLS → channels connect. Step 4 is HTTP on HttpAdapter; step 6 is channels over QUIC or TCP+TLS. The hub creates a mixed-fingerprint PeerEntry (ADR-034 §3) at registration. - OQ-58: worker registration flow — enrollment-token model, endpoint shape, register_worker API. Open (decision-ready, not blocked), one-way door, high priority. - ADR-081: fix stale references to channels-hub/channels-worker sub-crates (the ADR's Decision says they don't exist; the References section said they did). Review (architecture-reviewer): 3 critical (ADR-081 stale refs; bearer-token extraction flow; assembly example QUIC-only + unspecced into_connection), 7 warnings (registration 'or'→'both', channel/control translation, OQ-52 interim, HubError variant naming, RegistrationError definition, X.509-client-cert prose, adapter ownership phrasing), 5 suggestions. All criticals and warnings #4/#7/#8 addressed; #5/#6/#9/#10 addressed; #11-15 noted as optional.
This commit is contained in:
1 parent
73c621bf21
commit
a26401aadd
5 files changed
+568
-222
No files matched your search
@@ -0,0 +1,64 @@
|
||||
# OQ-58: Worker Registration Flow
|
||||
|
||||
- **Origin**: `docs/architecture/crates/hub/README.md` §"Worker
|
||||
registration" — the provisioning → enrollment → connection sequence
|
||||
that makes TCP+TLS a hard requirement for the hub.
|
||||
- **Status**: open
|
||||
- **Door type**: one-way (the registration endpoint shape and the
|
||||
enrollment-token model are an API surface; changing them after
|
||||
workers are provisioned against them is a breaking change for every
|
||||
deployment)
|
||||
- **Priority**: high
|
||||
- **Blocked on**: nothing structural — the identity machinery
|
||||
(`resolve_from_token`, `PeerEntry.auth_token_hash`, ADR-030/034)
|
||||
and the HTTP substrate (`HttpAdapter` on `h2`/`http/1.1` over
|
||||
TCP+TLS, ADR-010 Am. 1 / ADR-065) both exist. What remains is
|
||||
deciding the token model and the endpoint shape, not building new
|
||||
primitives.
|
||||
- **Resolution**: Not yet decided. The flow is decision-ready in
|
||||
shape (see "Decision-ready shape" below). The open sub-questions are:
|
||||
1. **Enrollment-token model.** Is the registration token one-time
|
||||
single-use (burned on first POST), one-time-per-worker (a worker
|
||||
can retry the POST until it succeeds, then the token is
|
||||
invalidated), or refresh-capable (the token can enroll multiple
|
||||
workers, e.g. a pool token)? One-time-per-worker is the likely
|
||||
default (matches the provisioning flow: one token per instance);
|
||||
pool tokens are a feature extension.
|
||||
2. **Session credential returned.** After registration, does the
|
||||
hub return a bearer token for the ongoing channels connection
|
||||
(the worker authenticates over TCP+TLS via `auth_token`), or
|
||||
does it record the worker's fingerprint and expect fingerprint
|
||||
auth on the channels connection (the worker authenticates over
|
||||
QUIC via its raw key)? Both are valid; the choice depends on
|
||||
whether the worker's transport is known at registration time. A
|
||||
hub that accepts both should probably support both return shapes
|
||||
(return a token *and* record the fingerprint).
|
||||
3. **Endpoint path.** `POST /register`? `POST /v1/workers/register`?
|
||||
A versioned path is safer for a one-way door.
|
||||
4. **Token source.** Does the hub generate the enrollment token, or
|
||||
does the assembly layer (the provisioning system) generate it
|
||||
and the hub just validates it? The latter keeps the hub out of
|
||||
the token-generation business but requires a shared secret or
|
||||
signature scheme.
|
||||
- **Decision-ready shape**: the registration endpoint is an HTTP POST
|
||||
on the hub's `HttpAdapter` (served on `h2`/`http/1.1` over TCP+TLS).
|
||||
The request carries the worker's public key and the enrollment
|
||||
token. The hub validates the token, creates a `PeerEntry` for the
|
||||
worker (fingerprint from the key, `auth_token_hash` from a
|
||||
session token the hub issues), and returns the session credential.
|
||||
The worker then connects via channels (QUIC or TCP+TLS) and
|
||||
authenticates with the fingerprint or the bearer token. The
|
||||
`PeerEntry` created at registration is what `resolve_from_token`
|
||||
/ `resolve_from_fingerprint` matches at connection time.
|
||||
- **What does NOT block on this**: the hub's multi-transport accept
|
||||
loop, the channels-over-TCP path, the identity-over-TCP path
|
||||
(bearer token via `resolve_from_token`), and the supervision loop.
|
||||
All of these are decided and use existing machinery. OQ-58 is
|
||||
about the registration endpoint specifically — the one new surface
|
||||
the hub introduces.
|
||||
- **Cross-references**: ADR-030 (PeerEntry, auth_token_hash),
|
||||
ADR-034 (bearer-token identity over non-fingerprint transports),
|
||||
ADR-010 Am. 1 (TCP+TLS dispatch via from_stream), ADR-065
|
||||
(Connection::from_bidi), ADR-080 (ChannelClient::from_connection),
|
||||
OQ-52 (CallConnection::wait_for_close — the supervision loop the
|
||||
registration flow feeds into).
|
||||
Reference in new issue
Block a user