Declaring a standing flow
Activation is declared on the package’s flow entry — explicitly, never inferred:package.yaml
activation: standingis valid only formode: singletonflows (one instance for the whole system).- Standing without
ingressis valid — a timer-driven or connect-fed always-on service. ingressrequiresactivation: standing, and itsaliasdefaults to the flow id. The alias is one URL path segment: the endpoint is/webhooks/{alias}/{provider}— here,/webhooks/chat/telegram.signing_secretis a deployment credential reference (resolved from the credential store at boot); the package never carries the value.- Every provider binding must line up with an external input pin consuming that provider’s events — a dangling ingress or an unfed pin is a verify error, not a runtime surprise.
Provider events, normalized
A provider pack (Telegram, Slack, Stripe, …) declares which webhooks it accepts and how they’re checked (admission), plus the normalized events — small, flat, typed versions of the provider payload that your flow subscribes to. Your contracts consumeinbound.telegram.text_message with typed flat fields; the pack owns signature verification, payload
dispatch, and field extraction. You never parse a raw webhook body in a handler.
agents.yaml
Lifecycle: what “standing” means operationally
- Materialized before ready: the standing instance, its routes, and its agents exist before the runtime reports readiness — the first webhook never races activation.
- Durable across restarts: the service’s identity is stable (derived from package + flow id); a restart reconciles the declared set against the store and resumes, it does not re-create. Removing or renaming the flow in a later revision marks the old service as orphaned: it stops taking work but stays paused and inspectable rather than deleted.
- Operator control: suspend, resume, and reset act on the same durable identity and survive restart.

