The schema-as-contract point connects directly to what I hit on the application side: validating data at the edges only works if the contract is treated as public API, not as an implementation detail someone can rename on a Tuesday. The idempotency section is the one I'd underline twice. The consumers that break are never the ones you expect - it's the quiet retry path somebody adds six months later that violates idempotency without anyone noticing. Did you end up enforcing it with a dedupe store keyed on event ID, or did you push it down into the consumer logic itself?
