Triage
Every cycle starts at Triage. Before a roadmap is drawn, before a task exists, before any agent touches a repository, the request is judged on what it actually is: how well understood it is, how costly a wrong answer would be, and how much it should jump the queue.
When this matters to you
Section titled “When this matters to you”- A cycle you asked for came back
canceled, and you want the reason it was refused. - A cycle parked for approval on a project where you never turned approvals on.
- Two cycles were ready at the same time and one dispatched first.
Where Triage sits
Section titled “Where Triage sits”request ──▶ Triage ──┬──▶ draft ──▶ planning ──▶ executing ──▶ … │ └──▶ canceledWhatever proposed the work — the dashboard chat, POST /v1/api/cycles, a Linear delegation, or the project’s own founding brief — none of them create a cycle directly. They all raise a proposal, and the roadmap planner is the single place a cycle row comes into existence. It creates every one at status triage and triages it immediately.
No agent has a path around that, including the orchestrator: a plan cannot be submitted for a cycle that is still in triage.
Cycle "…" is still in triage. The Triage Agent decides whether it goesforward; a plan cannot skip that gate.What the Triage Agent decides
Section titled “What the Triage Agent decides”The agent reads the request’s title, body, and the project it belongs to, and returns four judgements plus a written rationale.
| It judges | Meaning | Values |
|---|---|---|
| Complexity | How well understood the change is before work starts | simple · ambiguous · systemic |
| Risk | How costly a wrong answer would be | low · medium · high |
| Urgency | How much this should jump the queue ahead of work already waiting | urgent · high · normal · low |
| Decision | Whether this becomes a cycle at all | forward · cancel |
Urgency is judged from what the work is — something user-facing is broken, or other queued work is blocked on it — and explicitly not from how urgently the request happens to be worded.
Lanes are derived, not chosen
Section titled “Lanes are derived, not chosen”Complexity and risk resolve to one of nine lanes through a versioned rule set, hlix-web-v1:
Risk low |
Risk medium |
Risk high |
|
|---|---|---|---|
simple |
auto |
fast-review |
stop |
ambiguous |
plan-gate |
architecture-review |
design-review |
systemic |
experiment |
split-work |
manual-lane |
The lane lands on the cycle as lane, and the rule-set version that resolved it is recorded on the transition — so a lane can always be explained by the rules in force when it was assigned, not by the rules in force when you read it.
Four lanes change behaviour today. stop, design-review, architecture-review, and manual-lane force a human approval before the cycle dispatches, whether or not the project opted into approvals — see Review & QA gates. The remaining five are recorded as classification and carry no distinct mechanism of their own: plan-gate is already satisfied by the planning pass every cycle makes, and auto, fast-review, experiment, and split-work are metadata you can read, filter, and audit on.
Urgency becomes a priority
Section titled “Urgency becomes a priority”| Urgency | priority |
|---|---|
urgent |
300 |
high |
200 |
normal |
100 |
low |
0 |
priority is a plain integer on the cycle, not a named level, with 100-wide gaps so a later adjustment has room to land between tiers. It orders three things:
- Dispatch. Ready cycles are launched highest priority first. This is an order, not a cap — every ready cycle in the wave still launches on that pass, and equal priorities keep their roadmap order.
- Reading cycles back.
GET /v1/api/cycles?orderBy=prioritysorts by priority, then newest first; the dashboard’s cycles grid offers the same sort. The only other accepted value iscreatedAt, which is the default. - Planning. The roadmap planner is shown the priorities already on the board when it sequences and links the new work it proposes. It cannot change an existing cycle’s priority.
What gets recorded
Section titled “What gets recorded”A forward moves the cycle to draft; a cancel moves it to canceled. Either way, two records are written.
The cycle’s stage history gains an entry — this is the governed transition, and it is the same machinery every later status move uses:
{ "from": "triage", "to": "draft", "at": "2026-08-12T09:41:07.220Z", "actor": { "type": "agent", "id": "triage-agent" }, "ruleSetVersion": "hlix-web-v1", "reason": "Adds a currency column and a backfill; the schema change is understood and reversible."}An audit row is written as cycle.triaged or cycle.canceled, attributed to the Triage Agent, carrying the rationale as its reason and the lane, priority, and raw tiers as metadata.
lane, priority, stageHistory, and revision are all fields on the cycle itself and are part of the published contract. The complexity and risk tiers behind the lane are deliberately not: they exist only in the audit record, which is restricted to workspace owner and admin.
Reading a decision back
Section titled “Reading a decision back”Ask the project’s orchestrator in chat — “why was this cycle canceled?” — and it will return the decision, its rationale, the lane, and the rule-set version. Owners and admins additionally get the complexity and risk judgement behind the lane. The same material is in the audit log, filtered to that cycle.
When the Triage Agent cannot answer
Section titled “When the Triage Agent cannot answer”Triage fails open. If the model call errors, the cycle is forwarded rather than stranded, with a rationale saying exactly that, and it lands in the architecture-review lane — which forces the human gate. A triage outage costs you an approval, never a lost request.
That posture is chosen per signal, not globally. An unreadable lane does not gate on its own, because most cycles without one are simply older than the column. An unreadable project approval flag does gate, because an operator toggle whose state is unknown must be read as the safer answer.
Choosing the model that triages
Section titled “Choosing the model that triages”Triage is its own orchestration role. Set the model for it under Settings → AI models, on the row labelled Triage, or over the API:
curl -sS -X PUT "$HLIX_BASE_URL/v1/api/model-config/triage" \ -H "x-api-key: $HLIX_API_KEY" \ -H "X-Organization-Id: $HLIX_WORKSPACE_ID" \ -H 'content-type: application/json' \ -d '{"modelIdentifier":"'"$MODEL_IDENTIFIER"'","temperature":0}'modelIdentifier is required; temperature and maxTokens are optional. DELETE on the same path clears the override and returns the role to the deployment’s default. Writes are restricted to owner and admin.
If a cycle is not where you expect
Section titled “If a cycle is not where you expect”- A cycle reads
canceledand you did not cancel it. Triage refused it. The rationale is thereasonon its last stage-history entry, and on thecycle.canceledaudit row. - A cycle parked for approval on a project with the gate off. Its lane forces one. The pending request carries the lane in its
context. See Approvals. {"proposed":true,"adopted":false}and no cycle appeared. A proposal is not a cycle; the orchestrator did not fold it into the roadmap on that pass. See Cycles.- Two cycles dispatched in an order you did not expect. Compare their
priorityvalues, not their creation times. Anormalcycle created first still goes after anurgentone. - A cycle has no
lane. It was created before triage ran on it, or triage has not completed yet. A null lane never forces a gate on its own.
Where to go next
Section titled “Where to go next”| If you want to… | Read |
|---|---|
| See which lanes stop a dispatch | Review & QA gates |
| Resolve the request a lane opened | Approvals |
| Read a cycle’s stage history over the API | Cycles |
| Watch how work actually flows through the stages | Delivery metrics |