correctness
A clause says MUST. A client that does otherwise is wrong, and the cell says so. The only class where fail is an accusation.
Every one of these is a page: what the server emits, the clause it is judged against, and how each client answered. The full list carries the verdict tallies too.
Most conformance tooling drives a client and checks what comes back. This does the opposite. It is a server that is deliberately, precisely wrong — once per port, 59 times over — and the measurement is whatever the client does when it walks into one.
That inversion is the whole design. A client cannot be asked whether it rejects a second control stream; it can only be shown one. Every anomaly below exists because a clause in an RFC says a client must do something about it, and the only way to find out is to produce the situation on the wire and watch.
The listener runs inside the production proxy and binds
59 UDP sockets at
4460 + offset, ending at 4518.
Offsets are pinned by a unit test, because the port number is a public identifier:
renumbering would silently point somebody's script at a different anomaly and it
would still return results.
Where an anomaly is injected decides what can be concluded from the answer. A TLS anomaly is a configuration the handshake either survives or does not. A QUIC anomaly is mostly transport configuration and the socket underneath it. An HTTP/3 anomaly is bytes written after the handshake, on a stream chosen for the clause being tested.
An anomaly is not a function; it is a record, and the record is what makes the verdict checkable. Nothing in the suite may score a cell on a clause the entry did not name in advance.
idthe URL, the port’s identity, and the search termtitlethe sentence a reader sees, never the thing judgedspecclause-level citation — section, not just documentlayerquic, http3 or tls: decides how a close is readclasswhat a pass is worth, belowport_offsetpinned by a test; renumbering is silent breakageexpectationwhat a conforming client does, written before the runrequirement_labelMUST, SHOULD or MAY, taken from the clauseA clause says MUST. A client that does otherwise is wrong, and the cell says so. The only class where fail is an accusation.
Both answers are legal; the question is whether the exchange completes. A fail here is a thing that will not work, not a thing that is forbidden.
Reserved codepoints and GREASE. Passing means ignoring something unknown without flinching, which is what keeps the protocol able to change.
Loss, reordering, a black-holed path, a server that vanishes. Recovery is the measurement; the specification rarely mandates how.
The specification permits either. Nothing here is ever a failure — the cell records a choice, and exists so the choice is visible.
A test whose clause says MAY can never produce a fail. That is enforced in the reduction, not left to whoever writes the entry.
Several QUIC clauses are about conditions no configuration can express: a datagram
that never arrives, two that arrive out of order, a path that marks congestion. Those
live in a wrapper around the UDP socket which implements
poll_recv and poll_send and is free to lie about both.
Three impairments have no reachable code path in a correct implementation, which is exactly why they are worth testing and exactly why they cannot be configured. They live in vendored forks.
rustls-fixedA KeyShareImpairment hook on the server's ServerHello: a group the
client never offered, a hybrid share with its ML-KEM half corrupted, a share whose
length contradicts the group named with it, a GREASE codepoint in
supported_groups.
noqA fork of quinn carrying Connection::abandon(): terminate locally and
tell the endpoint the connection is drained while the peer still believes it is live,
so its next packet meets an unknown connection ID and draws a Stateless Reset.
Every graceful path says goodbye; this one has to not.
h3, h3-noqFrame and stream emission the HTTP/3 crate has no API for, plus the QPACK decoder state a blocked field section needs, including the dynamic table capacity a correct encoder would never exceed.
The reduction is two-stage on purpose. Thirteen observations describe what the connection did; five verdicts say what that is worth. Keeping them apart is what lets the suite distinguish a client that objected in the wrong place from one that did not object, and both from a run that never put the client in the situation.
A fail is never inferred from silence. Where a clause names a specific error code, a client that closes the QUIC connection instead has objected — the report says so — but the code the clause names never reached the wire, and the test asks what the client signalled.
Several HTTP/3 clauses are about a stream the client is not obliged to read promptly. If it never reads, it cannot have violated anything, and scoring it would be an accusation the run cannot support. The proof used is flow-control credit on the anomaly’s own stream, because a receiver extends credit only once its application has consumed what is already there.
A verdict is worth nothing if it belongs to the wrong connection, and on a port driven by twelve clients in sequence that is not automatic. These are the rules the session layer holds to.
The driver is a binary that runs one client command per anomaly, substituting the URL and port. Whatever the command connects with is what gets measured — there is no shim, no library binding, no mock.
h3-conformance \
--host conformance.pqcrypta.com \
--client 'curl -s --http3-only --max-time 15 -o /dev/null {url}' \
--filter q-stateless-reset \
--json
Exit status is deliberately ignored. A client failing a test frequently should exit non-zero, and treating that as an error would discard the result the run exists to collect. The verdict is read from the server side, which is the only side that knows what was emitted.
The whole matrix is driven repeatedly and compared cell by cell. A cell counts as reproducible only when every repeat returned the same verdict; a cell missing from any repeat counts as a disagreement rather than being dropped, because a client that failed to launch once is precisely the instability being measured.
The warm-up is discarded on evidence rather than superstition: the first run after a restart returns inconclusive for clients that pass on every later run, so it is measured and dropped.
12 implementations, each driven as its own binary against the same ports, version-pinned to a commit where the project has one. Nothing is simulated: whatever the command connects with is what gets measured, and its exit status is ignored, because a client failing a test frequently should exit non-zero.
The weekly job stages; it cannot write the live matrix. Promotion is a separate program, and it asks, because a run finishing is not a decision to publish it.
Stated rather than worked around, because a limit that is not published reads as a result. Each of these is a place where the honest answer is inconclusive and the tempting one is a verdict.
RFC 9000 ยง10.2.1 has a closing endpoint re-send CONNECTION_CLOSE only in response to an incoming packet. A close that is sent and lost is indistinguishable from one never sent, so the server keeps a packet flowing to prompt a repeat — and where it still never arrives, the cell says so.
Credit on the anomaly’s stream proves a read. No credit proves nothing: a client with a window bigger than the anomaly has no reason to extend any. Two probes failed identically here before the limit was accepted as a limit.
A client that closes the QUIC connection has plainly objected, and the report says so. But the HTTP/3 code the clause names never reached the wire, and the test asks what the client signalled.
A peer that has exited owes nothing and sends nothing. Distinguishing that from a peer ignoring an anomaly needs the wait to outlast the client’s own idle timer, not a round trip.
A driven run ends with its own report and badge, keyed by the session the endpoint
assigned. Those URLs are noindex, nofollow: the space is unbounded and
each one describes a single execution rather than the state of the field.
Full report: https://conformance.pqcrypta.com/report/<session>
Badge: https://conformance.pqcrypta.com/badge/<session>.svg
The published matrix is the other thing entirely: 12 implementations driven by us, on a schedule, promoted by hand.
The matrix is every client against every anomaly. The anomaly index is what the server emits and the clause it is judged against. Findings is only the failures. Post-quantum certificates is the one result that deserved an argument rather than a row.