events.yaml declares the payload schema for each event. It defines payload shapes, not
routing; routing is derived from subscriptions in nodes.yaml and agents.yaml.
Flat payload form
Payload fields are declared directly under the event name. There is nopayload: wrapper
(that form is retired).
events.yaml
types.yaml.
Payload completeness
Every declared field must be populated by the active emit site’semit.fields. There are no
payload defaults, no implicit passthrough, and no undeclared fields. Missing or extra fields
are contract violations.
Reserved metadata
Event-level metadata lives under the reservedswarm: namespace:
string
Non-derivable external or platform producer proof.
string
Non-derivable external sink proof.
string
Lifecycle marker, for example
planned.string
Exceptional non-derivable producer proof, for example
mailbox_human.event.source, event.target, event.target_set, and
others) are not author-declared; consumers read them through event.*. The platform.
event prefix is reserved for the engine’s own events.
Three small rules worth knowing
- Zero-field events are legal and common — declare them as an empty map:
award.approved: {}(decision-gate outcomes often need one). - Scalar list types are quoted:
vendor_ids: "[text]"— unquoted[text]is YAML flow-list syntax, not a type string. - An event that crosses a flow boundary is declared in both flows’
events.yaml, and the declarations must agree. Drift is caught: incompatible types across aconnectedge fail verify (key_types_incompatible) rather than corrupting at runtime.

