jiebi/TextFlow huggingface dataset:
Original text:
protect different content.  A server MAY abort the connection if it detects that the client reset the packet number. <del> A server acknowledges the use of a Retry packet for a connection using the retry_source_connection_id transport parameter; see transport-parameter-definitions.  If the server sends a Retry packet, it also subsequently includes the value of the Source Connection ID field from the Retry packet in its retry_source_connection_id transport parameter. If the client received and processed a Retry packet, it MUST validate that the retry_source_connection_id transport parameter is present and correct; otherwise, it MUST validate that the transport parameter is absent.  A client MUST treat a failed validation as a connection error of type PROTOCOL_VIOLATION. </del>  17.3.

Reviewer comments:
Please review carefully, but I think we can replace these paragraphs with a reference.
Nice find, thanks NAME !

Revised text:
protect different content.  A server MAY abort the connection if it detects that the client reset the packet number.  <ins> The connection IDs used on Initial and Retry packets exchanged between client and server are copied to the transport parameters and validated as described in cid-auth. </ins> 17.3.
Original text:
QUIC packet and framing add at least 36 bytes of overhead to the ClientHello message.  That overhead increases if the client chooses a <del> connection ID without zero length.  Overheads also do not include the token or a connection ID longer than 8 bytes, both of which might be required if a server sends a Retry packet. </del>  A typical TLS ClientHello can easily fit into a 1200-byte packet. However, in addition to the overheads added by QUIC, there are Session resumption allows servers to link activity on the original connection with the resumed connection, which might be a privacy issue for clients.  Clients can choose not to enable resumption to <del> avoid creating this correlation.  Client SHOULD NOT reuse tickets as </del>  that allows entities other than the server to correlate connections; see Section C.4 of TLS13. Packets protected with Initial secrets (initial-secrets) are not authenticated, meaning that an attacker could spoof packets with the intent to disrupt a connection.  To limit these attacks, Initial <del> packet protection keys can be discarded more aggressively than other </del>  keys. The successful use of Handshake packets indicates that no more

Reviewer comments:
Too fast! Thanks.
This will require rewrapping, which I can do if you prefer.

Revised text:
QUIC packet and framing add at least 36 bytes of overhead to the ClientHello message.  That overhead increases if the client chooses a  <ins> source connection ID longer than zero bytes.  Overheads also do not include the token or a destination connection ID longer than 8 bytes, both of which might be required if a server sends a Retry packet. </ins> A typical TLS ClientHello can easily fit into a 1200-byte packet. However, in addition to the overheads added by QUIC, there are Session resumption allows servers to link activity on the original connection with the resumed connection, which might be a privacy issue for clients.  Clients can choose not to enable resumption to  <ins> avoid creating this correlation.  Clients SHOULD NOT reuse tickets as </ins> that allows entities other than the server to correlate connections; see Section C.4 of TLS13. Packets protected with Initial secrets (initial-secrets) are not authenticated, meaning that an attacker could spoof packets with the intent to disrupt a connection.  To limit these attacks, Initial  <ins> packet protection keys are discarded more aggressively than other </ins> keys. The successful use of Handshake packets indicates that no more
Original text:
endpoint.  The connection ID is used by endpoints and the intermediaries that support them to ensure that each QUIC packet can be delivered to the correct instance of an endpoint.  At the <del> endpoint, the connection ID is used to identify which QUIC connection the packet is intended for. </del>  The connection ID is chosen by each endpoint using version-specific methods.  Packets for the same QUIC connection might use different

Reviewer comments:
Issue raised by NAME via : OLD:/At the endpoint, the connection ID is used to identify which QUIC connection the packet is intended for./ NEW:/At the endpoint, the connection ID is used to identify the QUIC connection for which the packet is intended./
Sounds good. I'll do that too. I have read Version-Independent Properties of QUIC (-30) in the WGLC and think this is ready, I found 3 editorial comments that might need consideration after the WGLC: (i) I suggest the introduction for this spec starts abruptly. Is it worth considering one sentence top explain what QUIC is, in case someone read this document first? - One possible solution could be to move the text in section 3 to section 1? (To me, the section 3 text does not need to come after the Section 2 definitions.) (ii) Does this read better with /for/ moved within the sentence? OLD:/At the endpoint, the connection ID is used to identify which QUIC connection the packet is intended for./ NEW:/At the endpoint, the connection ID is used to identify the QUIC connection for which the packet is intended./ (iii) I see the desire to emphasise the “NOT”, but I query if this is correct usage of a RFC2119 keyword in Appendix A?: /The following statements are NOT guaranteed to be true for every QUIC version:/ Best wishes, Gorry

