jiebi/TextFlow huggingface dataset:
Original text:
A client SHOULD NOT reuse a NEW_TOKEN token for different connection attempts.  Reusing a token allows connections to be linked by <del> entities on the network path; see migration-linkability.  A client MUST NOT reuse a token if it believes that its point of network attachment has changed since the token was last used; that is, if there is a change in its local IP address or network interface.  A client needs to start the connection process over if there is any change in its local address prior to completing the handshake. </del>  Clients might receive multiple tokens on a single connection.  Aside from preventing linkability, any token can be used in any connection

Reviewer comments:
states: This is an unnecessary constraint and there’s value in not having it. A server can, for example, include multiple IP addresses for a client in a token, enabling client validation from multiple attachment points.
Agreed. Just to give one example, it'd make sense for a server to issue a NEWTOKEN token containing two addresses, if the client is using one path to communicate while having another path being probed and validated. Note also that it is difficult to implement the MUST NOT that exists now. Consider the case where a client receives a NEWTOKEN frame during or after path migration. Is the client expected to bind the token to the old IP address? Or the new address? It is hard to tell the intention of the server.
I agree this seems unnecessary, given tokens cannot be used multiple times. The worst case scenario is including the token increases the number of Initial packets the client needs to send to two packets from one and the token turns out not to be useful for address validation.
As is clear from the PR, this should be marked design.

Revised text:
A client SHOULD NOT reuse a NEW_TOKEN token for different connection attempts.  Reusing a token allows connections to be linked by  <ins> entities on the network path; see migration-linkability. </ins> Clients might receive multiple tokens on a single connection.  Aside from preventing linkability, any token can be used in any connection
Original text:
packets, and the more out-of-order the packets are, the more important it is to send an updated ACK frame quickly, to prevent the peer from declaring a packet as lost and spuriously retransmitting <del> the frames it contains. </del>  ack-tracking and ack-limiting describe an exemplary approach for determining what packets to acknowledge in each ACK frame.

Reviewer comments:
If so, don't serialize the oldest ranges, as previously specified.
This isn't the right section; Section 13.2.4 already has context for this. I'll make a small PR.
NAME In terms of which is the right section, I'll explain my thinking. In my mind, I think of the subsequent two sections as examples of how one could limit ACK frame size, but not really required reading, because I think that's how they were originally written? However, there's quite a bit of normative text in there, so maybe I have an obsolete mental model. An easy alternative to doing what's in those sections is to set a max number of ACK ranges(ie: 3), which I think should be considered acceptable, even if it might not be optimal.
Let's land this and handle any redundancies in an editorial pass along with .
In trying to do a simple fix for , I found other irrelevant or poorly-written recommendations in how a receiver could limit ACK ranges it sends. This section needs to be rewritten. Specifically, the sentence below is a poor recommendation and contradicts earlier recommendation on acking until the ACK frame is acknowledged. The recommendation below is fine, but the rationale does not make sense: This should be a design change.
I'm not in love with this (entire) section either, but I'd like to better understand this issue. I agree that sentence is mis-written, though I think the intent was fine. On the rationale, can you clarify why it does not make sense?
The of the Transport Draft should explain what to do when generated ACK is too large to fit in a packet: Generate a shorter ACK frame (instead of aborting connection or erroring out). To generate the shorter frame, don't include older (smaller) packet numbers. (As opposed to not including newer packet numbers.)
There is a good amount of existing text about what ranges to send, ie "ACK frames SHOULD always acknowledge the most recently received packets," I think this can be solved with some editorial additions to 13.2.2. URL
The text we already have in 13.2.4 has the right context:
Ok, this became a bigger fix. See and .
Seems fine.A few suggestions

