HTTP semantics aren’t hard enforced but that only means something if you always control the client, server, and all the middle layers like proxies or CDNs that your traffic flows over.
Your GET request can modify state. But if your request exceeds a browser’s timeout threshold, the browser will retry it. And then you get to spend a few days debugging why a certain notification is always getting sent three times (ask me how I know this)
Similarly, you can put a body on your GET request in curl. But a browser can’t. And if you need to move your server behind cloudflare one day, that body is gonna get dropped.