jiebi/TextFlow huggingface dataset:
Original text:
this connection, while requests on the indicated stream ID and greater were rejected.  This enables client and server to agree on which requests were accepted prior to the connection shutdown.  This <del> identifier MAY be lower than the stream limit identified by a QUIC MAX_STREAM_ID frame, and MAY be zero if no requests were processed. Servers SHOULD NOT increase the QUIC MAX_STREAM_ID limit after sending a GOAWAY frame. </del>  Clients MUST NOT send new requests on the connection after receiving GOAWAY; a new connection MAY be established to send additional might already have retried unprocessed requests on another connection.  A server that is attempting to gracefully shut down a connection SHOULD send an initial GOAWAY frame with the last Stream <del> ID set to the current value of QUIC's MAX_STREAM_ID and SHOULD NOT increase the MAX_STREAM_ID thereafter.  This signals to the client that a shutdown is imminent and that initiating further requests is prohibited.  After allowing time for any in-flight requests (at least one round-trip time), the server MAY send another GOAWAY frame with an updated last Stream ID.  This ensures that a connection can be cleanly shut down without losing requests. </del>  Once all accepted requests have been processed, the server can permit the connection to become idle, or MAY initiate an immediate closure

Reviewer comments:
TBH I'm not sure the whole "set GOAWAY last stream id to MAXSTREAMID / maximum value allowed by MAX_STREAMS" is really necessary, but I kept it for now.

Revised text:
this connection, while requests on the indicated stream ID and greater were rejected.  This enables client and server to agree on which requests were accepted prior to the connection shutdown.  This  <ins> identifier MAY be zero if no requests were processed.  Servers SHOULD NOT increase the QUIC MAX_STREAMS limit after sending a GOAWAY frame. </ins> Clients MUST NOT send new requests on the connection after receiving GOAWAY; a new connection MAY be established to send additional might already have retried unprocessed requests on another connection.  A server that is attempting to gracefully shut down a connection SHOULD send an initial GOAWAY frame with the last Stream  <ins> ID set to the maximum value allowed by QUIC's MAX_STREAMS and SHOULD NOT increase the MAX_STREAMS limit thereafter.  This signals to the client that a shutdown is imminent and that initiating further requests is prohibited.  After allowing time for any in-flight requests (at least one round-trip time), the server MAY send another GOAWAY frame with an updated last Stream ID.  This ensures that a connection can be cleanly shut down without losing requests. </ins> Once all accepted requests have been processed, the server can permit the connection to become idle, or MAY initiate an immediate closure
Original text:
An endpoint SHOULD ensure that its peer has a sufficient number of available and unused connection IDs.  Endpoints store received <del> connection IDs for future use.  An endpoint uses the active_connection_id_limit transport parameter to advertise the number of connection IDs it can store for future use.  An endpoint SHOULD NOT provide more connection IDs than the peer's limit.  If an endpoint has provided its peer with the maximum number of connection IDs, it SHOULD only provide a new connection ID when the peer retires one.  An endpoint MAY limit the frequency or the total number of connection IDs issued for each connection to avoid the risk of running out of connection IDs (see reset-token). </del>  An endpoint that initiates migration and requires non-zero-length connection IDs SHOULD ensure that the pool of connection IDs

Reviewer comments:
Reword the text to be a bit more clear about what's expected from a CID issuer.
I believe this is editorial, since it does not change any normative text.
This inverts the form of the recommendation, but doesn't really change the design.
We previously had text: In adding text for the TP (activeconnectionid_limit), we kept the same idea, but lost a little bit of the text: We still need the SHOULD replace used CIDs in the event that we haven't provided the peer with the maximum number of CIDs.
Putting together a PR for this

