CCLearn

Give agents the leaf nodes, keep the task graph

Author the task dependency graph yourself and hand agents only leaf tasks: the shared task list enforces the dependencies, but from v2.1.233 the Task tools are off by default on Opus 4.8 and Sonnet 5, so a team falls back to the agent-to-agent chatter the report calls a mess.

docs corroborate

The official documentation describes the mechanism this relies on. The technique itself is community practice.

What this costs you if it is wrong

Hand-authoring a graph is real work, and a graph goes stale the moment the plan turns out to be wrong mid-run — for exploratory work where you do not yet know the shape of the problem, letting the agent decompose is the point. The tools-off default and CLAUDE_CODE_ENABLE_TODO_TOOLS both arrive in v2.1.233, so on an older install there is nothing to opt into; where the opt-in exists it spends context on tool definitions and reminders the newer models shipped without. And the practice half is one practitioner's experience, not a measured result.

You told Claude to spawn a team and split the work up. Twenty minutes later two teammates have edited the same file, a third has re-derived a finding the first one already reported, and the lead's synthesis is a summary of three overlapping opinions instead of one finished job. Nothing errored. You just paid three context windows for roughly one context window of work.

A practitioner running a multi-agent orchestrator across Claude Code, Codex and Gemini CLI reported the lesson as two rules: define the task dependency graph yourself, hand agents only leaf tasks, and never let agents talk to each other directly — route structured output through one coordinator instead.

Why decomposition is the part that goes wrong

An agent asked to split a job splits it plausibly, not disjointly. Plausible splits share edges: "audit the auth module" and "audit the session handling" overlap in the middle, and neither agent knows the other is standing there. A graph you wrote has an answer to "is this mine?" that does not require the agent to guess.

Claude Code's own docs organize the whole delegation feature set around this axis — not around agent count, but around who holds the plan:

Where the plan livesWhat decides the next stepWhat that costs you
SubagentsClaude, turn by turnCheapest to start, no record of why the split was that split
Agent teamsThe lead agent, turn by turn, over a shared task listPeers run long, coordination overhead is real
WorkflowsA script, executed by the runtimeThe orchestration itself becomes rereadable and rerunnable
A graph you wrote in the promptYou, before anything spawnsYou do the thinking up front and it goes stale if the plan was wrong

The shared task list is the built-in home for a graph. Tasks are pending, in progress, or completed, and a task can depend on other tasks — a pending task with unresolved dependencies cannot be claimed until those dependencies complete, and Claude Code unblocks the dependents automatically when the blocking task finishes. That is a dependency graph with an enforcement mechanism, not a checklist.

The trap: your model decides whether the task tools are there by default

Here is the part that turns this from philosophy into a thing to go check. "In Claude Code v2.1.233 and later, the following tools aren't available on Opus 4.8, Sonnet 5, Fable 5, Mythos 5, or later versions of those families unless you opt in: TodoWrite, TaskCreate, TaskGet, TaskUpdate, and TaskList." Those models track multi-step work without a written checklist, and the tool definitions cost context. On any other model — Opus 4.7 among them — Claude Code still provides the four Task tools by default. So the question to ask is not whether your build is new enough. It is which model you are on. The withholding and the way out of it shipped together: CLAUDE_CODE_ENABLE_TODO_TOOLS "requires Claude Code v2.1.233 or later", the same release the models list starts at.

And the agent-teams docs are explicit about what a team does without them: agents without the task tools coordinate through messages instead of the shared task list.

So on a current model, the default team is the configuration the report calls a mess — peers negotiating in a mailbox, with no dependency edges anyone can enforce. If you want the graph, ask for it:

bash
CLAUDE_CODE_ENABLE_TODO_TOOLS=1 claude

Or per-session, without the env var:

bash
claude --allowedTools TaskCreate

To carry one graph across several sessions rather than rebuilding it each time, name the list:

bash
CLAUDE_CODE_TASK_LIST_ID=my-migration claude

Writing the graph

