Skip to content

Cycles

Submit a request for a cycle, run and stop it, watch it live, manage its tasks, and collect what it produced.

A cycle is a meaningful chunk of a project — a feature, a release or one stage of a larger change — and it is the unit that actually runs. One build agent works each run in a short-lived Cloud Machine on the cycle’s branch. Retries and review feedback continue that cycle. Its tasks are the build agent’s live checklist.

  • One run, one checklist. The plan agent writes the cycle’s tasks as small, ordered, verifiable items. The build agent works them in order on the cycle branch: it marks an item building, commits, then marks it done with a one-line note. It adds an item when it finds more work, and marks an item blocked with a reason when it cannot go on. Items move live on the Cycles board with no refresh.
  • One role per cycle. The project manager hires the role that fits the cycle: Senior Engineer (the default), Product Engineer, UI Engineer, QA Engineer, Security Engineer or Technical Writer, or one of your Workspace’s own custom agents.
  • Parallel work means independent cycles. The project manager runs independent cycles at the same time and makes dependent ones wait. A large request becomes a foundation cycle plus one cycle per independent area that depends on it.
  • Parallel cycles. Each cycle runs in its own Cloud Machine. A cycle in flight holds one build agent. A ready cycle beyond your cap waits as a draft and starts as soon as a build agent is free. Set the cap under Settings → Models & accounts → Defaults → Cycle; see Connect your agents.
  • Progress is saved. The run commits and pushes the cycle branch about once a minute. After a run stops, the next one continues from published commits. Unpushed edits in a lost Cloud Machine may need to be repeated.
  • Review sends work back onto the checklist. When the run finishes, a read-only review agent, the project’s verify command and its e2e suite check the cycle branch head. A finding that names an item reopens that item with the feedback. A finding that names none adds one “review” item. The next run of the same cycle fixes them on the same branch.
  • Delivery. A reviewed cycle lands on the project’s preview branch by fast-forward to the exact commit review checked. If the preview moved first, it is merged into the cycle branch and review runs again. A conflict adds the item “Merge the preview and resolve conflicts”, and the next run resolves it.

If you use a connected provider account, keep Parallel cycles within that provider’s rate limits. Increasing parallel work beyond the account’s capacity can add throttling instead of speeding delivery.

The Cycles board in the dashboard lists every cycle with its checklist moving live. Team now at the top shows who is building right now, by role.

  • A project with at least one cycle, usually planned by a project run
  • An agency role (owner, admin, member). A portal client with the Can message permission can run and stop a cycle but not edit it.
  • Models configured for the workspace, or hlix’s defaults

Send a title and description to the project manager. The request goes through triage, and the 202 response identifies the cycle it created or joined.

Terminal window
curl -sS -X POST "$HLIX_BASE_URL/v1/api/cycles" \
-H "x-api-key: $HLIX_API_KEY" \
-H "X-Organization-Id: $HLIX_WORKSPACE_ID" \
-H 'content-type: application/json' \
-d '{"projectId":"'"$PROJECT_ID"'","title":"Health and readiness","description":"Add liveness and readiness endpoints with tests and docs."}'
{"proposed":true,"adopted":true,"proposalId":"…","cycleId":"…"}

projectId, title (1–200 characters) and description (1–10 000 characters) are required. cycleId names the cycle your request created or joined; it is null when the request was not adopted on this pass. List the project’s cycles with GET /v1/api/cycles?projectId=… to see where it landed.

New-work requests go through triage, whichever way they arrive. A request can join an existing cycle rather than create another. A cycle at triage exists but has not yet completed classification. Cycles opened from already-pushed branches carry existing commits and skip request classification.

For one small, well-defined change, ask the project chat for a quick task: it becomes a cycle holding just that one task, starts at once without a planning step, and still goes through build, review and delivery to the preview branch. Lists show it as the task, labelled “Quick task”.

Terminal window
curl -sS -X POST "$HLIX_BASE_URL/v1/api/cycles/$CYCLE_ID/execute" \
-H "x-api-key: $HLIX_API_KEY" \
-H "X-Organization-Id: $HLIX_WORKSPACE_ID"

Expected result:

{"message":"Cycle execution started","threadId":"<workspace-id>:<cycle-id>"}

Start runs on cycles in draft, planning or failed status. Retrying a failed cycle continues its branch and checklist, returning failed or blocked tasks to queued. Hlix also retries failed cycles automatically using the failure as context.

Follow the queued run in the dashboard or with the SDK watch below.

POST /v1/api/cycles/:id/stop cancels the cycle, including a failed cycle that hlix would otherwise keep retrying. A stopped cycle reads canceled and is not retried automatically.

Status Meaning
triage Created and awaiting the triage decision
draft Admitted, not yet running
planning Being planned into a checklist of tasks
executing A build agent is working the checklist
review Automated review is checking the cycle’s changes
done Terminal — the work landed on the project’s preview branch
failed The attempt failed — hlix retries it automatically, with a different approach each time
canceled Terminal — triage declined the request, or a person stopped the cycle

Older cycles can also read pr_created, which means the same as done, or interviewing, which should be treated like planning.

Review is automated; it is separate from initial proposal approval and the final merge. Delivery metrics exclude review from in-flight work because building has finished. See Delivery metrics.

