The envelope is: actor, verb, object, context, consent. Nothing else.
Every field has a strict schema, but traits and metadata are free-form — we index what we need and store the rest as JSONB. That lets customers extend without forking.
Consent is the quiet hero. When a marketing message module asks `can I send this?`, it doesn't query a separate consent table — the consent list travels with the event.