I'm not sure if it's documented except indirectly but $! is never supposed to be reset on success, only set on failure. That's because it mimics the underlying errno variable in libc, and that's the way it works.
Thus, never look at $! unless you know the thing you just did caused an error from which you need details.