Revised text:
endpoint.  The connection ID is used by endpoints and the intermediaries that support them to ensure that each QUIC packet can be delivered to the correct instance of an endpoint.  At the  <ins> endpoint, the connection ID is used to identify the QUIC connection for which the packet is intended. </ins> The connection ID is chosen by each endpoint using version-specific methods.  Packets for the same QUIC connection might use different
Original text:
If an endpoint has cause to expect that IP packets with an ECT codepoint might be dropped by a faulty network element, the endpoint could set an ECT codepoint for only the first ten outgoing packets on <del> a path, or for a period of three RTTs.  If all packets marked with non-zero ECN codepoints are subsequently lost, it can disable marking on the assumption that the marking causes in loss. </del>  An endpoint thus attempts to use ECN and validates this for each new connection, when switching to a server's preferred address, and on

Reviewer comments:
I tried to just make a note here saying "if you don't send many packets, you won't send many packets", but then decided that 3PTO is probably more sensible. As it is, 3 RTT is the value that the PTO is initialized to (validation almost always happens on a new path). And the loss of a single packet just doesn't cut it. Even 3 packets (the first packet, plus two on PTO, assuming two are sent on PTO) is not that strong, but at least it isn't insanely tight.
URL and URL describe ECN validation and they say : dropped by a faulty network element, an endpoint could set the ECT(0) codepoint for only the first ten outgoing packets on a path, or for a period of three RTTs, whichever occurs first. Initial PTO timeout is also 3RTT. If client does not get ACK for its first flight Initial, after 3RTT later, it resends Initial without ECT set because client is now in "UNKNOWN" state. If the first client Initial is really lost, ECN validation fails. It seems to me that it would be better to lengthen timeout or ensure enough packets are sent not limited by the timeout?
It seems like this particular problem was introduced by reducing the initial RTT from 500ms to 333ms (in ).
We use 3*PTO everywhere else, so suggesting it here makes sense to me.

Revised text:
If an endpoint has cause to expect that IP packets with an ECT codepoint might be dropped by a faulty network element, the endpoint could set an ECT codepoint for only the first ten outgoing packets on  <ins> a path, or for a period of three PTOs (see Section 6.2 of QUIC- RECOVERY).  If all packets marked with non-zero ECN codepoints are subsequently lost, it can disable marking on the assumption that the marking causes in loss. </ins> An endpoint thus attempts to use ECN and validates this for each new connection, when switching to a server's preferred address, and on
Original text:
7. <del> It is possible that middleboxes could use traits of a specific </del>  version of QUIC and assume that when other versions of QUIC exhibit similar traits the same underlying semantic is being expressed. There are potentially many such traits; see bad-assumptions.  Some

Reviewer comments:
I can't stop re-reading this text. There isn't much of it, but that makes it easier to spot little annoyances like this.

Revised text:
7.  <ins> It is possible that middleboxes could observe traits of a specific </ins> version of QUIC and assume that when other versions of QUIC exhibit similar traits the same underlying semantic is being expressed. There are potentially many such traits; see bad-assumptions.  Some
Original text:
4.5.6. <del> The literal field line without name reference representation encodes a field name and a field value as string literals. </del>  This representation begins with the '001' three-bit pattern.  The fourth bit is the 'N' bit as described in literal-name-reference.

