Reviewing output
Review in hlix works on verified evidence: the diff is read back from the repository host or the workspace archive, not summarized by the agent that wrote it. Comments anchor to an exact commit, and a revision request folds them into the task and re-enters the cycle.
Prerequisites
Section titled “Prerequisites”- A task that ran through a cycle and produced a branch
- Agency role, or a client collaborator the project was shared with (comments need only view access; sending a revision needs steer)
The evidence document
Section titled “The evidence document”GET /v1/api/tasks/:id/review returns the same observation the QA evaluator reviewed.
With the CLI:
hlix tasks review "$TASK_ID"With the TypeScript SDK — see TypeScript SDK for building the hlix client:
const evidence = await hlix.tasks.review(taskId)Over the API:
curl -sS "$HLIX_BASE_URL/v1/api/tasks/$TASK_ID/review" \ -H "x-api-key: $HLIX_API_KEY" \ -H "X-Organization-Id: $HLIX_WORKSPACE_ID"The fields that matter when you are deciding whether to accept the work:
| Field | Meaning |
|---|---|
source |
github-compare when read from the connected provider, workspace-artifact when the project has no remote |
observedAt |
When the evidence was collected — evidence is a snapshot, not a live view |
baseRef / baseSha |
The exact commit the task branch was cut from — a commit sha, never a branch name (see below) |
headRef / headSha |
The task branch and the reviewed commit. headRef is derived as hlix/ms-<cycleId>/task-<first 12 of the task id>. Every comment anchors to headSha |
comparison |
{status, aheadBy, behindBy} — ahead, behind, identical, diverged, or unknown |
filesChanged, additions, deletions, commits |
Change size |
files[] |
Per file: path, previousPath, status, additions, deletions, patch, patchTruncated |
filesTruncated |
true when the file list itself was cut short |
evaluator |
{verdict, summary, headSha, observedAt, stale} — stale: true means the evaluator judged an older commit |
artifact |
For repo-less projects: {kind:"git-archive", reviewUrl, sizeBytes, capturedAt} |
Commenting on a line
Section titled “Commenting on a line”GET and POST /v1/api/tasks/:id/review/comments hold the line-level review conversation. Every comment is anchored to headSha, which is what stops a comment from silently drifting onto code it was never about.
curl -sS -X POST "$HLIX_BASE_URL/v1/api/tasks/$TASK_ID/review/comments" \ -H "x-api-key: $HLIX_API_KEY" \ -H "X-Organization-Id: $HLIX_WORKSPACE_ID" \ -H 'content-type: application/json' \ -d '{ "headSha": "9f2c1b0ae4d5768a3c2f1e0d9b8a7c6d5e4f3a2b", "path": "src/routes/healthz.ts", "side": "head", "lineStart": 12, "lineEnd": 14, "body": "Read the SHA from the build env, not from git at request time." }'The anchoring rules are enforced, not advisory:
headShais required and must be a 40-character hex commit sha.bodyis required, 1–10 000 characters.siderequirespath.lineStartrequires bothpathandside.lineEndrequireslineStartand must be greater than or equal to it.- Omit
pathentirely for a comment about the change as a whole.
A comment on a stale commit is refused with the commit you reviewed and the one that exists now:
{"error":"The branch moved on: you reviewed 9f2c1b0…, the current head is 3d7e5a1…. Refresh the diff and comment again.","headSha":"3d7e5a1…"}Listing comments returns the anchor alongside them:
{ "taskId": "b4a1f0d2-…", "headSha": "9f2c1b0ae4d5768a3c2f1e0d9b8a7c6d5e4f3a2b", "comments": [{ "id": "…", "path": "src/routes/healthz.ts", "side": "head", "lineStart": 12, "lineEnd": 14, "body": "…", "resolution": "open", "revisionIteration": 0, "stale": false }], "visualContext": { "enabled": false, "reasonCode": "no-live-preview", "reason": "…" }}stale: true on a comment means the branch has moved past the commit that comment was written against. When the head cannot be observed at all, headSha is null and every comment reads stale: true — that is a degraded read, not an error.
Resolve or reopen a comment with PATCH /v1/api/tasks/:id/review/comments/:commentId and a body of {"resolution":"resolved"} or {"resolution":"open"}. The call is idempotent.
Requesting a revision
Section titled “Requesting a revision”POST /v1/api/tasks/:id/review/request-revision folds every unresolved comment on headSha into the task’s review feedback and re-enters the cycle, so the same worker gets your notes as instructions.
curl -sS -X POST "$HLIX_BASE_URL/v1/api/tasks/$TASK_ID/review/request-revision" \ -H "x-api-key: $HLIX_API_KEY" \ -H "X-Organization-Id: $HLIX_WORKSPACE_ID" \ -H 'content-type: application/json' \ -d '{"headSha":"9f2c1b0ae4d5768a3c2f1e0d9b8a7c6d5e4f3a2b"}'Expected result:
{ "taskId": "b4a1f0d2-…", "cycleId": "0a9b8c7d-…", "headSha": "9f2c1b0ae4d5768a3c2f1e0d9b8a7c6d5e4f3a2b", "commentIds": ["…"], "staleSkipped": 0, "feedback": "…the composed feedback the worker receives…", "iteration": 1, "started": true, "reason": null}staleSkipped counts comments that were anchored to an older commit and therefore left out. started: true is the signal that the cycle was actually re-entered.
If queuing fails, nothing is recorded — the refusal says so explicitly rather than leaving a half-applied revision:
{"error":"The revision could not be queued (…), so it was not recorded. Nothing changed — try again.","started":false}Contract coverage
Section titled “Contract coverage”In the dashboard
Section titled “In the dashboard”The cycle queue’s review panel renders the same evidence: the file list, the patch per file, and a comment thread anchored to the reviewed commit, with Request revision as the action that sends unresolved comments back. It is the fastest path when you are reading a diff rather than automating one.
If review fails
Section titled “If review fails”{"error":"No review evidence: this task has no branch (it was never dispatched through a cycle)"}— the task never ran. See Tasks.{"error":"No review evidence: this task has no recorded branch point…"}— the task ran before a base was recorded; there is nothing to diff against.{"error":"Could not fetch review evidence — …"}with status502— the repository host could not be reached. Retry; nothing is wrong with the task.{"error":"Task repo not found"}— the project’s repository binding is gone.{"error":"The branch moved on: you reviewed …, the current head is ….","headSha":"…"}— refresh the evidence and comment against the new head.{"error":"This task has no reviewed commit …"}with status409— the evidence came from a workspace archive with no commit to anchor to.{"error":"This task has no cycle to retry through."}— a standalone task cannot be revised; only cycle-dispatched work can re-enter.{"error":"This task's cycle is already running. …"}— wait for the current run before requesting a revision.{"error":"Cannot anchor a comment: …"}— the evidence itself could not be read, so no anchor exists yet.{"error":"Read-only access to this project"}— you are a client collaborator without steer rights. You may comment; you may not request a revision.