Change:
the receiver SHOULD repeatedly acknowledge newly received packets in preference to packets received in the past. <ins> An endpoint SHOULD treat receipt of an acknowledgment for a packet it did not send as a connection error of type PROTOCOL_VIOLATION, if it is able to detect the condition. </ins> 13.1.2. ACK frames MUST only be carried in a packet that has the same packet

Discussion:
This is stacked on top of . So it looks worse than it really is. Review .
As discussed in URL, I'd like to advocate for introducing a new error code for loss recovery-related errors, e.g. when an unsent packet (in a respective packet number space) is acknowledged. In general, we have transport error codes to describe the area where an error occurred. For example, we have a STREAMSTATEERROR, which is used when the peer sends frames for the wrong stream type or unopened stream types. And we have a FLOWCONTROLERROR, for, obviously, flow-control related errors. Generating ACKs for multiple packet number spaces is not a trivial thing to do, and it would be of great help for debugging to have a more specific error here than the catch-all PROTOCOLVIOLATION.
I think this is best served in the associated error message string. In production this is a real attack, and less information to the attacker is a good thing.
Then why do we have different error codes stream states, flow control etc.? There are real attacks here as well, and I don't see why they would be less severe than loss recovery-related attacks. At least we should be consistent. If we really say that all errors just give an attacker more information, let's kill all error codes except NOERROR and SERVERBUSY.
(I sense sarcasm) MQTT tried to do that, but people were unhappy so they added more error codes, e.g. when incorrectly connecting multiple clients with the same client ID which was an easy mistake.
More seriously, an attacker could use the error code to find a way to avoid hitting gaps in optimistic acks with high probability. Granted, the attacker could probably also use PROTOCOL_VIOLATION to infer that, once it is confident it has a working implementation.
I'd like to add an error code for this. In general, I don't think we have a consistent view on error codes and error strings at the moment. We removed a lot of error codes around the time of the Paris interim, many of which could not be sent on the wire and so really needed to be removed. But we haven't added many(if any?) back and this seems like a good one to add.

But if we think the error code is providing too much information to the peer, then error details is almost certainly even more, unless it's always empty, in which case what's the point?
The error details can be flagged out in production and used for debugging. Perhaps there should be some guidelines on that.
Actually, optimistic ACK's could also be defended against by ignoring the invalid ACK's and silently downgrade the connection to min CWND. That would provide even less feedback to an attacker. But of course an error is needed for debugging. Not sure I would recommend this - but it is an option.
NAME I like the way you frame the issue. It is my understanding that we have so far assigned error codes for each feature rather than every one of the specific errors. Calling it "loss recovery-related errors" certainly follows that practice. The question is if there is a group of errors that fall into the category. Do you have something other than ACK containing an invalid packet number in mind?
I can think of three different cases why an ACK would contain an invalid packet number: the obvious case: you ack a too high packet number, which wasn't sent yet you ack in the wrong packet number space. This will most likely look like you acked a packet that the peer didn't send (in that packet number space) I assume that most implementations will sooner or later implement skipping of packet numbers as a mitigation of the optimistic ack attack. This error would occur when you ack a packet number that was intentionally skipped.
NAME Thank you for elaborating. To me it sounds that they would look like one symptom to the reciever; i.e. an invalid PN in ACK. I was wondering if there is a intent to use the error code for other symptoms, because it would imply that there are group of errors that might be categorized as a group (based on my understanding that we assign error codes to each feature or category). Though I am not strongly opposed to having an error code for this case, I fear if having an error code for this opens can of worms (i.e. "we have error code for this, so why not have another error code for X"). Therefore am trying to see what the line we would be trying to hold is.

I must have been dumb, but I now realize that the proposed error code would be equivalent of a connection error of (errorcode=PROTOCOLVIOLATION, frame_type=ACK)? Am I correct? Assuming that is correct, I wonder if we achieve anything by having a new error code.
NAME you make a good point. I think it'd be preferable to remove the frame type and have more error codes, but I think we'll get to have that larger discussion in Tokyo.
This error condition is a symptom of the "optimistic ack" attack. If I am under attack, I don't want to give more info to the attacker. Generic connection close is fine.
In Tokyo: close with no action.
I can't find text about this case anywhere. A peer that receives an acknowledgement for a packet that it didn't send should be required to close the connection. I'm not sure which error code to use for that though, none of those currently defined really matches this case, so you'd have to use INTERNAL_ERROR. We might want to consider introducing a more specific error code.
I think you are expected to use PROTOCOLVIOLATION in such case. Quoting from editors' draft: An endpoint detected an error with protocol compliance that was not covered by more specific error codes._ FWIW, I think that the requirement should be no stronger than "SHOULD if detected", to avoid endpoints memoizing the gaps for the previous 231 range. I assume that endpoints would typically just drop packets carrying a PN that is deemed too old.
This is always considered to be an Optimistic ACK attack. The only response is to treat the peer as hostile. URL
NAME If an endpoint cannot prove it didn't send the packet, it should just ignore the ACK for that particular packet. The congestion controller should not be sensitive to packets that old, so the Optimistic ACK attack is harmless in this case. Dropping the entire packet containing an ACK with an old packet is likely too strong - ignoring the ACK for the packet is sufficient. If a peer continually sends ACK's for very old packets, that might go under weird behaviour similar to sending too many gaps, and an implementation could decide the peer is being too confused and close the connection with an error.

FYI: the reason this always needs to be treated as hostile (when provable) is because it is the only defence against the potentially very harmful optimistic ack attack. There are very few other other reasons to have gaps in the range, such as when having multiple concurrent transmit queues.