jiebi/TextFlow huggingface dataset:
Original text:
begin gathering candidates for each transport, using ones from the candidate pool if available. <del> If setRemoteDescription was previously called with an offer, and </del>  setLocalDescription is called with an answer (provisional or final), <del> and the media directions are compatible, and media is available to send, this will result in the starting of media transmission. </del>  4.1.10. This API changes the local media state; among other things, it sets up local resources for sending and encoding media. <del> If setLocalDescription was previously called with an offer, and </del>  setRemoteDescription is called with an answer (provisional or final), <del> and the media directions are compatible, and media is available to send, this will result in the starting of media transmission. </del>  4.1.11.

Reviewer comments:
clarified that there are four conditions, removed comment. issue 14
14) [rfced] Sections 4.1.9 and 4.1.10: We had trouble following the purpose of all of the "and"s in these sentences. Are four conditions set in these sentences, or fewer? Original: If setRemoteDescription was previously called with an offer, and setLocalDescription is called with an answer (provisional or final), and the media directions are compatible, and media is available to send, this will result in the starting of media transmission. ... If setLocalDescription was previously called with an offer, and setRemoteDescription is called with an answer (provisional or final), and the media directions are compatible, and media is available to send, this will result in the starting of media transmission. Possibly: If (1) setRemoteDescription was previously called with an offer, (2) setLocalDescription is called with an answer (provisional or final), (3) the media directions are compatible, and (4) media is available to send, media transmission can start. ... If (1) setLocalDescription was previously called with an offer, (2) setRemoteDescription is called with an answer (provisional or final), (3) the media directions are compatible, and (4) media is available to send, media transmission can start.
need to keep 'this will result in the starting of media transmission'
There are 4 conditions that have to be satisfied, as noted.

Revised text:
begin gathering candidates for each transport, using ones from the candidate pool if available.  <ins> If (1) setRemoteDescription was previously called with an offer, (2) </ins> setLocalDescription is called with an answer (provisional or final),  <ins> (3) the media directions are compatible, and (4) media is available to send, this will result in the starting of media transmission. </ins> 4.1.10. This API changes the local media state; among other things, it sets up local resources for sending and encoding media.  <ins> If (1) setLocalDescription was previously called with an offer, (2) </ins> setRemoteDescription is called with an answer (provisional or final),  <ins> (3) the media directions are compatible, and (4) media is available to send, this will result in the starting of media transmission. </ins> 4.1.11.
Original text:
4.1.9. <del> The canTrickleIce property indicates whether the remote side supports receiving trickled candidates.  There are three potential values: </del>  No SDP has been received from the other side, so it is not known if it can handle trickle.  This is the initial value before As described in sec.ice-candidate-trickling, JSEP implementations always provide candidates to the application individually, consistent with what is needed for Trickle ICE.  However, applications can use <del> the canTrickleIce property to determine whether their peer can actually do Trickle ICE, i.e., whether it is safe to send an initial offer or answer followed later by candidates as they are gathered. As "true" is the only value that definitively indicates remote Trickle ICE support, an application which compares canTrickleIce against "true" will by default attempt Half Trickle on initial offers and Full Trickle on subsequent interactions with a Trickle ICE- compatible agent. </del>  4.1.10.

Reviewer comments:
It has a new name.
Overall this LG, although having thought about it a bit more, .canTrickleIce seems like a not-fully-formed clause. .canTrickleIceCandidates seems like it might match better to addIceCandidate().
LGTM. NAME NAME LMK if you have any issues with this
The diff is incomprehensible due to the all the gratuitous whitespace changes. I'll make a diff I can review at some point and see if I can figure it out.
LGTM
I will manually merge this.

