That was my understanding from the get go.
Unsoundness shouldn't be possible within the module, either. But if it helps, just imagine that data is a public field. The type is still sound in that case.
Yes, but #[pin_project] is an opt-in thing. They only guarantee it's safe in the absence of other unsafe code. When applying #[pin_project], you must be sure that your type is still sound when projecting all fields (whether with or without Pin wrapping).
However, how you have it, this language feature applies by default, and can allow undefined behavior in safe code for a previously sound type. It doesn't matter whether it's within the same module or a publicly visible field. It allows unsound usage of existing sound types just by existing, because it projects all fields by default.
If instead, you had to opt-in by explicitly enumerating which fields are projectable (or if your type as a whole is projectable - though that is less flexible), it wouldn't be a problem.