jiebi/TextFlow huggingface dataset:
Original text:
server from repeated client probes, the PTO backoff is not reset at a client that is not yet certain that the server has finished validating the client's address.  That is, a client does not reset <del> the PTO backoff factor on receiving acknowledgements until the handshake is confirmed; see Section 4.1.2 of QUIC-TLS. </del>  This exponential reduction in the sender's rate is important because consecutive PTOs might be caused by loss of packets or

Reviewer comments:
If you receive a handshake ACK, then the server has validated the client's address, so it's really only Initial ACKs.
I think this is good.
There is an inconsistency in URL w.r.t. resetting PTO backoff factor. Section 6.2.1: This suggests that for a client to be certain that the server has finished validating the client's address, the handshake should have been confirmed. However, the pseudo code uses PeerCompletedAddressValidation to determine whether to reset pto-count and PeerCompletedAddressValidation also checks for Handshake ACK received. That is not what the text in 6.2.1 says, as, according to URL, the handshake is confirmed when HANDSHAKEDONE is received or when a 1-RTT ack is received. That is a subtle difference. As kazu noted in the discussion on Slack, Sec 8.1 of QUIC says: "Once the server has successfully processed a Handshake packet from the client, it can consider the client address to have been validated.", so, the client can consider that the server validated the client address when either ACK in Handshake or HANDSHAKEDONE in 1-RTT is received. (See Figure 5 of TLS.) Hence, the pseudocode seems to be correct and that means the text in 6.2.1 should be corrected.
Thanks for filing this, I think the new text is simpler anyway.

Revised text:
server from repeated client probes, the PTO backoff is not reset at a client that is not yet certain that the server has finished validating the client's address.  That is, a client does not reset  <ins> the PTO backoff factor on receiving acknowledgements in Initial packets. </ins> This exponential reduction in the sender's rate is important because consecutive PTOs might be caused by loss of packets or
Original text:
Prior to making requests for an origin whose scheme is not "https", the client MUST ensure the server is willing to serve that scheme. <del> If the client intends to make requests for an origin whose scheme is "http", this means that it MUST obtain a valid "http-opportunistic" response for the origin as described in RFC8164 prior to making any such requests.  Other schemes might define other mechanisms. </del>  3.3.

Reviewer comments:
Text was already given the thumbs-up on the issue, so merging without waiting for review.
Section 3.2.2 states: "Prior to making requests for an origin whose scheme is not "https", the client MUST ensure the server is willing to serve that scheme. If the client intends to make requests for an origin whose scheme is "http", this means that it MUST obtain a valid http-opportunistic response for the origin as described in [RFC8164] prior to making any such requests. Other schemes might define other mechanisms." The first issue is that this text make normative use of RFC8164 to handle "http" scheme. RFC8164 is an experimental RFC. Thus we have a downref issue. I think it would be inappropriate to elevate RFC8164 status by allowing a downref here. I think one option would be to move the specification of the usage of RFC 8164 for the "http" URI scheme in HTTP/3 into its own experimental RFC. Another potential option is to simply inform about the ongoing experiment without specifying that it can be done with HTTP/3. Secondly, I am uncertain about the scope of the first sentence in that paragraph. Is there any other URI schemes other than "http" that this is applicable for? If it is which type of URI schemes is it applicable for? For clearly it is not applicable to the "rtsp" scheme that isn't using HTTP at all.
Second point first: HTTP doesn't restrict the scheme of URIs a client can request; URI schemes define what protocols can be used to access them, which might or might not include HTTP. For example, RFC7540 says: ":scheme" is not restricted to "http" and "https" schemed URIs. A proxy or gateway can translate requests for non-HTTP schemes, enabling the use of HTTP to interact with non-HTTP services. To the first point, I feel like not mentioning that RFC8164 can be done with HTTP/3 means it's irrelevant to include in this document, and the requirement to verify the peer can serve a scheme is necessary. Perhaps something like:
The proposed text looks good. I think that resolves it and you can move RFC8164 to be a informational ref. So I think this resolves my issue.
Based on this resolution, labeling this as "editorial"

Revised text:
Prior to making requests for an origin whose scheme is not "https", the client MUST ensure the server is willing to serve that scheme.  <ins> For origins whose scheme is "http", an experimental method to accomplish this is described in RFC8164.  Other mechanisms might be defined for various schemes in the future. </ins> 3.3.
Original text:
has already ended, the server MAY still abruptly terminate the stream or MAY take no action. <del> When a server sends CANCEL_PUSH, it is indicating that it will not be fulfilling a promise.  The client cannot expect the corresponding promise to be fulfilled, unless it has already received and processed the promised response.  A server SHOULD send a CANCEL_PUSH frame even if it has opened the corresponding stream. </del>  Sending a CANCEL_PUSH frame has no direct effect on the state of existing push streams.  A client SHOULD NOT send a CANCEL_PUSH frame