Revised text:
packets, and the more out-of-order the packets are, the more important it is to send an updated ACK frame quickly, to prevent the peer from declaring a packet as lost and spuriously retransmitting  <ins> the frames it contains.  An ACK frame is expected to fit within a single QUIC packet.  If it does not, then older ranges (those with the smallest packet numbers) are omitted. </ins> ack-tracking and ack-limiting describe an exemplary approach for determining what packets to acknowledge in each ACK frame.
Original text:
remains acknowledged, even if it does not appear in a future ACK frame.  This is unlike TCP SACKs (RFC2018). <del> It is expected that a sender will reuse the same packet number across different packet number spaces.  ACK frames only acknowledge the packet numbers that were transmitted by the sender in the same packet number space of the packet that the ACK was received in. </del>  Version Negotiation and Retry packets cannot be acknowledged because they do not contain a packet number.  Rather than relying on ACK

Reviewer comments:
by taking NAME suggestion and adding a sentence about how the same PN may be used in each space.
NAME -- PTAL at .
Thanks for the suggestion NAME , accepted.
I have an editorial disagreement here, but as with all such disagreements, I'm happy to go with whatever more people think reads better. I find this use of "numeric value" to be unnecessary. Making it implicit (which is what this sentence is doing) doesn't really change the way a reader consumes this sentence. As a reader, I will replace "numeric value" with "packet number"; there isn't a different definition for packet number that is anything more than the numeric value. At a minimum, I would swap the order of the two sentences.
The contains the following paragraph: I see a few problems with the first sentence: As written, it does not make sense. There is no mention of packet number reuse expectations across packet number spaces in . The connection between it and the sentence that follows is not clear. I propose that the first sentence simply be dropped.
The second sentence can stand some improvement as well: There is no need for the word "only." It is not necessary to say that the ACK frame was received. Packets, not packet numbers, are acknowledged. How about something like this:
Looks good.

Revised text:
remains acknowledged, even if it does not appear in a future ACK frame.  This is unlike TCP SACKs (RFC2018).  <ins> Packets from different packet number spaces can be identified using the same numeric value.  An acknowledgment for a packet needs to indicate both a packet number and a packet number space.  This is accomplished by having each ACK frame only acknowledge packet numbers in the same space as the packet in which the ACK frame is contained. </ins> Version Negotiation and Retry packets cannot be acknowledged because they do not contain a packet number.  Rather than relying on ACK
Original text:
accordingly.  Note that more than one connection ID can be associated with a connection; see connection-id. <del> If the Destination Connection ID is zero length and the packet matches the local address and port of a connection where the endpoint used zero-length connection IDs, QUIC processes the packet as part of that connection. </del>  Endpoints can send a Stateless Reset (stateless-reset) for any packets that cannot be attributed to an existing connection.  A

Reviewer comments:
Make the rules on matching packets to connections consistent with our existing advice on use of zero-length connection IDs. cc NAME for review
: : If only the local address is used, the described multiplexing is impossible. Multiplexing zero-length connection IDs is useful for reducing overhead when remote clients are known to not use the described features, so I think this language should be updated to refer to the 4-tuple rather than only the local connection.
I don't think that these are completely inconsistent, though there is an unstated section in those quotes from Section 5.2: that the implementation has followed the advice and provided a unique local address where it uses a zero-length connection ID. This needs a little care, but we could just remove "local" and this would be OK, but it's probably best to be a little less crude.
I think literally "the packet matches the address and port of a connection" would be much too vague, particularly due to the singular forms used.
Thanks!

Revised text:
accordingly.  Note that more than one connection ID can be associated with a connection; see connection-id.  <ins> If the Destination Connection ID is zero length and the addressing information in the packet matches the addressing information the endpoint uses to identify a connection with a zero-length connection ID, QUIC processes the packet as part of that connection.  An endpoint can use just destination IP and port or both source and destination addresses for identification, though this makes connections fragile as described in connection-id. </ins> Endpoints can send a Stateless Reset (stateless-reset) for any packets that cannot be attributed to an existing connection.  A
Original text:
21.10. <del> This document defines QUIC Version Negotiation packets version- </del>  negotiation, which can be used to negotiate the QUIC version used between two endpoints.  However, this document does not specify how this negotiation will be performed between this version and

Reviewer comments:
Typically we use "in {{}}" or "(see {{}})", so this lines up with that.