Revised text:
An endpoint SHOULD ensure that its peer has a sufficient number of available and unused connection IDs.  Endpoints store received  <ins> connection IDs for future use and advertise the number of connection IDs they are willing to store with the active_connection_id_limit transport parameter.  An endpoint SHOULD NOT provide more connection IDs than the peer's limit. An endpoint SHOULD supply a new connection ID when it receives a packet with a previously unused connection ID or when the peer retires one, unless providing the new connection ID would exceed the peer's limit.  An endpoint MAY limit the frequency or the total number of connection IDs issued for each connection to avoid the risk of running out of connection IDs; see reset-token. </ins> An endpoint that initiates migration and requires non-zero-length connection IDs SHOULD ensure that the pool of connection IDs
Original text:
A Retry packet uses a long packet header with a type value of 0x3. It carries an address validation token created by the server.  It is <del> used by a server that wishes to perform a stateless retry (see validate-handshake). </del>  A Retry packet (shown in retry-format) does not contain any protected fields.  In addition to the long header, it contains these additional

Reviewer comments:
ekr says there used to be stateless and stateful retry, but now there is just stateless. This is the only place the phrase is used, so instead just say "retry".

Revised text:
A Retry packet uses a long packet header with a type value of 0x3. It carries an address validation token created by the server.  It is  <ins> used by a server that wishes to perform a retry (see validate- handshake). </ins> A Retry packet (shown in retry-format) does not contain any protected fields.  In addition to the long header, it contains these additional
Original text:
ECN codepoints to affect the sender's rate.  If duplicate packets are discarded by a receiver, an off-path attacker will need to race the duplicate packet against the original to be successful in this <del> attack.  Therefore, QUIC receivers ignore ECN codepoints set in duplicate packets (see ecn). </del>  21.8.

Reviewer comments:
NAME made a good suggestion in , which I have taken and tweaked further. It is not sufficient to discard ECN if one QUIC packet is discared, you need to discard ALL QUIC packets in the IP packet.
Sounds about right to me.
S 21.7 This could use more elaboration. As written, it seems like if you win the race (which you might like half the time) then you will succeed in the attack. Is that true?
Yes, the winner of a race can reduce the congestion window or maybe prevent it from being reduced.
As I see this: QUIC receivers ignore the ECN codepoint field received in IP packets that carry duplicate QUIC packets (see {{ecn}}).
So NAME is this resolved or do you expect more than what Martin wrote?
I think that I can make that call now. If there is a problem, we can open an issue.

Revised text:
ECN codepoints to affect the sender's rate.  If duplicate packets are discarded by a receiver, an off-path attacker will need to race the duplicate packet against the original to be successful in this  <ins> attack.  Therefore, QUIC endpoints ignore the ECN codepoint field on an IP packet unless at least one QUIC packet in that IP packet is successfully processed; see ecn. </ins> 21.8.
Original text:
QPACK defines two settings which are included in the HTTP/3 SETTINGS frame. <del> An integer with a maximum value of 2^30 - 1.  The default value is zero bytes.  See _table-dynamic for usage.  This is the equivalent of the SETTINGS_HEADER_TABLE_SIZE from HTTP/2. </del>  <del> An integer with a maximum value of 2^16 - 1.  The default value is zero.  See overview-hol-avoidance. </del>  6.

Reviewer comments:
In addition, remove verbiage stating that the settings values are integers, as the are integers by the definition of the SETTINGS frame.
Both specify the maximum value the decoder supports. The encoder is free to pick and use a smaller value. There is no reason to add artificial limits to the way an decoder is implemented.
This could be viewed as an alternative resolution to .
Also, historical note: These have maxima because settings used to be length-prefixed blobs. By defining them to be integers of a maximum size, the length could be constrained. Now that we use varints, there is a maximum structural size already.

