Probably a key thing you misunderstood is that &str wasn't from the prelude. It's a type in the actual Rust language, that's why it has the lowercase name like u16 or bool
So we didn't bring str::strip_prefix from the prelude in preference to our custom trait, we made a string literal and those have type &'static str -- an immutable reference to a string which lives forever. So the "prelude doesn't win" rule does not apply for &str because it didn't come from the prelude.
If we were talking about a type which implements Iterator for example, new Iterator features would come from Iterator, which is in the prelude and you didn't specifically ask for Iterator so the things you did ask for beat Iterator. But here the language primitive type grew new methods, a thing which Rust does but many languages don't do - Rust has methods on pointers and bytes and anything, whereas a language like Java or C++ can only put methods on "classes" not the ordinary types.