Skip to main content
The static analyzer runs at boot, after loading all contracts and before starting any nodes or agents, and on demand with swarm verify. It is the authoritative integration test for a contract bundle: a bundle that boots has passed it. Every check below runs on states-era and stages-era grammar alike; the docs use stage, some check messages still say state.

Severities

lint_evidence: lines print on stdout alongside verify ok; verify still passes. They are design nudges, not failures. Two examples you may see in practice are cross_surface_named_type_use (several surfaces share a reusable field shape) and entity_reader_coverage (an entity field has no internal handler that reads it). Do not contort a contract to silence an advisory unless the change is itself a good design choice; the advisories are hints, not mandates.

Informational design evidence

  • cross_surface_named_type_use (lint_evidence). Multiple entity/event/node-state surfaces reuse the same structural shape and may be clearer as a named type in types.yaml. (The thresholds are tuned to skip small two-field handoffs and flag only larger or substantially overlapping repeated shapes.)
  • entity_reader_coverage (lint_evidence). A declared entity field has no internal handler reader. This is often intentional for audit/operator readout fields. Add _unused_reader_reason: <reason> to the entity field when the value is externally read through operator/API surfaces rather than internally consumed. The reason must be non-empty after trimming and at least 10 characters. It suppresses only entity_reader_coverage; it does not satisfy writer coverage, authorize runtime/API reads, or change persistence semantics.
This catalog covers every check that runs at boot and in swarm verify; none can be disabled.

Events and routing

  • single_node_per_event (error). Two system nodes declare a handler for the same event. Only one node may own an event. Rationale: one event, one state authority, so a transition is never ambiguous.
  • event_runtime_wiring_validation (error). An event that requires node handling has no owning node, or the owning node has no handler for it.
  • transition_reference_validation (error). An advances_to, on_complete branch, or pin references an event not defined in any events.yaml in the flow tree.
  • event_cycle_detection (error). A handler chain emits an event that eventually re-triggers the same handler. Rationale: catch infinite loops at boot; the runtime chain-depth limit of 50 is only a safety net.
  • platform_namespace_violation (error). A product event name (or agent emit_events entry) uses the reserved platform. prefix.
  • event_chain_integrity (warning). An emitted event has no handler path to a terminal state or output pin. Flags dead-end events.
  • event_consumer_exists (warning). An event is emitted but nothing subscribes to it. Suppressed by swarm.consumer or swarm.status.
  • event_producer_exists (warning). An agent subscribes to an event nothing emits. Suppressed by swarm.source, swarm.producer, or swarm.status.
  • semantic_drift_dead_event_schema (warning). A declared event has no active authored role anywhere in the bundle. Rationale: dead schema entries drift out of sync; either use the event or remove it.

Payloads and expressions

  • payload_field_coverage (error). A data_accumulation write reads a source payload field that does not exist in the source event’s schema.
  • emitted_event_payload_completeness (error). An emit site does not populate every field the emitted event declares. Rationale: a consumer can rely on every declared field being present.
  • condition_payload_alignment (error). A CEL condition references payload.X where X is not declared in the triggering event’s schema.
  • condition_policy_alignment (warning). A CEL condition references policy.X where X is not a key in any reachable policy.yaml.
  • condition_expression_validation (error). A guard on_fail is not one of reject, kill, discard, escalate; or a CEL condition fails to parse; or a condition lacks a required context prefix (entity., payload., policy., accumulated., fan_out.).
  • expression_field_reference_validation (error). An entity.* reference in a CEL surface does not resolve to a declared field (and must be a scalar or enum leaf in a query filter).

State machine

  • state_machine_coherence (error). An advances_to target is not in the flow’s states list, or initial_state is not in states.
  • transition_ownership_validation (error). A node owns a transition whose target state is not in the schema, or whose trigger event is not in its subscribes_to.
  • semantic_drift_unreachable_state (warning). A declared state cannot be reached from initial_state through any transition. Rationale: an unreachable state is dead, usually a leftover or a missing transition. (This is a warning, not a boot-abort, but it almost always signals a mistake.)
  • node_state_schema_typed_counterpart (error, with an informational variant). A node’s state_schema field uses an unsupported type, names a type not declared in types.yaml, or is jsonb while a typed counterpart for that field exists downstream (switch it to the declared named type instead of jsonb). When the field is jsonb and no typed counterpart exists, the finding drops to informational (lint_evidence): confirm the untyped shape is intended. Rationale: keep node scratch state typed where a type already exists, so it does not drift from the entity or event it mirrors.

