0014 — Task plan and checkpoints¶
- Status: Implemented (step 11.7, unreleased). Shipped behaviour: SPEC; tools: MCP tools → Plan.
- Size: ~2 agent-days (model, migration and service ~0.75; hooks, todo and reminders ~0.5; MCP, board and docs ~0.75).
Problem¶
An agent should always work by a plan the owner can see. A report at the end of a stage says what
happened, not what was meant to happen, and nothing shows a drift while the work goes on. Claude
Code keeps its own todo list, but it lives inside one context, disappears with /clear and is not
something the owner accepted.
Model¶
- Plan on the task: ordered
plan_steprows (title, "what and why" markdown, statuspending/in_progress/done/blocked). A done step is a checkpoint:done_at, a link (a report of the task or a PR URL), a one-line outcome and a conformance line, eitheras plannedordeviation: <why>(required for done). Deviations are highlighted on the card and in the Plan tab. - Plan status on the task row: none (no steps),
draft,accepted(with who and when). The owner accepts on the board, the coordinator withplan_accept. A change of the step titles or their order turns an accepted plan back to draft; status changes and "what and why" edits do not. - History: every plan write adds a
plan_revisionrow with the whole plan as JSON, the author and a reason; the board shows them with the diff of the titles. - Task size: an optional
sizefield (S/M/L), editable like the other fields; the first report whose first line names a size sets it when the task has none. - Second layer, never merged: the agent's Claude Code todo (
session_todo, per relaybay session and Claude Code id) shows under the current plan step as "now doing: …" with the list collapsed. A task with no plan steps shows the todo marked "Agent's plan, not accepted".
Rules¶
A new requirement kind in the rules document: {"kind": "plan_accepted", "unless_size": ["S"]},
in the default stage_requirements.dev. A task of unknown size needs the plan. warn mode adds a
warning to the move (a draft plan: "the plan is not accepted yet"); strict refuses it. A move to
dev with neither plan steps nor a todo also adds a soft hint: "write down what you are going to do
(todo or 2-3 steps with plan_set)".
Hooks¶
- Todo capture. Checked live on Claude Code 2.1.309: the todo tools are off by default (desktop
and CLI); with the env
CLAUDE_CODE_ENABLE_TODO_TOOLS=1they areTaskCreate(tool_inputsubject,description,activeForm; tool_response{"task": {"id", "subject"}}) andTaskUpdate(tool_inputtaskId,status; tool_response withstatusChange: {from, to}). Older builds useTodoWritewith the whole list (todos: [{content, status, activeForm}]). relaybay reads all three fromPostToolUse, before the activity coalescing, so no change is lost; unknown shapes are ignored and sizes capped (50 items, 200 characters). A new Claude Code id (after/clear) starts a fresh list; a list written before the agent linked its hook session moves with the exact link. - Reminder. For an exactly linked session (
cc_exact) and its bound open tasks: the current step (N/M, title, "what and why") and the todo item in progress go intoadditionalContextonSessionStart, after a todo change and everyplan_reminder_everytool events (default 30), never the same text twice in a row (a newSessionStartis a new context). Owner comments in the same answer keep the rest of the 8000-character budget.
API¶
plan_get(task), plan_set(task, steps, reason?) (replace semantics like review_steps_set:
step N keeps status and checkpoint while its title stays), plan_step_update(task, step, status,
outcome?, link?, conformance?), plan_accept(task); task_update gains size. Events
plan.set, plan.step_updated, plan.accepted, session.todo_updated.
Decided by default¶
- relaybay setup does not write
CLAUDE_CODE_ENABLE_TODO_TOOLS: it is the user's choice and easy to add or remove in Claude Code's settings. - Plan writes that change nothing (same titles and details, same status and checkpoint) are not kept as revisions.
- Leaving
doneclears the checkpoint; marking a done step done again (a new outcome or conformance) keeps itsdone_at. - A plan step's text is
detailsinplan_set, as inreview_steps_set. - A link is a report of the same task (
12,#12,report:12, stored asreport:12) or an http(s) URL; anything else is refused. - Agents do not accept plans;
plan_acceptis meant for the coordinator. - Reminders count
PostToolUseevents only;0turns the periodic reminder off. - The card shows the plan, not the todo; the todo is in the Plan tab.
Risks¶
| Risk | Mitigation |
|---|---|
| Todo tool payloads change between Claude Code builds | Defensive parsing, unknown shapes ignored, both generations supported |
| Reminders crowd the agent's context | Only on start, todo change and every N tools; never the same text twice; capped length |
| The plan turns into ceremony for small tasks | S tasks need no accepted plan; the todo counts as the agent's plan |