jiebi/TextFlow huggingface dataset:
Original text:
3.2. The dynamic table consists of a list of field lines maintained in <del> first-in, first-out order.  Each HTTP/3 endpoint holds a dynamic table that is initially empty.  Entries are added by encoder instructions received on the encoder stream; see encoder- instructions. </del>  The dynamic table can contain duplicate entries (i.e., entries with the same name and same value).  Therefore, duplicate entries MUST NOT The size of the dynamic table is the sum of the size of its entries. The size of an entry is the sum of its name's length in bytes, its <del> value's length in bytes, and 32.  The size of an entry is calculated using the length of its name and value without Huffman encoding applied. </del>  3.2.2.

Reviewer comments:
I opted to reframe the language from HTTP/3 endpoint to decoder, since encoder and decoder instances are what this spec primarily talks about. We already say that HTTP/3 endpoints contain both an encoder and a decoder. I also added a comment that encoders track the contents of the table at the decoder. I specifically did not say that they keep a full copy of the table, however; they might not.
NAME said:
NAME said:

Revised text:
3.2. The dynamic table consists of a list of field lines maintained in  <ins> first-in, first-out order.  A QPACK encoder and decoder share a dynamic table that is initially empty.  The encoder adds entries to the dynamic table and sends them to the decoder via instructions on the encoder stream; see encoder-instructions. </ins> The dynamic table can contain duplicate entries (i.e., entries with the same name and same value).  Therefore, duplicate entries MUST NOT The size of the dynamic table is the sum of the size of its entries. The size of an entry is the sum of its name's length in bytes, its  <ins> value's length in bytes, and 32 additional bytes.  The size of an entry is calculated using the length of its name and value without Huffman encoding applied. </ins> 3.2.2.
Original text:
Indicates that x can be any length from A to B; A can be omitted to indicate a minimum of zero bits and B can be omitted to <del> indicate no set upper limit; values in this format always end on an byte boundary </del>  Indicates that x, with a length described by L, has a fixed value of C Indicates that x can be any length from A to B; A can be omitted to indicate a minimum of zero bits and B can be omitted to <del> indicate no set upper limit; values in this format always end on an byte boundary </del>  Indicates that x has a fixed value of C with the length described by L, which can use any of the three length forms above

Reviewer comments:
Draft 34 changed notation from "octet" to "byte" in a few places, but forgot to change the article in two places.
Thanks, NAME

Revised text:
Indicates that x can be any length from A to B; A can be omitted to indicate a minimum of zero bits and B can be omitted to  <ins> indicate no set upper limit; values in this format always end on a byte boundary </ins> Indicates that x, with a length described by L, has a fixed value of C Indicates that x can be any length from A to B; A can be omitted to indicate a minimum of zero bits and B can be omitted to  <ins> indicate no set upper limit; values in this format always end on a byte boundary </ins> Indicates that x has a fixed value of C with the length described by L, which can use any of the three length forms above
Original text:
RTT samples for the network path are recorded in latest_rtt; see latest-rtt.  On the first RTT sample after initialization, the estimator is reset using that sample.  This ensures that the <del> estimator retains no history of past samples. </del>  On the first RTT sample after initialization, smoothed_rtt and rttvar are set as follows: only packets being sent, but this document does not describe a mechanism for doing so.  The algorithm in this document specifies and uses the controller's congestion window in bytes.

Reviewer comments:
From the transport draft's connection migration section.
Section 9.4 in Transport(URL) does a nice job of explaining the RTT and congestion control implications of migration, but given one might reasonably expect some or all of that text to exist in recovery, I think it makes sense to reference it more. In particular, "Packets sent on the old path MUST NOT contribute to congestion control or RTT estimation for the new path." is a useful sentence.