Reviewer comments:
In Section 7.2.3: URL A server SHOULD send a CANCELPUSH frame even if it has opened the corresponding stream. Is the intention that this sentence should have this meaning? "A server that has opened a stream for a PUSH and is unable to fulfill this promise SHOULD send a CANCEL_PUSH frame with the corresponding Push ID." I think as currently formulated it is missing the criteria as well when this may occur. Secondly the alternative is also not clear. I assume this is a SHOULD as the stream can be reset with an error code? Does that need to be added and which error will be used? Especially as the next paragraph only discusses that the client SHOULD abort reading. Can't the server terminate the stream from its side? If only the later is allowed, I think that should be made explicit but appears unnecessary.
To the second question, stating clearly that the server can abort the Push stream with H3REQUESTCANCELLED seems like a good improvement.
Looking at the larger paragraph, the point is that there are two possible states when a server decides not to fulfill a push: a. No stream has been created; CANCELPUSH is sufficient. b. A stream has been created. The server could simply reset the stream; this is valid, but risks the client processing the RESET before learning the Push ID, so it won't know which Push ID is no longer being fulfilled. Better if the server both resets the stream and sends a CANCELPUSH. You're right that this could be reworded to emphasize that you always send CANCEL_PUSH if you're not fulfilling a promise, and also close the stream if you've opened one.
This seems like the right framing. But everything seems to correspond.

Revised text:
has already ended, the server MAY still abruptly terminate the stream or MAY take no action.  <ins> A server sends CANCEL_PUSH to indicate that it will not be fulfilling a promise which was previously sent.  The client cannot expect the corresponding promise to be fulfilled, unless it has already received and processed the promised response.  Regardless of whether a push stream has been opened, a server SHOULD send a CANCEL_PUSH frame when it determines that promise will not be fulfilled.  If a stream has already been opened, the server can abort sending on the stream with an error code of H3_REQUEST_CANCELLED. </ins> Sending a CANCEL_PUSH frame has no direct effect on the state of existing push streams.  A client SHOULD NOT send a CANCEL_PUSH frame
Original text:
Section 22.1.1 of QUIC-TRANSPORT. The initial allocations in these registries created in this document <del> are all assigned permanent status and list as contact both the IESG (iesg@ietf.org) and the HTTP working group (ietf-http-wg@w3.org). </del>  11.2.1.

Reviewer comments:
NAME see .
Section 11.2: URL "The initial allocations in these registries created in this document are all assigned permanent status and list as contact both the IESG (EMAIL) and the HTTP working group (EMAIL)." From my perspective it is better to have IETF as change controller. In practice that would mean that any chartered WG to work on this registry would by completing the IETF process be allowed to introduce changes to the registry. Having HTTP Working Group as contact is fine. So I would propose to change this to: "The initial allocations in these registries created in this document are all assigned permanent status and list as change controller the IETF and the HTTP working group (EMAIL) as contact."

Revised text:
Section 22.1.1 of QUIC-TRANSPORT. The initial allocations in these registries created in this document  <ins> are all assigned permanent status and list as contact both the IETF and the HTTP working group (ietf-http-wg@w3.org). </ins> 11.2.1.
Original text:
The date of last update to the registration.  Contact details for the registrant. Supplementary notes about the registration. permanent. All registrations in this document are assigned a permanent status <del> and list as contact the IETF (quic@ietf.org). </del>  22.2. Section 22.1.1 of QUIC-TRANSPORT. The initial allocations in these registries created in this document <del> are all assigned permanent status and list as contact both the IETF and the HTTP working group (ietf-http-wg@w3.org). </del>  11.2.1.

Reviewer comments:
At NAME suggestion this adds a "change controller" field to registries and splits between a change controller (IETF) and contact (QUIC WG). Not really sure if this is worth a design label...
Section 22.1.1: It is quite common that one may want to separate who has the change control over an registration entry vs who is the contact. Change control can often be assigned to an organization rather than an individual while a contact information may be an individual or a specific contact address for the organization. Contact information has a tendency to get stale, and in many case the contact if a person may no longer represent the organization that made the registration. Thus, my suggestion would be to add a separation between contact and change controller. In fact just for the registration in the Transport doc it makes sense to make the change controller "IETF" and have the contact be "QUIC WG".
This also applies to permanent registrations in Section 22.1.4
NAME does the PR address your issue?
Change looks good and implements what I proposed.
Labeling as "editorial" based on

