Auditing a Real Task's Edges
Read11 min · Map → Contract → Route → Verify · Updated 2026-09-15
You end this lesson with: Your task's dependency map redrawn with every fake edge removed — only true read-dependencies remain.
Chapters
- The audit: reads and writes, not order01
- Four kinds of real edges02
- Doing the audit on your own task03
- Faded case04
- Open case05
- Key takeaways06
Practice project: Project 01. Build a Fan/Join Graph
Lecture 02. Auditing a Real Task's Edges
A team's document-intake pipeline processed one contract in eleven steps: fetch, four extracts, four checks, write risk note. It ran the same eleven steps, in the same order, on every contract that landed, and every run took twenty-two minutes even though only two of the ten hops between those steps ever depended on each other. At forty contracts a day, that was close to fifteen hours a week spent waiting on nothing.
Illustrative composite. The 22-minutes-per-run and 15-hours-per-week figures are a teaching example for this course, not a measurement from a real team.
Someone finally asked the obvious question out loud: does "check liability against policy" need "check parties against vendor list" to have finished first? No. Does "extract termination clause" need "extract liability clause" to have finished first? No. Both just need the fetched contract text. Of the ten arrows in that diagram, two were real. The other eight were an artifact of the order someone typed the steps into a spec document.
This lecture is the method for finding out which is which, on any task, not just this one.
The audit: reads and writes, not order
For every node in a candidate graph, write down two lists: what it reads (which prior outputs it actually consumes) and what it writes (what it produces for later nodes). Then draw an edge only where a write feeds a read. Nothing else.
| Node | Reads | Writes |
|---|---|---|
| fetch contract | (nothing, entry point) | contract text |
| extract parties | contract text | parties |
| extract liability | contract text | liability clause |
| extract termination | contract text | termination clause |
| extract data-handling | contract text | data-handling clause |
| check parties | parties | parties verdict |
| check liability | liability clause | liability verdict |
| check termination | termination clause | termination verdict |
| write risk note | all four verdicts | risk note |
Read the table straight through and the graph draws itself: fetch feeds all four extract nodes, each extract feeds its matching check, and all four check nodes feed write risk note. Nothing in this table justifies making extract liability wait for extract parties to finish. The eleven-step chain was never derived from this table. It was derived from the order someone wrote the steps down.
State that as a rule you can apply to any two rows: draw an edge from node A to node B only when B's reads list contains something A's writes list produced; otherwise treat A and B as independent and let them run in parallel. The reads/writes table is where you check that condition — not intuition, not the order the steps got written down in.
| B's reads list | Edge from A to B | What to do |
|---|---|---|
| Contains something on A's writes list | Real | Draw it; B waits for A |
| Contains nothing on A's writes list | None | A and B are independent, run in parallel |
| Contains a failure signal a downstream check wrote | Real, backward | A rollback edge, not a plain dependency |
Everything after fetch runs at once; only write risk note needs to wait for all four pairs to land.
Four kinds of real edges
Once fake edges are gone, what's left isn't always a plain arrow. A real edge can carry one of four meanings:
- Plain dependency:
extract liability→check liability. B always runs after A, because B reads what A wrote. - Parallel fan:
fetch contract→ fourextractnodes at once. Several real edges leave the same node with no ordering between them. - Conditional:
check liability→write risk noteon a pass,check liability→re-extract liabilityon a "clause not found" result. Which edge fires depends on the node's output. - Rollback / retry: a downstream failure returns to an upstream node instead of stopping. If
write risk notefinds a missing verdict, it can route back to the extract step that should have produced it, not just halt.
All four are still "real" in this lecture's sense: the receiving node genuinely reads something the sending node produced. What makes an edge fake isn't its shape; it's the absence of a read on the other end.
Doing the audit on your own task
Three steps, repeatable on anything:
- List every node, in whatever order they currently run.
- Write reads and writes for each one. Be specific about which upstream output it consumes, not just "the previous step's result."
- Draw edges only from a write to a matching read. Anything left unconnected either runs independently (candidate for a fan, next lecture) or was never a dependency at all.
Do this before touching contracts (Lecture 03) or shapes (Lecture 04). A contract for a node whose real dependencies you haven't mapped is a contract for the wrong node.
Faded case
Skip to the open case if this is familiar. A separate part of the same contract-review pipeline handles renewal reminders: fetch contract, extract renewal-date clause, extract auto-renewal clause, check renewal window, check auto-renewal terms, write reminder note. The runbook lists the two checks one after another, so the batch job runs check renewal window first, then check auto-renewal terms, waiting for the first to finish before starting the second. Write out what each check node actually reads. check renewal window reads the renewal-date clause. check auto-renewal terms reads the auto-renewal clause. Decide, from those two reads lists alone, whether the edge between the two check nodes belongs in the graph.
Open case
Run the same reads-list check against the task from your Lecture 01 exercise: for two steps that currently run one after another, write out what the second one actually reads, and decide whether an edge belongs between them at all.
Key takeaways
- The audit tool is a reads/writes table, not a redrawn diagram. List what each node actually consumes and produces; edges follow from the table, not from intuition about "what feels sequential."
- A real edge can still branch, condition, or roll back. Parallelism, conditionals, and retries are all real edges: what disqualifies an edge is a missing read, not a particular shape.
- Do this before contracts or shapes. Auditing edges is the first move because everything downstream in this course assumes the dependency map is honest.
What You Have Now
Your task's dependency map redrawn with every fake edge removed — only true read-dependencies remain. It replaces the rough sketch from Lecture 01 in your design document, and it's what the rest of the course routes, contracts, and joins against. This closes the Map stage: everything from here on assumes this map is honest.
Save it as graph/lecture-02.md; the lab's checker looks for that file at that path.
Exercises
- Build the reads/writes table for the task you mapped in Lecture 01's exercise. For every node, write down exactly what it reads and what it writes, not "the previous output," the specific field or artifact.
- Count fake edges. Compare the table-derived graph to the order you originally ran the task in. How many of the original arrows survive the audit?
Check your understanding
Reading is free — your progress isn't being saved
Nothing you did on this page is recorded. Paid students get saved progress and verified completions, recorded quiz answers, the spaced-repetition review queue, labs, and a certificate for each course they finish.
30-day money-back guarantee. One-time payment — lifetime access and updates.