jiebi/TextFlow huggingface dataset:
Original text:
If packets sent prior to the largest acknowledged packet cannot yet be declared lost, then a timer SHOULD be set for the remaining time. <del> Using max(SRTT, latest_RTT) protects from the two following cases: </del>  <del> the latest RTT sample is lower than the SRTT, perhaps due to reordering where the acknowledgement encountered a shorter path; </del>  <del> the latest RTT sample is higher than the SRTT, perhaps due to a sustained increase in the actual RTT, but the smoothed SRTT has not yet caught up. </del>  The RECOMMENDED time threshold (kTimeThreshold), expressed as a round-trip time multiplier, is 9/8. This document does not specify a pacer, but it is RECOMMENDED that a sender pace sending of all in-flight packets based on input from the congestion controller.  For example, a pacer might distribute the <del> congestion window over the SRTT when used with a window-based </del>  controller, and a pacer might use the rate estimate of a rate-based controller.

Reviewer comments:
In section "Time Threshold", is used for the first time. I guess that would reference the same value before called ? If that's the case they should be named the same. Further down in the same paragraph "smoothed SRTT" is used which is even more confusing. SRTT is used a few more times further down.
There was a cleanup a while ago to ensure definitions such as SRTT happened before use, but that might have been lost in recovery to transport migration?
:+1:

Revised text:
If packets sent prior to the largest acknowledged packet cannot yet be declared lost, then a timer SHOULD be set for the remaining time.  <ins> Using max(smoothed_rtt, latest_rtt) protects from the two following cases: </ins>  <ins> the latest RTT sample is lower than the smoothed RTT, perhaps due to reordering where the acknowledgement encountered a shorter path; </ins>  <ins> the latest RTT sample is higher than the smoothed RTT, perhaps due to a sustained increase in the actual RTT, but the smoothed RTT has not yet caught up. </ins> The RECOMMENDED time threshold (kTimeThreshold), expressed as a round-trip time multiplier, is 9/8. This document does not specify a pacer, but it is RECOMMENDED that a sender pace sending of all in-flight packets based on input from the congestion controller.  For example, a pacer might distribute the  <ins> congestion window over the smoothed RTT when used with a window-based </ins> controller, and a pacer might use the rate estimate of a rate-based controller.
Original text:
Some stream types are reserved (stream-grease).  Two stream types are defined in this document: control streams (control-streams) and push <del> streams (push-streams).  Other stream types can be defined by extensions to HTTP/3; see extensions for more details. </del>  The performance of HTTP/3 connections in the early phase of their lifetime is sensitive to the creation and exchange of data on

Reviewer comments:
The Stream Types registry (URL) currently lists two types only (0 - control, 1 - push). While working on a dissector for the base HTTP/3 protocol, I ran across 2 and 3. It turns out these are defined in the QPACK document (URL) with 2 - QPACK Encoder Stream, 3 - QPACK Decoder Stream. Since QPACK has already been referenced multiple times from the -http document, what about mentioning (or registering) the two codepoints in the -http document and reference to the -qpack document for the definition?
We can, and as QPACK is a required component of HTTP/3, you'd probably need to support QPACK for that to work. However, this is an extensible space and your dissector would need to tolerate other types it might not recognize, or that are added by future extensions. So the fact that there are definitions in other documents not mentioned by HTTP/3 is to be expected.

Revised text:
Some stream types are reserved (stream-grease).  Two stream types are defined in this document: control streams (control-streams) and push  <ins> streams (push-streams).  QPACK defines two additional stream types. Other stream types can be defined by extensions to HTTP/3; see extensions for more details. </ins> The performance of HTTP/3 connections in the early phase of their lifetime is sensitive to the creation and exchange of data on
Original text:
header fields are defined in Section 8.1.2.3 and 8.1.2.4 of HTTP2. Pseudo-header fields are not HTTP header fields.  Endpoints MUST NOT generate pseudo-header fields other than those defined in HTTP2.  The <del> restrictions on the use of pseudo-header fields in Section 8.1.2.1 of HTTP2 also apply to HTTP/3. </del>  HTTP/3 uses QPACK header compression as described in QPACK, a variation of HPACK which allows the flexibility to avoid header-