Revised text:
QPACK defines two settings which are included in the HTTP/3 SETTINGS frame.  <ins> The default value is zero.  See _table-dynamic for usage.  This is the equivalent of the SETTINGS_HEADER_TABLE_SIZE from HTTP/2. </ins>  <ins> The default value is zero.  See overview-hol-avoidance. </ins> 6.
Original text:
parameters "initial_max_stream_data_bidi_local".  An HTTP/3 server SHOULD send non-zero values for the QUIC transport parameters "initial_max_stream_data_bidi_remote" and "initial_max_bidi_streams". <del> It is recommended that "initial_max_bidi_streams" be no smaller than </del>  100, so as to not unnecessarily limit parallelism. HTTP/3 does not use server-initiated bidirectional streams; clients

Reviewer comments:
IIUC, RFC 2119 keywords used in RFC 7540 need to be converted to uppercase words in HTTP/3, because HTTP/3 invokes RFC 8174.
That was never an interoperability requirement, just a suggestion. So I think that this should be reverted. If it isn't, using the active voice might be better.

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:
parameters "initial_max_stream_data_bidi_local".  An HTTP/3 server SHOULD send non-zero values for the QUIC transport parameters "initial_max_stream_data_bidi_remote" and "initial_max_bidi_streams".  <ins> It is RECOMMENDED that "initial_max_bidi_streams" be no smaller than </ins> 100, so as to not unnecessarily limit parallelism. HTTP/3 does not use server-initiated bidirectional streams; clients
Original text:
future connections.  The client includes this token in Initial packets to provide address validation in a future connection.  The client MUST include the token in all Initial packets it sends, unless <del> a Retry or NEW_TOKEN frame replaces the token with a newer one.  The client MUST NOT use the token provided in a Retry for future connections.  Servers MAY discard any Initial packet that does not carry the expected token. </del>  A token SHOULD be constructed for the server to easily distinguish it from tokens that are sent in Retry packets as they are carried in the

Reviewer comments:
The client only replaces a token sent in Initial packets when receiving a Retry. NEW_TOKEN is an orthogonal mechanism to provide tickets for subsequent connections, and doesn't have any effect on the current connection.

Revised text:
future connections.  The client includes this token in Initial packets to provide address validation in a future connection.  The client MUST include the token in all Initial packets it sends, unless  <ins> a Retry replaces the token with a newer one.  The client MUST NOT use the token provided in a Retry for future connections.  Servers MAY discard any Initial packet that does not carry the expected token. </ins> A token SHOULD be constructed for the server to easily distinguish it from tokens that are sent in Retry packets as they are carried in the
Original text:
compatible with the QUIC version that the client has selected.  If the server cannot select a compatible combination of application protocol and QUIC version, it MUST abort the connection.  A client <del> MUST abort a connection if the server picks an incompatible combination of QUIC version and ALPN identifier. </del>  8.2.

Reviewer comments:
The server doesn't pick a version. The server only picks the application protocol from what the client offered, and it might do that based on the QUIC version that the client picked.
NAME That depends on how you read RFC 7301, doesn't it? Section 3.1 says: I interpret "suitable" as "one of the options that the client proposed", but unfortunately that RFC is not very specific.
That is confusing, but it doesn't mean that the server doesn't pick an ALPN. We do require that it select an ALPN value, and even if it picks one that the client doesn't offer (whether legitimate or not), that doesn't invalidate this text.
No, I was suggesting restoring the sentence that was there before, but with alternate wording to address NAME concern. Now the server MUST abort if it can't pick a proper combination, and the client MUST abort if the server fails to abide by that requirement.
I think removing the sentence entirely is the wrong approach.OK, I see now. Yes, this WFM.

Revised text:
compatible with the QUIC version that the client has selected.  If the server cannot select a compatible combination of application protocol and QUIC version, it MUST abort the connection.  A client  <ins> MUST abort a connection if the server picks an application protocol incompatible with the protocol version being used. </ins> 8.2.
Original text:
When the crypto retransmission timer is active, the probe timer (pto) is not active. <del> 6.2.1. 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 Version Negotiation packet is received.  The client MAY use this value to seed the RTT estimator for a subsequent connection attempt to the server. </del> 6.3. A Probe Timeout (PTO) triggers a probe packet when ack-eliciting data 6.4.  When packet protection keys are discarded (see Section 4.9 of QUIC- TLS), all packets that were sent with those keys can no longer be acknowledged because their acknowledgements cannot be processed might be destroyed sooner, as soon as handshake keys are available (see Section 4.10 of QUIC-TLS). <del> 6.5. </del>  The majority of constants were derived from best common practices among widely deployed TCP implementations on the internet.

