jiebi/TextFlow huggingface dataset:
Original text:
flight, the timer MUST be set to the earlier value of the Initial and Handshake packet number spaces. <del> An endpoint MUST NOT set its PTO timer for the application data </del>  packet number space until the handshake is confirmed.  Doing so prevents the endpoint from retransmitting information in packets when either the peer does not yet have the keys to process them or the

Reviewer comments:
For this document, I believe the best option is to use "Application Data" when referring to the packet number space, and "application data" when referring to generic application data, such as when discussing being app-limited due to lack of application data. 6) [rfced] Throughout the text, the following term appears to be used inconsistently. Please review these occurrences and let us know if/how they may be made consistent. application data / Application Data Note that RFC-to-be 9000 uses the lowercase form consistently. We raised a similar question for RFC-to-be 9001; the authors decided on the following: (see URL)

Revised text:
flight, the timer MUST be set to the earlier value of the Initial and Handshake packet number spaces.  <ins> An endpoint MUST NOT set its PTO timer for the Application Data </ins> packet number space until the handshake is confirmed.  Doing so prevents the endpoint from retransmitting information in packets when either the peer does not yet have the keys to process them or the
Original text:
QUIC aims to constrain the capabilities of an on-path attacker as follows: <del> An on-path attacker can prevent use of a path for a connection, causing the connection to fail if it cannot use a different path that does not contain the attacker.  This can be achieved by dropping all packets, modifying them so that they fail to decrypt, or other methods. </del>  An on-path attacker can prevent migration to a new path for which the attacker is also on-path by causing path validation to fail on

Reviewer comments:
Do you need to rebase? There's a change that seems to have been repeated in a previously merged PR.

Revised text:
QUIC aims to constrain the capabilities of an on-path attacker as follows:  <ins> An on-path attacker can prevent the use of a path for a connection, causing the connection to fail if it cannot use a different path that does not contain the attacker.  This can be achieved by dropping all packets, modifying them so that they fail to decrypt, or other methods. </ins> An on-path attacker can prevent migration to a new path for which the attacker is also on-path by causing path validation to fail on
Original text:
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 <del> 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:
The repeated "when" clauses in this sentence make it difficult to parse. If our suggestion does not correctly capture your intent, could you please rephrase? Original: 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. Perhaps: 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.
It actually looks as though the words "becomes unblocked when the Insert Count" are duplicated, which would make the corrected text: That might still be confusing, but the proposed text certainly isn't the right change. The key point to capture is: The decoder has started reading at least one encoded field section from the stream and encountered a Required Insert Count value in some or all of them which exceeds its current Insert Count. This caused the stream to be considered blocked. When the Insert Count is greater than or equal to the RIC value from all of the encoded field sections the decoder has attempted to process, the stream becomes unblocked.
Fixed in .
Good catch.

Revised text:
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  <ins> 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:
the message exchange, they must be received and processed before the message can be consumed.  See header-formatting for more details. <del> Transfer codings (see Section 6.1 of HTTP11) are not defined for </del>  HTTP/3; the Transfer-Encoding header field MUST NOT be used. A response MAY consist of multiple messages when and only when one or

Reviewer comments:
Noticed in URL that we're pointing to different sections: 6.1 is the Transfer-Encoding header 7.1 is specifically 7 is transfer codings in general Since this passage is referring to the concept in general not being present in HTTP/3, Section 7 is the correct reference.

Revised text:
the message exchange, they must be received and processed before the message can be consumed.  See header-formatting for more details.  <ins> Transfer codings (see Section 7 of HTTP11) are not defined for </ins> HTTP/3; the Transfer-Encoding header field MUST NOT be used. A response MAY consist of multiple messages when and only when one or
Original text:
A TCP connection error is signaled by abruptly terminating the stream.  A proxy treats any error in the TCP connection, which includes receiving a TCP segment with the RST bit set, as a stream <del> error of type H3_CONNECT_ERROR; see errors.  Correspondingly, if a proxy detects an error with the stream or the QUIC connection, it MUST close the TCP connection.  If the underlying TCP implementation permits it, the proxy SHOULD send a TCP segment with the RST bit set. </del>  Since CONNECT creates a tunnel to an arbitrary server, proxies that support CONNECT SHOULD restrict its use to a set of known ports or a

