I've been planning out an event sourcing like system for our healthtech startup, and you're definitely right re namespacing and versioning.
I explicitly keep a version in the event - which is a date. It's similar in how Stripe versions their API. We're also planning to handle the events in the same way as stripe's API: each event has side effects; the side effects may change depending on the version and each version has its own application logic (cascading, so you can have 2018-08-01 run all of 2018-07-30 plus its own changes).
This lets us replay events as they happened, run an event using two different versions and perform only the diffs etc.
Our system is probably not a typical CQRS/event sourcing setup.
The event system itself idempotent: you take an event with all input data necessary to run the event (form data, necessary current state), so the system can run independently. This means that every event is typed such that the input data dictates what is necessary.