jiebi/TextFlow huggingface dataset:
Original text:
defined in long-header.  A Version Negotiation packet is identifiable as such by the Version field, which is set to 0x00000000. <del> The Version Negotiation packet contains a list of Supported Version fields, each identifying a version that the endpoint sending the packet supports.  The Supported Version fields follow the Version field.  A Version Negotiation packet contains no other fields.  An endpoint MUST ignore a packet that contains no Supported Version fields, or a truncated Supported Version. </del>  Version Negotiation packets do not use integrity or confidentiality protection.  Specific QUIC versions define mechanisms to authenticate

Reviewer comments:
As Magnus noted, the description of the first byte is missing, and I also noticed that the Supported Version field was described as following Version, which is wrong.
For -09 in WG LC. Section 6 has a packet header structure with the field: Unused (7) All the other fields are either fixed value or kind of defined earlier. In fact I would argue they represent concepts that are defined in -transport. Thus a second part of this is if -transport needs to be normative reference for the concepts used in this document. But back to Unused: I think this field can take any value on transmission, and should be ignored on reception. Maybe this needs to be noted explicitly in Section 6.
It's very deliberate that Invariants does not normatively depend on Transport. Invariants needs to stand alone, as a description of what versionless QUIC means. Arguably, Transport could normatively depend on Invariants, but it chooses instead to restate the things it depends on and make the reference informative.

Revised text:
defined in long-header.  A Version Negotiation packet is identifiable as such by the Version field, which is set to 0x00000000.  <ins> Only the most significant bit of the first byte of a Version Negotiation packet has any defined value.  The remaining 7 bits, labeled Unused, can be set to any value when sending and MUST be ignored on receipt. After the Source Connection ID field, the Version Negotiation packet contains a list of Supported Version fields, each identifying a version that the endpoint sending the packet supports.  A Version Negotiation packet contains no other fields.  An endpoint MUST ignore a packet that contains no Supported Version fields, or a truncated Supported Version. </ins> Version Negotiation packets do not use integrity or confidentiality protection.  Specific QUIC versions define mechanisms to authenticate
Original text:
If a max_idle_timeout is specified by either peer in its transport parameters (transport-parameter-definitions), the connection is silently closed and its state is discarded when it remains idle for <del> longer than the minimum of both peers max_idle_timeout values and three times the current Probe Timeout (PTO). </del>  Each endpoint advertises a max_idle_timeout, but the effective value at an endpoint is computed as the minimum of the two advertised a packet.  Restarting this timer when sending a packet ensures that connections are not closed after new activity is initiated.  10.2.1. An endpoint that sends packets close to the effective timeout risks

Reviewer comments:
The text as written implied that the actual timeout period was calculated using: This is silly, as 3PTO is usually smaller than the other two values, and connections would time out too fast. Splitting the text regarding the 3PTO backstop makes this clearer.
Wasn't the intended meaning
I can only speak about my intent, but I did not intend to always add 3PTO to the timeout. The text was clearly more confused than I thought.
I actually wasn't sure what you meant before, but this is what I assumed.

Revised text:
If a max_idle_timeout is specified by either peer in its transport parameters (transport-parameter-definitions), the connection is silently closed and its state is discarded when it remains idle for  <ins> longer than the minimum of both peers max_idle_timeout values. </ins> Each endpoint advertises a max_idle_timeout, but the effective value at an endpoint is computed as the minimum of the two advertised a packet.  Restarting this timer when sending a packet ensures that connections are not closed after new activity is initiated. <ins> To avoid excessively small idle timeout periods, endpoints MUST increase the idle timeout period to be at least three times the current Probe Timeout (PTO). </ins> 10.2.1. An endpoint that sends packets close to the effective timeout risks
Original text:
The remainder of the Version Negotiation packet is a list of 32-bit versions which the server supports. <del> A Version Negotiation packet cannot be explicitly acknowledged in an ACK frame by a client.  Receiving another Initial packet implicitly acknowledges a Version Negotiation packet. </del>  The Version Negotiation packet does not include the Packet Number and Length fields present in other packets that use the long header form.

Reviewer comments:
This is a left-over from removing version negotiation from the draft.
by a client. Receiving another Initial packet implicitly acknowledges a Version Negotiation packet. This seems like old text from when we removed real VN. I think that you just need to say that no ACK is required because you only send it in response to Initial.
LGTM

Revised text:
The remainder of the Version Negotiation packet is a list of 32-bit versions which the server supports.  <ins> A Version Negotiation packet is not acknowledged.  It is only sent in response to a packet that indicates an unsupported version; see server-pkt-handling. </ins> The Version Negotiation packet does not include the Packet Number and Length fields present in other packets that use the long header form.
Original text:
or Handshake packets. Section 4 of QUIC-TLS provides more detail about these restrictions. <del> Note that all frames can appear in 1-RTT packets. </del>  The "Spec" column in frame-types summarizes any special rules governing the processing or generation of the frame type, as

