jiebi/TextFlow huggingface dataset:
Original text:
stateless reset size. Endpoints MUST discard packets that are too small to be valid QUIC <del> packets.  With the set of AEAD functions defined in QUIC-TLS, packets that are smaller than 21 bytes are never valid. </del>  Endpoints MUST send stateless reset packets formatted as a packet with a short header.  However, endpoints MUST treat any packet ending

Reviewer comments:
Minimum packet size varies between the packet types (and other things like the length of CID being used). Therefore, the sentence is merely providing an example, and should be stated as such. .
Currently section 10.3 of the transport doc says: However, Version Negotiation packets are not guaranteed to be larger than 21 bytes. For example, a VN packet with an 0-byte destination connection ID, 8 byte source connection ID and single version would be 19 bytes. If a client receives such a packet, must it be dropped? This text suggests it must. But it's not clear to mean (or the slack channel) that this interpretation is expected. Of course, a server could work around this issue by appending a sufficient number of GREASE'd versions to make the packet large enough. But I'm not sure if that is mandatory?
The second sentence merely points out that QUIC packets that use AEAD can never be smaller than 21 bytes. VN packets do not use AEAD, hence that 21 byte limit does not apply. Of course, endpoints can do their own maths to figure out the minimal size of VN packets that they might receive. Just my two cents. We might want to clarify the italic part ("that use AEAD") in the specification.
I agree with NAME that the spec isn't technically wrong, but I find it unclear. It wouldn't surprise me if someone were to read this and add to their packet ingestion code. I think all we need here is an editorial clarification such as
Note: 21 is the correct number, as requires endpoints to expand the payload size to at least 4 + len(AEAD tag), so that we can always have full-sized entropy for header protection.
Thanks Kazuho, this is great. What I like about this is that it also implies the possibility of a higher minimum. For instance, the limit on long headers is higher (28 for Initial, 27 for 0-RTT and handshake if I'm right, but you can also add the minimum connection ID length for receiving to that).

Revised text:
stateless reset size. Endpoints MUST discard packets that are too small to be valid QUIC  <ins> packets.  To give an example, with the set of AEAD functions defined in QUIC-TLS, short header packets that are smaller than 21 bytes are never valid. </ins> Endpoints MUST send stateless reset packets formatted as a packet with a short header.  However, endpoints MUST treat any packet ending
Original text:
An opaque blob that the client can use with a future Initial packet.  The token MUST NOT be empty.  A client MUST treat receipt <del> of a NEW_TOKEN frame with </del>  A client might receive multiple NEW_TOKEN frames that contain the same token value if packets containing the frame are incorrectly

Reviewer comments:
I looked into the commits but I cannot identify the commit which removed this line.
Gah! Thanks NAME for catching this!!

Revised text:
An opaque blob that the client can use with a future Initial packet.  The token MUST NOT be empty.  A client MUST treat receipt  <ins> of a NEW_TOKEN frame with an empty Token field as a connection error of type FRAME_ENCODING_ERROR. </ins> A client might receive multiple NEW_TOKEN frames that contain the same token value if packets containing the frame are incorrectly
Original text:
7.6.2. A sender establishes persistent congestion after the receipt of an <del> acknowledgement if at least two ack-eliciting packets are declared </del>  lost, and: all packets, across all packet number spaces, sent between the <del> send times of two ack-eliciting packets are declared lost; </del>  the duration between the send times of these two packets exceeds the persistent congestion duration (pc-duration); and <del> a prior RTT sample existed when both packets were sent. </del>  These two packets MUST be ack-eliciting, since a receiver is required to acknowledge only ack-eliciting packets within its maximum ack

Reviewer comments:
NAME rightly noted lack of clarity (), which this PR attempts to fix. There's a new MUST here, but I think it was again implicit. EDIT: Removed this MUST since NAME notes correctly that this is a definition, not an action.

Revised text:
7.6.2. A sender establishes persistent congestion after the receipt of an  <ins> acknowledgement if two packets that are ack-eliciting are declared </ins> lost, and: all packets, across all packet number spaces, sent between the  <ins> send times of these two packets are declared lost; </ins> the duration between the send times of these two packets exceeds the persistent congestion duration (pc-duration); and  <ins> a prior RTT sample existed when these two packets were sent. </ins> These two packets MUST be ack-eliciting, since a receiver is required to acknowledge only ack-eliciting packets within its maximum ack
Original text:
support for one of these versions and can expect that clients ignore the value. <del> [[RFC editor: please remove the remainder of this section before publication.]] The version number for the final version of this specification (0x00000001), is reserved for the version of the protocol that is published as an RFC. Version numbers used to identify IETF drafts are created by adding the draft number to 0xff000000.  For example, draft-ietf-quic- transport-13 would be identified as 0xff00000d. Implementors are encouraged to register version numbers of QUIC that they are using for private experimentation on the GitHub wiki at <https://github.com/quicwg/base-drafts/wiki/QUIC-Versions>. </del> 16. QUIC packets and frames commonly use a variable-length encoding for

Reviewer comments:
Note: Don't merge until the last minute.
I want to do more than just approve this, but this'll have to do

Revised text:
support for one of these versions and can expect that clients ignore the value.  16. QUIC packets and frames commonly use a variable-length encoding for
Original text:
acknowledgement if two packets that are ack-eliciting are declared lost, and: <del> all packets, across all packet number spaces, sent between the send times of these two packets are declared lost; </del>  the duration between the send times of these two packets exceeds the persistent congestion duration (pc-duration); and

Reviewer comments:
Persistent congestion means that no packets between two ack-eliciting packets was received by the peer. This was codified as all packets between those boundary packets being lost. However, non-ack-eliciting packets can be often never declared as lost, since loss declaration requires a packet to be in-flight (URL). What we really want to say is that none of the packets between these boundary packets were acknowledged. This PR makes this change. Note that the example below the definition already follows this; packets in between the boundary packets are noted as "not acknowledged" rather than marked as lost. (Problem also noted here: URL)

Revised text:
acknowledgement if two packets that are ack-eliciting are declared lost, and:  <ins> across all packet number spaces, none of the packets sent between the send times of these two packets are acknowledged; </ins> the duration between the send times of these two packets exceeds the persistent congestion duration (pc-duration); and
Original text:
Indicates that x can be any length from A to B; A can be omitted to indicate a minimum of zero bits and B can be omitted to indicate no set upper limit; values in this format always end on <del> an octet boundary </del>  Indicates that x has a fixed value of C Indicates that x can be any length from A to B; A can be omitted to indicate a minimum of zero bits and B can be omitted to indicate no set upper limit; values in this format always end on <del> an octet boundary </del>  Indicates that x has a fixed value of C with the length described by ?, as above (RFC6265) MAY be split into separate field lines, each with one or more cookie-pairs, before compression.  If a decompressed field section contains multiple cookie field lines, these MUST be <del> concatenated into a single octet string using the two-octet delimiter </del>  of 0x3b, 0x20 (the ASCII string "; ") before being passed into a context other than HTTP/2 or HTTP/3, such as an HTTP/1.1 connection, or a generic HTTP server application.

Reviewer comments:
Maybe leftovers from , or newly added text.
I'm sure the document was touched by his noodly appendage of the Octocat :octocat:
How did those slip through!?Yes, I think these are mostly new / imported from other docs.Thanks, NAME !

Revised text:
Indicates that x can be any length from A to B; A can be omitted to indicate a minimum of zero bits and B can be omitted to indicate no set upper limit; values in this format always end on  <ins> an byte boundary </ins> Indicates that x has a fixed value of C Indicates that x can be any length from A to B; A can be omitted to indicate a minimum of zero bits and B can be omitted to indicate no set upper limit; values in this format always end on  <ins> an byte boundary </ins> Indicates that x has a fixed value of C with the length described by ?, as above (RFC6265) MAY be split into separate field lines, each with one or more cookie-pairs, before compression.  If a decompressed field section contains multiple cookie field lines, these MUST be  <ins> concatenated into a single byte string using the two-byte delimiter </ins> of 0x3b, 0x20 (the ASCII string "; ") before being passed into a context other than HTTP/2 or HTTP/3, such as an HTTP/1.1 connection, or a generic HTTP server application.
Original text:
IPv4 networks.  Assuming the minimum IP header size of 40 bytes for IPv6 and 20 bytes for IPv4 and a UDP header size of 8 bytes, this results in a maximum datagram size of 1232 bytes for IPv6 and 1252 <del> bytes for IPv4.  Thus, modern IPv4 and all IPv6 network paths will be able to support QUIC. </del>  Any maximum datagram size larger than 1200 bytes can be discovered using Path Maximum Transmission Unit Discovery (PMTUD; see pmtud) or

Reviewer comments:
NAME said: >14 "Thus, modern IPv4 and all IPv6 network paths will be able to support QUIC." Generally true, but should be qualified for the presence of arbitrary numbers of tunnels.
This is not one that I have an answer to currently. We could just wave this away as Martin suggests, but I'm not sure that is best. What do tunneling protocols say about ensuring the IPv6 minimum MTU?
I don't know what the IETF tunneling protocols say about MTU, but I don't expect them to violate IPv6 minimum MTU (someone should correct me if I'm wrong). The problem here might not be about what allowances we make for tunneling -- I don't want to create a list of exceptions in this document -- but about wording. I propose changing "will be able to support" to "are expected to support". As long as we are not making assumptions that violate permissions afforded by spec or practice, I think we're good.
Thanks. This is weaker, but truer.

Revised text:
IPv4 networks.  Assuming the minimum IP header size of 40 bytes for IPv6 and 20 bytes for IPv4 and a UDP header size of 8 bytes, this results in a maximum datagram size of 1232 bytes for IPv6 and 1252  <ins> bytes for IPv4.  Thus, modern IPv4 and all IPv6 network paths are expected to be able to support QUIC. </ins> Any maximum datagram size larger than 1200 bytes can be discovered using Path Maximum Transmission Unit Discovery (PMTUD; see pmtud) or
Original text:
Section 7.5 of QUIC-TRANSPORT. Once the TLS handshake is complete, this is indicated to QUIC along <del> with any final handshake bytes that TLS needs to send.  TLS also provides QUIC with the transport parameters that the peer advertised during the handshake. </del>  Once the handshake is complete, TLS becomes passive.  TLS can still receive data from its peer and respond in kind, but it will not need error of type 0x16d (equivalent to a fatal TLS missing_extension alert, see tls-errors). <del> While the transport parameters are technically available prior to the completion of the handshake, they cannot be fully trusted until the handshake completes, and reliance on them should be minimized. However, any tampering with the parameters will cause the handshake to fail. </del>  Endpoints MUST NOT send this extension in a TLS connection that does not use QUIC (such as the use of TLS with TCP defined in TLS13).  A

Reviewer comments:
This is OK, but only in a limited fashion.
NAME said: parameters are not delivered until the handshake is complete. In 8.2 it says that the TPs are "available" but "not fully trusted" before completion. The latter is certainly true; but the server can't send 0.5-RTT packets (e.g. a SETTINGS frame) without any indication of the client transport parameters. I would suggest a clarification in 4.1.3 and letting the language in 8.2 stand.
Proposed resolution is
I think the limitations could be a be clearer, but heading in a good direction.I think the changes add clarity.

Revised text:
Section 7.5 of QUIC-TRANSPORT. Once the TLS handshake is complete, this is indicated to QUIC along  <ins> with any final handshake bytes that TLS needs to send.  At this stage, the transport parameters that the peer advertised during the handshake are authenticated; see quic_parameters. </ins> Once the handshake is complete, TLS becomes passive.  TLS can still receive data from its peer and respond in kind, but it will not need error of type 0x16d (equivalent to a fatal TLS missing_extension alert, see tls-errors).  <ins> Transport parameters become available prior to the completion of the handshake.  A server might use these values earlier than handshake completion.  However, the value of transport parameters is not authenticated until the handshake completes, so any use of these parameters cannot depend on their authenticity.  Any tampering with transport parameters will cause the handshake to fail. </ins> Endpoints MUST NOT send this extension in a TLS connection that does not use QUIC (such as the use of TLS with TCP defined in TLS13).  A
Original text:
Application Data may appear only in the Early Data and Application Data levels.  Handshake and Alert messages may appear in any level. <del> The 0-RTT handshake is only possible if the client and server have </del>  previously communicated.  In the 1-RTT handshake, the client is unable to send protected Application Data until it has received all of the Handshake messages sent by the server.

Reviewer comments:
Though I guess provisioning of a PSK depends on prior communication of a sort, there is no need to be so absolute here.
NAME said:
I will suggest that we strike the "only" here.

Revised text:
Application Data may appear only in the Early Data and Application Data levels.  Handshake and Alert messages may appear in any level.  <ins> The 0-RTT handshake can be used if the client and server have </ins> previously communicated.  In the 1-RTT handshake, the client is unable to send protected Application Data until it has received all of the Handshake messages sent by the server.
Original text:
Handshake state updates <del> Additional functions might be needed to configure TLS. </del>  4.1.1.

Reviewer comments:
Important enough to call out in this section.
Roman Danyliw said:
I think that we're OK, and the text added in should help avoid any need for this point.
NAME said:
Should we split this bit out into a separate issue? per §4.8 TLS alerts are translated into QUIC connection errors and are not sent natively. (The prose also says "TLS Handshake and Alert messages are carried directly over the QUIC transport".)
I don't think we need to do anything in response to that. Those messages are carried by QUIC.
I will defer to your preference, but I do not agree that "those messages" are carried by QUIC; QUIC does not carry TLS Alert structures.
a nit but lgtm

Revised text:
Handshake state updates  <ins> Additional functions might be needed to configure TLS.  In particular, QUIC and TLS need to agree on which is responsible for validation of peer credentials, such as certificate validation (RFC5280). </ins> 4.1.1.
Original text:
from the range reserved for CRYPTO_ERROR.  The resulting value is sent in a QUIC CONNECTION_CLOSE frame of type 0x1c. <del> The alert level of all TLS alerts is "fatal"; a TLS stack MUST NOT generate alerts at the "warning" level. </del>  QUIC permits the use of a generic code in place of a specific error code; see Section 11 of QUIC-TRANSPORT.  For TLS alerts, this

Reviewer comments:
This changes the shape of the requirement from one that proscribes the behaviour of a TLS stack to the reaction of QUIC to a warning level alert. This recommends treating them as fatal as QUIC never deliberately closes TLS. This is a normative change that should have no practical effect on implementations.
NAME said:
I'm going to request that we flag this one "design". I think that we want to say: the TLS connection is never closed using TLS mechanisms QUIC can treat any TLS alert as fatal PR created and email in the pipe.
Marking this as design as requested.
Returning to an open state as the chairs directed in their plan.
Closing this now that the IESG have approved the document(s).
I agree that this is a good improvement, especially for folks who can't modify their TLS stack.

Revised text:
from the range reserved for CRYPTO_ERROR.  The resulting value is sent in a QUIC CONNECTION_CLOSE frame of type 0x1c.  <ins> QUIC is only able to convey an alert level of "fatal".  In TLS 1.3, the only existing uses for the "warning" level are to signal connection close; see Section 6.1 of TLS13.  As QUIC provides alternative mechanisms for connection termination and the TLS connection is only closed if an error is encountered, a QUIC endpoint MUST treat any alert from TLS as if it were at the "fatal" level. </ins> QUIC permits the use of a generic code in place of a specific error code; see Section 11 of QUIC-TRANSPORT.  For TLS alerts, this
Original text:
The same number of bytes are always sampled, but an allowance needs to be made for the endpoint removing protection, which will not know <del> the length of the Packet Number field.  In sampling the packet ciphertext, the Packet Number field is assumed to be 4 bytes long (its maximum possible encoded length). </del>  An endpoint MUST discard packets that are not long enough to contain a complete sample.

Reviewer comments:
Though people will undoubtedly rely on pseudocode to understand this, there is no reason why we can't also use prose.
NAME said:
That's just an oops. There is a paragraph that almost defines this in prose. It just needs a little push and we don't need to rely exclusively on pseudocode.

Revised text:
The same number of bytes are always sampled, but an allowance needs to be made for the endpoint removing protection, which will not know  <ins> the length of the Packet Number field.  The sample of ciphertext is taken starting from an offset of 4 bytes after the start of the Packet Number field.  That is, in sampling packet ciphertext for header protection, the Packet Number field is assumed to be 4 bytes long (its maximum possible encoded length). </ins> An endpoint MUST discard packets that are not long enough to contain a complete sample.
Original text:
Once an endpoint successfully receives a packet with a given packet number, it MUST discard all packets in the same packet number space with higher packet numbers if they cannot be successfully unprotected <del> with either the same key, or - if there is a key update - the next packet protection key (see key-update).  Similarly, a packet that appears to trigger a key update, but cannot be unprotected successfully MUST be discarded. </del>  Failure to unprotect a packet does not necessarily indicate the existence of a protocol error in a peer or an attack.  The truncated

Reviewer comments:
This is a little pedantic, but it's more correct. Also fix reference format.
NAME said:

Revised text:
Once an endpoint successfully receives a packet with a given packet number, it MUST discard all packets in the same packet number space with higher packet numbers if they cannot be successfully unprotected  <ins> with either the same key, or - if there is a key update - a subsequent packet protection key; see key-update.  Similarly, a packet that appears to trigger a key update, but cannot be unprotected successfully MUST be discarded. </ins> Failure to unprotect a packet does not necessarily indicate the existence of a protocol error in a peer or an attack.  The truncated
Original text:
avoid replay attacks on the protocol. Of the frames defined in QUIC-TRANSPORT, the STREAM, RESET_STREAM, <del> and CONNECTION_CLOSE frames are potentially unsafe for use with 0-RTT as they carry application data.  Application data that is received in 0-RTT could cause an application at the server to process the data multiple times rather than just once.  Additional actions taken by a server as a result of processing replayed application data could have unwanted consequences.  A client therefore MUST NOT use 0-RTT for application data unless specifically requested by the application that is in use. </del>  An application protocol that uses QUIC MUST include a profile that defines acceptable use of 0-RTT; otherwise, 0-RTT can only be used to

Reviewer comments:
So it could be unsafe for use in 0-RTT.
NAME said:
STOP_SENDING can be sent in 0-RTT. It should be in the list.

Revised text:
avoid replay attacks on the protocol. Of the frames defined in QUIC-TRANSPORT, the STREAM, RESET_STREAM,  <ins> STOP_SENDING, and CONNECTION_CLOSE frames are potentially unsafe for use with 0-RTT as they carry application data.  Application data that is received in 0-RTT could cause an application at the server to process the data multiple times rather than just once.  Additional actions taken by a server as a result of processing replayed application data could have unwanted consequences.  A client therefore MUST NOT use 0-RTT for application data unless specifically requested by the application that is in use. </ins> An application protocol that uses QUIC MUST include a profile that defines acceptable use of 0-RTT; otherwise, 0-RTT can only be used to