Reviewer comments:
This saves bytes (that's the most important reason). This uses something positive rather than something negative to define the instruction. Yes, it means that there are two "Literal"s in the name of an instruction. But now it says what is inside rather than what isn't.
NAME I can't solve all the problems :) I think that in HPACK "literal" was reserved for the value more than the name. Maybe this only highlights that...
I understand. This commit at least solves some of them, thank you for the improvement!
Beauty is in the eye of the beholder. What am I to do with all the "wonr" variable names?
Without Name Reference might be better replaced as "With Literal Name" (Damn my enter key...)
Also consider changing on line 1640, but GitHub won't let me comment that far from a change.I think this is an improvement. It has always bothered me that "literal field line" is used in sitations when only part of the field line is literal, and this change does not address that. An alternative would be: insert with literal name => insert literal field line (or literal entry) literal field line with name reference => field line with name reference and literal value literal field line with literal name => literal field lineSeems like a sensible change.

Revised text:
4.5.6.  <ins> The literal field line with literal name representation encodes a field name and a field value as string literals. </ins> This representation begins with the '001' three-bit pattern.  The fourth bit is the 'N' bit as described in literal-name-reference.
Original text:
Errors that result in the connection being unusable, such as an obvious violation of protocol semantics or corruption of state that affects an entire connection, MUST be signaled using a <del> CONNECTION_CLOSE frame (frame-connection-close).  An endpoint MAY close the connection in this manner even if the error only affects a single stream. </del>  Application-specific protocol errors are signaled using the CONNECTION_CLOSE frame with a frame type of 0x1d.  Errors that are

Reviewer comments:
The spec says: First of all, I have no idea what a "corruption of state" is supposed to be. More importantly, the second sentence seems to suggest that if an error only affects a single stream, it might not be required to send a connection-level error. I'm thinking of a stream-level flow control violation.
The challenge here is that the transport doesn't define how streams can be used by application layer protocols, but seems to want to strongly encourage how an application uses error codes. An example of "corruption of state" is something like a QPACK error that renders the HTTP/3 connection unusable because the QPACK state cannot be assured. In contrast, an application might treat receiving a header with an uppercase field name as a stream error that otherwise would not affect the rest of the H3 connection.
Anything remain to be done here?
It seems like NAME is interpreting this sentence as only applying to application protocol errors. If that's the intention, we should make that clear:
It's not exclusive to the application. Another example of corrupt state at the transport layer is CRYPTOBUFFEREXCEEDED -- you had to drop some bytes, so now your TLS handshake state is corrupted. As to the second piece, I think you're reading that backward. A stream error MAY always be promoted to a connection error if the implementation decides it's severe enough; it doesn't say anything about deciding to downplay errors if they're localized. If an error is defined to be a connection error, it's a connection error. If it's defined to be a stream error, however, you're always allowed to decide it's the last straw and walk away.
QUIC transport does not have stream-level errors, though applications can. As such, the last sentence references a circumstance that does not exist in the transport draft. So the best solution seems to be to remove the last sentence.
NAME : to your two points: "corruption of state that affects an entire connection" is clear that if the connection state is affected then it should result in a connection error agree that the second sentence seems unnecessary entirely, since stream-level errors are always treated as connection errors within the transport.

Revised text:
Errors that result in the connection being unusable, such as an obvious violation of protocol semantics or corruption of state that affects an entire connection, MUST be signaled using a  <ins> CONNECTION_CLOSE frame (frame-connection-close). </ins> Application-specific protocol errors are signaled using the CONNECTION_CLOSE frame with a frame type of 0x1d.  Errors that are
Original text:
a path, or for a period of three PTOs (see Section 6.2 of QUIC- RECOVERY).  If all packets marked with non-zero ECN codepoints are subsequently lost, it can disable marking on the assumption that the <del> marking causes in loss. </del>  An endpoint thus attempts to use ECN and validates this for each new connection, when switching to a server's preferred address, and on

Reviewer comments:
Section 13.4.2: If all packets marked with non-zero ECN codepoints are subsequently lost, it can disable marking on the assumption that the marking causes in loss. s/in/the?

Revised text:
a path, or for a period of three PTOs (see Section 6.2 of QUIC- RECOVERY).  If all packets marked with non-zero ECN codepoints are subsequently lost, it can disable marking on the assumption that the  <ins> marking caused the loss. </ins> An endpoint thus attempts to use ECN and validates this for each new connection, when switching to a server's preferred address, and on
Original text:
A sender SHOULD restart its PTO timer every time an ack-eliciting packet is sent or acknowledged, when the handshake is confirmed (Section 4.1.2 of QUIC-TLS), or when Initial or Handshake keys are <del> discarded (Section 9 of QUIC-TLS).  This ensures the PTO is always </del>  set based on the latest estimate of the round-trip time and for the correct packet across packet number spaces. 6.4. <del> When packet protection keys are discarded (see Section 4.8 of QUIC- </del>  TLS), all packets that were sent with those keys can no longer be acknowledged because their acknowledgements cannot be processed anymore.  The sender MUST discard all recovery state associated with

Reviewer comments:
So there are a couple of section references in the doc that points the wrong section in other documents. Section 6.2.1: "A sender SHOULD restart its PTO timer every time an ack-eliciting packet is sent or acknowledged, when the handshake is confirmed (Section 4.1.2 of [QUIC-TLS]), or when Initial or Handshake keys are discarded (Section 9 of [QUIC-TLS])", should that last ref be to section 4.9 in QUIC-TLS?"Section 6.4: "see Section 4.8 of [QUIC-TLS])" This is now Section 4.9.Section B.2: maxdatagramsize: The sender's current maximum payload size. Does not include UDP or IP overhead. The max datagram size is used for congestion window computations. An endpoint sets the value of this variable based on its PMTU (see Section 14.1 of [QUIC-TRANSPORT]), with a minimum value of 1200 bytes." Should that Section 14.1 reference be to 14.2.
Thank you for catching these, NAME

