Usually, it’s just some core calculus of the language that is rigorously specified and the rest is hand waving.
There are some exceptions like JS.
But even Java has the problem that if you just implement what’s in the spec, you won’t be able to run anything meaningful unless you also do things exactly how the JDK would. You can find out what the JDK does by reading its code and writing test cases and I think that’s what folks do, if they want to be compatible.
UB and memory safety are orthogonal. If we specified formally and super rigorously that a pointer is an integer and that memory is an array of bytes, we could have a UB-free language but memory safety would still be on fire.
That's PVI (Provenance Via Integers) and it's a performance disaster. If anything in memory might be pointed to, almost all the nice modern optimisations aren't correct. It is really popular with a certain kind of "Portable assembler" programmer, who typically has no idea how the machine actually works, nor how their language is defined but is very confident the nonsense they're writing ought to do what they wanted it to do.
So, the "bad" news is that you can't have this, your compiler vendor won't make it, and the "good" news is that you'd have hated it anyway which is why they won't make it.
JS is maybe closer on this front but it's also quite old & JS is also a mess & a lot of development has shifted to TS as the language for those reasons & TS only has 1 frontend & no formal spec.
Still, if memory serves there have been a handful of cases where egc's implementation of the spec differed from javac's with resulting fixes in javac itself (though I don't have sources at hand, so perhaps I misremember).