Revised text:
The date of last update to the registration. <ins> The entity that is responsible for the definition of the registration. </ins> Contact details for the registrant. Supplementary notes about the registration. permanent. All registrations in this document are assigned a permanent status  <ins> and list a change controller of the IETF and a contact of the QUIC working group (quic@ietf.org). </ins> 22.2. Section 22.1.1 of QUIC-TRANSPORT. The initial allocations in these registries created in this document  <ins> are all assigned permanent status and list a change controller of the IETF and a contact of the HTTP working group (ietf-http-wg@w3.org). </ins> 11.2.1.
Original text:
fields; this document uses "fields" for generality. A name-value pair sent as part of an HTTP field section.  See <del> Section 5 of SEMANTICS. </del>  Data associated with a field name, composed from all field line values with that field name in that section, concatenated together

Reviewer comments:
Section 1.1: HTTP field line: A name-value pair sent as part of an HTTP field section. See Section 5 of [SEMANTICS]. I would guess that this can be refined to point to section 5.4.
Proposed change is "editorial".

Revised text:
fields; this document uses "fields" for generality. A name-value pair sent as part of an HTTP field section.  See  <ins> Section 5.4 and Section 5.6 of SEMANTICS. </ins> Data associated with a field name, composed from all field line values with that field name in that section, concatenated together
Original text:
Pseudo-header fields are not HTTP fields.  Endpoints MUST NOT generate pseudo-header fields other than those defined in this <del> document, except as negotiated via an extension; see extensions. </del>  Pseudo-header fields are only valid in the context in which they are defined.  Pseudo-header fields defined for requests MUST NOT appear

Reviewer comments:
Taken from NAME suggestion on the list.
On the mailing list NAME raised a question about pseudo-headers. That discussion seemed to identify that HTTP/3 oversteps the mark by saying that psuedo-headers are extensible. We can make an editorial change to bring this back to something equivalent to what RFC 7540 says. See .
Conversation evolved, I''ve created a PR that takes Mike's suggestion.

Revised text:
Pseudo-header fields are not HTTP fields.  Endpoints MUST NOT generate pseudo-header fields other than those defined in this  <ins> document; however, an extension could negotiate a modification of this restriction; see extensions. </ins> Pseudo-header fields are only valid in the context in which they are defined.  Pseudo-header fields defined for requests MUST NOT appear
Original text:
(indicating whether the string is Huffman-coded), followed by the Length encoded as a 7-bit prefix integer, and finally Length bytes of data.  When Huffman encoding is enabled, the Huffman table from <del> Appendix B of RFC7541 is used without modification. </del>  This document expands the definition of string literals by permitting them to begin other than on a byte boundary.  An "N-bit prefix string <del> literal" begins with the same Huffman flag, followed by the length encoded as an (N-1)-bit prefix integer.  The prefix size, N, can have a value between 2 and 8 inclusive.  The remainder of the string literal is unmodified. </del>  A string literal without a prefix length noted is an 8-bit prefix string literal and follows the definitions in RFC7541 without

Reviewer comments:
Section 4.1.2: Although this is summary of the definition in HPACK, where this issue is clear I think this document should describe things corretly. HPACK defines string literals to begin on a byte boundary. They begin with a single bit flag, denoted as 'H' in this document (indicating whether the string is Huffman-coded), followed by the Length encoded as a 7-bit prefix integer, and finally Length bytes of data. When Huffman encoding is enabled, the Huffman table from Appendix B of [RFC7541] is used without modification. The length field as described here, provides an uncertainty if it is the data pre huffman (if applied) encoding or post encoding. HPACK is clear that it is the later. Can you please clarify that the length if the length of the encoded string that is encoded using N-bit prefix integer encoding. "An "N-bit prefix string literal" begins with the same Huffman flag, followed by the length encoded as an (N-1)-bit prefix integer." This definition if it is the byte or the prefix field that begins with the huffman flag. I would guess that what is meant is that a 6-bit prefix string literal would have a start byte of "??Hxxxxx" rather than "H??xxxxx".
This would be an "editorial" change.
Yes, the latter is correct. A prefixed string literal does not begin on a byte boundary; the first bit (when it begins) is the Huffman bit, and the remainder is a prefixed integer.

