The composer
How the canvas checks a graph as you build it, why a version never changes once saved, and what a deploy actually publishes.
The canvas
The composer is a canvas of block nodes joined by wires between typed ports. Dragging a wire between two ports the same way `blocks` describes is the only way to connect two nodes — there is no way to save a wire between incompatible types, because the canvas runs the same check POST /flows/:id/versions runs server-side before it lets the wire land.
The "Try it" demo on the home page runs a real flow through the composer’s own contract-checker rather than a scripted response — what it shows behaves like what a signed-up tenant builds, not a mock of it.
Versions are immutable
A flow starts as just a name; the graph itself is saved as its first version, and every save after that creates a new one rather than editing the last. Nothing before deploy time refers to a flow by its live graph — always by a specific version — so a version an eval run scored, a deployment published, or Copilot advised on cannot change out from under whatever named it.
A graph with a cycle, an unknown block or a port mismatch is rejected at save time with 422 ERR_UNPROCESSABLE, before it ever becomes a version — the same validation the quickstart shows from the terminal.
From version to deployment
Deploying names one version and returns a deployment immediately — the Worker is built and uploaded behind it, asynchronously, which is why the response is 202 and not 200. The deployment carries the version it was built from for as long as it is live, which is what lets Migrate and Retrieval Monitor compare what changed between two of a flow’s deployments rather than between two arbitrary points in time.