Skip to main content
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 no payload: wrapper (that form is retired).
events.yaml
Field types are built-in scalars or named types from types.yaml.

Payload completeness

Every declared field must be populated by the active emit site’s emit.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 reserved swarm: 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.
Runtime-owned envelope fields (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 a connect edge fail verify (key_types_incompatible) rather than corrupting at runtime.