all very valid questions.
GUID / UUID have a preference, because they can be safely generated on the client side, allowing a client to send a create command followed by a number of updates, without forcing the client to wait for the result. Also, UUID are safe to generate in distributed environments, while incremental identifiers aren’t (hence the weird offset/increment setups in master-master setups of relational databases). I tend to use UUID as technical identifiers and then any “business identifier” as a derived identifier to that one. These business identifiers tend to change from time to time, even though everybody promises in blood that they will never…
CRUD events are the source of all evil… Well, at least they won’t get you much further from where you are at the moment. Ideally, you want the events to contain business meaning. You should be able to show your events to anyone in your department, and they should understand what they mean. Don’t throw the events from your repository (where all you know is "stuff has been inserted, updated or deleted), but from the service layer, where the business logic is performed. There, you should still have the business meaning of the event.
It may run in a separate process, or as part of the monolith. It depends on why you are tearing the monolith apart. If it is because deploying it has become a nightmare, I would recommend against adding more stuff in it. Having it in-process will definitely simplify things like transaction management.
In terms of the ID translation (if you were to decide to move to UUIDs), the monolith doesn’t know about the UUID’s (yet). You could have a component maintain a translation table between the old identifiers and the new ones. This could be something that lives in the component that creates the events, so that it is transparent from the point of view of the current logic. Alternatively, you can also publish events using the identifiers you have now, and have your new view model(s) perform the translation.
Hope this helps.