Revised text:
21.10.  <ins> This document defines QUIC Version Negotiation packets in version- </ins> negotiation, which can be used to negotiate the QUIC version used between two endpoints.  However, this document does not specify how this negotiation will be performed between this version and
Original text:
example, draft-ietf-quic-http-01 is identified using the string "h3-01".  Non-compatible experiments that are based on these draft versions MUST append the string "-" and an experiment name to the identifier. For example, an experimental implementation based on draft-ietf-quic- 3.3. <del> HTTP/3 relies on QUIC as the underlying transport.  The QUIC version being used MUST use TLS version 1.3 or greater as its handshake </del>  protocol.  HTTP/3 clients MUST indicate the target domain name during the TLS handshake.  This may be done using the Server Name Indication (SNI) RFC6066 extension to TLS or using some other mechanism.

Reviewer comments:
As discussed in Singapore, this ties HTTP/3 to QUIC version 1 until someone writes down how another QUIC version is used.
We've removed the text saying that application protocols can constrain which QUIC versions they can run over. We need to discuss where the correlation between ALPN tokens and version numbers gets considered. Some proposals discussed in Cupertino: ALPN tokens imply one specific QUIC version. This leads to a possible error case, where an ALPN token is offered/accepted over another QUIC version. Application protocols can restrict which QUIC versions they run over. This implies that the QUIC version being spoken must be considered when selecting an ALPN token.
Discussed with NAME this is fine in the TLS draft, but the HTTP/3 draft needs to have a firmer opinion. Right now it says "anything with TLS 1.3".
The discussion in Singapore seemed to end with the conclusion that HTTP/3 would be defined to refer to QUIC version 1 exclusively. But we decided not to answer the broader question of what ALPN actually refers to. That was considered too broad a topic for the QUIC WG to address without involving TLS, HTTP, and others.

Revised text:
example, draft-ietf-quic-http-01 is identified using the string "h3-01". <ins> Draft versions MUST use the corresponding draft transport version as their transport.  For example, the application protocol defined in draft-ietf-quic-http-25 uses the transport defined in draft-ietf- quic-transport-25. </ins> Non-compatible experiments that are based on these draft versions MUST append the string "-" and an experiment name to the identifier. For example, an experimental implementation based on draft-ietf-quic- 3.3.  <ins> HTTP/3 relies on QUIC version 1 as the underlying transport.  The use of other QUIC transport versions with HTTP/3 MAY be defined by future specifications. QUIC version 1 uses TLS version 1.3 or greater as its handshake </ins> protocol.  HTTP/3 clients MUST indicate the target domain name during the TLS handshake.  This may be done using the Server Name Indication (SNI) RFC6066 extension to TLS or using some other mechanism.
Original text:
A sender can make exceptions for probe packets so that their loss detection is independent and does not unduly cause the congestion controller to reduce its sending rate.  An endpoint might set a <del> separate timer when a PATH_CHALLENGE is sent, which is cancelled when </del>  the corresponding PATH_RESPONSE is received.  If the timer fires before the PATH_RESPONSE is received, the endpoint might send a new PATH_CHALLENGE, and restart the timer for a longer period of time.  9.5.

Reviewer comments:
Section 9.4 of draft-ietf-quic-transport: An endpoint might set a separate timer when a PATHCHALLENGE is sent, which is cancelled when the corresponding PATHRESPONSE is received. If the timer fires before the PATHRESPONSE is received, the endpoint might send a new PATHCHALLENGE, and restart the timer for a longer period of time. GF: Possibly so, but what value has this timeout? To avoid potential congestion collapse, I think this needs to be conservative enough to deal with paths with significant RTT variance, or where there is a change of base RTT. 1 sec, then 3 seconds, and then exponentially backed-off would be expected for TCP SYNs, and I suggest could be appropriate.
The suggestion is to move some of this text to recovery(ie: Handshakes and New Paths) and reference that text from transport.
As Jana pointed out, this specifies a separate timer, which fits fine with the model that there's one timer per path.
This can be simpler -- just add the new sentence. I've made suggestions.