Entities

  • entity_write_target_compliance (error). A handler write targets an envelope field, an undeclared entity field, or a flow with no entity contract.
  • entity_writer_coverage (error). A declared entity field has no writer, no initial, and no _unused_reason. Rationale: a field nothing ever sets is either a bug or dead weight; the analyzer forces you to state your intent.
  • create_entity_field_initialization (error). A create_entity handler reads entity.X for a field not declared on the entity contract.
  • accumulator_entity_projection (error). A materialize_from declaration does not resolve through the projection resolver (bad reference, type mismatch, or a competing writer).
  • entity_reader_coverage (informational). A declared field has no internal reader. Often fine: the field may be read by an agent or an external consumer. Use _unused_reader_reason for fields that are deliberately external/operator readout only.

Handlers and dialect

  • handler_field_compliance (error). A handler uses a field name outside the defined handler-field set.
  • invalid_field_detection (error). A node uses a top-level field outside the node-field set, or an agent declares a retired field (conversation_mode, session_scope, mode); the error names the memory: replacement.
  • dialect_compliance (error). on_complete is a map instead of a list; or both on_complete and rules; or both create_entity and accumulate; or more than one entity acquisition mode on one handler.
  • config_from_payload_alignment (error). A create_flow_instance action’s config_from references payload fields not in the triggering event’s schema.
  • gate_schema_validation (error). A sets_gate references a gate not declared in the node’s gate_state.

Agents, sessions, and prompts

  • required_agents_match (error). A required_agents role has no matching agent (by map key) in agents.yaml.
  • memory_scope_validation (error). memory: true on an agent whose flow has no per-instance identity. Rationale: a durable conversation is keyed by (run, agent, flow instance); without an instance owner there is nothing to scope it to, and the platform never guesses.
  • agent_permission_validation (error). An agent declares an unknown permission, or uses a builtin tool whose required permission it lacks.
  • native_tools_valid (error). native_tools names an unrecognized capability (not bash, web_search, file_io) or a non-boolean value.
  • flow_data_access_validation (error). A flow_data_access entry is invalid, missing, escaping, or outside the flow’s data root; or a root-scoped agent declares it.
  • workspace_class_exists (error). An agent’s workspace_class is not defined in policy.yaml and is not platform-reserved.
  • agent_prompt_lint_structural (error). A parseable structural reference in a prompt drifts from the declared event or entity contract.
  • prompt_exists (warning). An agent has no prompt file at prompts/{agent-id}.md.

Tools and credentials

  • tool_resolution (warning). An agent’s tools entry is not in the merged registry (tools.yaml plus MCP catalogs).
  • mcp_server_reachable (warning). An MCP server in policy.yaml is unreachable at boot; its tools are unavailable.
  • credential_key_exists (warning). A tool’s credentials or an MCP server’s credentials_key references a key absent from the credential store.

Pins and cross-flow routing

  • write_pin_ownership_validation (error). Two flows declare writes to the same output data pin. Rationale: one writer per field keeps entity state authoritative.
  • RETIRED-EMIT-ROUTING (error, at parse). Emits no longer choose their recipients: delivery is decided by the receiver’s subscriptions and the parent’s connect edges, and swarm verify checks every edge at boot. This error fires when an emit still carries target: or broadcast:.
  • missing_external_select_entity (error). A stateful handler consumes an external or no-target event but declares no select_entity/select_or_create_entity, so it would run against the sender instead of a receiving-flow-owned entity.
  • input_pin_wiring (warning). A required input event pin has no satisfiable producer path in the authored bundle (checked against sibling output pins, root agent emits, root node emits, the platform event catalog, swarm.source: external, and same-flow timers).
  • redundant_in_topology_select_entity (warning). A handler declares select_entity for an event whose only producers already set event.target; the receiver-side acquisition is redundant.

Timers, policy, and produces

  • timer_validation (error). A timer is missing its owner, its owner is not a flow participant, or its fire event is not in events.yaml.
  • policy_conflict_detection (warning). A child flow overrides a parent policy key with a different value. Informational; overriding is allowed.
  • produces_drift (warning). A node’s explicit produces list does not match the events derived from its emit sites.
  • phantom_produces (warning). A node’s produces lists an event no handler emits.

Common failures and fixes