Skip to main content
Swarm evaluates all guard checks, rule conditions, filter conditions, and on_complete branch conditions with CEL. CEL is strongly typed and non-Turing-complete. For the conceptual intro see Expressions.

Context variables

Declared entity fields are always readable at a type-valid value; an undeclared field reference is a contract error caught at boot.

Where each variable is available

The five condition sites run at different points in the handler pipeline, so accumulated and fan_out are not usable everywhere. Referencing one where it is not available is a boot error. accumulated is only readable after accumulation completes (on_complete, filter), so it is absent in guard (runs before accumulation) and in rules (an alternative to on_complete). fan_out.count is populated after the fan-out step and is read only in data_accumulation.expression; in on_complete, read the entity field you wrote it to instead.

Operators

  • Comparison: ==, !=, <, <=, >, >=
  • Logical: &&, ||, !
  • Arithmetic: +, -, *, /
  • Membership: in, contains
  • String: startsWith, endsWith, matches
  • List: size, exists, all, filter, map

The prefix rule

Every condition carries a context prefix: payload., entity., policy., accumulated., or fan_out.. A bare identifier is a dialect violation. See Dialect rules.

Examples

Cross-entity count

query_entities(<field> <op> <value>).count returns how many flow-owned entities match a single comparison, for use inside a condition. The operator is one of ==, !=, >=, <=, >, <, and the value is a literal or a resolved reference (payload.*, event.*):
This is for cardinality assertions, most often idempotency: accept the event only when exactly one entity already carries its request_id. The predicate is a single comparison, not a compound expression, and only .count is exposed.

Presence

has(entity.field) is true for declared entity fields (redundant under universal presence, useful for dynamic maps). Comparing against null works; timestamp and uuid fields read null when unwritten, while most others read their non-null type default.