Reviewer comments:
This looks great to me.
NAME that's a good point. Let me reword it to use the operation terms rather than the v1 frame names.
From ... : URL be improved in h3. Not the TCP RST part, but the bit that leads up to it. Otherwise, we might not get the right behaviour. If the proxy just closes the connection in response to RESET_STREAM, it might then just end the stream (with a FIN bit), which would be wrong. Perhaps instead: Somewhat substantive, unfortunately, and very, very, very late. I'm happy to wait and file an erratum.
This seems like a solid improvement, but it's definitely not editorial. NAME and NAME will need to decide whether this is a change they're willing to accept post-IESG.
Endpoints that overlook the proposed behaviour risk zombie streams. This seems like something worth addressing while we have the opportunity. Can one of you please file create a PR and we'll take it to the AD.
Closed in .
Better than my text :)This looks ready to go, are we merging it soon?

Revised text:
A TCP connection error is signaled by abruptly terminating the stream.  A proxy treats any error in the TCP connection, which includes receiving a TCP segment with the RST bit set, as a stream  <ins> error of type H3_CONNECT_ERROR; see errors. Correspondingly, if a proxy detects an error with the stream or the QUIC connection, it MUST close the TCP connection.  If the proxy detects that the client has reset the stream or aborted reading from the stream, it MUST close the TCP connection.  If the stream is reset or reading is aborted by the client, a proxy SHOULD perform the same operation on the other direction in order to ensure that both directions of the stream are cancelled.  In all these cases, if the underlying TCP implementation permits it, the proxy SHOULD send a TCP segment with the RST bit set. </ins> Since CONNECT creates a tunnel to an arbitrary server, proxies that support CONNECT SHOULD restrict its use to a set of known ports or a
Original text:
If the stream header indicates a stream type that is not supported by the recipient, the remainder of the stream cannot be consumed as the <del> semantics are unknown.  Recipients of unknown stream types MAY abort reading of the stream with an error code of H3_STREAM_CREATION_ERROR or a reserved error code (http-error-codes), but the recipients MUST NOT consider such streams to be a connection error of any kind. </del>  As certain stream types can affect connection state, a recipient SHOULD NOT discard data from incoming unidirectional streams prior to and stream types (iana-stream-types). Implementations MUST ignore unknown or unsupported values in all <del> extensible protocol elements.  Implementations MUST discard frames and abort reading on unidirectional streams that have unknown or </del>  unsupported types.  This means that any of these extension points can be safely used by extensions without prior arrangement or negotiation.  However, where a known frame type is required to be in

Reviewer comments:
NAME observed a seeming conflict in the requirements around unknown unidirectional stream types. Section 9 says: This has two problems. First and editorial, if the type is unknown/unsupported, the presence of frames can't be determined. This should refer to discarding any data, not frames specifically. Second, it appears to disagree with Section 6.2: I think the intent was MUST abort, but MAY pick an error code. Looking at the history of the commits in Section 6.2, it was first MUST abort, then SHOULD use a particular code, then became MAY use the specific code with the prohibition on blowing up the whole connection. The text should clarify the scope of the MAY.
Agree. This change would meet the intent of the text and is editorial. So it the proposal here something like:
I think I'd say "MUST either abort reading of the stream or discard incoming data without further processing. If reading is aborted, the recipient SHOULD use...."
That would work for me too, care to make a PR?
Closed in .
LGTM thank you

Revised text:
If the stream header indicates a stream type that is not supported by the recipient, the remainder of the stream cannot be consumed as the  <ins> semantics are unknown.  Recipients of unknown stream types MUST either abort reading of the stream or discard incoming data without further processing.  If reading is aborted, the recipient SHOULD use the H3_STREAM_CREATION_ERROR error code or a reserved error code (http-error-codes).  The recipient MUST NOT consider unknown stream types to be a connection error of any kind. </ins> As certain stream types can affect connection state, a recipient SHOULD NOT discard data from incoming unidirectional streams prior to and stream types (iana-stream-types). Implementations MUST ignore unknown or unsupported values in all  <ins> extensible protocol elements.  Implementations MUST discard data or abort reading on unidirectional streams that have unknown or </ins> unsupported types.  This means that any of these extension points can be safely used by extensions without prior arrangement or negotiation.  However, where a known frame type is required to be in
Original text:
more cookie-pairs, before compression.  If a decompressed field section contains multiple cookie field lines, these MUST be concatenated into a single byte string using the two-byte delimiter <del> of 0x3b, 0x20 (the ASCII string "; ") before being passed into a context other than HTTP/2 or HTTP/3, such as an HTTP/1.1 connection, or a generic HTTP server application. </del>  4.2.2. 4.3. Like HTTP/2, HTTP/3 employs a series of pseudo-header fields, where <del> the field name begins with the ':' character (ASCII 0x3a).  These </del>  pseudo-header fields convey message control data; see HTTP. Pseudo-header fields are not HTTP fields.  Endpoints MUST NOT Similarly, HTTP/3 can transport field values that are not valid. While most values that can be encoded will not alter field parsing, <del> carriage return (CR, ASCII 0x0d), line feed (LF, ASCII 0x0a), and the zero character (NUL, ASCII 0x00) might be exploited by an attacker if they are translated verbatim.  Any request or response that contains a character not permitted in a field value MUST be treated as malformed (malformed).  Valid characters are defined by the "field- content" ABNF rule in HTTP. </del>  10.4.

