I think that SFINAE and, to a lesser extent, concepts is fundamentally a bit odd when multiple translation units are involved, but otherwise I don’t see the problem.
It’s regrettable that the question of whether a type meets the requirements to call some overload or to branch in a particular if constexpr expression, etc, can depend on what else is in scope.
This is one of those wicked language design problems that comes up again and again across languages, and they solve it in different ways.
In Haskell, you can't ever check that a type doesn't implement a type class.
In Golang, a type can only implement an interface if the implementation is defined in the same module as the type.
In C++, in typical C++ style, it's the wild west and the compiler doesn't put guard rails on, and does what you would expect it to do if you think about how the compiler works, which probably isn't what you want.
I don't know what Rust does.