"Break big goals into small tasks, order them, persist them" — a file-persisted task graph, the foundation of multi-agent collaboration.

In TodoWrite — an Agent without a plan drifts off course as it works, we mentioned that CC does not rely solely on a single set of Todos to implement its task list; there is a dedicated task system to maintain it. Sorry for the wait! And congratulations on making it here.

The problem

Imagine an Agent receives a project: set up the database, write the API, add tests. It uses TodoWrite to list out a checklist, then starts writing the API; halfway through it realizes there are no database tables, so it goes back to add them; when adding tests it finds the API interface signatures have changed again... back and forth with constant changes, and in the end the todo has been changed beyond recognition...

Long before Agent planning capabilities emerged, we already knew of something called Workflow, which uses a DAG to implement branching, loops, and other flows. Todos should work the same way, with dependency relationships between them forming a flowchart, rather than the linear style of the previous todo.

TodoWrite is the execution checklist for the current task, stored in session memory. But what is needed here is the task system: each task is a JSON file, and tasks have blockedBy dependencies, persisted on disk across sessions.

Solution

Task system—break oversized goals into small tasks

Compared to before, there's one more feature: there's a thing called a task, which is a json file—each task is a json file.

@dataclass
class Task:
    id: str
    subject: str
    description: str
    status: str          # pending | in_progress | completed
    owner: str | None    # Agent 名(多 Agent 场景)
    blockedBy: list[str] # 依赖的任务 ID 列表

Use this thing to replace Todo, but why do it this way? The original text provides this table:

TodoWrite (s05)

Task System (s12)

Positioning

Execution checklist for the current task

Recoverable task system

Storage

In-process / session state

.tasks/{id}.json

Dependencies

None

blockedBy / blocks Dependency graph

Lifecycle

Current session / current task

Retained across sessions

Division of labor

Not responsible for task claiming

owner / claim

Status

pending / in_progress / completed

pending / in_progress / completed

Granularity

The agent's own steps

Tasks that can be claimed, tracked, and unlocked

With so many parameters to compare, it's really hard to understand. Don't worry—actually, all of these things can be summarized into three points:

  • Recoverable, and capable of persistence;

  • Dependencies exist;

  • It can support multiple Agents processing tasks, with claim and tracking capabilities.

Stored to a file

This is why it is recoverable and capable of persistence. When we introduced Todo earlier, we said that it is a piece of context that loops along with everything, just like something we keep in our heads—after enough repetitions, it may be forgotten, and even the AI itself forgets what its todo is supposed to do.

The task system, however, exists in a file, and that is its advantage. No matter how you loop, this file is still there; it can even be called across conversations, so there is no need to worry about this problem at all.

Dependencies exist

This is the most important part. As we said at the beginning, even if we previously set the todo to check once every 3 loops, if the AI finds a problem after checking once, it may change it—but after several changes, the logic of the todo may be changed beyond recognition. For example, if you ask it to write the code first, then produce the design draft, and finally produce the PRD, the order may be directly reversed. The reason is that there are no mutual dependencies between tasks.

In the task system, usingblockedbyyou can ensure that if a certain step is not finished, the next step is impossible; the AI is forced to execute in order, and illogical step-skipping is prohibited.

Task claiming

This is mainly for Subagent. As we all know, the main reason CC is fast is that it hands tasks off to Subagent for execution, unlike codex, which does not proactively use Subagent to do work.

These tasks can be assigned by the main agent to these subagents. Once a task is claimed, it ensures that they do not collide with each other.

Summary

The core of this approach is that, compared with before, when everyone merely verbally listed a to-do list, now everyone directly puts tasks into tools like jira and linear, with accountability and status transitions, and they can check at any time if they forget.

Task system — when goals are too big, break them into small tasks

The task system in CC

As we said before, CC does not use only todo or only the task system; it uses both. Interactive sessions enable Task by default, while non-interactive/SDK defaults to TodoWrite.

In addition, when claiming, a lock mechanism is also provided to prevent race conditions from duplicate claims.

  • Task file lock:proper-lockfile Locked {taskId}.json (up to 30 retries, exponential backoff 5-100ms). Inside the lock:

    1. Re-read the task (to prevent TOCTOU)

    2. Check whether it has been claimed by someone else → already_claimed

    3. Check whether it is already completed → already_resolved

    4. Check whether upstream is incomplete → blocked

    5. Set owner

  • List-level lock(when checking agent busy):.lock file, atomically scan all tasks and check whether this agent already has another open task.