# progress/v1 (/docs/a2a/progress/v1)



URI: `https://docs.nylorun.com/a2a/progress/v1`

```json
{
  "statusUpdate": {
    "taskId": "t1.…",
    "contextId": "ticket-4821",
    "status": { "state": "TASK_STATE_WORKING", "timestamp": "2026-11-02T09:12:40.031Z" },
    "metadata": {
      "https://docs.nylorun.com/a2a/progress/v1": {
        "steps": [
          { "label": "Inspect wikis and toolchain", "state": "done", "note": "Node 22, pnpm 9" },
          { "label": "Build in parts", "state": "active" },
          { "label": "Package zip and write summary", "state": "pending" }
        ]
      }
    }
  }
}
```

An agent keeps its plan with `update_plan`, a built-in tool of our harness
that is off by default. Turn it on in the agent's `AGENT.md`:

```markdown title="AGENT.md"
---
name: coder
description: Writes and ships changes to the team's repositories.
loop:
  plan: true
---
```

The session's root agent then gets the tool, unless it declares its own tool
of that name. Each call takes `{ steps: [...] }`, records a durable
`plan.updated` event in the session, and answers `Plan updated`. The A2A
endpoint sends each one as a status update with this extension, and
`GetTask` and `ListTasks` carry the latest plan in the task's `metadata`. A
caller gets the whole plan each time, never a diff: replace the plan you show
with the latest one.

| Field           | Type                                                 | Meaning                                    |
| --------------- | ---------------------------------------------------- | ------------------------------------------ |
| `steps`         | array, at most 20                                    | The plan, in order.                        |
| `steps[].label` | string, at most 120 characters                       | What the step does.                        |
| `steps[].state` | `pending`, `active`, `done`, `blocked`, or `skipped` | Where the step is.                         |
| `steps[].note`  | string, at most 280 characters, optional             | A short note, such as what the step found. |

A longer label or note is cut to its limit, ending in `…`, and steps past the
20th are dropped; the call does not fail for length. A plan of the wrong shape
is a failed tool result the model sees. Labels and notes are short text the
agent writes. They never carry tool arguments or results.

Status updates can arrive more than once or out of order. Order them by
`status.timestamp`, and keep the plan from the latest. An agent without
`update_plan` sends no plan; its status updates carry states and step text
only. See [AGENT.md](/docs/build/agent-manifests#agentmd).