Revised text:
RTT samples for the network path are recorded in latest_rtt; see latest-rtt.  On the first RTT sample after initialization, the estimator is reset using that sample.  This ensures that the  <ins> estimator retains no history of past samples.  Packets sent on other paths do not contribute RTT samples to the current path, as described in Section 9.4 of QUIC-TRANSPORT. </ins> On the first RTT sample after initialization, smoothed_rtt and rttvar are set as follows: only packets being sent, but this document does not describe a mechanism for doing so. <ins> The congestion controller is per path, so packets sent on other paths do not alter the current path's congestion controller, as described in Section 9.4 of QUIC-TRANSPORT. </ins> The algorithm in this document specifies and uses the controller's congestion window in bytes.
Original text:
Because the setting has no defined meaning, the value of the setting can be any value the implementation selects. <del> Setting identifiers which were used in HTTP/2 where there is no </del>  corresponding HTTP/3 setting have also been reserved (iana-settings). <del> These settings MUST NOT be sent, and their receipt MUST be treated as a connection error of type H3_SETTINGS_ERROR. </del>  Additional settings can be defined by extensions to HTTP/3; see extensions for more details.

Reviewer comments:
Specifically those defined in RFC 7540.
URL says: The table of defined HTTP/3 settings is in URL The diverges a little bit from everything that is stated in RFC 7540. is stated as reserved in IANA but no mention of it in RFC 7540. Therefore it is ambiguous if an HTTP/3 implementation should reject this Type value. The range is reserved for HTTP/2 experimental use. Its not clear if I should reject those too. IANA also includes some extension settings: (RFC 8441), 0x10 (MS-HTTP2E). I might expect to be reused by some extension that defines Websocket over H3. seems like something that is not reusable? And finally, we have Extensible Priorities that defines SETTINGSDEPRECATEHTTP2_PRIORITIES and wants to claim . I don't expect any need to also define that in HTTP/3 settings, unless the purpose is to prohibit it. In summary, I don't think there is a huge problem. Maybe we can editorialize our way out of the ambiguity. However, I'd really like to avoid H/3 connections instantly failing due to implementations disagreeing about this rejection requirement.
I overlooked that NAME already made the point about in .
The intent is to reserve things that are defined in 7540; things reserved by other extensions might later be defined for HTTP/3, so there shouldn't be any assumptions. Let's make that requirement crisper to apply specifically to those values explicitly reserved.
WfM
I wonder if we should ask IANA if they can tell how it came to be that 0x0 was marked as reserved with 7540 as the reference even though we are failing to see what part of 7540 should be effectuating that.

Revised text:
Because the setting has no defined meaning, the value of the setting can be any value the implementation selects.  <ins> Setting identifiers which were defined in HTTP2 where there is no </ins> corresponding HTTP/3 setting have also been reserved (iana-settings).  <ins> These reserved settings MUST NOT be sent, and their receipt MUST be treated as a connection error of type H3_SETTINGS_ERROR. </ins> Additional settings can be defined by extensions to HTTP/3; see extensions for more details.
Original text:
processed immediately.  Otherwise, the stream on which the field section was received becomes blocked. <del> To bound the memory requirements of the decoder for blocked streams, encoded field section data SHOULD remain in the stream's flow control window while the stream is blocked.  A stream becomes unblocked when the Insert Count becomes greater than or equal to the Required Insert Count for all encoded field sections the decoder has started reading from the stream. </del>  When processing encoded field sections, the decoder expects the Required Insert Count to equal the lowest possible value for the

Reviewer comments:
NAME said
One could imagine an implementation using a small buffer to read the beginning of the stream. If the whole field section happens to fit into it, so be it. A MUST would probably mean that a conforming implementation had to unread the field section.
We can probably just use "can" here. From an interoperability standpoint, there is no value to recommending any particular value.
Does SHOULD -> can mean this is a design change?
Yes, so if you're advocating doing that then I'll mark this as design.
The SHOULD is there to guard against memory exhaustion attacks. Streams "parking" is a QPACK design feature. The SHOULD should stay.
The plan is to leave the SHOULD, but add more editorial text in 2.2.1 explaining why it's a good idea.