Reviewer comments:
The constraints of 8.1.2.1 apply to all requests, but I missed that there are additional requirements in 8.1.2.3 for requests and 8.1.2.4 for responses. I've broadened the statement to "the restrictions on the use of pseudo-headers in Section 8.1.2" to sweep them all up. Does anyone think we need pointers to each specific subsection? At Lucas's suggestion, I've also cross-referenced handling of malformed messages here, since those restrictions talk about what is malformed in a given context.
I'm carefully parsing the wording in quic-http sec. 4.1.1 and don't think it's right: In RFC 7540, 8.1.2.1 says This notably does NOT include the further restrictions in 8.1.2.3: I am far from an expert on HTTP headers, but I suspect it's not right that clients could send quantities of :method, :scheme, and :path other than 1. We should probably fix the section reference, though I haven't reviewed 8.1.2 carefully enough to know exactly how that should read.
Good point.
The cited HTTP/2 sections mention malformed requests and response, so we probably also want to add some text to the H3 spec that links to it's section 4.1.3 on how to deal with these.

Revised text:
header fields are defined in Section 8.1.2.3 and 8.1.2.4 of HTTP2. Pseudo-header fields are not HTTP header fields.  Endpoints MUST NOT generate pseudo-header fields other than those defined in HTTP2.  The  <ins> restrictions on the use of pseudo-header fields in Section 8.1.2 of HTTP2 also apply to HTTP/3.  Messages which are considered malformed under these restrictions are handled as described in malformed. </ins> HTTP/3 uses QPACK header compression as described in QPACK, a variation of HPACK which allows the flexibility to avoid header-
Original text:
SETTINGS frame MUST NOT reduce any limits or alter any values that might be violated by the client with its 0-RTT data.  The server MUST include all settings which differ from their default values.  If a <del> server accepts 0-RTT, but then sends a SETTINGS frame which reduces a setting the client understands or omits a value that was previously specified to have a non-default value, this MUST be treated as a connection error of type H3_SETTINGS_ERROR. </del>  7.2.5.

Reviewer comments:
The HTTP draft currently specifies Is it intentional that a client MUST remember SETTINGS values that it doesn't support (to check that the server didn't omit a setting)?
The comment about checking for omitted settings says ... "omits a value that was previously specified to have a non-default value". In order for a client to know what the default value is for that setting, surely the client must support that setting, right?
You're right that for the client to know whether or not it's the default value it needs to support the setting (or at least know about it). Suppose the server sends SETTING BLORP (which the client knows nothing about) with value X in the original SETTINGS, but omits it on the 0-RTT resumed connection. As currently specified, if value X is not the default value, the client MUST close the connection, but if it is the default value, then that's fine. (Meaning the client needs to know all possible default values for all possible settings.) I think this needs an editorial fix to apply something like "a setting the client understands" to the bit about omitting a value as well.
Oh, I see your reading now. Interesting! Good point about an editorial tweak.
I think this could affect reserved settings (aka grease) too, just in a slightly different way. Some editorial tweak to address the problem would be good.

Revised text:
SETTINGS frame MUST NOT reduce any limits or alter any values that might be violated by the client with its 0-RTT data.  The server MUST include all settings which differ from their default values.  If a  <ins> server accepts 0-RTT but then sends settings that are not compatible with the previously specified settings, this MUST be treated as a connection error of type H3_SETTINGS_ERROR.  If a server accepts 0-RTT but then sends a SETTINGS frame that omits a setting value that the client understands (apart from reserved setting identifiers) that was previously specified to have a non-default value, this MUST be treated as a connection error of type H3_SETTINGS_ERROR. </ins> 7.2.5.
Original text:
first request occurs on QUIC stream 0, with subsequent requests on stream 4, 8, and so on.  In order to permit these streams to open, an HTTP/3 server SHOULD configure non-zero minimum values for the number <del> of permitted streams and the initial stream flow control window.  It is RECOMMENDED that at least 100 requests be permitted at a time, so as to not unnecessarily limit parallelism. </del>  HTTP/3 does not use server-initiated bidirectional streams, though an extension could define a use for these streams.  Clients MUST treat

