Original text:
6.3.2. <del> When a PTO timer expires, the sender MUST send one ack-eliciting packet as a probe, unless there is nothing to send.  A sender MAY send up to two ack-eliciting packets, to avoid an expensive consecutive PTO expiration due to a single packet loss. </del>  Consecutive PTO periods increase exponentially, and as a result, connection recovery latency increases exponentially as packets Sending different payloads each time reduces the chances of spurious retransmission. <del> When a PTO timer expires, new or previously-sent data may not be available to send and packets may still be in flight.  A sender can be blocked from sending new data in the future if packets are left in flight.  Under these conditions, a sender SHOULD mark any packets still in flight as lost.  If a sender wishes to establish delivery of packets still in flight, it MAY send an ack-eliciting packet and re- arm the PTO timer instead. </del> 6.3.3. Delivery or loss of packets in flight is established when an ACK

Reviewer comments:
This PR adds text and pseudo-code to clarify what an endpoint should do when PTO fires and there is no data or other ack-eliciting frames to send.
NAME I've done s/endpoint/sender. Let's deal with this separately. On the SHOULD, thinking about this, yes, I think I agree with you. I'll modify the PR, let's see how that looks.
Ok, modified, take a look
As written now, this swaps a SHOULD and a MAY, so I'm changing it to design.
As discussed with NAME 6.2.2.2 is awkward, because in the first paragraph it says And then the very last paragraph changes that by saying What is super unclear is that the final paragraph apparently means to imply that when there is no new or unACKed data to send, nothing should be send, i.e., it invalidates the SHOULD in the first paragraph. Related to that, the pseudo code still uses , which is also inaccurate, since it's really "at least one (unless you don't have new or unACKed data) but can also send two". Good luck finding a good name for that function :-)
The pseudocode now uses SendOneOrTwoPackets(), but the last paragraph pretty clearly violates the previous MUST, which is very bad. The simplest fix would be to change the MUST to a "SHOULD unless otherwise specified", but I'm increasingly thinking we should stick with the MUST and if you get into a situation you have nothing to send, require sending something ack-eliciting to ensure in-flight packets are removed from flight. Thoughts?

Revised text:
6.3.2.  <ins> When a PTO timer expires, a sender MUST send at least one ack- eliciting packet as a probe, unless there is no data available to send.  An endpoint MAY send up to two ack-eliciting packets, to avoid an expensive consecutive PTO expiration due to a single packet loss. It is possible that the sender has no new or previously-sent data to send.  As an example, consider the following sequence of events: new application data is sent in a STREAM frame, deemed lost, then retransmitted in a new packet, and then the original transmission is acknowledged.  In the absence of any new application data, a PTO timer expiration now would find the sender with no new or previously- sent data to send. When there is no data to send, the sender SHOULD send a PING or other ack-eliciting frame in a single packet, re-arming the PTO timer. Alternatively, instead of sending an ack-eliciting packet, the sender MAY mark any packets still in flight as lost.  Doing so avoids sending an additional packet, but increases the risk that loss is declared too aggressively, resulting in an unnecessary rate reduction by the congestion controller. </ins> Consecutive PTO periods increase exponentially, and as a result, connection recovery latency increases exponentially as packets Sending different payloads each time reduces the chances of spurious retransmission.  6.3.3. Delivery or loss of packets in flight is established when an ACK