Revised text:
4.1.9.  <ins> The canTrickleIceCandidates property indicates whether the remote side supports receiving trickled candidates.  There are three potential values: </ins> No SDP has been received from the other side, so it is not known if it can handle trickle.  This is the initial value before As described in sec.ice-candidate-trickling, JSEP implementations always provide candidates to the application individually, consistent with what is needed for Trickle ICE.  However, applications can use  <ins> the canTrickleIceCandidates property to determine whether their peer can actually do Trickle ICE, i.e., whether it is safe to send an initial offer or answer followed later by candidates as they are gathered.  As "true" is the only value that definitively indicates remote Trickle ICE support, an application which compares canTrickleIceCandidates against "true" will by default attempt Half Trickle on initial offers and Full Trickle on subsequent interactions with a Trickle ICE-compatible agent. </ins> 4.1.10.
Original text:
Likewise, the requirements for parameters on templated links are the same as those for a Link header field.  This specification defines additional semantics for the "var-base" parameter on templated links; see below.

Reviewer comments:
Has there been any consideration of allowing a URI Template for the parameter? A particular use case would be for a collection resource that includes links from each item in the collection. If the media type supports fragments, then the item link could be templatized to point from specific locations in the representation. If we had a collection of books represented as an object with an array, and the instance media type allowed JSON Pointers: As an example of links between the full book resource and another resource, so as not to have to fetch the entire book resource if it is not needed, an author link template could be something like this (ignoring the likelihood of multiple authors): I was looking at this I-D in comparison to the (currently tabled) JSON Hyper-Schema project, and I think that anchor templates are the most notable relevant Hyper-Schema feature that is not present here. I would love to be able to use a revived Hyper-Schema as a bridge between a link-template header field and JSON-compatible data.

Revised text:
Likewise, the requirements for parameters on templated links are the same as those for a Link header field. <ins> However, the "anchor" parameter MAY contain a URI Template.  For example: Here, the link to the author for a particular book in a list of books can be found by following the link template. </ins> This specification defines additional semantics for the "var-base" parameter on templated links; see below.
Original text:
For example: indicates that a resource with the relation type <del> "https://example.org/rel/user" can be found by interpolating the </del>  "username" variable into the template given. The target for the link (as defined in WEB-LINKING) is the result of For example: indicates that a resource with the relation type <del> "https://example.org/rel/widget" can be found by interpolating the </del>  "https://example.org/vars/widget_id" variable into the template given.

Reviewer comments:
"interpolate" feels very odd. Other choices would be "expanding" or "substituting". I am not picky about the exact choice, but the current terminology seems odd.
The URI Template RFC uses 'expand', so that seems most appropriate.

Revised text:
For example: indicates that a resource with the relation type  <ins> "https://example.org/rel/user" can be found by expanding the </ins> "username" variable into the template given. The target for the link (as defined in WEB-LINKING) is the result of For example: indicates that a resource with the relation type  <ins> "https://example.org/rel/widget" can be found by expanding the </ins> "https://example.org/vars/widget_id" variable into the template given.
Original text:
To avoid this, the configuration agent SHOULD issue QUIC-LB configurations to mutually distrustful servers that have different <del> keys for encryption algorithms.  The load balancers can distinguish these configurations by external IP address, or by assigning different values to the config rotation bits (config-rotation).  Note that either solution has a privacy impact; see multiple-configs. These techniques are not necessary for the plaintext algorithm, as it does not attempt to conceal the server ID. </del>  11.5.

Reviewer comments:
Sec 11.4 recommends either separating mistrustful servers by IP, or assigning them different config rotation bits. The text is not adequate. Separating by IP address undermines the privacy value of ECHO & DoH (see the MAPRG IETF 110 talk) Any sub-IP routing has to be SNI-switched; if ECHO is operating, the load balancer must be a "client-facing server" in the ECHO architecture (draft-ietf-tls-esni Sec 3.1). Doing SNI switching as an ECHO server and then just encoding the result in the config rotation bits leaks the information they're trying to conceal. It might be worth it to fix up the "arbitrary algorithm" text to consider possible SNI switching. As we migrate towards ECHO and DoH, maybe the best we can do is give all tenants on an IP the same config and try to obscure their co-tenancy as much as possible.