Reviewer comments:
At the interim, we talked about this not being an interop requirement, but "a really good idea" which still warrants RFC2119 language. So, keeping the all-caps, but taking the suggestion to make it active voice.

That was never an interoperability requirement, just a suggestion. So I think that this should be reverted. Originally posted by NAME in URL Look at a better way to phrase this guidance, while still retaining the guidance. (Note this text has also been touched by other PRs in the meantime.)

Revised text:
first request occurs on QUIC stream 0, with subsequent requests on stream 4, 8, and so on.  In order to permit these streams to open, an HTTP/3 server SHOULD configure non-zero minimum values for the number  <ins> of permitted streams and the initial stream flow control window.  So as to not unnecessarily limit parallelism, at least 100 requests SHOULD be permitted at a time. </ins> HTTP/3 does not use server-initiated bidirectional streams, though an extension could define a use for these streams.  Clients MUST treat
Original text:
containing a random payload on the path to be validated. An endpoint MAY send multiple PATH_CHALLENGE frames to guard against <del> packet loss, however an endpoint SHOULD NOT send multiple </del>  PATH_CHALLENGE frames in a single packet.  An endpoint SHOULD NOT send a PATH_CHALLENGE more frequently than it would an Initial packet, ensuring that connection migration is no more load on a new

Reviewer comments:
I really appreciate all of these PRs. It's easy to miss these things with larger changes.

Revised text:
containing a random payload on the path to be validated. An endpoint MAY send multiple PATH_CHALLENGE frames to guard against  <ins> packet loss.  However, an endpoint SHOULD NOT send multiple </ins> PATH_CHALLENGE frames in a single packet.  An endpoint SHOULD NOT send a PATH_CHALLENGE more frequently than it would an Initial packet, ensuring that connection migration is no more load on a new
Original text:
5.4. <del> A Retry or Version Negotiation packet causes a client to send another Initial packet, effectively restarting the connection process and resetting congestion control and loss recovery state, including resetting any pending timers.  Either packet indicates that the Initial was received but not processed.  Neither packet can be treated as an acknowledgment for the Initial. The client MAY however compute an RTT estimate to the server as the time period from when the first Initial was sent to when a Retry or a </del>  Version Negotiation packet is received.  The client MAY use this <del> value to seed the RTT estimator for a subsequent connection attempt to the server. </del>  5.5.

Reviewer comments:
This section was well out of date. Also, this covers what needs to be retained across this transition better. Basically, the only thing that needs to go is the congestion and loss recovery state. The rest can stay; in fact, the crypto handshake has to stay.
Follow-up to . As NAME suggests, we might want to add text to the transport draft that enumerates what is reset: all state except for connection IDs, packet numbers and, optionally, an RTT measurement.
Thanks, nice update!

Revised text:
5.4.  <ins> A Retry packet causes a client to send another Initial packet, effectively restarting the connection process.  A Retry packet indicates that the Initial was received, but not processed.  A Retry packet MUST NOT be treated as an acknowledgment. Clients that receive a Retry packet reset congestion control and loss recovery state, including resetting any pending timers.  Other connection state, in particular cryptographic handshake messages, is retained; see Section 17.2.5 of QUIC-TRANSPORT. The client MAY compute an RTT estimate to the server as the time period from when the first Initial was sent to when a Retry or a </ins> Version Negotiation packet is received.  The client MAY use this  <ins> value in place of its default for the initial RTT estimate. </ins> 5.5.
Original text:
Sending multiple packets into the network without any delay between them creates a packet burst that might cause short-term congestion and losses.  Implementations MUST either use pacing or limit such <del> bursts to the minimum of 10 * kMaxDatagramSize and max(2* kMaxDatagramSize, 14720)), the same as the recommended initial congestion window. </del>  As an example of a well-known and publicly available implementation of a flow pacer, implementers are referred to the Fair Queue packet

