Planning · Free preview

Order by Dependencies

Some steps must wait

When subtasks have prerequisites, a valid execution order must run every task only after everything it needs is already done — that's a topological sort of the dependency graph.

Some steps must wait

In the reflect-and-retry lesson, your agent tripped over a hidden prerequisite — write failed until focus had run — and had to discover the ordering at runtime, the expensive way. That handles one surprise, but a real plan has prerequisites everywhere, and you'd rather get the order right before you start than fail your way into it. So make the dependencies explicit and schedule on them.

Decompose "deploy the service" and the subtasks don't stand alone: deploy needs build image; build image needs both write code and write config. Those "needs" form a small dependency graph — a DAG — and a runnable plan is a topological sort of it: every task appears only after all of its prerequisites. The order the tasks are listed in is a trap; it's just how someone typed them.

The mechanism is drain-the-ready-set. A task is ready when everything it needs is already done. Repeatedly gather the ready tasks, run one, mark it done, and finishing it unlocks whatever waited on it. With a (needs nothing) done first, both c and e become ready — and here determinism matters: when several tasks are ready at once, break the tie by ascending id, so the same graph always yields the same schedule and a failure is reproducible. That's why c precedes e, giving a, c, b, d, e.

The starter emits the listed order, which puts b (build) before the a/c it depends on. Replace it: filter to tasks whose needs are all in done, sort ascending, append the first, mark it done, repeat until all five are scheduled. Done means order: a, c, b, d, e.

A plan with prerequisites isn't a list you read top to bottom — it's a graph you drain one ready task at a time.

In the full academy, you write and run this — live, graded:

// Subtasks for "deploy the service". Each one lists the ids it NEEDS first.
// They are given in a messy listed order — NOT a runnable order.
const tasks = [
  { id: "b", needs: ["a", "c"] }, // build image (needs code + config)
  { id: "e", needs: ["a"] },      // write docs (needs code)
  { id: "a", needs: [] },         // write code
  { id: "d", needs: ["b"] },      // deploy (needs image)
  { id: "c", needs: ["a"] },      // write config (needs code)
];

// Produce a VALID execution order: every task comes after all of its needs.
// Break ties (several tasks ready at once) by ascending id, for determinism.
// TODO: replace this — right now it just uses the listed order, which is invalid.
const order = tasks.map((t) => t.id);

console.log("order: " + order.join(", "));

🔒 Live code execution, real agent runs, mastery tracking and verifiable credentials unlock with the full academy.

This is 1 of 50 lessons.

The full academy: write real code, watch real agents run, and earn verifiable credentials — across 8 tracks, in a 3D campus.

Unlock the full academy — $100 →

14-day refund · 🔒 Stripe-secured checkout · lifetime access

More free lessons: An LLM Is a Function  ·  The Agent Loop  ·  Define a Tool  ·  Give an Agent a Tool  ·  Durable State

← The Agent Marketplace