Everything should be explicit and non-transitive.
You should specify which crates a dependency is allowed to depend on.
You should specify what that dependency is directly allowed to do, that isn’t covered by its dependencies.
Dependencies of dependencies can be regulated separately.
Feature flags (compiler/std), crate features, and better rustc-args-based lint control are the main source-wise control features. Everything else is Cargo.
Even better: 90% of this is already implemented. In rustc, all that’s missing is finer-grained feature flags, which is almost as trivial as documentation changes, and the ability to disallow them with rustc args. That’s it. The system for disallowing them is already in place, we just need to expose it to cargo/CLI.