Reviewer comments:
From discussion on people prefer the normative text to apply to the initial congestion window, not the specific value recommended in the recovery document. URL
I approve of this editorial change

Revised text:
Sending multiple packets into the network without any delay between them creates a packet burst that might cause short-term congestion and losses.  Implementations MUST either use pacing or limit such  <ins> bursts to the initial congestion window, which is recommended to be the minimum of 10 * kMaxDatagramSize and max(2* kMaxDatagramSize, 14720)). </ins> As an example of a well-known and publicly available implementation of a flow pacer, implementers are referred to the Fair Queue packet
Original text:
them creates a packet burst that might cause short-term congestion and losses.  Implementations MUST either use pacing or limit such bursts to the initial congestion window, which is recommended to be <del> the minimum of 10 * kMaxDatagramSize and max(2* kMaxDatagramSize, 14720)). </del>  As an example of a well-known and publicly available implementation of a flow pacer, implementers are referred to the Fair Queue packet

Reviewer comments:
Clarifies that this is the maximum datagram size currently in use on the connection.
kMaxDatagramSize is currently set to the minimum packet size of 1200 bytes. It should be set instead to the max packet size used by the connection, which is discussed in Section 14.1 of the transport draft. (Issue raised by Timo Völker on the mailing list.)
My reading is that this value is the actual max packet size used in the connection, it's just not clear from the explanation. kInitialWindow and kMinimumWindow are also per-connection fields defined directly below. URL There is one potential detail, which is if the MTU increases after the handshake, do the min CWND and Reno behavior change accordingly? I think it's simpler to reason about them not changing, but I can see both arguments and in the end I don't think it'll matter that much.
WinQuic uses the currently calculated path MTU instead a constant kMaxDatagramSize.

Revised text:
them creates a packet burst that might cause short-term congestion and losses.  Implementations MUST either use pacing or limit such bursts to the initial congestion window, which is recommended to be  <ins> the minimum of 10 * max_datagram_size and max(2* max_datagram_size, 14720)), where max_datagram_size is the current maximum size of a datagram for the connection, not including UDP or IP overhead. </ins> As an example of a well-known and publicly available implementation of a flow pacer, implementers are referred to the Fair Queue packet
Original text:
An indexed header field representation identifies an entry in the static table, or an entry in the dynamic table with an absolute index <del> less than the Base. </del>  This representation starts with the '1' 1-bit pattern, followed by the 'T' bit indicating whether the reference is into the static or An indexed header field with post-base index representation identifies an entry in the dynamic table with an absolute index <del> greater than or equal to the Base. </del>  This representation starts with the '0001' 4-bit pattern.  This is followed by the post-base index (post-base) of the matching header A literal header field with name reference representation encodes a header field where the header field name matches the header field name of an entry in the static table, or the header field name of an <del> entry in the dynamic table with an absolute index less than the Base. </del>  This representation starts with the '01' two-bit pattern.  The following bit, 'N', indicates whether an intermediary is permitted to A literal header field with post-base name reference representation encodes a header field where the header field name matches the header field name of a dynamic table entry with an absolute index greater <del> than or equal to the Base. </del>  This representation starts with the '0000' four-bit pattern.  The fifth bit is the 'N' bit as described in literal-name-reference.

Reviewer comments:
This change has been suggested by afrind at URL on the basis that the Base is a count, and comparing an index to a count feels awkward.

