I would start with modeling the events and not entities.
If you have events such as:
- BookAssigned(category)
- VendorAssigned(category)
- BookAssigned(vendor)
what should they apply to? Perhaps it makes sense to have an event such as "CategoryAssigned(book_id, category)" instead? Working along these lines will lead you to discover the aggregates in your domain. Aggregates should define consistency boundaries, not "collections" of things. What is the thing that should be "consistent" - e.g. cannot be modified by two things at once?
How you ensure that commands are correct and that no wrong assignment is made can be left to later. In general, I find that this is not such a big problem as initially seems. Command can be rejected at the command handler (before it is even passed onto aggregate). Sometimes this will not ensure complete consistency - e.g. you may have two books that are assigned to a single vendor. But then this may be an ok tradeoff, and this error can be detected later, by running periodic queries on your projections. After such an error is found, it can be flagged in the UI. After all, in reality, these things do happen and they are corrected, rather than prevented.