Reviewer comments:
The RFC Editor asks:
Along the way, there are two equivalent statements that need to be deduplicated that this change touches: I would suggest collapsing these two into the first statement, but using OPTIONS as an example and keeping the reference into http-core. Or perhaps that should be a question -- is there a difference between asterisk-form and OPTIONS-without-path?
Resolved in .

Revised text:
more cookie-pairs, before compression.  If a decompressed field section contains multiple cookie field lines, these MUST be concatenated into a single byte string using the two-byte delimiter  <ins> of "; " (ASCII 0x3b, 0x20) before being passed into a context other than HTTP/2 or HTTP/3, such as an HTTP/1.1 connection, or a generic HTTP server application. </ins> 4.2.2. 4.3. Like HTTP/2, HTTP/3 employs a series of pseudo-header fields, where  <ins> the field name begins with the ":" character (ASCII 0x3a).  These </ins> pseudo-header fields convey message control data; see HTTP. Pseudo-header fields are not HTTP fields.  Endpoints MUST NOT Similarly, HTTP/3 can transport field values that are not valid. While most values that can be encoded will not alter field parsing,  <ins> carriage return (ASCII 0x0d), line feed (ASCII 0x0a), and the null character (ASCII 0x00) might be exploited by an attacker if they are translated verbatim.  Any request or response that contains a character not permitted in a field value MUST be treated as malformed (malformed).  Valid characters are defined by the "field-content" ABNF rule in HTTP. </ins> 10.4.
Original text:
and structure of data that follows this integer is determined by the stream type. <del> Two stream types are defined in this document: control streams (control-streams) and (push-streams).  RFC9204 defines two additional stream types.  Other stream types can be defined by extensions to HTTP/3; see extensions for more details.  Some stream types are reserved (stream-grease). </del>  The performance of HTTP/3 connections in the early phase of their lifetime is sensitive to the creation and exchange of data on If an entire connection needs to be terminated, QUIC similarly provides mechanisms to communicate a reason; see QUIC-TRANSPORT. <del> This is referred to as a "".  Similar to stream errors, an HTTP/3 implementation can terminate a QUIC connection and communicate the reason using an error code from http-error-codes. </del>  Although the reasons for closing streams and connections are called "errors", these actions do not necessarily indicate a problem with CANCEL_PUSH connection error control stream <del> control streams control streams </del> D DATA

Reviewer comments:
NAME was helpful enough to show me how to do this in URL, so now singular and plural versions of the same term are a single index entry.