Revised text:
(indicating whether the string is Huffman-coded), followed by the Length encoded as a 7-bit prefix integer, and finally Length bytes of data.  When Huffman encoding is enabled, the Huffman table from  <ins> Appendix B of RFC7541 is used without modification and Length indicates the size of the string after encoding. </ins> This document expands the definition of string literals by permitting them to begin other than on a byte boundary.  An "N-bit prefix string  <ins> literal" begins mid-byte, with the first (8-N) bits allocated to a previous field.  The string uses one bit for the Huffman flag, followed by the Length encoded as an (N-1)-bit prefix integer.  The prefix size, N, can have a value between 2 and 8 inclusive.  The remainder of the string literal is unmodified. </ins> A string literal without a prefix length noted is an 8-bit prefix string literal and follows the definitions in RFC7541 without
Original text:
For example:  2. Streams in QUIC provide a lightweight, ordered byte-stream

Reviewer comments:
are encoded as variable-length integers; see Section 16. A QUIC endpoint MUST NOT reuse a stream ID within a connection. This was a common problem throughout the text. I found the use of (0x1) and similar confusing in the text. Where you use this notation you mean the bit manipulated by the mask 0x1 (and similar). It would be helpful to the reader to be a little more pedantic in the use of the term in each case. We will get to it later, in the comments but a lot of readers would be helped by the use of the classic ASCII art style representation of bit fields.
slightly more text

Revised text:
For example: <ins> When a single-bit field is referenced in prose, the position of that field can be clarified by using the value of the byte that carries the field with the field's value set.  For example, the value 0x80 could be used to refer to the single-bit field in the most significant bit of the byte, such as One-bit Field in fig-ex-format. </ins> 2. Streams in QUIC provide a lightweight, ordered byte-stream
Original text:
The maximum datagram size is defined as the largest size of UDP payload that can be sent across a network path using a single UDP <del> datagram. QUIC depends upon a minimum IP packet size of at least 1280 bytes. This is the IPv6 minimum size (IPv6) and is also supported by most modern 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 bytes for IPv4. The maximum datagram size MUST be at least 1200 bytes. </del>  Any maximum datagram size larger than 1200 bytes can be discovered using Path Maximum Transmission Unit Discovery (PMTUD; see pmtud) or

Reviewer comments:
On endpoints.
This is the IPv6 minimum size ([IPv6]) and is also supported by most modern 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 bytes for IPv4. The previous two paras are quite confusing. I think the first para refers to the max packet size in the network layer, but the second para is not clear, nor is the next para.
The paragraph preceding the first is this: So it is clear what the second paragraph means. QUIC doesn't operate if the network is incapable of carrying a datagram payload of 1200 bytes. I think that rewording that way might help. What is less clear is where the extra 32 (or 52) bytes go. In that we've been very generous in providing for header extensions or UDP extensions. But I don't see a need to explain that aspect.
I found this to still be very confusing, FWIW. It's unclear why the limit would be 1200 bytes when the text very clearly explains that at least 1232 can be relied upon, or alternatively why the text claims "QUIC assumes a minimum IP packet size of at least 1280 bytes." when in fact it appears to only mandate a 32 bytes smaller figure. It reads like someone forgot to update a constant. NAME above suggests that this was intentional, to leave space for unspecified future use by lower layers. I think some allusion to this is justified, just to clarify the otherwise seeming inconsistency.
A sentence to tie it together but LGTM

Revised text:
The maximum datagram size is defined as the largest size of UDP payload that can be sent across a network path using a single UDP  <ins> datagram.  QUIC MUST NOT be used if the network path cannot support a maximum datagram size of at least 1200 bytes. QUIC assumes a minimum IP packet size of at least 1280 bytes.  This is the IPv6 minimum size (IPv6) and is also supported by most modern 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 bytes for IPv4.  Thus, modern IPv4 and all IPv6 network paths will 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:
RETIRE_CONNECTION_ID frame (frame-retire-connection-id). An endpoint that receives packets that it cannot process sends a <del> packet in the following layout: </del>  This design ensures that a stateless reset packet is - to the extent possible - indistinguishable from a regular packet with a short

Reviewer comments:
Fixed Bits (2) = 1, Unpredictable Bits (38..), Stateless Reset Token (128), } When I first met this my reaction was that I was sure it sends a lot more bits on the wire than this, but so far I have not see a packet definition nor a pointer to a packet definition. Please could you clarify what is happening?
This seems like a nit. I guess the only thing being that this is the first time the notation introduced in Section 1.3 is used. And now it is Section 10.3. I'll add a cross reference.

Revised text:
RETIRE_CONNECTION_ID frame (frame-retire-connection-id). An endpoint that receives packets that it cannot process sends a  <ins> packet in the following layout (see notation): </ins> This design ensures that a stateless reset packet is - to the extent possible - indistinguishable from a regular packet with a short