Revised text:
A sender can make exceptions for probe packets so that their loss detection is independent and does not unduly cause the congestion controller to reduce its sending rate.  An endpoint might set a  <ins> separate timer when a PATH_CHALLENGE is sent, which is cancelled if </ins> the corresponding PATH_RESPONSE is received.  If the timer fires before the PATH_RESPONSE is received, the endpoint might send a new PATH_CHALLENGE, and restart the timer for a longer period of time. <ins> This timer SHOULD be set as described in Section 5.3 of QUIC-RECOVERY and MUST NOT be more aggressive. </ins> 9.5.
Original text:
5.5. <del> When packet protection keys are discarded (see Section 4.9 of QUIC- </del>  TLS), all packets that were sent with those keys can no longer be acknowledged because their acknowledgements cannot be processed anymore.  The sender MUST discard all recovery state associated with It is expected that keys are discarded after packets encrypted with them would be acknowledged or declared lost.  Initial secrets however might be destroyed sooner, as soon as handshake keys are available <del> (see Section 4.9.1 of QUIC-TLS). </del>  6. packet.  Though packets might still be in flight or awaiting acknowledgment, no further Initial packets need to be exchanged beyond this point.  Initial packet protection keys are discarded (see <del> Section 4.9.1 of QUIC-TLS) along with any loss recovery and </del>  congestion control state (see Section 6.5 of QUIC-RECOVERY). Any data in CRYPTO frames is discarded - and no longer retransmitted

Reviewer comments:
and 4.9.1 are now 4.10 and 4.10.1, I believe.

Revised text:
5.5.  <ins> When packet protection keys are discarded (see Section 4.10 of QUIC- </ins> TLS), all packets that were sent with those keys can no longer be acknowledged because their acknowledgements cannot be processed anymore.  The sender MUST discard all recovery state associated with It is expected that keys are discarded after packets encrypted with them would be acknowledged or declared lost.  Initial secrets however might be destroyed sooner, as soon as handshake keys are available  <ins> (see Section 4.10.1 of QUIC-TLS). </ins> 6. packet.  Though packets might still be in flight or awaiting acknowledgment, no further Initial packets need to be exchanged beyond this point.  Initial packet protection keys are discarded (see  <ins> Section 4.10.1 of QUIC-TLS) along with any loss recovery and </ins> congestion control state (see Section 6.5 of QUIC-RECOVERY). Any data in CRYPTO frames is discarded - and no longer retransmitted
Original text:
13.2.5. An endpoint measures the delays intentionally introduced between when <del> an ack-eliciting packet is received and the corresponding acknowledgment is sent.  The endpoint encodes this delay for the largest acknowledged packet in the Ack Delay field of an ACK frame (see frame-ack).  This allows the receiver of the ACK to adjust for any intentional delays, which is important for getting a better estimate of the path RTT when acknowledgments are delayed.  A packet might be held in the OS kernel or elsewhere on the host before being processed.  An endpoint MUST NOT include delays that is does not control when populating the Ack Delay field in an ACK frame. </del>  13.2.6.

Reviewer comments:
From Timo Völker's comment on the QUIC mailing list. There might be a better way to state this, but I think this is more accurate.

Revised text:
13.2.5. An endpoint measures the delays intentionally introduced between when  <ins> the packet with the largest packet number is received and an acknowledgment is sent.  The endpoint encodes this delay in the Ack Delay field of an ACK frame (see frame-ack).  This allows the receiver of the ACK to adjust for any intentional delays, which is important for getting a better estimate of the path RTT when acknowledgments are delayed.  A packet might be held in the OS kernel or elsewhere on the host before being processed.  An endpoint MUST NOT include delays that it does not control when populating the Ack Delay field in an ACK frame. </ins> 13.2.6.
Original text:
(i.e. 2^62-4 in case of QUIC version 1).  This GOAWAY frame signals to the client that shutdown is imminent and that initiating further requests is prohibited.  After allowing time for any in-flight <del> requests (at least one round-trip time), the server would send another GOAWAY frame with an updated last Stream ID.  This ensures that a connection can be cleanly shut down without causing requests to fail. </del>  Once all accepted requests have been processed, the server can permit the connection to become idle, or MAY initiate an immediate closure

