The MTU should have been reified to the IP layer. And it would have been so easy!
When a system sends a packet, it sets the "forward MTU" field in the IP packet to be equal to the MTU of the outgoing link. Each router along the way inspects the packet and if its outgoing link has a lower MTU, it replaces the "forward MTU" with its own.
Once the packet reaches the destination, the target host copies the "forward MTU" field (which now has the lowest MTU seen along the path) to the "reflected MTU" and sets it on the next reply packet.
So the originating system can discover the limiting MTU by the time it gets the ACK packet.
Sigh. Instead, we have a Ruby Goldberg machine with fragmentation, ICMP and all the related unreliable crap that has forever cemented max MTU as 1500.
The destination will detect that the packet has been chopped, send the updated reflected MTU and everything would be fine. Of course, the minimal allowed MTU (say, 512 bytes) should provide enough information for the target to find the correct TCP flow to which the packet belongs.
No need for out-of-band ICMP signalling or fragmentation.
And in practice, topology changes happen rarely, so this should be very infrequent.
Retrofitting features like this into the middleboxen takes decades, and never finishes, so you either get them in on day zero or you never get them.
UDP-based applications would have to do MTU discovery, but that's much easier when you're receiving truncated packets.
I work with magnetic tape and have seen tape block sizes grow from ~512 bytes in the early 1990s, to 10s MB today, resulting in huge performance improvements. Network packet sizes haven't changed by anything near that amount in 30 years.