The graph is read-only
I rebuilt a workflow engine around one rule — code is the single source of truth, the visual graph is a projection of it. Twenty years of round-trip tools say that's the only direction that holds.
A workflow product wants two things that quietly fight each other: a visual graph anyone can read, and code a model can author and a team can review. The tempting answer is to let you edit both and keep them in sync. I tried that. It's a tar pit.
The honest version is unidirectional. The code is the source of truth. The graph is a read-only view, generated by reading the code itself. "Editing the graph" isn't a second authority — it's an editor command that writes the change back into the code, then re-reads it. One arrow, not two.
This isn't a new lesson; it's a 20-year-old one. Round-tripping a diagram and its code — the UML model/code sync dream — "typically fails after two or three iterations and leaves the diagram and code in a bad state." Behavioral round-trip is literally called a myth: loops, conditionals and parallelism don't survive a faithful trip through a node graph. So the serious runtimes all quietly chose one direction — Temporal, Restate, Inngest, Mastra, Cloudflare: author in code, derive the picture.
Cloudflare shipped exactly this and said why: their workflows "are just code" — Promises, loops, conditionals, nested in functions — so they parse the AST at deploy time to statically generate a read-only diagram. A declarative drag-and-drop builder simply can't represent that control flow. It's not my theory; it's a production architecture from a vendor with no reason to agree with me.
The reason it matters more now is that the author changed. The author is a model. And a model writes a typed function far more reliably than it writes a JSON graph: types give it a contract to satisfy and a compiler to catch it, where a JSON-DSL gives it a thousand ways to be subtly, validly wrong. In my own benchmarks the same model wrote workflows as typed code at a meaningfully higher pass rate, using a fraction of the tokens.
This isn't only my data. In a peer-reviewed comparison across seventeen models, code actions beat JSON actions by up to 20% success with about 30% fewer tokens; and forcing a model into a rigid grammar measurably lowers its reasoning, because the grammar can't hold the intermediate steps. Let the model write typed code and let the compiler be the hard gate — you get higher quality, lower cost, and a real contract instead of a hope-it's-valid blob.
So the visual graph earns its place as a lens, not a form. You read it to understand; you don't fight it to edit. The edit lands in the code, where the type system, the diff, and the review already live. The picture follows.
The discipline is to never let the picture become an authority. The moment you can edit both, you've signed up to keep two truths in sync forever — and the model, the compiler, and your future self all pay the interest.