Revised text:
To avoid this, the configuration agent SHOULD issue QUIC-LB configurations to mutually distrustful servers that have different  <ins> keys for encryption algorithms.  In many cases, the load balancers can distinguish these configurations by external IP address. However, assigning multiple entities to an IP address is complimentary with concealing DNS requests (e.g., DoH RFC8484) and the TLS Server Name Indicator (SNI) (I-D.ietf-tls-esni) to obscure the ultimate destination of traffic.  While the load balancer's fallback algorithm (fallback-algorithm) can use the SNI to make a routing decision on the first packet, there are three ways to route subsequent packets: all co-tenants can use the same QUIC-LB configuration, leaking the server mapping to each other as described above; co-tenants can be issued one of up to three configurations distinguished by the config rotation bits (config-rotation), exposing information about the target domain to the entire network; or tenants can use 4-tuple routing in their CIDs (in which case they SHOULD disable migration in their connections), which neutralizes the value of QUIC-LB but preserves privacy. When configuring QUIC-LB, administrators must evaluate the privacy tradeoff considering the relative value of each of these properties, given the trust model between tenants, the presence of methods to obscure the domain name, and value of address migration in the tenant use cases. As the plaintext algorithm makes no attempt to conceal the server mapping, these deployments SHOULD simply use a common configuration. </ins> 11.5.
Original text:
address validation. The 96 bit unique token number is set to a random value using a <del> cryptography- grade random number generator. </del>  The token key identifier and the corresponding AEAD key and AEAD IV are provisioned by the configuration agent. The input plaintext for the AEAD is the token body.  The output ciphertext of the AEAD is transmitted in place of the token body. <del> The AEAD Checksum is computed as part of the AEAD encryption process, and is verified during decryption. </del>  7.3.2. no token. The service SHOULD decrypt incoming tokens.  The service SHOULD drop <del> packets with unknown key sequence, or an AEAD checksum that does not match the expected value.  (By construction, the AEAD checksum will only match if the client IP Address also matches.) </del>  <del> If the token checksum passes, and the ODCIL and RSCIL fields are both zero, then this is a NEW_TOKEN token generated by the server. </del>  Processing of NEW_TOKEN tokens is subtly different from Retry tokens, as described below.

Reviewer comments:
detail info: fix a typo. change AEAD checksum to AEAD ICV(defined in rfc4106)
Hi martin: is not a standard name of AEAD verification message, which should be , see section 6 of rfc4106

Revised text:
address validation. The 96 bit unique token number is set to a random value using a  <ins> cryptography-grade random number generator. </ins> The token key identifier and the corresponding AEAD key and AEAD IV are provisioned by the configuration agent. The input plaintext for the AEAD is the token body.  The output ciphertext of the AEAD is transmitted in place of the token body.  <ins> The AEAD Integrity Check Value(ICV), defined in Section 6 of RFC4106, is computed as part of the AEAD encryption process, and is verified during decryption. </ins> 7.3.2. no token. The service SHOULD decrypt incoming tokens.  The service SHOULD drop  <ins> packets with unknown key sequence, or an AEAD ICV that does not match the expected value.  (By construction, the AEAD ICV will only match if the client IP Address also matches.) </ins>  <ins> If the token verification passes, and the ODCIL and RSCIL fields are both zero, then this is a NEW_TOKEN token generated by the server. </ins> Processing of NEW_TOKEN tokens is subtly different from Retry tokens, as described below.
Original text:
The tokens are protected using AES128-GCM as follows: <del> The token key and IV are retrieved using the Key Sequence. </del>  <del> The nonce, N, is formed by combining the IV with the 96 bit unique token number.  The 96 bits of the unique token number are left- padded with zeros to the size of the IV.  The exclusive OR of the padded unique token number and the IV forms the AEAD nonce. </del>  The associated data is a formatted as a pseudo header by combining the cleartext part of the token with the IP address of the client. The Shared-State Retry Service defined in shared-state-retry describes the format of retry tokens or new tokens protected and encrypted using AES128-GCM.  Each token includes a 96 bit randomly <del> generated unique token number, and an 8 bit identifier of the AES-GCM encryption key.  There are three important security considerations for these tokens: </del>  An attacker that obtains a copy of the encryption key will be able to decrypt and forge tokens.