Every status change records who made it, when and why. Read stageHistory on GET /v1/api/cycles/:id to follow a cycle’s progress or understand a retry, cancellation or review decision. Entries are ordered oldest first.

The Cycles API documents the full history record and revision fields.

Triage writes two more fields onto every cycle it forwards.

  • priority — an integer from the urgency triage judged: 300 urgent, 200 high, 100 normal, 0 low. Ready cycles start highest first.
  • lane — the handling hlix’s rules assign from the judged complexity and risk. No handling waits for a person.

Both are fields on the cycle and part of the published API. Triage covers how each is derived.

To list a project’s cycles in start order rather than creation order:

Terminal window
curl -sS "$HLIX_BASE_URL/v1/api/cycles?projectId=$PROJECT_ID&orderBy=priority" \
-H "x-api-key: $HLIX_API_KEY" \
-H "X-Organization-Id: $HLIX_WORKSPACE_ID"

orderBy accepts createdAt (the default, newest first) or priority (highest first, ties newest first). The dashboard’s cycles grid offers the same two sorts.

A cycle is watched live through @hlix/sdk: the first update is the cycle as it stands — its status, its stage, its tasks — and every later one arrives as it changes.

for await (const { state, event } of hlix.live.project(projectId, { cycleId })) {
const [cycle] = state.cycles
console.log(cycle.stage, state.tasks.map((task) => task.status))
}
Field What it carries
state.cycles[0].status The cycle’s status, which can be pr_created on an older cycle
state.cycles[0].stage That status folded to what a board shows — planned, triage, running, review, done, failed or canceled
state.tasks The cycle’s checklist items, each with its status and assigned agent
state.activity The timeline, oldest first, the newest 50: the loop’s stored decisions, then the running workflow’s own steps

Use stage for board-style status, including normalized values for older cycles. Leave the loop or abort its signal when you have received the updates you need.

For a non-streaming read of the same material use GET /v1/api/cycles/:id/timeline (cycle plus child-task events) or GET /v1/api/cycles/:id/events (cycle events only).

GET /v1/api/cycles/:id returns the cycle plus its tasks — each with a dependsOn array — and previewUrl and linearIssueUrl when they exist.

Terminal window
curl -sS "$HLIX_BASE_URL/v1/api/cycles/$CYCLE_ID" \
-H "x-api-key: $HLIX_API_KEY" \
-H "X-Organization-Id: $HLIX_WORKSPACE_ID"

GET /v1/api/cycles?projectId=… lists them.

Operation Endpoint Constraint
Add a task POST /v1/api/cycles/:id/tasks title and description required; dependsOn optional
Edit a task PATCH /v1/api/cycles/:id/tasks/:taskId title, description, sortOrder
Remove a task DELETE /v1/api/cycles/:id/tasks/:taskId Only queued or blocked tasks
Edit the cycle PATCH /v1/api/cycles/:id title, description, targetBranch
Delete the cycle DELETE /v1/api/cycles/:id Only draft or failed cycles

Delete cycles in draft or failed status. Running and canceled cycles retain their records.

POST /v1/api/cycles/:id/messages stores a message in the cycle’s chat and hands it, word for word, to the build agent working the cycle (content required; agentId addresses one agent’s 1:1 chat; messageId makes it idempotent). It answers 202 with {"stored":true,"delivery":…}. The delivery value tells you when the build agent receives the message:

delivery What happened
next_turn The build agent reads it at the start of its next step. A ready draft cycle starts.
now You sent "urgent":true and the current turn stopped. The next turn starts with your message. If the turn could not be stopped first, delivery remains next_turn.
queued The cycle has no build agent yet (every build agent is busy, it waits on another cycle, or it runs again later). Its first step starts with your message.
follow_up The cycle is finished. Its message is carried into a new cycle opened from it, through triage.
thread Stored only: the message only named people, you sent "deliver":false, the cycle is an older one that reads interviewing, or the same messageId was sent before ("replayed":true).

The project manager hears about every delivered message.

Use the TypeScript SDK’s live methods for streaming conversations and typed events.

  • GET /v1/api/cycles/:id/artifacts lists what the run produced.
  • GET /v1/api/cycles/:id/artifacts/:filename returns {"url":…,"key":…}, or the raw bytes with ?download=1.
  • GET /v1/api/cycles/:id/usage returns {"totals":{…},"byRole":[…]} with token counts and cost per agent role.
  • {"error":"Cycle cannot be executed in \"executing\" status"} — it is already running. Watch it instead of starting a second run.
  • {"error":"Cycle not found"} — wrong id, or another workspace. Check X-Organization-Id.
  • {"error":"Project not found for cycle"} — the cycle’s project was deleted; it cannot be run.
  • {"error":"The cycle run could not be queued, so it was not started. Nothing is running — try again."} — a 502. Retry the request.
  • {"error":"Can only delete tasks in queued or blocked status"} — the task has already started, so it can no longer be removed.
  • {"proposed":true,"adopted":false} — the request was not adopted on this pass. Re-read the project’s cycles before sending it again; it may already be covered.
  • {"error":"Cycle cannot be executed in \"triage\" status"} — triage has not decided yet. Follow its progress in the dashboard.
  • The cycle reads canceled — triage declined the request, or someone stopped it. The reason is on the last stageHistory entry.
  • The cycle sits in draft — check dependencies, the build agents available, the spending cap, and any initial proposal still waiting for approval.