Reviewer comments:
error of type FRAMEENCODINGERROR. What about a frame of an impermissible type for this key space?
URL
This seems to only apply to 0-RTT, but there are lots of frames which may not appear in Initial

Revised text:
or Handshake packets. Section 4 of QUIC-TLS provides more detail about these restrictions.  <ins> Note that all frames can appear in 1-RTT packets.  An endpoint MUST treat receipt of a frame in a packet type that is not permitted as a connection error of type PROTOCOL_VIOLATION. </ins> The "Spec" column in frame-types summarizes any special rules governing the processing or generation of the frame type, as
Original text:
The sequence number specified in a RETIRE_CONNECTION_ID frame MUST NOT refer to the Destination Connection ID field of the packet in which the frame is contained.  The peer MAY treat this as a <del> connection error of type FRAME_ENCODING_ERROR. </del>  An endpoint cannot send this frame if it was provided with a zero- length connection ID by its peer.  An endpoint that provides a zero-

Reviewer comments:
This seems like another instance of deciding the scope of "context." Is the packet that the frame arrived in part of the connection context, or is it part of looking at the bytes?
NAME Even if the packet header is part of the context, that still doesn't help. The RETIRECONNECTIONID frame only carries the sequence number, not the actual connection ID. You have to access connection-level information to detect this error, which makes the FRAMEENCODINGERROR a poor choice here.
+1 to what NAME says. In addition this is a "MAY send" error, therefore I do not think we need to be cautious in trying to list all the possible error codes.
Our principle regarding error codes states that only those errors that are detectable without accessing connection state should result in a FRAMEENCODINGERROR. Since the RETIRECONNECTIONID frame contains only the sequence number of the connection ID, but not the actual connection ID itself, this should be a different error. Looking through the list of error codes, it seems like we don't have any more specific error code here, so this would be a PROTOCOL_VIOLATION.
Seems OK.
As the proposed PR indicates, this would be a design change.
Agreed, this seems OK.
As I noted in the PR, I agree that PROTOCOL_VIOLATION seems like a more appropriate error. In addition to NAME point, this is a semantic error, not one of encoding (which suggests syntactic).
It seems we have a proposed resolution, marking as such.
PR was less than a year ago, that's when this error code went from PROTOCOLVIOLATION to FRAMEENCODINGERROR_
I agree that this seems like a more appropriate error. In addition to NAME 's point, I will not that this is a semantic error, not one of encoding (which suggests syntactic).This seems like a more correct error, but I also don't have strong opinions about it.

Revised text:
The sequence number specified in a RETIRE_CONNECTION_ID frame MUST NOT refer to the Destination Connection ID field of the packet in which the frame is contained.  The peer MAY treat this as a  <ins> connection error of type PROTOCOL_VIOLATION. </ins> An endpoint cannot send this frame if it was provided with a zero- length connection ID by its peer.  An endpoint that provides a zero-
Original text:
value.  This Destination Connection ID MUST be at least 8 bytes in length.  Until a packet is received from the server, the client MUST use the same Destination Connection ID value on all packets in this <del> connection.  This Destination Connection ID is used to determine packet protection keys for Initial packets. </del>  The client populates the Source Connection ID field with a value of its choosing and sets the Source Connection ID Length field to

Reviewer comments:
This is better defined elsewhere, but it doesn't hurt to repeat it.
Initial or Retry packet from the server, the client populates the Destination Connection ID field with an unpredictable value. This Destination Connection ID MUST be at least 8 bytes in length. Until a packet is received from the server, the client MUST use the same Destination Connection ID value on all packets in this connection. This Destination Connection ID is used to determine packet protection keys for Initial packets. I had understood that you changed keys for the later initial packets when DCID changed. No?
That is correct. I guess the confusion comes from the "This" in the last sentence. We should make clear which CID it is referring to.
Depends why it changed. Retry starts a new connection attempt, with a new DCID, and new Initial keys. But the Initial keys don't change when the server's Initial provides a new SCID.

Revised text:
value.  This Destination Connection ID MUST be at least 8 bytes in length.  Until a packet is received from the server, the client MUST use the same Destination Connection ID value on all packets in this  <ins> connection. The Destination Connection ID field from the first Initial packet sent by a client is used to determine packet protection keys for Initial packets.  These keys change after receiving a Retry packet; see Section 5.2 of QUIC-TLS. </ins> The client populates the Source Connection ID field with a value of its choosing and sets the Source Connection ID Length field to
Original text:
a client is optionally authenticated, <del> every connection produces distinct and unrelated keys, </del>  keying material is usable for packet protection for both 0-RTT <del> and 1-RTT packets, and 1-RTT keys have forward secrecy </del>  authenticated values for transport parameters of both endpoints, and confidentiality protection for server transport parameters