Revised text:
processed immediately.  Otherwise, the stream on which the field section was received becomes blocked.  <ins> While blocked, encoded field section data SHOULD remain in the blocked stream's flow control window.  This data is unusable until the stream becomes unblocked, and releasing the flow control prematurely makes the decoder vulnerable to memory exhaustion attacks.  A stream becomes unblocked when the Insert Count becomes unblocked when the Insert Count becomes greater than or equal to the Required Insert Count for all encoded field sections the decoder has started reading from the stream. </ins> When processing encoded field sections, the decoder expects the Required Insert Count to equal the lowest possible value for the
Original text:
ClientHello message in their first Initial packet. The TLS implementation does not need to ensure that the ClientHello <del> is large enough to meet the requirements for QUIC packets.  QUIC PADDING frames are added to increase the size of the packet as necessary; see Section 14.1 of QUIC-TRANSPORT. </del>  4.4.

Reviewer comments:
Cleanup the language here a little.
This text could be better: Maybe instead:
Does anyone want to prepare a PR? Otherwise, this will get dropped I guess.
I didn't want to clutter our list of stuff with post-IESG PRs. I'll copy the above text once HTTP is done (real soon now). We're going to have to be careful that these little tweaks don't pile up.
I think this should be good to go now?

Revised text:
ClientHello message in their first Initial packet. The TLS implementation does not need to ensure that the ClientHello  <ins> is large enough to meet QUIC's requirements for datagrams that carry Initial packets; see Section 14.1 of QUIC-TRANSPORT.  QUIC implementations use PADDING frames or packet coalescing to ensure that datagrams are large enough. </ins> 4.4.
Original text:
H3_STREAM_CREATION_ERROR; see errors. Each Push ID MUST only be used once in a push stream header.  If a <del> push stream header includes a Push ID that was used in another push stream header, the client MUST treat this as a connection error of type H3_ID_ERROR; see errors. </del>  6.2.3.

Reviewer comments:
Adds the all-important conditional.
For clients that have sent CANCEL_PUSH, they don't know if server's push stream will still arrive or not. They have to remember Push IDs forever in order to differentiate between cancelled push and completed push.
I would appreciate some quick discussion if this issue is important to address before I approve or not.
We could make this a MAY. The other formulation we've used is "MUST ... if the client detects", making the response mandatory if the condition is detected, but not specifying the required level of effort to detect it.
I don't know that this issue is critical to address, but I agree that with certain (reasonable) implementation strategies this particular MUST becomes unenforceable / unachievable.
+1 for "MUST if the client detects" if we're going to make a change.
I think "MUST if detects" is suitable here - it points at the core problem. Simply s/MUST/MAY doesn't help people appreciate that might not be able to detect the condition. I'd also suggest that "MUST if detects" is an editorial change.
NAME can you confirm if addresses your issue?
Looks good!
Thanks. In that case I believe we have addressed this issue with an editorial change. NAME please confirm if we can merge the related PR and incorporate the change in during the RFC editor process.
Yes, the change looks good. I could actually include it as an RFC-edtior note in my approval message.
An elegant solution :)

Revised text:
H3_STREAM_CREATION_ERROR; see errors. Each Push ID MUST only be used once in a push stream header.  If a  <ins> client detects that a push stream header includes a Push ID that was used in another push stream header, the client MUST treat this as a connection error of type H3_ID_ERROR; see errors. </ins> 6.2.3.
Original text:
initial_max_stream_data_bidi_remote, or initial_max_streams_uni and initial_max_stream_data_uni.  A server MAY store and recover the previously sent values of the max_idle_timeout, max_udp_payload_size, and disable_active_migration parameters and reject 0-RTT if it selects smaller values.  Lowering

Reviewer comments:
If the client has opened a stream in 0-RTT with , and the server increases to , does this apply to this stream as well, or only to streams opened after handshake completion? Consensus in Slack seems to be that the limit should apply to all streams. The text should be explicit about that.
Isn't that already clear enough? states:
NAME This is what the definition of the TP says: Arguably, the stream used in 0-RTT is not a "newly created" stream.
Yeah, let's just be really clear about this. Though NAME quotes the section that is most important, this has proven to be a mistake common enough to spend text on.

Revised text:
initial_max_stream_data_bidi_remote, or initial_max_streams_uni and initial_max_stream_data_uni. <ins> A server might provide larger initial stream flow control limits for streams than the remembered values that a client applies when sending 0-RTT.  Once the handshake completes, the client updates the flow control limits on all sending streams using the updated values of initial_max_stream_data_bidi_remote and initial_max_stream_data_uni. </ins> A server MAY store and recover the previously sent values of the max_idle_timeout, max_udp_payload_size, and disable_active_migration parameters and reject 0-RTT if it selects smaller values.  Lowering
Original text:
8.  8.1. This document specifies two settings.  The entries in the following