Reviewer comments:
Moves the "Retry and Version Negotiation" out of the "Crypto Retransmission Timeout" section in preparation for a redo of

Revised text:
When the crypto retransmission timer is active, the probe timer (pto) is not active.  6.3. A Probe Timeout (PTO) triggers a probe packet when ack-eliciting data 6.4. <ins> 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 Version Negotiation packet is received.  The client MAY use this value to seed the RTT estimator for a subsequent connection attempt to the server. 6.5. </ins> When packet protection keys are discarded (see Section 4.9 of QUIC- TLS), all packets that were sent with those keys can no longer be acknowledged because their acknowledgements cannot be processed might be destroyed sooner, as soon as handshake keys are available (see Section 4.10 of QUIC-TLS).  <ins> 6.6. </ins> The majority of constants were derived from best common practices among widely deployed TCP implementations on the internet.
Original text:
immediate-close). Endpoints MUST NOT exceed the limit set by their peer.  An endpoint <del> that receives a STREAM frame with a stream ID exceeding the limit it has sent MUST treat this as a stream error of type STREAM_LIMIT_ERROR </del>  (error-handling). Once a receiver advertises a stream limit using the MAX_STREAMS

Reviewer comments:
This aligns section 4.5 with section 19.11's text: "An endpoint MUST terminate a connection with a STREAMLIMITERROR error if a peer opens more streams than was permitted."
I'm going to recommend calling this editorial on the basis that it reconciles this text with another MUST-level requirement. But I will leave the issue open for the chairs to make a design/editorial assessment and any resulting consensus call.
In most places in QUIC, if an error is clearly avoidable(ie: only a buggy implementation would do so), then we advise closing the connection with an error, not just closing the stream with an error. In section 4.5 of transport(URL) it says: "Endpoints MUST NOT exceed the limit set by their peer. An endpoint that receives a STREAM frame with a stream ID exceeding the limit it has sent MUST treat this as a stream error of type STREAMLIMITERROR" Came up in discussion of
As I commented in the updated PR description, section 19.11 already says this: "An endpoint MUST terminate a connection with a STREAMLIMITERROR error if a peer opens more streams than was permitted."
Reopening to keep this visible.
is effectively the proposal, correct?
Yes. It was editorial. So I merged it. But then this issue really isn't editorial.
Yes, I opened this issue, then found that text in section 19.11 in the doc said exceeding MAXSTREAMID was a connection error, so the PR ended up aligning the two sections.
In HTTP/3 Appendix A.4 it states : : HTTPREQUESTREJECTED (in {{http-error-codes}}) is used to indicate that a request was not processed. Otherwise, not applicable because QUIC handles stream management. A STREAMIDERROR at the QUIC layer is used for streams that are improperly opened. But STREAMIDERROR was removed in transport draft 17.
Since URL there are different error codes that the transport might use depending on error conditions (maybe STREAMSTATEERROR or maybe STREAMLIMITERROR). I'm inclined to simply omit the sentence.

Revised text:
immediate-close). Endpoints MUST NOT exceed the limit set by their peer.  An endpoint  <ins> that receives a frame with a stream ID exceeding the limit it has sent MUST treat this as a connection error of type STREAM_LIMIT_ERROR </ins> (error-handling). Once a receiver advertises a stream limit using the MAX_STREAMS
Original text:
data on this stream.  Either frame might arrive before a STREAM or STREAM_DATA_BLOCKED frame if packets are lost or reordered. <del> Before creating a stream, all streams of the same type with lower- </del>  numbered stream IDs MUST be created.  This ensures that the creation order for streams is consistent on both endpoints.

