The work itself is a graph
You just watched LangGraph spell it out: nodes are steps, edges say what runs after what. Here's the part worth keeping even if you never touch the framework — that structure isn't a LangGraph invention. It's what multi-step work already looks like, and you can hold the whole idea in a dict.
The editor shows a three-step workflow as plain data. Each step lists
what it needs; a step is runnable when everything it needs is done.
That one comprehension — find steps whose dependencies are all
satisfied — is the entire scheduling logic of every workflow engine
you'll ever meet.
Four ideas turn this toy into a vocabulary for real agent workflows:
Dependencies. An edge means "this must finish before that starts." Write them down and you've made the implicit order of your work explicit — which is the precondition for automating any of it.
Joins. A step can need several upstream steps
("needs": ["research", "legal-review"]). The all(...) check
handles it for free: the step waits until every branch lands. Most
real workflows are diamonds, not straight lines.
Cycles need convergence rules. A retry edge ("check failed → back to draft") makes the graph loop. Loops without an exit condition run forever — so every cycle must carry a rule that guarantees it ends: a maximum number of passes, a threshold that counts as good enough, or an escalation to a human. If you can't say what makes the loop stop, the loop isn't finished being designed.
Verification gates. The send step carries
"gate": "human approval" — an edge whose condition is a check
passing, not just the previous step finishing. Gates are where you
put the checks this course keeps drilling: schema validation on the
way in, a human sign-off before anything irreversible goes out.
One portable format captures all four. Any workflow you can fill into this table, you can automate — and any row you can't fill is a design question you haven't answered yet:
| From | Relationship | To | Condition | Evidence |
|---|---|---|---|---|
| check | must pass before | send | human approves diff | approval logged |
Run the editor. Only draft is runnable — nothing it needs, nothing
done yet. Flip draft to "done": True and rerun: now check
becomes runnable, and send still waits. That's dependency ordering,
in four lines you wrote yourself.