Reviewer comments:
RFC-to-be 9114 (draft-ietf-quic-http) includes the following note to indicate that the registrations have a status of permanent and the Change Controller is the IETF. Should a similar statement be included in this document? From RFC-to-be 9114: The initial allocations in these registries created in this document are all assigned permanent status and list a change controller of the IETF and a contact of the HTTP working group (EMAIL). In addition, note that the padding in the Settings, Stream Types, and Error Codes differs from what appears in the IANA registry. IANA included the following note when they notified us that their actions for RFC-to-be 9114 were complete: NOTE: In the new registries, the padding has been adjusted for consistency from one registry to another and with URL We understand that there may be a request to change it. We have asked Mike (as editor of RFC-to-be 9114) to review, as the padding for the HTTP/3 registries is now inconsistent with the padding for the HTTP/2 registries. Please review and dicuss and let us know if any updates are needed.
Fixed in .
The QUIC registry policies, imported to HTTP/3, specify that a change controller and their contact information should be listed with each permanent registration. QPACK doesn't provide one, though almost certainly it should be the HTTP WG.

Revised text:
8. <ins> This document makes multiple registrations in the registries defined by HTTP3.  The allocations created by this document 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> 8.1. This document specifies two settings.  The entries in the following
Original text:
(error-handling). Once a receiver advertises a stream limit using the MAX_STREAMS <del> frame, advertising a smaller limit has no effect.  A receiver MUST ignore any MAX_STREAMS frame that does not increase the stream limit. </del>  As with stream and connection flow control, this document leaves implementations to decide when and how many streams should be

Reviewer comments:
Rather than saying who ignores MAX_STREAMS, we can just that it is ignored.
has the following requirement: frame, advertising a smaller limit has no effect. A receiver MUST ignore any MAXSTREAMS frame that does not increase the stream limit. I believe this should be: frame, advertising a smaller limit has no effect. A sender MUST ignore any MAXSTREAMS frame that does not increase the stream limit. This would be in line with the similar requirements for MAXSTREAMDATA and MAXDATA in : is not an error to advertise a smaller limit, but the smaller limit has no effect. [...] A sender MUST ignore any MAXSTREAMDATA or MAXDATA frames that do not increase flow control limits.
I believe the sentence was intended to read: "A receiver(of the frame) MUST ignore any MAX_STREAMS frame that does not increase the stream limit."
Using "receiver" in this context is confusing, maybe it could just be replaced by "endpoint": frame, advertising a smaller limit has no effect. An endpoint MUST ignore any MAX_STREAMS frame that does not increase the stream limit. Or just take the language from : ignored.
Yeah, this is the right fix.

Revised text:
(error-handling). Once a receiver advertises a stream limit using the MAX_STREAMS  <ins> frame, advertising a smaller limit has no effect.  MAX_STREAMS frames that do not increase the stream limit MUST be ignored. </ins> As with stream and connection flow control, this document leaves implementations to decide when and how many streams should be
Original text:
STOP_SENDING requests that a peer cease transmission on a stream. A STOP_SENDING frame can be sent for streams in the Recv or Size <del> Known states; see stream-send-states.  Receiving a STOP_SENDING frame </del>  for a locally-initiated stream that has not yet been created MUST be treated as a connection error of type STREAM_STATE_ERROR.  An endpoint that receives a STOP_SENDING frame for a receive-only stream a peer of the maximum amount of data that can be sent on a stream. A MAX_STREAM_DATA frame can be sent for streams in the Recv state; <del> see stream-send-states.  Receiving a MAX_STREAM_DATA frame for a </del>  locally-initiated stream that has not yet been created MUST be treated as a connection error of type STREAM_STATE_ERROR.  An endpoint that receives a MAX_STREAM_DATA frame for a receive-only

Reviewer comments:
Tommy points out that we accidentally cited the sending parts, but these are receive states.
Very editorial nit: The section has the following text: The states referenced here are in fact receive stream states, not send stream states. Should this be: The same goes for MAXSTREAM_DATA:

Revised text:
STOP_SENDING requests that a peer cease transmission on a stream. A STOP_SENDING frame can be sent for streams in the Recv or Size  <ins> Known states; see stream-recv-states.  Receiving a STOP_SENDING frame </ins> for a locally-initiated stream that has not yet been created MUST be treated as a connection error of type STREAM_STATE_ERROR.  An endpoint that receives a STOP_SENDING frame for a receive-only stream a peer of the maximum amount of data that can be sent on a stream. A MAX_STREAM_DATA frame can be sent for streams in the Recv state;  <ins> see stream-recv-states.  Receiving a MAX_STREAM_DATA frame for a </ins> locally-initiated stream that has not yet been created MUST be treated as a connection error of type STREAM_STATE_ERROR.  An endpoint that receives a MAX_STREAM_DATA frame for a receive-only
Original text:
A variable-length integer error code that indicates the reason for closing this connection.  A CONNECTION_CLOSE frame of type 0x1c uses codes from the space defined in transport-error-codes.  A <del> CONNECTION_CLOSE frame of type 0x1d uses codes from the application protocol error code space; see app-error-codes. </del>  A variable-length integer encoding the type of frame that triggered the error.  A value of 0 (equivalent to the mention of

Reviewer comments:
This avoids the implication of a single error code space. Even if one is permissible, that is not necessary.
NAME originally posted in URL a comment highlighting that although HTTP/3 uses a single error code space for connection and stream errors, there is no requirement for other application protocol mappings to do the same. I found the text in URL to give me the wrong assumptions. This is the only mention of an error code space in the text that will make it into RFC. So I suggest in the offending paragraph we delete the 2 occurrences of "space" and just state that the frame contains a value, either defined in transport [ref] or application [ref]
"uses codes defined by the application protocol"?

Revised text:
A variable-length integer error code that indicates the reason for closing this connection.  A CONNECTION_CLOSE frame of type 0x1c uses codes from the space defined in transport-error-codes.  A  <ins> CONNECTION_CLOSE frame of type 0x1d uses codes defined by the application protocol; see app-error-codes. </ins> A variable-length integer encoding the type of frame that triggered the error.  A value of 0 (equivalent to the mention of
Original text:
the new RTT to be included in smoothed_rtt. Endpoints SHOULD set the min_rtt to the newest RTT sample after <del> persistent congestion is established.  This is to allow a connection to reset its estimate of min_rtt and smoothed_rtt (smoothed-rtt) after a disruptive network event, and because it is possible that an increase in path delay resulted in persistent congestion being incorrectly declared. </del>  Endpoints MAY re-establish the min_rtt at other times in the connection, such as when traffic volume is low and an acknowledgment

Reviewer comments:
3) [rfced] Does the following improve the readability of the paragraph? Current: Endpoints SHOULD set the minrtt to the newest RTT sample after persistent congestion is established. This is to allow a connection to reset its estimate of minrtt and smoothedrtt after a disruptive network event (Section 5.3), and because it is possible that an increase in path delay resulted in persistent congestion being incorrectly declared. Perhaps: Endpoints SHOULD set the minrtt to the newest RTT sample after persistent congestion is established because it is possible that an increase in path delay resulted in persistent congestion being incorrectly declared. This also allows a connection to reset its estimate of minrtt and smoothedrtt after a disruptive network event (Section 5.3).
I find this easier to read, but I think it may be subtly different, so I put it into a separate PR.
It doesn't change the meaning, but it does feel like the first sentence is trying to span too many topics. I like the reordering, but I'd split it out.This is good, thank you !

Revised text:
the new RTT to be included in smoothed_rtt. Endpoints SHOULD set the min_rtt to the newest RTT sample after  <ins> persistent congestion is established.  This avoids repeatedly declaring persistent congestion when the RTT increases.  This also allows a connection to reset its estimate of min_rtt and smoothed_rtt after a disruptive network event; see smoothed-rtt. </ins> Endpoints MAY re-establish the min_rtt at other times in the connection, such as when traffic volume is low and an acknowledgment