This is all good and useful, but I wish OAuth folks would fix the bugs in the spec like, e.g.
"The authorization server MAY issue a new refresh token, in which case
the client MUST discard the old refresh token and replace it with the
new refresh token. The authorization server MAY revoke the old
refresh token after issuing a new refresh token to the client."
This sounds reasonable on the surface, and technically it might be correct (depending on your interpretation of the words). But if someone naively follows this instruction to implement the server - issue a new refresh token and revoke the old one in the same refresh request at the server, what happens is when the client doesn't receive the new refresh token due to any transient failure, the client effectively loses its authorization, since the old refresh token is revoked and they didn't get the new one. Thus the protocol becomes "leaky" - you lose users because of transient errors.
i.e. "after issuing a new refresh token to the client" needs to be "after the new refresh token is being used at least once", or otherwise invent some other way to ensure the new refresh token is correctly received at the client before revoking the old.
"… or otherwise invent some other way to ensure the new refresh token is correctly received at the client before revoking the old."
These sorts of details will typically wind up in an implementation report document. It's rare that an IETF protocol specification document will attempt to pre-determine the solution to all such implementation details up front, and IMO, not good when they do.
In some contexts, it may be much better to require the application to re-obtain resource owner authorisation than to allow a replay of a refresh token. In others, it may be much better to avoid requiring resource owner authorisation. What you see as a bug, others would see as a critical feature.
There are many parts to the spec for the full picture. This here specifies that server MAY issue a new refresh token (clarifying whether it is required), and if new refresh token is issued, the client MUST discard the old.
I believe the intention here is not to verify whether it was used once as you state. And transient matters (how the client will detect if not received would be a different scope), for example, if client didn't receive (or lost), then likely here you may need restart auth cycle.
"The authorization server MAY issue a new refresh token, in which case the client MUST discard the old refresh token and replace it with the new refresh token. The authorization server MAY revoke the old refresh token after issuing a new refresh token to the client."
This sounds reasonable on the surface, and technically it might be correct (depending on your interpretation of the words). But if someone naively follows this instruction to implement the server - issue a new refresh token and revoke the old one in the same refresh request at the server, what happens is when the client doesn't receive the new refresh token due to any transient failure, the client effectively loses its authorization, since the old refresh token is revoked and they didn't get the new one. Thus the protocol becomes "leaky" - you lose users because of transient errors.
i.e. "after issuing a new refresh token to the client" needs to be "after the new refresh token is being used at least once", or otherwise invent some other way to ensure the new refresh token is correctly received at the client before revoking the old.