Leaf-sized means a teammate can finish it without asking another teammate a question. Two tests: it names the files it may touch, and its output is a described artifact rather than "findings". Then state the edges explicitly in the prompt, and assign rather than letting teammates self-claim, since a lead can assign tasks explicitly or teammates can pick up the next unblocked one themselves.

Name the model per task too, in the same breath — that was the second HN report's point, and it costs you one clause.

text
Create these tasks, with 3 and 4 depending on 1 and 2:
1. [sonnet] Inventory every call site of getSession() in src/auth/. Output: a list of file:line.
2. [sonnet] Inventory every test that stubs getSession(). Output: a list of file:line.
3. [opus] Rewrite only the call sites from task 1. Touch nothing else.
4. [opus] Update only the tests from task 2.
Assign each explicitly. Do not let teammates self-claim.

If you want the graph to be non-negotiable, the TaskCreated hook fires when a task is being created and exiting with code 2 rolls the creation back — a hard stop on an agent inventing work that is not on your graph.

What is actually verified here

The mechanism is documented and checkable: the shared task list, its dependency blocking, the task tools being absent by default on current models, the message-based fallback without them, and the TaskCreated hook's rollback. Those you can trust.

The judgement is not. "You should own the decomposition" and "agent-to-agent messaging is a mess" come from one engineer's build on a stack that was not only Claude Code, plus a second commenter's agreement that explicitly specified subagents beat letting the orchestrator fan out. No documentation states the practice; no one has A/B'd it. The docs actively design for teammates messaging each other directly, which is at minimum a difference of opinion with the report.

What would settle it: run the same well-understood task twice on one repo, once as "split this up and parallelize it" and once as an explicit assigned graph, then count duplicated file edits and compare total tokens. Until someone does that, treat this as a strong prior from a person who shipped an orchestrator, not as a finding.

Checkpoint

  • Does your current session actually have the task tools, or is your team coordinating by mailbox without them?

    Show answer

    Go and look, and look at your model rather than your build number. In v2.1.233 and later, TodoWrite, TaskCreate, TaskGet, TaskUpdate and TaskList are not available on Opus 4.8, Sonnet 5, Fable 5, Mythos 5 or later versions of those families unless you opt in; on any other model, Opus 4.7 among them, Claude Code still provides them by default.

    The symptom of the tools-absent case is a task list that stays empty while Claude works and a Ctrl+T that appears to do nothing — that is not a broken UI. The agent-teams docs say what a team does instead: agents without the task tools coordinate through messages rather than the shared task list. Which side of that you are on is yours to check; if you want the graph, start with CLAUDE_CODE_ENABLE_TODO_TOOLS=1 claude (v2.1.233 or later) or claude --allowedTools TaskCreate.

  • For your last multi-agent run: could you have written the leaf tasks in advance, or did you genuinely not know the shape of the problem yet?

    Show answer

    Only your own run answers this, and the answer is what picks the technique. The tip's test for leaf-sized is that a teammate can finish the task without asking another teammate a question — in practice, it names the files it may touch and its output is a described artifact rather than "findings". Replay your task list against that: if the tasks pass it in hindsight, you could have written them up front, and the overlap you paid for was avoidable.

    If you genuinely did not know the shape of the problem, letting the agent decompose is the point — hand-authoring a graph is real work and it goes stale the moment the plan turns out wrong mid-run. Weigh it knowing that the "own the decomposition" half is one practitioner's experience across a mixed stack, not a measured result; no documentation states the practice and nobody has A/B'd it.

  • If two of your leaf tasks would edit the same file, is a team the right tool at all?

    Show answer

    Almost certainly not. The docs say teams work best when teammates operate independently, and that sequential work, same-file edits, or work with many dependencies is better served by a single session or subagents — so two leaf tasks converging on one file is the signal to stop spawning peers, not to write the graph more carefully. Where the split is genuine and the edges are few, the shared task list does enforce them: a pending task with unresolved dependencies cannot be claimed until those complete, and Claude Code unblocks the dependents automatically. Deep chains are where you drop back to one session.

Where this came from

Official pages that back this