Revised text:
A sender SHOULD restart its PTO timer every time an ack-eliciting packet is sent or acknowledged, when the handshake is confirmed (Section 4.1.2 of QUIC-TLS), or when Initial or Handshake keys are  <ins> discarded (Section 4.9 of QUIC-TLS).  This ensures the PTO is always </ins> set based on the latest estimate of the round-trip time and for the correct packet across packet number spaces. 6.4.  <ins> When packet protection keys are discarded (see Section 4.9 of QUIC- </ins> TLS), all packets that were sent with those keys can no longer be acknowledged because their acknowledgements cannot be processed anymore.  The sender MUST discard all recovery state associated with
Original text:
attacker. Future versions of QUIC may have different requirements for the <del> lengths of connection IDs larger than version 1.  In particular, connection IDs might not be required to have a minimum lengths, and might be longer than 20 bytes.  A server therefore MUST respond with a Version Negotiation packets for all lengths of connection IDs allowed by the layout defined here. </del>  The remainder of the Version Negotiation packet is a list of 32-bit versions that the server supports.

Reviewer comments:
Could we also maybe add a pointer to the requirement that a DCID in an Initial must be eight bytes to Section 17.2? Because at the moment, it's buried in Section 7.2, where I didn't find it.
I've taken this change manually, after reverting the change to the invariants doc. After looking at this more closely, the invariants doc does not include specifics of how to generate a Version Negotiation packet and this takes an awkward step in that direction. Rather than start to import the rules into invariants piecemeal like this, I think that it is cleaner to leave the rules for generating a Version Negotiation packet as version-specific, which is already clearly the case.
Addendum: I missed the bit about this being a blanket "version-specific rules for packets". I've changed this to "version-specific rules for connection IDs", to reflect the context better. And to avoid tripping up on the packet size rules in version 1.
Since future QUIC versions might have different CID length requirements for Initial packets (or however that packet type will be called in that version), we already require servers to be able to send Version Negotiation packets with CIDs longer than 20 bytes (which is the maximum length that v1 allows). We need to clarify that this also applies to the minimum CID length, which is 8 byte for the DCID in v1. A future version of QUIC might relax this limit, so a server also needs to generate a VN packet if it receives a packet with an unknown version and a shorter DCID, otherwise it won't be possible to roll out such a QUIC version. This is coming out of a Slack discussion with NAME and NAME as well as recent tests on the interop runner. It turns out that 2 server implementations on the interop runner didn't get this right, and at least one server implementation that's not on the interop runner, but is running QUIC in production.
I think the CID specific aspect is fine. It is unclear what other aspects that are specified by the protocol and are not invariant here.

Revised text:
attacker. Future versions of QUIC may have different requirements for the  <ins> lengths of connection IDs.  In particular, connection IDs might have a smaller minimum length or a greater maximum length.  Version- specific rules for QUIC packets therefore MUST NOT influence a server decision about whether to send a Version Negotiation packet. </ins> The remainder of the Version Negotiation packet is a list of 32-bit versions that the server supports.
Original text:
Removing header protection only differs in the order in which the packet number length (pn_length) is determined.  fig-sample shows an example long header packet (Initial) and a short header packet. fig-sample shows the fields in each header that are covered by header protection and the portion of the protected packet AES is defined in AES. This algorithm samples 16 bytes from the packet ciphertext.  This <del> value is used as the input to AES-ECB.  In pseudocode: </del>  5.4.4. a sequence of 32-bit little-endian integers. The encryption mask is produced by invoking ChaCha20 to protect 5 <del> zero bytes.  In pseudocode: </del>  5.5.

Reviewer comments:
This could have been more explicit, so now it is. Doubly so.
Section 5.4.1, Figure 6: mask = headerprotection(hpkey, sample) I think it is a bit unclear that the headerprotection function is what is producing the stream cipher cipher text that will be masked and xored with the header bits. Especially as the instantiations of these functions for AESGCM (Section 5.4.3) and ChaCha20 (Section 5.4.4) is not defined as instantiation of that function, only as providing the same variable output. I think this could be clarified in both places so that the linkage between the general application and the stream cipher producing function is clear.
Looks good and resolve my issue.
indubitably

Revised text:
Removing header protection only differs in the order in which the packet number length (pn_length) is determined. <ins> Specific header protection functions are defined based on the selected cipher suite; see hp-aes and hp-chacha. </ins> fig-sample shows an example long header packet (Initial) and a short header packet. fig-sample shows the fields in each header that are covered by header protection and the portion of the protected packet AES is defined in AES. This algorithm samples 16 bytes from the packet ciphertext.  This  <ins> value is used as the input to AES-ECB.  In pseudocode, the header protection function is defined as: </ins> 5.4.4. a sequence of 32-bit little-endian integers. The encryption mask is produced by invoking ChaCha20 to protect 5  <ins> zero bytes.  In pseudocode, the header protection function is defined as: </ins> 5.5.