Reviewer comments:
using mostly the text proposed in that issue.
On NAME proposes a change to GOAWAY that reduces the exposure of the QUIC API to HTTP/3. The paragraph in question also suggests behaviour that relies on exposure of QUIC transport information: . This seems to be the only occurence of round-trip time in the HTTP/3 document. I think we can editorialize ourselves out of this. For some HTTP/3 implementations, the RTT could be readily accessible, for others maybe not.
The other issue of the last two sentences (quoted below) is that they do not suggest how an endpoint should choose last Stream ID of the second GOAWAY frame.
Regarding how we should change, maybe something like below would be sufficient. My observation is that we can drop "at least one round-trip time" because the text that directly precede that implies that already. "After allowing time for any in-flight requests to reach the server, the server MAY send another GOAWAY frame that carries the greatest request stream ID it has seen. This ensures that a connection can be cleanly shut down without losing requests."
The text implies a little bit of interaction with the QUIC Stream ID space. Because we had to change GOAWAY to signal the first unprocessed Stream ID, the HTTP layer needs to be able to get "the next" stream ID from QUIC in a given space. But as to the general issue, I don't object to removing the specific dependency; anyone reading should be able to conclude that you need to allow an RTT for the requests to arrive, and if they have access to that value, they'll use it.
Seems alright.Thanks!

Revised text:
(i.e. 2^62-4 in case of QUIC version 1).  This GOAWAY frame signals to the client that shutdown is imminent and that initiating further requests is prohibited.  After allowing time for any in-flight  <ins> requests to reach the server, the server can send another GOAWAY frame indicating which requests it will accept before the end of the connection.  This ensures that a connection can be cleanly shut down without causing requests to fail. </ins> Once all accepted requests have been processed, the server can permit the connection to become idle, or MAY initiate an immediate closure
Original text:
samples, estimated using a mean variation. The calculation of smoothed_rtt uses path latency after adjusting RTT <del> samples for ACK delays.  For packets sent in the ApplicationData packet number space, a peer limits any delay in sending an acknowledgement for an ack-eliciting packet to no greater than the value it advertised in the max_ack_delay transport parameter. Consequently, when a peer reports an Ack Delay that is greater than its max_ack_delay, the delay is attributed to reasons out of the peer's control, such as scheduler latency at the peer or loss of previous ACK frames.  Any delays beyond the peer's max_ack_delay are therefore considered effectively part of path delay and incorporated into the smoothed_rtt estimate. </del>  When adjusting an RTT sample using peer-reported acknowledgement delays, an endpoint:

Reviewer comments:
Notes that ack delays are right shifted by ackdelayexponent when transmitted in ACK frames.
The recovery draft currently assumes you've already applied the ack delay exponent. It should spell that out explicitly so readers of the draft don't miss it. Ideally it'd be obvious if you just read transport, but that's a long draft, so there's no harm in stating it again. From an on-list comment by Timo Völker
Lgtm

Revised text:
samples, estimated using a mean variation. The calculation of smoothed_rtt uses path latency after adjusting RTT  <ins> samples for acknowledgement delays.  These delays are computed using the ACK Delay field of the ACK frame as described in Section 19.3 of QUIC-TRANSPORT.  For packets sent in the ApplicationData packet number space, a peer limits any delay in sending an acknowledgement for an ack-eliciting packet to no greater than the value it advertised in the max_ack_delay transport parameter.  Consequently, when a peer reports an Ack Delay that is greater than its max_ack_delay, the delay is attributed to reasons out of the peer's control, such as scheduler latency at the peer or loss of previous ACK frames.  Any delays beyond the peer's max_ack_delay are therefore considered effectively part of path delay and incorporated into the smoothed_rtt estimate. </ins> When adjusting an RTT sample using peer-reported acknowledgement delays, an endpoint: