Route: /app/workflows/chain/{slug}/chain. ChainEditor is form-based, not React Flow. Save PATCHes the full chain document. Test runs use POST /v1/workflow-chains/{slug}/run from the studio (requires Editor + runtime.simulate).

Editable fields
- Name, status (draft/live/paused), summary blurb.
- When trigger — free-text label describing entry (e.g. cron, webhook received).
- Primary steps — ordered list; add/remove/reorder; each step picks kind + label + config.
- Branches — named branch + nested step list for parallel paths after decide.
- Primitive chips preview — visual summary on card and in editor header.
Assistant & Agent steps
assistant steps resolve Assistants by label/slug match in the workspace and call the assistant runtime. agent steps invoke AI Agents via run_playground_turn with guardrails. Output text feeds decide branches (case-insensitive substring match on match labels).
Webhook & human steps
- webhook (outbound) — sends signed JSON to config.url with retries and timeout; local, private, reserved, credentialed, non-http(s), and DNS-resolved private targets are blocked.
- webhook (inbound) — set config.secret on the webhook step; external callers POST to public or authenticated ingress URLs with HMAC of the raw JSON body.
- human — sets run status to awaiting_human; resume via POST .../runs/{run_id}/resume after operator action.
Deploy readiness
The Deploy tab gates Live status and external ingress behind readiness checks. Unsafe webhook targets, missing labels, and invalid branch definitions are shown before operators can send production traffic.

Run history
GET /v1/workflow-chains/{slug}/runs returns recent runs (status, branch_taken, duration). GET .../runs/{run_id} includes primary_trace and branch_trace step timelines. Audit events: workflow_chain.run, workflow_chain.resume, workflow_chain.ingress.