A message shape is a contract with every consumer that exists and every consumer that is mid-deploy.
{
"type": "order.placed",
"version": 2,
"order_id": "01H8...",
"total_cents": 4900,
"currency": "GBP",
"channel": "web" // added in v2, optional
}
Adding an optional field is safe because an old consumer ignores it and a new one handles its absence. Everything else needs a new message type, published alongside the old one until every consumer has moved — which requires knowing who the consumers are. The version field is documentation rather than a mechanism; the compatibility comes from the additive rule, not from the number.