Revised text:
An indexed header field representation identifies an entry in the static table, or an entry in the dynamic table with an absolute index  <ins> less than the value of the Base. </ins> This representation starts with the '1' 1-bit pattern, followed by the 'T' bit indicating whether the reference is into the static or An indexed header field with post-base index representation identifies an entry in the dynamic table with an absolute index  <ins> greater than or equal to the value of the Base. </ins> This representation starts with the '0001' 4-bit pattern.  This is followed by the post-base index (post-base) of the matching header A literal header field with name reference representation encodes a header field where the header field name matches the header field name of an entry in the static table, or the header field name of an  <ins> entry in the dynamic table with an absolute index less than the value of the Base. </ins> This representation starts with the '01' two-bit pattern.  The following bit, 'N', indicates whether an intermediary is permitted to A literal header field with post-base name reference representation encodes a header field where the header field name matches the header field name of a dynamic table entry with an absolute index greater  <ins> than or equal to the value of the Base. </ins> This representation starts with the '0000' four-bit pattern.  The fifth bit is the 'N' bit as described in literal-name-reference.
Original text:
Either the client or server of the connection. The smallest unit of communication on a stream in HTTP/3, <del> consisting of a header and a variable-length sequence of octets </del>  structured according to the frame type.  Protocol elements called "frames" exist in both this document and QUIC-TRANSPORT.  Where frames from QUIC-TRANSPORT are referenced, the frame name will be A variable-length integer that identifies the frame type. <del> A variable-length integer that describes the length of the Frame Payload. </del>  A payload, the semantics of which are determined by the Type field.

Reviewer comments:
Probably a bit overkill, but since it wasn't explicitly stated + I thought we had replaced "octets" with bytes everywhere else.

Revised text:
Either the client or server of the connection. The smallest unit of communication on a stream in HTTP/3,  <ins> consisting of a header and a variable-length sequence of bytes </ins> structured according to the frame type.  Protocol elements called "frames" exist in both this document and QUIC-TRANSPORT.  Where frames from QUIC-TRANSPORT are referenced, the frame name will be A variable-length integer that identifies the frame type.  <ins> A variable-length integer that describes the length in bytes of the Frame Payload. </ins> A payload, the semantics of which are determined by the Type field.
Original text:
client or server MAY advertise support for any of these reserved versions. <del> Reserved version numbers will probably never represent a real protocol; a client MAY use one of these version numbers with the expectation that the server will initiate version negotiation; a server MAY advertise 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.]]

Reviewer comments:
This seems unnecessarily wishy-washy. Either they're reserved by definition, and therefore will never represent a real protocol, or they're available for use. We should remove the "probably" unless there's a good reason to keep it that I'm missing.
Use of that word was entirely intentional. If there is certainty about this status, then it creates a temptation to apply certain optimizations that could be disruptive. What if middleboxes cached Version Negotiation packets from servers and helpfully provided responses to greased connection attempts?
We fear that someone might ossify if they discover that these are definitely not real protocol versions. On the other hand, the thing that breaks is use of these as real protocol versions, which I don't believe we're trying to achieve. If the middlebox is generating accurate VN packets, that seems entirely reasonable (and indistinguishable from actual VN packets). If they're generating inaccurate VN packets, then our anti-downgrade protections that we've decided to implement RSN will break. On the other hand, if these ever are real protocol versions, then a junk grease packet using the reserved version will fail to parse as a valid Initial and will just fail rather than eliciting a VN response. This seems like an impossible battle to win, and a lot of subtlety to expect of middlebox vendors. Write what we mean and move on.

Revised text:
client or server MAY advertise support for any of these reserved versions.  <ins> Reserved version numbers will never represent a real protocol; a client MAY use one of these version numbers with the expectation that the server will initiate version negotiation; a server MAY advertise support for one of these versions and can expect that clients ignore the value. </ins> [[RFC editor: please remove the remainder of this section before publication.]]
Original text:
2.1. <del> The HTTP/3 specification is split into seven parts.  The document begins with a detailed overview of the connection lifecycle and key concepts: </del>  Connection Setup and Management (connection-setup) covers how an HTTP/3 endpoint is discovered and a connection is established.

Reviewer comments:
I count eight including the additional resources or six not including them. But what I'm most concerned about is that Sections 1 and 2 are also part of the HTTP/3 specification.

Revised text:
2.1.  <ins> The following sections provide a detailed overview of the connection lifecycle and key concepts: </ins> Connection Setup and Management (connection-setup) covers how an HTTP/3 endpoint is discovered and a connection is established.