Reviewer comments:
This claim isn't necessary, as the statement about suitability is what matters here.
S 7. Claims 1-RTT keys have forward secrecy This is only true if you only resume with PSK-(EC)DHE, but I don't see a requirement for this. So we need to either require this or change the text.
This obsession with forward secrecy is a hang-up from Google QUIC. I think that we should instead say that 1-RTT keys are derived from the completed cryptographic handshake instead.

Revised text:
a client is optionally authenticated,  <ins> every connection produces distinct and unrelated keys, and </ins> keying material is usable for packet protection for both 0-RTT  <ins> and 1-RTT packets </ins> authenticated values for transport parameters of both endpoints, and confidentiality protection for server transport parameters
Original text:
Packets with a supported version, or no version field, are matched to a connection using the connection ID or - for packets with zero- <del> length connection IDs - the local address and port.  If the packet doesn't match an existing connection, the server continues below. </del>  If the packet is an Initial packet fully conforming with the specification, the server proceeds with the handshake (handshake).

Reviewer comments:
Not saying explicitly that was a small oversight.
S 5.2.2 says: Packets with a supported version, or no version field, are matched to a connection using the connection ID or - for packets with zero-length connection IDs - the local address and port. If the packet doesn't match an existing connection, the server continues below. So, this tells us what to do if we don't match, but not if we do match. I know this is a nit, but I think there should be some kind of pointer after the first sentence.
LGTM

Revised text:
Packets with a supported version, or no version field, are matched to a connection using the connection ID or - for packets with zero-  <ins> length connection IDs - the local address and port.  These packets are processed using the selected connection, otherwise the server continues below. </ins> If the packet is an Initial packet fully conforming with the specification, the server proceeds with the handshake (handshake).
Original text:
acceptable provided that the features of TLS 1.3 that are used by QUIC are supported by the newer version. <del> A badly configured TLS implementation could negotiate TLS 1.2 or another older version of TLS.  An endpoint MUST terminate the connection if a version of TLS older than 1.3 is negotiated. </del>  4.3.

Reviewer comments:
Just in case this wasn't blindingly obvious.
The TLS spec says: version of TLS. An endpoint MUST terminate the connection if a version of TLS older than 1.3 is negotiated. I would propose that we forbid clients from offering 1.2 or older [and maybe require servers to enforce this].

Revised text:
acceptable provided that the features of TLS 1.3 that are used by QUIC are supported by the newer version.  <ins> Clients MUST NOT offer TLS versions older than 1.3.  A badly configured TLS implementation could negotiate TLS 1.2 or another older version of TLS.  An endpoint MUST terminate the connection if a version of TLS older than 1.3 is negotiated. </ins> 4.3.
Original text:
1. HTTP semantics SEMANTICS are used for a broad range of services on <del> the Internet.  These semantics have most commonly been used with two different TCP mappings, HTTP/1.1 and HTTP/2.  HTTP/3 supports the same semantics over a new transport protocol, QUIC. </del>  1.1. <del> HTTP/1.1 HTTP11 is a TCP mapping which uses whitespace-delimited text fields to convey HTTP messages.  While these exchanges are human- readable, using whitespace for message formatting leads to parsing complexity and motivates tolerance of variant behavior.  Because HTTP/1.x does not include a multiplexing layer, multiple TCP connections are often used to service requests in parallel.  However, that has a negative impact on congestion control and network efficiency, since TCP does not share congestion control across multiple connections. </del>  HTTP/2 HTTP2 introduced a binary framing and multiplexing layer to improve latency without modifying the transport layer.  However,

Reviewer comments:
The introduction is oddly narrow about HTTP/1.1 (and h2) being a TCP mapping, even though HTTP/1.x is commonly used on many different transports and session-layers. In fact, it was specifically designed to not be dependent on TCP so that it could be implemented over every network and every security layer. A simple solution would be to delete that as a description, since it is neither accurate nor useful. It's fine to say that HTTP/3 is specific to QUIC.