Reviewer comments:
Made the changes to merge this.
Hi martin: The defination of and brought me a great confusion when I implement the share-state retry service. Though finally I got what the draft want to express, I still suggest we should give more information about them According to section 1.5 of rfc5084: According to section 3.4 of rfc5116 I guess that in current draft is the define in rfc5116, is just a random value(or a incrementing number) to generate . If I were true, please consider my PR for my suggestion.
Additional, it's no need to make the length of (current draft define) variable, just 96 bit is sufficient. Current aes-128-gcm related cipher suites all use this value
We can also add some illustration of , draft use in other place

Revised text:
The tokens are protected using AES128-GCM as follows:  <ins> The Key Sequence is the 8 bit identifier to retrieve the token key and IV. </ins>  <ins> The AEAD IV, is a 96 bit data which produced by implementer's custom AEAD IV derivation function. The AEAD nonce, N, is formed by combining the AEAD IV with the 96 bit unique token number.  The 96 bits of the unique token number are left-padded with zeros to the size of the IV.  The exclusive OR of the padded unique token number and the AEAD IV forms the AEAD nonce. </ins> The associated data is a formatted as a pseudo header by combining the cleartext part of the token with the IP address of the client. The Shared-State Retry Service defined in shared-state-retry describes the format of retry tokens or new tokens protected and encrypted using AES128-GCM.  Each token includes a 96 bit randomly  <ins> generated unique token number, and an 8 bit identifier used to get the AES-GCM encryption context.  The AES-GCM encryption context contains a 128 bit key and an AEAD IV.  There are three important security considerations for these tokens: </ins> An attacker that obtains a copy of the encryption key will be able to decrypt and forge tokens.
Original text:
MUST NOT reject tokens because they lack opaque data and therefore the packet number.  7.3.1. On the wire, the token is presented as:

Reviewer comments:
Secure ciphers are much more important for Shared State Retry than for the load balancer stuff and Initial Encryption. Therefore, some crypto agility to allow this mechanism to adapt as ciphers deprecate would be good. The key sequence can also imply a cipher, so we'll add that to the data model. Some fields will vary length based on the cipher. We should also make it so everyone MUST support AES128-GCM.

Revised text:
MUST NOT reject tokens because they lack opaque data and therefore the packet number. <ins> Shared-state Retry Services use the AES-128-ECB cipher.  Future standards could add new algorithms that use other ciphers to provide cryptographic agility in accordance with RFC7696.  Retry Service and server implementations SHOULD be extensible to support new algorithms. </ins> 7.3.1. On the wire, the token is presented as:
Original text:
7.  Some network architectures may have multiple tiers of low-state load balancers, where a first tier of devices makes a routing decision to the next tier, and so on until packets reach the server.  Although numbers of load-balancing tiers, as the maximum server ID space is quite large.  8. QUIC-LB is intended to prevent linkability.  Attacks would therefore

Reviewer comments:
Intended to
Some text on how a server cluster might support moving of connections from one server instance to another would be useful. The current design might permit portability under certain conditions, but there are things that might need to be considered, such as the way in stateless resets are generated.
Are you referring to load balancing already existing connections to a new server? Are you envisioning the first server issuing new CIDs (that point to the new server) and setting Retire Prior To to retire the old CIDs so that future traffic redirect to the new server? How do you imagine the rest of the connection state would get moved?
This applies to cases where clusters are rebalanced, where instances go down and others are expected to pick up the slack, and all similar cases. In some cases this requires an unspecified mechanism for transferring state between instances. In others, the instance might remain constant but the identifiers used might need to rotate. This is likely addressed by using Retire Prior To as you say. Text on that would help.
Good idea, it wouldn't hurt to have a short non-normative section on this.
Seems fine.

