# todo — Manual

## What it does
Tracks the steps of the current task and their status. The list is **already populated** when the task starts — the planner fills the todo with the plan's steps — so you normally never call `set`; you call `update` as you go and `view` when you lose the thread.

The tool is the record of *what you actually verified*. Marking a step `done` without a `validation` field is rejected outright, which is the point: it stops "done" from meaning "I moved on".

Tasks are per-session and do not survive a server restart.

## Parameters

| Parameter | Required | Description |
|-----------|----------|-------------|
| `op` | yes | `set` \| `view` \| `update` \| `add` \| `clear`. |
| `tasks` | for `set`/`add` | Ordered list of step descriptions (strings). |
| `index` | for `update` | 1-based step number. |
| `status` | for `update` | `pending` \| `in_progress` \| `done` \| `failed` \| `skipped`. |
| `validation` | for `status: "done"` | How you verified the result. |

An omitted `op` is **inferred** from the arguments you did send — `{"index": 1, "status": "in_progress"}` is read as an `update`, `{"tasks": [...]}` as a `set` — so a missing discriminator costs you nothing. An explicitly *wrong* `op` is rejected with the list of valid ones. A `status` outside the five is stored as sent rather than rejected, which means a typo (`"Done"`) silently stops the step from ever counting as done — spell them lower-case exactly as listed.

## Actions

### `update` — the one you use constantly
```json
{"op": "update", "index": 1, "status": "in_progress"}
{"op": "update", "index": 1, "status": "done", "validation": "ran uv run pytest tests/unit/tools -q — 38 passed"}
{"op": "update", "index": 2, "status": "failed", "validation": "ssh timeout after 60s; host unreachable, tried both key and password"}
```

- `index` is 1-based and must be within the plan — an out-of-range index returns the plan's length so you can correct it.
- **`done` requires `validation`.** Without it the call fails with `validation_required` and nothing changes. Say what you checked, not what you did: *"ran X — output matched Y"*, *"read the file and confirmed the block is gone"*.
- `failed` without `validation` is accepted, with a tip. Provide one anyway — it is what makes re-planning possible.
- Set `in_progress` when you **start** a step, and move it to `done`/`failed` **before starting the next one**. A status that lags reality turns the todo into decoration.

### `view`
Re-orients you: current statuses plus the validation notes. Call it after a sub-agent returns, after a long tool chain, or whenever the plan in your head may have drifted from the plan in the store. "No plan set for this session." means exactly that — no plan exists yet.

### `set`
Creates or **replaces** the Master Plan. Use it only when the plan must be rebuilt mid-task. It takes the whole list and discards every existing status, so it is the expensive, destructive option.

### `add`
Appends steps discovered mid-task and **preserves existing steps and their statuses**. This is what you want for a newly surfaced subtask — never rebuild the list with `set` to add one line. Requires a plan to already exist.

### `clear`
Resets the plan. Rarely right: a finished plan is the record of what was verified, and the final answer should be able to point at every step marked `done`.

## The pattern

1. Start a step → `{"op": "update", "index": N, "status": "in_progress"}`.
2. Do the work.
3. Verify it — actually run the check, read the output.
4. `{"op": "update", "index": N, "status": "done", "validation": "..."}`.
5. Repeat. Nothing is left `in_progress` when you answer.

Before your final message, every completed step — including the last one — must be `done` with validation. If you discover work the plan does not cover, `add` it rather than silently doing it.

## Common mistakes

- `set` instead of `add`, wiping the statuses of steps already finished.
- Marking several steps `done` at the end in one sweep, with validations written from memory. Verify per step; the todo is only worth reading if it tracked reality while it happened.
- Leaving the last step `in_progress` in the final answer.
- Using a 0-based index. It is 1-based, like the rendered list.
- Treating `view` as optional after a sub-agent run — its steps are not in your head.
