Files
amethyst/quic/src
Claude 3a5c25ad36 feat(marmot): the direct QUIC path, and a pin instead of blind trust
Two halves of the same gap in `transports/quic.md`.

**The direct path.** The binding has a second delivery mode we had not
built: the sender dials the receiver, opens one unidirectional stream and
writes records with no control envelope at all. It is deliberately smaller
than the broker path — the dialed endpoint is already the one receiver, so
there is no room to claim — and it negotiates its own ALPN so an
incompatible change to either mode cannot reach the other. Note the
inverted direction: here the RECEIVER listens and the SENDER dials, which
is also why v1 gives it no start-payload discovery and it is only usable
against an endpoint known out of band.

Only the sending half is here. `:quic` is a client stack with no server
role, so this module can dial a direct receiver but cannot be one; that is
recorded in the README rather than half-built.

**The pin.** Preview endpoints and brokers are commonly self-signed and
the binding expects that, saying a client MAY pin by exact DER or SHA-256
fingerprint. What we had instead was `PermissiveCertificateValidator` on
the CLI path, which is not a weaker trust model — it is none, and anyone
on the path can be the broker. `PinnedCertificateValidator` replaces the
chain and the hostname check and nothing else: the peer still has to sign
the TLS transcript with the pinned certificate's private key, so copying a
public certificate off the wire buys an attacker nothing. `amy marmot
stream send|watch` takes `--pin-sha256`, and `--insecure` still exists for
a throwaway local broker but now has to be asked for by name.

Both are verified against the reference implementation, which is the only
thing that can tell an ALPN string, a stream direction, an absent envelope
and a frame prefix from an implementation agreeing with itself: our direct
sender against `wn stream receive`, and the pin — accepted and refused —
against a real handshake with `marmot-quic-broker`.

One thing that only showed up under a real handshake: a certificate the
validator refuses closes the connection before it is established, and the
transport was reporting that as PeerClosed. A caller walking a candidate
list reads that kind to decide what to do next, and "never connected" is
not "the peer hung up on us", so it is classified on the connection's
actual status now.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kCuA6tc4JQzHPCDd39GHq
2026-09-09 15:30:50 +00:00
..