On one hand, the invariants should be protected (To make invalid states impossible early and preferably at compile time rather than run time), and on the other hand, passing domain knowledge out of the domain is wrong.
On one hand, the value objects protect our domain invariants at first place, on the other hand using them as commands or as it's properties equals passing domain knowledge around.
The only solution for both protecting the invariants, and avoiding the domain knowledge from leaking the domain boundary (encapsulating the domain model), seems to wrap the aggregates in a command-to-value-object-mapper.
I'm using CQRS along with ES.
Is it ok to have a wrapper as a command-to-value-object-mapper around my aggregate roots? Is there any other solution?
The value objects can have constraints such as for instance valid range on a integer or a regex on a string. If these constraints are validated and the values are passed around in the same compiled code boundary it should be ok. If you validate the values in another boundary and then just accept it as valid after deserialization, that would be leaky.
The commands just express intent. Its values are validated when handling the command with respect to the current domain state. Domain values are created and can both validate themselves internally or be validated by other domain logic.