Revised text:
and structure of data that follows this integer is determined by the stream type.  <ins> Two stream types are defined in this document: (control-streams) and (push-streams).  RFC9204 defines two additional stream types.  Other stream types can be defined by extensions to HTTP/3; see extensions for more details.  Some stream types are reserved (stream-grease). </ins> The performance of HTTP/3 connections in the early phase of their lifetime is sensitive to the creation and exchange of data on If an entire connection needs to be terminated, QUIC similarly provides mechanisms to communicate a reason; see QUIC-TRANSPORT.  <ins> This is referred to as a "".  Similar to , an HTTP/3 implementation can terminate a QUIC connection and communicate the reason using an error code from http-error-codes. </ins> Although the reasons for closing streams and connections are called "errors", these actions do not necessarily indicate a problem with CANCEL_PUSH connection error control stream  D DATA
Original text:
stream.  Receipt of a second instance of either stream type MUST be treated as a connection error of type H3_STREAM_CREATION_ERROR. <del> These streams MUST NOT be closed.  Closure of either unidirectional stream type MUST be treated as a connection error of type H3_CLOSED_CRITICAL_STREAM. </del>  An endpoint MAY avoid creating an encoder stream if it will not be used (for example, if its encoder does not wish to use the dynamic

Reviewer comments:
builds on .
URL stream type MUST be treated as a connection error of type H3CLOSEDCRITICALSTREAM. I'd like to clarify that whether this effectively says that receiver is not allowed to send STOPSENDING. STOPSENDING is elicit RESETSTREAM that closes a stream. MUST send a RESETSTREAM frame if the stream is in the "Ready" or "Send" state. STOPSENDING itself does not close a stream, but it is an action to request a closure. I found in interop runner test, one implementation sends STOPSENDING to QPACK streams. My implementation sends RESETSTREAM when it is received as mandated by spec, and upon stream closure, the connection is closed because QPACK streams are closed, then the test fails. HTTP draft explicitly says that requesting closure for the control stream is prohibited: request that the sender close the control stream. It would be nice to add the similar statement to QPACK streams.
It's super-late in the process, but maybe the editors can see a way to squeeze an editorial change in.
Thanks Tatsuhiro. I agree, IMO the intention was always for consistent treatment of open control streams and open qpack streams when it comes to not closing them. Finding a way to address this during AUTH48 would be nice.
I agree, this was the intention -- closing the stream is treated as an error, and being asked to commit an error is itself an error. One could squint and say it's covered by the existing text -- upon receipt of the STOP_SENDING, the send is required to close the stream; closure of the stream is already required to be treated as an error. It's technically a normative change, but there's no effective change in behavior.
If it's a normative change, is it still OK to change in auth48 just with a WG consensus call or is more process required?
The AD has to decide what to do and approve this change to the RFC editor.
Since the fix includes a gentle normative change, marking this as a design issue and we'll put out a consensus call to the list.
Consensus was declared, so was merged.

Revised text:
stream.  Receipt of a second instance of either stream type MUST be treated as a connection error of type H3_STREAM_CREATION_ERROR.  <ins> The sender MUST NOT close either of these streams, and the receiver MUST NOT request that the sender close either of these streams. Closure of either unidirectional stream type MUST be treated as a connection error of type H3_CLOSED_CRITICAL_STREAM. </ins> An endpoint MAY avoid creating an encoder stream if it will not be used (for example, if its encoder does not wish to use the dynamic
Original text:
section.  An encoder MUST emit field representations in the order they appear in the input field section. <del> QPACK is designed to contain the more complex state tracking to the encoder, while the decoder is relatively simple. </del>  2.1.1.

Reviewer comments:
Inspired by NAME suggestion;
Is "to the encoder" intended? Should this be "within the encoder" or might "contain" be made "limit" or something else? Original: QPACK is designed to contain the more complex state tracking to the encoder, while the decoder is relatively simple.
"Limit" is probably the closest if we want to keep the phrase as-is. Writing something de novo might be better, but I'm having trouble coming up with anything pithy.
Some alternatives (aka throwing mud at the wall) "The design of QPACK requires an encoder to implement relatively more-complex state tracking than a decoder." "QPACK's design requires state tracking in various degrees of complexity. In relative terms, encoders have complex requirements, while decoders are more simple. "QPACK is designed to put the state tracking complexity onus on encoders, resulting in relatively simple decoders."
I like the third one.
Fixed in with a variant of the third option.
LGTM

Revised text:
section.  An encoder MUST emit field representations in the order they appear in the input field section.  <ins> QPACK is designed to place the burden of optional state tracking on the encoder, resulting in relatively simple decoders. </ins> 2.1.1.
Original text:
connection with error PROTOCOL_VIOLATION.  Endpoints that wish to use DATAGRAM frames need to ensure they send a max_datagram_frame_size value sufficient to allow their peer to use them.  It is RECOMMENDED <del> to send the value 65536 in the max_datagram_frame_size transport </del>  parameter as that indicates to the peer that this endpoint will accept any DATAGRAM frame that fits inside a QUIC packet.

Reviewer comments:
Current text says: This is nice, but I'm wondering if it should be 65535. The max UDP payload for a QUIC packet is 65527, which is lower than both. It's nice for an implementation to only need to store 16-bit integers for max datagram size to avoid excess memory, and it's of course easy to round down from 65536 to 65535, but it just seems arbitrary to have it be 1 more than the max value for a 16-bit integer...
NAME thoughts?
That sounds reasonable, 65535 is fine by me. (as long as the 1s don't take longer to travel than the 0s )

Revised text:
connection with error PROTOCOL_VIOLATION.  Endpoints that wish to use DATAGRAM frames need to ensure they send a max_datagram_frame_size value sufficient to allow their peer to use them.  It is RECOMMENDED  <ins> to send the value 65535 in the max_datagram_frame_size transport </ins> parameter as that indicates to the peer that this endpoint will accept any DATAGRAM frame that fits inside a QUIC packet.