Revised text:
7. <ins> This section discusses considerations for some deployment scenarios not implied by the specification above. 7.1. </ins> Some network architectures may have multiple tiers of low-state load balancers, where a first tier of devices makes a routing decision to the next tier, and so on until packets reach the server.  Although numbers of load-balancing tiers, as the maximum server ID space is quite large. <ins> 7.2. Some deployments may transparently move a connection from one server to another.  The means of transferring connection state between servers is out of scope of this document. To support a handover, a server involved in the transition could issue CIDs that map to the new server via a NEW_CONNECTION_ID frame, and retire CIDs associated with the new server using the "Retire Prior To" field in that frame. Alternately, if the old server is going offline, the load balancer could simply map its server ID to the new server's address. </ins> 8. QUIC-LB is intended to prevent linkability.  Attacks would therefore
Original text:
6.2.  Some deployments may transparently move a connection from one server to another.  The means of transferring connection state between servers is out of scope of this document.

Reviewer comments:
Many server architectures have multiple processes. There are many ways to properly route packets between them, but many have severely limited capabilities. Add some non-normative text about options here: run QUIC-LB at the demultiplexer, packet toss, register connection IDs at the demultiplexer, or rewrite the CID with the decrypted one at the LB (which has security limitations)

Revised text:
6.2. <ins> QUIC servers might have QUIC running on multiple processes listening on the same address, and have a need to demultiplex between them.  In principle, this demultiplexer is a Layer 4 load balancer, and the guidance in lb-chains applies.  However, in many deployments the demultiplexer lacks the capability to perform decryption operations. There are some other techniques that might work, depending on the capabilities of the server architecture. Some bytes of the server ID are reserved to encode the process ID. The demultiplexer might operate based on the 4-tuple or other legacy indicator, but the receiving server process extracts the server ID, and if it does not match the one for that process, the process could "toss" the packet to the correct destination process. Each process could register the connection IDs it generates with the demultiplexer, which routes those connection IDs accordingly. Some bytes of the server ID are reserved to encode the process ID. The load balancer writes the decrypted connection ID into the packet.  The demultiplexer reads the process ID from the relevant bytes and routes it accordingly.  The receiving server process immediately re-encrypts the connection ID in deliver the packet to the correct connection and successfully authenticate the packet. While this requires coordination between load balancer and server, this document does not standardize the technique because it is unsafe to use unless the path between load balancer and server is fully secure.  An observer at that point can determine the server mapping via the IP address of the destination server, but the process ID provides additional linkability information. 6.3. </ins> Some deployments may transparently move a connection from one server to another.  The means of transferring connection state between servers is out of scope of this document.
Original text:
Local hardware cryptographic offload devices may accelerate QUIC servers by receiving keys from the QUIC implementation indexed to the connection ID.  However, on physical devices operating multiple QUIC <del> servers, it is impractical to efficiently lookup these keys if the connection ID does not self-encode its own length. </del>  Note that this is a function of particular server devices and is irrelevant to load balancers.  As such, load balancers MAY omit this

Reviewer comments:
This only applies if the CID varies in length (so say that). Also, it only applies if the common stem doesn't otherwise distinguish itself enough to allow an efficient lookup (so say "might" rather than get into all that). In other words, it's probably inefficient, but not necessarily so.

Revised text:
Local hardware cryptographic offload devices may accelerate QUIC servers by receiving keys from the QUIC implementation indexed to the connection ID.  However, on physical devices operating multiple QUIC  <ins> servers, it might be impractical to efficiently lookup keys if the connection ID varies in length and does not self-encode its own length. </ins> Note that this is a function of particular server devices and is irrelevant to load balancers.  As such, load balancers MAY omit this