what prevents a library from taking an allocator, saving it hidden somewhere and using it silently?
You missed the point that libraries can have their own allocators and don't expose customisation points.
However if the library is trying to be as idiomatic / general purpose / good citizen as possible, then they should strongly consider not doing that and only use the user provided allocator (unless there is a clear and documented reason why that is not the case).
I don't think it would make sense to restrict this at the language level. As a developer it's up to you to exercise your judgement when you examine what libraries you choose to depend on.
I appreciate the fact it's a common design pattern in Zig libraries and I also appreciate the fact I'm not forced to do it if I don't want to. If it matters to me then I'll consider libraries that are designed that way, if it does not matter to me then I can consider libraries that do not support this.