Revised text:
1. HTTP semantics SEMANTICS are used for a broad range of services on  <ins> the Internet.  These semantics have most commonly been used with HTTP/1.1, over a variety of transport and session layers, and with HTTP/2 over TLS.  HTTP/3 supports the same semantics over a new transport protocol, QUIC. </ins> 1.1.  <ins> HTTP/1.1 HTTP11 uses whitespace-delimited text fields to convey HTTP messages.  While these exchanges are human-readable, using whitespace for message formatting leads to parsing complexity and excessive tolerance of variant behavior.  Because HTTP/1.x does not include a multiplexing layer, multiple TCP connections are often used to service requests in parallel.  However, that has a negative impact on congestion control and network efficiency, since TCP does not share congestion control across multiple connections. </ins> HTTP/2 HTTP2 introduced a binary framing and multiplexing layer to improve latency without modifying the transport layer.  However,
Original text:
When a stream is closed, this indicates the end of an HTTP message. Because some messages are large or unbounded, endpoints SHOULD begin processing partial HTTP messages once enough of the message has been <del> received to make progress.  If a client stream terminates without enough of the HTTP message to provide a complete response, the server SHOULD abort its response with the error code H3_REQUEST_INCOMPLETE. </del>  A server can send a complete response prior to the client sending an entire request if the response does not depend on any portion of the result of having their request terminated abruptly, though clients can always discard responses at their discretion for other reasons. If the server sends a partial or complete response but does not abort <del> reading, clients SHOULD continue sending the body of the request and close the stream normally. </del>  4.1.1.

Reviewer comments:
client stream should be clearly written as client initiated stream the word which pair of send response is receive request, so its better to be does not abort recieving request here for clearify.
First one is good. The second one is intended to align with Section 2.4 of the transport draft, where "abort reading" is a defined operation on a stream; maybe "does not abort reading the request"?
NAME > "does not abort reading the request" SGTM too

Revised text:
When a stream is closed, this indicates the end of an HTTP message. Because some messages are large or unbounded, endpoints SHOULD begin processing partial HTTP messages once enough of the message has been  <ins> received to make progress.  If a client-initiated stream terminates without enough of the HTTP message to provide a complete response, the server SHOULD abort its response with the error code H3_REQUEST_INCOMPLETE. </ins> A server can send a complete response prior to the client sending an entire request if the response does not depend on any portion of the result of having their request terminated abruptly, though clients can always discard responses at their discretion for other reasons. If the server sends a partial or complete response but does not abort  <ins> reading the request, clients SHOULD continue sending the body of the request and close the stream normally. </ins> 4.1.1.
Original text:
field section, some endpoints could be forced to commit a large amount of available memory for header fields. <del> An endpoint can use the SETTINGS_MAX_HEADER_LIST_SIZE (settings- </del>  parameters) setting to advise peers of limits that might apply on the size of field sections.  This setting is only advisory, so endpoints MAY choose to send field sections that exceed this limit and risk

Reviewer comments:
Replace SETTINGSMAXHEADERLISTSIZE with SETTINGSMAXFIELDSECTIONSIZE in one last place. Add comment to HTTP/2 identifier mapping section about rename.

Revised text:
field section, some endpoints could be forced to commit a large amount of available memory for header fields.  <ins> An endpoint can use the SETTINGS_MAX_FIELD_SECTION_SIZE (settings- </ins> parameters) setting to advise peers of limits that might apply on the size of field sections.  This setting is only advisory, so endpoints MAY choose to send field sections that exceed this limit and risk
Original text:
A client could have received and acknowledged a Handshake packet, causing it to discard state for the Initial packet number space, but not sent any ack-eliciting Handshake packets.  In this case, the PTO <del> is set from the current time. </del>  6.2.3.

Reviewer comments:
This is a rephrase of NAME suggestion.
The pseudo code says the following: With the change introduced in , the spec says the following for the time from which the timer should be armed if there are no outstanding packets in the Handshake packet number space:
This code is called from where Initial keys are discarded, so I believe it still matches the text, which only discusses the "(has handshake keys)" case.
That being said, it feels odd we mention one case of using now() and not the other, so I updated PR
This paragraph does not really provide any context that would allow you to infer what the "current time" is. Based on the pseudocode, this time is when SetLossDetectionTimer() is invoked, but that covers a range of cases: When a packet is received and the endpoint is at its anti-amplification limit When an in-flight packet is sent When an ACK is received When the loss detection timer pops When a packet number space is discarded Of these, the "current time" clause only really applies to the last two, and the last one is the real baseline (because the other only matters if the first was set). I think that this can be more precisely worded to say "In this case, the PTO is set from the time at which the Initial packet number space is discarded." That's far more direct, but I would like others to check my work to ensure that it catches all the cases properly.
Setting the time from when the Initial PN space is discarded is a good clarification, and conveniently it lines up with the pseudocode. The pseudocode for OnPacketNumberSpaceDiscarded(pn_space) calls SetLossDetectionTimer().
There are actually two cases now() is used, so we can't solely rely on handshake keys being discarded. See for a larger change.
This is good, but I wouldn't talk about "current time" at all.

Revised text:
A client could have received and acknowledged a Handshake packet, causing it to discard state for the Initial packet number space, but not sent any ack-eliciting Handshake packets.  In this case, the PTO  <ins> timer is armed from the time that the Initial packet number space is discarded. </ins> 6.2.3.