Reviewer comments:
The phrase, , is semantically equal to This is not correct since all streams don't create a (new) stream. Moreover, by definition, a stream is created by sending data[1] or STREAM frames implicitly create a stream[2]. This indicates a stream itself doesn't create another stream. [1] URL [2] URL
Looks good. Just a minor comment.

Revised text:
data on this stream.  Either frame might arrive before a STREAM or STREAM_DATA_BLOCKED frame if packets are lost or reordered.  <ins> Before a stream is created, all streams of the same type with lower- </ins> numbered stream IDs MUST be created.  This ensures that the creation order for streams is consistent on both endpoints.
Original text:
protection for all 0-RTT packets because the same key and nonce could be used to protect different content. <del> Receiving a Retry packet, especially a Retry that changes the connection ID used for subsequent packets, indicates a strong possibility that 0-RTT packets could be lost.  A client only receives acknowledgments for its 0-RTT packets once the handshake is complete. Consequently, a server might expect 0-RTT packets to start with a packet number of 0.  Therefore, in determining the length of the packet number encoding for 0-RTT packets, a client MUST assume that all packets up to the current packet number are in flight, starting from a packet number of 0.  Thus, 0-RTT packets could need to use a longer packet number encoding. </del>  A client MUST NOT send 0-RTT packets once it starts processing 1-RTT packets from the server.  This means that 0-RTT packets cannot

Reviewer comments:
Retry always changes the connection ID.
NAME The paragraph 2 before this one says exactly that.
Ah... I missed that. Thanks for pointing it out NAME

Revised text:
protection for all 0-RTT packets because the same key and nonce could be used to protect different content.  <ins> A client only receives acknowledgments for its 0-RTT packets once the handshake is complete.  Consequently, a server might expect 0-RTT packets to start with a packet number of 0.  Therefore, in determining the length of the packet number encoding for 0-RTT packets, a client MUST assume that all packets up to the current packet number are in flight, starting from a packet number of 0. Thus, 0-RTT packets could need to use a longer packet number encoding. </ins> A client MUST NOT send 0-RTT packets once it starts processing 1-RTT packets from the server.  This means that 0-RTT packets cannot
Original text:
If the packet is a 0-RTT packet, the server MAY buffer a limited number of these packets in anticipation of a late-arriving Initial <del> Packet.  Clients are forbidden from sending Handshake packets prior to receiving a server response, so servers SHOULD ignore any such </del>  packets. Servers MUST drop incoming packets under all other circumstances.

Reviewer comments:
Clients aren't forbidden from sending a Handshake packet before receiving the ServerHello, they just don't have the keys to do so.
LGTM

Revised text:
If the packet is a 0-RTT packet, the server MAY buffer a limited number of these packets in anticipation of a late-arriving Initial  <ins> packet.  Clients are not able to send Handshake packets prior to receiving a server response, so servers SHOULD ignore any such </ins> packets. Servers MUST drop incoming packets under all other circumstances.
Original text:
with any other value as a connection error of type PROTOCOL_VIOLATION. <del> Early data within the TLS connection MUST NOT be used.  As it is for other TLS application data, a server MUST treat receiving early data on the TLS connection as a connection error of type PROTOCOL_VIOLATION. </del> 4.6. A server rejects 0-RTT by rejecting 0-RTT at the TLS layer.  This

Reviewer comments:
As of -12, TLS records are not used in QUIC (TLS handshake messages are directly transmitted instead), and therefore it is impossible in QUIC to transmit early data using the machinery provided by TLS.

Revised text:
with any other value as a connection error of type PROTOCOL_VIOLATION.  4.6. A server rejects 0-RTT by rejecting 0-RTT at the TLS layer.  This