# Cycle lifecycle

**A cycle's status says where a delivery has got to.** Every change to it is recorded, attributed and timestamped. This page is the whole status vocabulary: what is in flight, what is terminal, and which statuses you can run a cycle from.

## When this matters to you

- A cycle will not execute and you want to know whether its status is the reason.
- You are filtering or charting cycles and need the full set of values a cycle can hold.
- You are watching a stream and want to know what its final frame means.

## The statuses

A cycle moves through these statuses in this order.

| Status | What it means | Can you execute from it? |
| --- | --- | --- |
| `triage` | Created, awaiting the [triage](/concepts/triage/) decision | No |
| `draft` | Admitted, not yet running | Yes |
| `planning` | Being decomposed into tasks | Yes |
| `executing` | Tasks are running in the Coding Workspace | No |
| `review` | The completed work is being reviewed | No |
| `done` | Terminal — the work landed on the project's branch | No |
| `failed` | The attempt failed — the project retries it automatically | Yes, as a retry |
| `canceled` | Terminal — the request was declined at triage, or a person stopped it | No |

Every cycle is created at `triage`, whichever door it came through — chat, the board, Linear, a GitHub issue, or the API. There is no intake path that starts a cycle further along.

### `review` is a stage, not a checkpoint

A cycle enters `review` when the automated review starts, so you can tell **work still being written** from **work being checked**.

Nothing waits on a person in `review`. An agent does the reviewing and the cycle moves on by itself, as it does at every other status. The [one human decision](/concepts/review-gates/#the-one-human-decision) is at the end of the project.

**`review` is not counted as work in progress:** The delivery metrics count `draft`, `triage`, `planning` and `executing` as in flight and leave `review` out. A cycle under review has finished building, so counting it would overstate how much work is still open. See [Delivery metrics](/running/metrics/).

### `done` is the terminal success status

A cycle does **not** open a pull request. Every cycle merges into the project's preview branch, and the single pull request from that branch into your default branch is opened once per project. `done` is what a delivered cycle reads.

## Statuses you may still read

Two values can appear on older cycles. New cycles never enter them, but anything that reads cycles — a dashboard, a script, a report — should accept both.

| Status | How to read it |
| --- | --- |
| `pr_created` | Delivered. Treat it exactly like `done`. |
| `interviewing` | In flight. Treat it like `planning`. |

## Which statuses you can execute from

`POST /v1/api/cycles/:id/execute` accepts exactly three: **`draft`**, **`planning`**, and **`failed`**. Anything else is refused with the status quoted back at you:

```json
{"error":"Cycle cannot be executed in \"executing\" status"}
```

Executing a `failed` cycle is a retry, not a second parallel run: it moves the cycle back to `draft`, attributed to you, and returns every `failed` or `blocked` task to `queued` before the run starts. You rarely need to: hlix retries a failed cycle on its own, with the failure as context and a different approach each attempt.

## Every status change is recorded

A status never changes quietly. Each change is appended to the cycle's `stageHistory` with who decided it and why:

```json
{
  "from": "triage",
  "to": "draft",
  "at": "2026-08-12T09:41:07.220Z",
  "actor": { "type": "agent", "id": "intake-agent" },
  "ruleSetVersion": "hlix-web-v1",
  "reason": "Schema change is understood and reversible."
}
```

`actor.type` is the field that carries the most meaning:

- **`human`** — a person, through the dashboard or the API.
- **`agent`** — a decision made by an agent, such as triage admitting a request or the project manager submitting a plan.
- **`rule`** — a platform rule with no model involved, such as an automatic retry.

`ruleSetVersion` names the version of hlix's delivery rules that applied. Alongside the history sits a `revision` counter, incremented on every change: if two changes to the same cycle collide, the later one is rejected rather than overwriting the first.

## If a status does not look right

- `{"error":"Cycle cannot be executed in \"triage\" status"}` — triage has not decided yet, and no request can skip that decision. See [Triage](/concepts/triage/).
- `{"error":"Cycle cannot be executed in \"executing\" status"}` — it is already running. Watch it rather than starting a second run.
- `{"error":"Can only delete cycles in draft or failed status"}` — a cycle cannot be deleted while it runs. Stop it first.
- **A cycle reads `pr_created` and you expected `done`.** Both mean delivered; treat them identically.
- **A cycle sits in `draft` and never starts.** It is waiting for a cycle it depends on, or the project is paused at its spending cap. Check the project's activity.
- **A cycle reads `canceled` and you did not cancel it.** Triage refused the request; the reason is on the last `stageHistory` entry.

## Where to go next

| If you want to… | Read |
| --- | --- |
| Propose, execute, stream and read a cycle over the API | [Cycles](/running/cycles/) |
| See what admits a cycle in the first place | [Triage](/concepts/triage/) |
| Understand what happens in `review` | [Review & QA gates](/concepts/review-gates/) |
| See what these transitions add up to across a project | [Delivery metrics](/running/metrics/) |

## Next steps

[Cycles](/running/cycles/)
  [Triage](/concepts/triage/)
  [Review & QA gates](/concepts/review-gates/)
  [Work tree](/concepts/work-tree/)