Original text:
becoming idle.  Non-ack-eliciting packets are eventually acknowledged when the endpoint sends an ACK frame in response to other events.  In order to assist loss detection at the sender, an endpoint SHOULD generate and send an ACK frame without delay when it receives an ack- eliciting packet either: for connections made by the endpoint and for other users of the network. <del> An endpoint that is only sending ACK frames will not receive acknowledgments from its peer unless those acknowledgments are included in packets with ack-eliciting frames.  An endpoint SHOULD send an ACK frame with other frames when there are new ack-eliciting packets to acknowledge.  When only non-ack-eliciting packets need to be acknowledged, an endpoint MAY wait until an ack-eliciting packet has been received to include an ACK frame with outgoing frames. A receiver MUST NOT send an ack-eliciting frame in all packets that would otherwise be non-ack-eliciting, to avoid an infinite feedback loop of acknowledgments. </del> 13.2.2. A receiver determines how frequently to send acknowledgments in

Reviewer comments:
There is a little connective tissue added here to connect to the ACK tracking thing.
NAME -- ptal when you get a chance
In the Loss Recovery Pseudocode, is initialized to 0: URL This can result in dividing by zero if one implements a Cubic congestion controller () that incorporates (as the ). Cubic specifies the , used in congestion avoidance, as: An endpoint can enter congestion avoidance without receiving any acks for any ack-eliciting packets (only non-ack eliciting packets). In such a scenario, would still be 0, due to the requirement from : Since is 0 when is calculated, the divide by 0 occurs. This could be addressed by initializing to instead of 0.
FWIW this was changed from back to 0 in URL
I feel the existing pseudocode is ok, because minrtt in the text and pseudocode is used for the purpose of rejecting potentially bad RTT samples, and is not a general purpose minrtt. URL For example, BBR uses a windowed min_rtt that's fairly different. This does bring up an edge case I hadn't thought much about, where no ack-eliciting packets are acknowledged, but a packet is declared lost. A compliant transport implementation shouldn't ACK only ACK-only packets, but a non-compliant one could.

This does bring up an edge case I hadn't thought much about, where no ack-eliciting packets are acknowledged, but a packet is declared lost. A compliant transport implementation shouldn't ACK only ACK-only packets, but a non-compliant one could. The situation we saw was under severe packet loss, the peer sending probe packets containing a PING and ACK for non ack eliciting packets (ACKs and PADDING). The ACK-eliciting packets we send are getting dropped, so eventually we declare an ACK-eliciting packet lost and enter Recovery. When the next ACK comes in for a packet sent after we entered Recovery, we enter Congestion Avoidance and experience the issue with .
I'm still a bit unclear. Under what circumstances would a compliant peer send an ACK that only acknowledges non ack-eliciting packets?
After a probe timeout. Would that be non-compliant?
In regards to the issue originally raised about minrtt, I still feel the minrtt is not general purpose, so the originally stated issue is not a problem in the context of QUIC recovery. Other discussion follows. First, you'd have to complete the handshake without an RTT sample, which seems unlikely, but possible, so let's assume that. A PTO would send an ack-eliciting packet, and when the ACK for that packet came back, you'd have an RTT sample. However, if the peer was sending ACK+PING for every other ACK+PADDING packet, then you're correct that the incoming ACK bundled with the PING would not create an RTT measurement, but would allow any previously sent ACK-eliciting packets to be declared as lost if the packet threshold was reached. In regards to "peer sending probe packets containing a PING and ACK for non ack eliciting packets (ACKs and PADDING)", if you're saying that the peer is sending those in response to every ACK+PADDING packet, that sounds non-compliant to me. In regards to whether it's ok to send ACK+PING in response to ACK+PADDING, I re-read "Sending ACK Frames"(URL) and it says: "An endpoint MUST NOT send a non-ack-eliciting packet in response to a non-ack-eliciting packet, even if there are packet gaps that precede the received packet." Are you sending PADDING+PING due to that prohibition? I'm a bit concerned that could cause an infinite or near-infinite loop under the wrong circumstance, which was exactly the issue the paragraph highlights. The last paragraph does specifically preclude sending ack-eliciting packets in response to every non-ack-eliciting packet: "A receiver MUST NOT send an ack-eliciting frame in all packets that would otherwise be non-ack-eliciting, to avoid an infinite feedback loop of acknowledgments." It may make sense to move that final paragraph up, as it's a bit disconnected at the moment?
Agree that its not a problem within the context of QUIC recovery, I just wanted to call it out as an issue I experienced. If there wasn't much reason to initialize to 0 perhaps initializing to a value that is actually possible would make sense (and would prevent issues like the one I saw), but its not a big deal. Just to clarify, only the peer is sending PINGS in the scenario we saw (actually PADDING+PING+ACK) The peer is sending ack-eliciting packets (PADDING+PING+ACK) due to PTO timeouts, its not a case of upgrading non-ack-eliciting packets to ack-eliciting by throwing in a PING every time, more that the ACKs are getting included when the probes get sent. I did find this paragraph confusing until I read URL, I'm not sure moving it up would help without some additional rewording.
LG, one possible suggestion to a sentence I've been confused by before.

Revised text:
becoming idle.  Non-ack-eliciting packets are eventually acknowledged when the endpoint sends an ACK frame in response to other events. <ins> An endpoint that is only sending ACK frames will not receive acknowledgments from its peer unless those acknowledgments are included in packets with ack-eliciting frames.  An endpoint SHOULD send an ACK frame with other frames when there are new ack-eliciting packets to acknowledge.  When only non-ack-eliciting packets need to be acknowledged, an endpoint MAY choose not to send an ACK frame with outgoing frames until an ack-eliciting packet has been received. An endpoint that is only sending non-ack-eliciting packets might choose to occasionally add an ack-eliciting frame to those packets to ensure that it receives an acknowledgment; see ack-tracking.  In that case, an endpoint MUST NOT send an ack-eliciting frame in all packets that would otherwise be non-ack-eliciting, to avoid an infinite feedback loop of acknowledgments. </ins> In order to assist loss detection at the sender, an endpoint SHOULD generate and send an ACK frame without delay when it receives an ack- eliciting packet either: for connections made by the endpoint and for other users of the network.  13.2.2. A receiver determines how frequently to send acknowledgments in