Jobs
Submit a job, read it, wait for it, stream its events, read its summary and cancel it.
List jobs
Jobs without their tasks.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
actor | string | Optional | |
ref | string | Optional | |
repo | string | Optional | |
state | string | Optional |
Response
datahas_morenext_cursor
curl "$CIRESK_API/v1/ci/jobs" \
-H "Authorization: Bearer $CIRESK_KEY"Submit a job
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
Idempotency-Key | string | Required |
Request body
actorbase_digest- commit sha
base_refbudget_unitsclientdiff_digest- sha-256 digest as
sha256:<64 hex> fail_fast- the cell cancels the job's queued tasks at the first task that ends other than
succeeded; running tasks finish and report, so a failure staysfailed fullkindcheck,test,build,lintor a manifest task idlabelsmanifest_digest- required without a tree; with one, the cell reads it from the tree's leaf at
manifest_pathand, when it is sent, checks that the two agree manifest_pathno_cache- skip the task cache for this job: every task runs; a success is still recorded for the next job
no_dedupnote- the submitter's one line for the person who decides the job's approval gates: untrusted text, at most 280 characters, shown and never interpreted
repo_id- uuidv7 rendered as
repo_<32 hex> sessiontargetstree- the working tree as a merkle root with the small change inline
tree.bytestree.entriestree.inlinetree.inline[].data_b64tree.inline[].digest- sha-256 digest as
sha256:<64 hex> tree.manifeststree.manifests[].data_b64tree.manifests[].digest- sha-256 digest as
sha256:<64 hex> tree.parent_root- the root digest of a working tree: sha-256 of the root directory manifest
tree.root- the root digest of a working tree: sha-256 of the root directory manifest
tree.tree_schema- the
TREE_SCHEMA_VERSIONthe root was hashed under; absent from a client older than it tree_id- sha-256 hex of the repo identity plus the absolute tree location, one per checkout
tree_root- a root already committed in the organisation's store (a dev checkpoint, an earlier upload),
built with nothing uploaded;
422 tree_not_committedwhen the store lacks any of it. never withtree trust- the tier the submitter asks for:
untrusted, or the tier the cell derives anyway; any other is refused withpolicy_denied(policy_fieldtrust), never appliedOne ofuntrusted,trusted_ci,trusted_interactive
Response
actoraffected- what expansion selected for the job and why, when the submission carried a tree
affected.changed_files- distinct changed paths between the reference root and the submitted one
affected.escalatedaffected.graph_root- the root whose recorded graph answered; absent when none was read
affected.reason- the condition column of's table, as
crates/ci/affectedwords it affected.reference_root- the root the diff was taken against; absent for a first submission
affected.selected- targets the tasks received through
targets_arg; 0 when escalated (the full set runs) affected.strategy- One of
cargo,pnpm,go,turbo,nx,files,none affected.total- nodes of the recorded graph, when one was read
base_digest- commit sha
base_ref- ref name as submitted
clientcost_unitscreated_atdeduplicateddiff_digest- sha-256 digest as
sha256:<64 hex> duration_msexit_codefail_fast- the cell cancels the job's queued tasks at the first task that ends other than
succeeded; a deduplicated job carries the first submitter's choice finished_atfullid- uuidv7 rendered as
job_<32 hex> kindcheck,test,build,lintor a manifest task idno_cache--no-cache: no task is served from the task cache; successes still recordprincipalpriorityreporepo_id- uuidv7 rendered as
repo_<32 hex> request_id- the
X-Request-Idthis answer was produced under, so a--jsonenvelope can name it sessionstarted_atstate- One of
queued,leased,running,succeeded,failed,cancelled,timed_out,infra_error superseded_by- the newer job of the same submitter, branch, kind and targets that cancelled this one under the
policy's
cancel_in_progress; absent otherwise targetstasks- absent on list rows and inside
Summary.job tasks[].approval- : the task's approval gate; a gated task stays
queueduntil it is approved tasks[].approval.approversuser:<id>androle:<name>; empty means any person holdingci:approvals.approvetasks[].approval.commenttasks[].approval.decided_attasks[].approval.decided_bytasks[].approval.expires_attasks[].approval.reached- the task's dependencies have succeeded: an approval starts it at once
tasks[].approval.sod_exception- the requester decided their own gate under the policy's
approval_self: record tasks[].approval.state- One of
pending,approved,rejected,expired tasks[].artifact_counttasks[].blocked_by- on a
skippedtask, the dependency whose end skipped it (build,build[1/2]) tasks[].cache- how a task met the task cache: served without a run, looked up and run, recorded after the run,
or never keyed (
cache: false,cache: { results: false }or--no-cache)One ofhit,miss,write,none tasks[].cache_hit- the task did not run: its key matched a recorded success;
cached_fromnames it tasks[].cache_note- why the task was neither answered from the cache nor recorded in it, when the cell knows a reason
beyond "these inputs never passed": the manifest keeps it out, or the run changed a tracked path.
ciresk ci explain-misscompares a miss with the last recorded run of the task tasks[].cached_failure- the task did not run: its key failed cleanly in the named run and never passed, so it ended with that run's exit code, tests and first failure;
--no-cacheruns it tasks[].cached_failure.job_id- uuidv7 rendered as
job_<32 hex> tasks[].cached_failure.task_id- uuidv7 rendered as
tsk_<32 hex> tasks[].cached_from- the run a cache hit stands on: the job and task whose success was recorded under the key, so a hit names where its verdict, log, junit and artifacts come from
tasks[].cached_from.job_id- uuidv7 rendered as
job_<32 hex> tasks[].cached_from.task_id- uuidv7 rendered as
tsk_<32 hex> tasks[].cached_targets- a task split into per-target units: how many targets reused a recorded verdict
tasks[].cached_targets.hittasks[].cached_targets.oftasks[].cold_start- how warm the member was when it took the lease:
warmwas online before the job was submitted,startedcame online after it (the factory started it for the queue),first_after_bootwas online before but this is its first lease since its bootOne ofwarm,started,first_after_boot tasks[].cost_unitstasks[].duration_mstasks[].exit_codetasks[].expected_ms- how long the planner expects the task to run, from the repository's history or the kind default; shorter tasks lease first within a job
tasks[].finished_attasks[].first_failure- the first failing line the worker saw, present from the moment it was seen
tasks[].first_failure.at- the worker's clock when the line was seen
tasks[].first_failure.excerpttasks[].first_failure.kind- what the first failing line of a task's log was: a compiler diagnostic, a test
runner's failed case, a panic or uncaught exception, or nothing matched before a non-zero exitOne of
compiler,test,panic,exit tasks[].first_failure.line- the matched line, trimmed
tasks[].first_failure.locationpath:line[:col]when the line or its excerpt names onetasks[].first_failure.shardk/Nwhen the task is a shardtasks[].first_failure.task- the namespaced task name
tasks[].first_failure.tool- the detector rule that matched:
rustc,nextest,tsc,pytest,shellfor an exit,... tasks[].fit_attasks[].flaky_inputs- the targets (or the task's name for its whole key) whose identical inputs both passed and failed on record: reported, never quarantined
tasks[].has_junittasks[].labels- what the queue matches a worker on:
osandarchonly when the submit or the manifest set them,toolchains,workspace_warm, and the manifest's own labels tasks[].leased_attasks[].log_bytestasks[].matrix- : the matrix cell's values, axis to value, so a client groups a task's cells; empty for a task without a matrix
tasks[].nametasks[].no_eligible_worker- why a
queuedtask matches no online worker, counted per mismatch (os, arch, trust); absent once a worker could take it tasks[].prepared_attasks[].queued_at- the phase marks of the current attempt (Neon item 4,
Task::timeline): queued at submission;fit_atwhen an eligible member first existed for it;leased_at;prepared_atwhen the worker had the workspace ready;cold_starthow warm the member was at the lease tasks[].ready_at- when the task became leasable: its submission for a root task, the moment its last dependency succeeded for a dependant
tasks[].refusals- the members that handed the task back for a reason of their own, oldest first
tasks[].refusals[].attasks[].refusals[].reason- the worker's
infra_error.code tasks[].refusals[].worker- the member's registered name (
worker-6) tasks[].refusals[].worker_id- uuidv7 rendered as
wrk_<32 hex> tasks[].requeued_at- when a lease of it was last given back and it queued again: its next lease's wait starts here
tasks[].shardk/Ntasks[].slots- the worker slots the task's lease weighs,
ceil(resources.memory / memory_per_slot)on the worker that took it; absent until leased tasks[].started_attasks[].state- One of
queued,leased,running,succeeded,failed,cancelled,timed_out,infra_error,skipped tasks[].termination- why the task stopped short of its own exit, or why it went back to the queue:
oom,timeout,cancelled,worker_shutdown,lease_lost, or a host infra code; absent while nothing ended it. on aqueued,leasedorrunningtask it names the previous attempt's end tasks[].warnings- the warnings the worker collected from the task's log, bounded; present once the task reported
tasks[].warnings.by_kindtasks[].warnings.by_kind[].counttasks[].warnings.by_kind[].kindtasks[].warnings.first- at most 20, in the order they were seen
tasks[].warnings.first[].filetasks[].warnings.first[].kindtasks[].warnings.first[].linetasks[].warnings.first[].linttasks[].warnings.first[].message- the first line of the warning, trimmed, at most 512 bytes
tasks[].warnings.total- every occurrence the collector saw, repeats included
tasks[].warnings.unique- distinct
(kind, file, lint)the collector kept, at most 200 per task tasks[].worker_id- uuidv7 rendered as
wrk_<32 hex> tree- the verified working tree the job runs on; absent for a delta submission
tree.bytestree.entriestree.root- the root digest of a working tree: sha-256 of the root directory manifest
tree_schema- the
TREE_SCHEMA_VERSIONtree.rootwas hashed under; absent when the client did not say trust- tiers, with no order on purpose (amendment 2026-10-27):
trusted_ciis protected-branch automation and the cache writer every tier reads,trusted_interactivea person's own work, and neither is "below" the other, so every rule over tiers names the tiers it meansOne ofuntrusted,trusted_ci,trusted_interactive urlverify_ms- milliseconds the cell spent verifying
treebefore the job transaction; absent for a delta submission or a cell older than the field budgetBudget: returned in every job response and tool resultbudget.concurrentbudget.concurrent.limitbudget.concurrent.usedbudget.daySpendbudget.day.jobsbudget.day.jobs_limitbudget.day.limit_unitsbudget.day.remaining_unitsbudget.day.spent_unitsbudget.month- the tenant's monthly budget, when one is set on platform or in the policy
budget.month.currencybudget.month.hard_limitbudget.month.limit_amountbudget.month.limit_unitsbudget.month.percent_used- whole percent of the limit spent; past 100 when exceeded
budget.month.period_end- the first instant of the next month (UTC), when the spend resets
budget.month.remaining_unitsbudget.month.source- who set the monthly budgetOne of
platform,tenant budget.month.spent_amountbudget.month.spent_unitsbudget.month.state- where the month stands against its budgetOne of
ok,warning,exceeded budget.month.unit_price_micros- micro units of
currencyper cost unit (1 EUR = 1,000,000), so a client prices any count of units exactly; absent without a platform price budget.month.warn_at_percentbudget.rate_table- version of the cost-unit table
budget.resets_atbudget.sessionSpendbudget.session.jobsbudget.session.jobs_limitbudget.session.limit_unitsbudget.session.remaining_unitsbudget.session.spent_unitsdeduplicated_from- the first submitter's actor, never its credential
policyPolicy: the client-facing subset ofpolicy.allow_full_buildpolicy.default_kindcheck,test,build,lintor a manifest task idpolicy.limits- the tree caps of the tenant policy, served to every principal so the cli
pre-checks a tree against the numbers the cell enforces instead of constants of its own; absent
from an older cell, in which case the cli checks nothing locally and the cell answers
413 policy.limits.max_blob_bytespolicy.limits.max_tree_bytespolicy.limits.max_tree_entriespolicy.max_concurrent_per_actorpolicy.trust- tiers, with no order on purpose (amendment 2026-10-27):
trusted_ciis protected-branch automation and the cache writer every tier reads,trusted_interactivea person's own work, and neither is "below" the other, so every rule over tiers names the tiers it meansOne ofuntrusted,trusted_ci,trusted_interactive policy.untrusted_refssubmitted- on a deduplicated answer, what this request sent, for the client to compare with
job submitted.base_digestsubmitted.base_refsubmitted.tree_root- the root digest of a working tree: sha-256 of the root directory manifest
submitted.tree_schema
curl -X POST "$CIRESK_API/v1/ci/jobs" \
-H "Authorization: Bearer $CIRESK_KEY" \
-H "Idempotency-Key: ad8f34bd-99b3-458c-8dbf-4d3cca9a8c60" \
-H "Content-Type: application/json" \
-d '{
"actor": "agent:claude-code",
"base_digest": "feef45d804737fdf7a297e27e443d914551629de",
"base_ref": "main",
"budget_units": 2000,
"client": "cli",
"diff_digest": "sha256:2ee8d2702d84b778100050828d96e8def095c9a4871507f5757e124784173df3",
"fail_fast": true,
"full": false,
"kind": "check",
"labels": {
"os": "linux"
},
"manifest_digest": "sha256:06d663911cadf74b2c54b4c4c73383abd01cb35c741369624bec204a17b4ea6c",
"manifest_path": ".ciresk/ci.yaml",
"no_cache": true,
"no_dedup": false,
"note": "acme/platform",
"repo_id": "repo_0129354d7b6b4146ad16c315d960365b",
"session": "s_4f2a9c",
"targets": [
"platform-api"
],
"tree": {
"bytes": 18432000,
"entries": 1,
"inline": [
{
"data_b64": "acme/platform",
"digest": "sha256:c21fa32a40d82233c44e76e6ae776b4d403ac1a564ca26de95a14c6bb47eaf49"
}
],
"manifests": [
{
"data_b64": "acme/platform",
"digest": "sha256:c21fa32a40d82233c44e76e6ae776b4d403ac1a564ca26de95a14c6bb47eaf49"
}
],
"parent_root": "sha256:7ab33a3a29d38ba8d833e1f2a7dda171ca0435fe79a5305d01a6466da27625d7",
"root": "sha256:4827d3132b09e1cedc07788771ef7bca9c1140b2dff2ac370fc8433a94de43e5",
"tree_schema": 1
},
"tree_id": "acme/platform",
"tree_root": "sha256:f6d6c911b491012f14dea3f3004b6101280793ee31519604aecd29f823cca9db",
"trust": "trusted_interactive"
}'List lease timing
Submit-to-lease p50/p95 per cold start label over the last 24 h, labs and audits left out.
Response
requeued- what requeues took back: the runs they lost, kept apart from the wait; absent from an older cell
requeued.leasesrequeued.lost_msrequeued.p50_msrequeued.p95_msrowsrows[].cold_start- how warm the member was when it took the lease:
warmwas online before the job was submitted,startedcame online after it (the factory started it for the queue),first_after_bootwas online before but this is its first lease since its bootOne ofwarm,started,first_after_boot rows[].leasesrows[].p50_msrows[].p95_mssince
curl "$CIRESK_API/v1/ci/jobs/timing" \
-H "Authorization: Bearer $CIRESK_KEY"Get a job
A job with its tasks and budget.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Required | The job's ID. |
Response
actoraffected- what expansion selected for the job and why, when the submission carried a tree
affected.changed_files- distinct changed paths between the reference root and the submitted one
affected.escalatedaffected.graph_root- the root whose recorded graph answered; absent when none was read
affected.reason- the condition column of's table, as
crates/ci/affectedwords it affected.reference_root- the root the diff was taken against; absent for a first submission
affected.selected- targets the tasks received through
targets_arg; 0 when escalated (the full set runs) affected.strategy- One of
cargo,pnpm,go,turbo,nx,files,none affected.total- nodes of the recorded graph, when one was read
base_digest- commit sha
base_ref- ref name as submitted
clientcost_unitscreated_atdeduplicateddiff_digest- sha-256 digest as
sha256:<64 hex> duration_msexit_codefail_fast- the cell cancels the job's queued tasks at the first task that ends other than
succeeded; a deduplicated job carries the first submitter's choice finished_atfullid- uuidv7 rendered as
job_<32 hex> kindcheck,test,build,lintor a manifest task idno_cache--no-cache: no task is served from the task cache; successes still recordprincipalpriorityreporepo_id- uuidv7 rendered as
repo_<32 hex> request_id- the
X-Request-Idthis answer was produced under, so a--jsonenvelope can name it sessionstarted_atstate- One of
queued,leased,running,succeeded,failed,cancelled,timed_out,infra_error superseded_by- the newer job of the same submitter, branch, kind and targets that cancelled this one under the
policy's
cancel_in_progress; absent otherwise targetstasks- absent on list rows and inside
Summary.job tasks[].approval- : the task's approval gate; a gated task stays
queueduntil it is approved tasks[].approval.approversuser:<id>androle:<name>; empty means any person holdingci:approvals.approvetasks[].approval.commenttasks[].approval.decided_attasks[].approval.decided_bytasks[].approval.expires_attasks[].approval.reached- the task's dependencies have succeeded: an approval starts it at once
tasks[].approval.sod_exception- the requester decided their own gate under the policy's
approval_self: record tasks[].approval.state- One of
pending,approved,rejected,expired tasks[].artifact_counttasks[].blocked_by- on a
skippedtask, the dependency whose end skipped it (build,build[1/2]) tasks[].cache- how a task met the task cache: served without a run, looked up and run, recorded after the run,
or never keyed (
cache: false,cache: { results: false }or--no-cache)One ofhit,miss,write,none tasks[].cache_hit- the task did not run: its key matched a recorded success;
cached_fromnames it tasks[].cache_note- why the task was neither answered from the cache nor recorded in it, when the cell knows a reason
beyond "these inputs never passed": the manifest keeps it out, or the run changed a tracked path.
ciresk ci explain-misscompares a miss with the last recorded run of the task tasks[].cached_failure- the task did not run: its key failed cleanly in the named run and never passed, so it ended with that run's exit code, tests and first failure;
--no-cacheruns it tasks[].cached_failure.job_id- uuidv7 rendered as
job_<32 hex> tasks[].cached_failure.task_id- uuidv7 rendered as
tsk_<32 hex> tasks[].cached_from- the run a cache hit stands on: the job and task whose success was recorded under the key, so a hit names where its verdict, log, junit and artifacts come from
tasks[].cached_from.job_id- uuidv7 rendered as
job_<32 hex> tasks[].cached_from.task_id- uuidv7 rendered as
tsk_<32 hex> tasks[].cached_targets- a task split into per-target units: how many targets reused a recorded verdict
tasks[].cached_targets.hittasks[].cached_targets.oftasks[].cold_start- how warm the member was when it took the lease:
warmwas online before the job was submitted,startedcame online after it (the factory started it for the queue),first_after_bootwas online before but this is its first lease since its bootOne ofwarm,started,first_after_boot tasks[].cost_unitstasks[].duration_mstasks[].exit_codetasks[].expected_ms- how long the planner expects the task to run, from the repository's history or the kind default; shorter tasks lease first within a job
tasks[].finished_attasks[].first_failure- the first failing line the worker saw, present from the moment it was seen
tasks[].first_failure.at- the worker's clock when the line was seen
tasks[].first_failure.excerpttasks[].first_failure.kind- what the first failing line of a task's log was: a compiler diagnostic, a test
runner's failed case, a panic or uncaught exception, or nothing matched before a non-zero exitOne of
compiler,test,panic,exit tasks[].first_failure.line- the matched line, trimmed
tasks[].first_failure.locationpath:line[:col]when the line or its excerpt names onetasks[].first_failure.shardk/Nwhen the task is a shardtasks[].first_failure.task- the namespaced task name
tasks[].first_failure.tool- the detector rule that matched:
rustc,nextest,tsc,pytest,shellfor an exit,... tasks[].fit_attasks[].flaky_inputs- the targets (or the task's name for its whole key) whose identical inputs both passed and failed on record: reported, never quarantined
tasks[].has_junittasks[].labels- what the queue matches a worker on:
osandarchonly when the submit or the manifest set them,toolchains,workspace_warm, and the manifest's own labels tasks[].leased_attasks[].log_bytestasks[].matrix- : the matrix cell's values, axis to value, so a client groups a task's cells; empty for a task without a matrix
tasks[].nametasks[].no_eligible_worker- why a
queuedtask matches no online worker, counted per mismatch (os, arch, trust); absent once a worker could take it tasks[].prepared_attasks[].queued_at- the phase marks of the current attempt (Neon item 4,
Task::timeline): queued at submission;fit_atwhen an eligible member first existed for it;leased_at;prepared_atwhen the worker had the workspace ready;cold_starthow warm the member was at the lease tasks[].ready_at- when the task became leasable: its submission for a root task, the moment its last dependency succeeded for a dependant
tasks[].refusals- the members that handed the task back for a reason of their own, oldest first
tasks[].refusals[].attasks[].refusals[].reason- the worker's
infra_error.code tasks[].refusals[].worker- the member's registered name (
worker-6) tasks[].refusals[].worker_id- uuidv7 rendered as
wrk_<32 hex> tasks[].requeued_at- when a lease of it was last given back and it queued again: its next lease's wait starts here
tasks[].shardk/Ntasks[].slots- the worker slots the task's lease weighs,
ceil(resources.memory / memory_per_slot)on the worker that took it; absent until leased tasks[].started_attasks[].state- One of
queued,leased,running,succeeded,failed,cancelled,timed_out,infra_error,skipped tasks[].termination- why the task stopped short of its own exit, or why it went back to the queue:
oom,timeout,cancelled,worker_shutdown,lease_lost, or a host infra code; absent while nothing ended it. on aqueued,leasedorrunningtask it names the previous attempt's end tasks[].warnings- the warnings the worker collected from the task's log, bounded; present once the task reported
tasks[].warnings.by_kindtasks[].warnings.by_kind[].counttasks[].warnings.by_kind[].kindtasks[].warnings.first- at most 20, in the order they were seen
tasks[].warnings.first[].filetasks[].warnings.first[].kindtasks[].warnings.first[].linetasks[].warnings.first[].linttasks[].warnings.first[].message- the first line of the warning, trimmed, at most 512 bytes
tasks[].warnings.total- every occurrence the collector saw, repeats included
tasks[].warnings.unique- distinct
(kind, file, lint)the collector kept, at most 200 per task tasks[].worker_id- uuidv7 rendered as
wrk_<32 hex> tree- the verified working tree the job runs on; absent for a delta submission
tree.bytestree.entriestree.root- the root digest of a working tree: sha-256 of the root directory manifest
tree_schema- the
TREE_SCHEMA_VERSIONtree.rootwas hashed under; absent when the client did not say trust- tiers, with no order on purpose (amendment 2026-10-27):
trusted_ciis protected-branch automation and the cache writer every tier reads,trusted_interactivea person's own work, and neither is "below" the other, so every rule over tiers names the tiers it meansOne ofuntrusted,trusted_ci,trusted_interactive urlverify_ms- milliseconds the cell spent verifying
treebefore the job transaction; absent for a delta submission or a cell older than the field budgetBudget: returned in every job response and tool resultbudget.concurrentbudget.concurrent.limitbudget.concurrent.usedbudget.daySpendbudget.day.jobsbudget.day.jobs_limitbudget.day.limit_unitsbudget.day.remaining_unitsbudget.day.spent_unitsbudget.month- the tenant's monthly budget, when one is set on platform or in the policy
budget.month.currencybudget.month.hard_limitbudget.month.limit_amountbudget.month.limit_unitsbudget.month.percent_used- whole percent of the limit spent; past 100 when exceeded
budget.month.period_end- the first instant of the next month (UTC), when the spend resets
budget.month.remaining_unitsbudget.month.source- who set the monthly budgetOne of
platform,tenant budget.month.spent_amountbudget.month.spent_unitsbudget.month.state- where the month stands against its budgetOne of
ok,warning,exceeded budget.month.unit_price_micros- micro units of
currencyper cost unit (1 EUR = 1,000,000), so a client prices any count of units exactly; absent without a platform price budget.month.warn_at_percentbudget.rate_table- version of the cost-unit table
budget.resets_atbudget.sessionSpendbudget.session.jobsbudget.session.jobs_limitbudget.session.limit_unitsbudget.session.remaining_unitsbudget.session.spent_unitsdeduplicated_from- the first submitter's actor, never its credential
policyPolicy: the client-facing subset ofpolicy.allow_full_buildpolicy.default_kindcheck,test,build,lintor a manifest task idpolicy.limits- the tree caps of the tenant policy, served to every principal so the cli
pre-checks a tree against the numbers the cell enforces instead of constants of its own; absent
from an older cell, in which case the cli checks nothing locally and the cell answers
413 policy.limits.max_blob_bytespolicy.limits.max_tree_bytespolicy.limits.max_tree_entriespolicy.max_concurrent_per_actorpolicy.trust- tiers, with no order on purpose (amendment 2026-10-27):
trusted_ciis protected-branch automation and the cache writer every tier reads,trusted_interactivea person's own work, and neither is "below" the other, so every rule over tiers names the tiers it meansOne ofuntrusted,trusted_ci,trusted_interactive policy.untrusted_refssubmitted- on a deduplicated answer, what this request sent, for the client to compare with
job submitted.base_digestsubmitted.base_refsubmitted.tree_root- the root digest of a working tree: sha-256 of the root directory manifest
submitted.tree_schema
curl "$CIRESK_API/v1/ci/jobs/job_0109badfc220cd056b2c0e862ac73d40" \
-H "Authorization: Bearer $CIRESK_KEY"Cancel a job
Request cancellation.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Required | The job's ID. |
Request body
reasonremaining_only- fail-fast: only the queued tasks end
cancelled; running tasks finish and report, and the job's state comes from them, so a failure staysfailed
Response
budgetBudget: returned in every job response and tool resultbudget.concurrentbudget.concurrent.limitbudget.concurrent.usedbudget.daySpendbudget.day.jobsbudget.day.jobs_limitbudget.day.limit_unitsbudget.day.remaining_unitsbudget.day.spent_unitsbudget.month- the tenant's monthly budget, when one is set on platform or in the policy
budget.month.currencybudget.month.hard_limitbudget.month.limit_amountbudget.month.limit_unitsbudget.month.percent_used- whole percent of the limit spent; past 100 when exceeded
budget.month.period_end- the first instant of the next month (UTC), when the spend resets
budget.month.remaining_unitsbudget.month.source- who set the monthly budgetOne of
platform,tenant budget.month.spent_amountbudget.month.spent_unitsbudget.month.state- where the month stands against its budgetOne of
ok,warning,exceeded budget.month.unit_price_micros- micro units of
currencyper cost unit (1 EUR = 1,000,000), so a client prices any count of units exactly; absent without a platform price budget.month.warn_at_percentbudget.rate_table- version of the cost-unit table
budget.resets_atbudget.sessionSpendbudget.session.jobsbudget.session.jobs_limitbudget.session.limit_unitsbudget.session.remaining_unitsbudget.session.spent_unitscancelledid- uuidv7 rendered as
job_<32 hex> state- One of
queued,leased,running,succeeded,failed,cancelled,timed_out,infra_error
curl -X POST "$CIRESK_API/v1/ci/jobs/job_0109badfc220cd056b2c0e862ac73d40/cancel" \
-H "Authorization: Bearer $CIRESK_KEY" \
-H "Content-Type: application/json" \
-d '{
"reason": null,
"remaining_only": true
}'Stream a job's events
The job's journal as server-sent events.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Required | The job's ID. |
since | string | Optional |
Response
atbase_refbudgetBudget: returned in every job response and tool resultbudget.concurrentbudget.concurrent.limitbudget.concurrent.usedbudget.daySpendbudget.day.jobsbudget.day.jobs_limitbudget.day.limit_unitsbudget.day.remaining_unitsbudget.day.spent_unitsbudget.month- the tenant's monthly budget, when one is set on platform or in the policy
budget.month.currencybudget.month.hard_limitbudget.month.limit_amountbudget.month.limit_unitsbudget.month.percent_used- whole percent of the limit spent; past 100 when exceeded
budget.month.period_end- the first instant of the next month (UTC), when the spend resets
budget.month.remaining_unitsbudget.month.source- who set the monthly budgetOne of
platform,tenant budget.month.spent_amountbudget.month.spent_unitsbudget.month.state- where the month stands against its budgetOne of
ok,warning,exceeded budget.month.unit_price_micros- micro units of
currencyper cost unit (1 EUR = 1,000,000), so a client prices any count of units exactly; absent without a platform price budget.month.warn_at_percentbudget.rate_table- version of the cost-unit table
budget.resets_atbudget.sessionSpendbudget.session.jobsbudget.session.jobs_limitbudget.session.limit_unitsbudget.session.remaining_unitsbudget.session.spent_unitscost_unitsduration_msevent- the journal kinds of and; the sse
event:nameOne ofjob.created,job.deduplicated,job.leased,job.started,job.finished,job.cancelled,job.fail_fast,task.queued,task.leased,task.started,task.finished,task.requeued,task.cancelled,task.first_failure,task.warnings,task.approval_requested,task.approval_decided,task.approval_expired,lease.renewed,lease.expired,budget.reserved,budget.charged exit_codefailing_tests- up to 20, terminal events only
failing_tests[].filefailing_tests[].linefailing_tests[].messagefailing_tests[].namefirst_failuretask.first_failureevents onlyfirst_failure.at- the worker's clock when the line was seen
first_failure.excerptfirst_failure.kind- what the first failing line of a task's log was: a compiler diagnostic, a test
runner's failed case, a panic or uncaught exception, or nothing matched before a non-zero exitOne of
compiler,test,panic,exit first_failure.line- the matched line, trimmed
first_failure.locationpath:line[:col]when the line or its excerpt names onefirst_failure.shardk/Nwhen the task is a shardfirst_failure.task- the namespaced task name
first_failure.tool- the detector rule that matched:
rustc,nextest,tsc,pytest,shellfor an exit,... job_id- uuidv7 rendered as
job_<32 hex> kindcheck,test,build,lintor a manifest task idrepo_id- uuidv7 rendered as
repo_<32 hex> schema_versionseq- per-job sequence from the journal; the sse
id: state- One of
queued,leased,running,succeeded,failed,cancelled,timed_out,infra_error tail- last 50 lines of the first failing task, terminal events only
tasktask.exit_codetask.id- uuidv7 rendered as
tsk_<32 hex> task.nametask.shardtask.state- One of
queued,leased,running,succeeded,failed,cancelled,timed_out,infra_error,skipped urls- api urls in v1 (the console url is p5)
urls.artifactsurls.logurls.summaryurls.testswarningstask.warningsevents onlywarnings.by_kindwarnings.by_kind[].countwarnings.by_kind[].kindwarnings.first- at most 20, in the order they were seen
warnings.first[].filewarnings.first[].kindwarnings.first[].linewarnings.first[].lintwarnings.first[].message- the first line of the warning, trimmed, at most 512 bytes
warnings.total- every occurrence the collector saw, repeats included
warnings.unique- distinct
(kind, file, lint)the collector kept, at most 200 per task
curl "$CIRESK_API/v1/ci/jobs/job_0109badfc220cd056b2c0e862ac73d40/events" \
-H "Authorization: Bearer $CIRESK_KEY"Get cache misses
Why each task the task cache did not answer missed, against the last recorded run of it.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Required | The job's ID. |
task | string | Optional |
Response
job_id- uuidv7 rendered as
job_<32 hex> taskstasks[].cache- how a task met the task cache: served without a run, looked up and run, recorded after the run,
or never keyed (
cache: false,cache: { results: false }or--no-cache)One ofhit,miss,write,none tasks[].changed- the key items that differ from that run:
run,cwd,env,inputs,global_inputs,toolchains,files,manifest tasks[].changed_files- the input files that differ from that run, repository-relative and sorted, at most
[
TaskMiss::MAX_FILES] tasks[].changed_files_total- every input file that differs, past the cap included
tasks[].compared_with- the run it was compared with
tasks[].compared_with.job_id- uuidv7 rendered as
job_<32 hex> tasks[].compared_with.task_id- uuidv7 rendered as
tsk_<32 hex> tasks[].key- sha-256 digest as
sha256:<64 hex> tasks[].reason- the cause in one word:
no_cache,disabled,not_recorded,failed,not_keyed,first_run,changedorsame_key tasks[].taskname, orname[k/N]for a shardtasks[].why- the cause in sentences, the first one the cause itself
curl "$CIRESK_API/v1/ci/jobs/job_0109badfc220cd056b2c0e862ac73d40/explain-miss" \
-H "Authorization: Bearer $CIRESK_KEY"Get a job's summary
The bounded verdict.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Required | The job's ID. |
format | string | Optional | |
tail | string | Optional |
Response
approvals- the job's gates waiting for a person's decision
approvals[].actor- who asks, as a person reads it:
Claude Code · user:user_01J8... approvals[].approve- the command a person runs to approve it
approvals[].approversapprovals[].expires_atapprovals[].job- uuidv7 rendered as
job_<32 hex> approvals[].note- the submitter's one line for the person: untrusted text, shown and never interpreted
approvals[].reachedapprovals[].repoapprovals[].requested_atapprovals[].requester- the job's requester (
user:...,key:...,agent:...) approvals[].task- the task row's name:
deploy, or a matrix celldeploy[region=eu] cachecache.hitscache.missescache.public- the job's tasks' registry downloads answered by the workers' public cache; absent when no task reported any
cache.public.bytescache.public.hitscache.public.missescache.writescritical- the job's critical path from its task rows; absent until a worker ran a task, and from an older cell
critical.edge_mscritical.post_run_mscritical.prepare_mscritical.queue_mscritical.run_mscritical.tasks- the tasks on it, first to last,
nameorname[k/N]; a task the api completed is walked through critical.total_mscritical_path- the job's critical path as one line,
fmt → clippy-rust (4m 12s: edges 3.1s, queue 6.0s, prepare 9.2s, run 3m 50s, post-run 3.4s);criticalholds the numbers fail_fast- present once the cell's fail-fast cut the job: the task that triggered it and how many queued tasks never ran
fail_fast.cancelledfail_fast.taskfailing_tests- at most 20
failing_tests[].duration_msfailing_tests[].filefailing_tests[].linefailing_tests[].message- first 5 lines
failing_tests[].namefailing_tests[].shardfailing_tests[].stack- the first 20 frames of the failure, one per entry
failing_tests[].started_at- when the test started, where the runner's report says (nextest's testcase
timestamp); withduration_msthe run's timeline. absent from other runners and on rows ingested before it failing_tests[].status- One of
passed,failed,skipped,flaky failing_tests[].stderr_tail- only in
detailed failing_tests[].stdout_tail- only in
detailed failing_tests[].suite- the class, package or file the runner grouped the test under; absent on rows ingested before P5
failing_tests[].taskfailing_tests[].truncated- a message, stack or tail was cut at the ingestion bounds
failing_tests_totalfirst_failed_taskfirst_failure- the first failed task's first failing line and its excerpt
first_failure.at- the worker's clock when the line was seen
first_failure.excerptfirst_failure.kind- what the first failing line of a task's log was: a compiler diagnostic, a test
runner's failed case, a panic or uncaught exception, or nothing matched before a non-zero exitOne of
compiler,test,panic,exit first_failure.line- the matched line, trimmed
first_failure.locationpath:line[:col]when the line or its excerpt names onefirst_failure.shardk/Nwhen the task is a shardfirst_failure.task- the namespaced task name
first_failure.tool- the detector rule that matched:
rustc,nextest,tsc,pytest,shellfor an exit,... first_no_ms- milliseconds from submission to the first "no": the first
task.first_failureor the first task that ended other thansucceeded, else the verdict when it is not a success; absent while nothing failed job- without
tasks job.actorjob.affected- what expansion selected for the job and why, when the submission carried a tree
job.affected.changed_files- distinct changed paths between the reference root and the submitted one
job.affected.escalatedjob.affected.graph_root- the root whose recorded graph answered; absent when none was read
job.affected.reason- the condition column of's table, as
crates/ci/affectedwords it job.affected.reference_root- the root the diff was taken against; absent for a first submission
job.affected.selected- targets the tasks received through
targets_arg; 0 when escalated (the full set runs) job.affected.strategy- One of
cargo,pnpm,go,turbo,nx,files,none job.affected.total- nodes of the recorded graph, when one was read
job.base_digest- commit sha
job.base_ref- ref name as submitted
job.clientjob.cost_unitsjob.created_atjob.deduplicatedjob.diff_digest- sha-256 digest as
sha256:<64 hex> job.duration_msjob.exit_codejob.fail_fast- the cell cancels the job's queued tasks at the first task that ends other than
succeeded; a deduplicated job carries the first submitter's choice job.finished_atjob.fulljob.id- uuidv7 rendered as
job_<32 hex> job.kindcheck,test,build,lintor a manifest task idjob.no_cache--no-cache: no task is served from the task cache; successes still recordjob.principaljob.priorityjob.repojob.repo_id- uuidv7 rendered as
repo_<32 hex> job.request_id- the
X-Request-Idthis answer was produced under, so a--jsonenvelope can name it job.sessionjob.started_atjob.state- One of
queued,leased,running,succeeded,failed,cancelled,timed_out,infra_error job.superseded_by- the newer job of the same submitter, branch, kind and targets that cancelled this one under the
policy's
cancel_in_progress; absent otherwise job.targetsjob.tasks- absent on list rows and inside
Summary.job job.tasks[].approval- : the task's approval gate; a gated task stays
queueduntil it is approved job.tasks[].approval.approversuser:<id>androle:<name>; empty means any person holdingci:approvals.approvejob.tasks[].approval.commentjob.tasks[].approval.decided_atjob.tasks[].approval.decided_byjob.tasks[].approval.expires_atjob.tasks[].approval.reached- the task's dependencies have succeeded: an approval starts it at once
job.tasks[].approval.sod_exception- the requester decided their own gate under the policy's
approval_self: record job.tasks[].approval.state- One of
pending,approved,rejected,expired job.tasks[].artifact_countjob.tasks[].blocked_by- on a
skippedtask, the dependency whose end skipped it (build,build[1/2]) job.tasks[].cache- how a task met the task cache: served without a run, looked up and run, recorded after the run,
or never keyed (
cache: false,cache: { results: false }or--no-cache)One ofhit,miss,write,none job.tasks[].cache_hit- the task did not run: its key matched a recorded success;
cached_fromnames it job.tasks[].cache_note- why the task was neither answered from the cache nor recorded in it, when the cell knows a reason
beyond "these inputs never passed": the manifest keeps it out, or the run changed a tracked path.
ciresk ci explain-misscompares a miss with the last recorded run of the task job.tasks[].cached_failure- the task did not run: its key failed cleanly in the named run and never passed, so it ended with that run's exit code, tests and first failure;
--no-cacheruns it job.tasks[].cached_failure.job_id- uuidv7 rendered as
job_<32 hex> job.tasks[].cached_failure.task_id- uuidv7 rendered as
tsk_<32 hex> job.tasks[].cached_from- the run a cache hit stands on: the job and task whose success was recorded under the key, so a hit names where its verdict, log, junit and artifacts come from
job.tasks[].cached_from.job_id- uuidv7 rendered as
job_<32 hex> job.tasks[].cached_from.task_id- uuidv7 rendered as
tsk_<32 hex> job.tasks[].cached_targets- a task split into per-target units: how many targets reused a recorded verdict
job.tasks[].cached_targets.hitjob.tasks[].cached_targets.ofjob.tasks[].cold_start- how warm the member was when it took the lease:
warmwas online before the job was submitted,startedcame online after it (the factory started it for the queue),first_after_bootwas online before but this is its first lease since its bootOne ofwarm,started,first_after_boot job.tasks[].cost_unitsjob.tasks[].duration_msjob.tasks[].exit_codejob.tasks[].expected_ms- how long the planner expects the task to run, from the repository's history or the kind default; shorter tasks lease first within a job
job.tasks[].finished_atjob.tasks[].first_failure- the first failing line the worker saw, present from the moment it was seen
job.tasks[].first_failure.at- the worker's clock when the line was seen
job.tasks[].first_failure.excerptjob.tasks[].first_failure.kind- what the first failing line of a task's log was: a compiler diagnostic, a test
runner's failed case, a panic or uncaught exception, or nothing matched before a non-zero exitOne of
compiler,test,panic,exit job.tasks[].first_failure.line- the matched line, trimmed
job.tasks[].first_failure.locationpath:line[:col]when the line or its excerpt names onejob.tasks[].first_failure.shardk/Nwhen the task is a shardjob.tasks[].first_failure.task- the namespaced task name
job.tasks[].first_failure.tool- the detector rule that matched:
rustc,nextest,tsc,pytest,shellfor an exit,... job.tasks[].fit_atjob.tasks[].flaky_inputs- the targets (or the task's name for its whole key) whose identical inputs both passed and failed on record: reported, never quarantined
job.tasks[].has_junitjob.tasks[].labels- what the queue matches a worker on:
osandarchonly when the submit or the manifest set them,toolchains,workspace_warm, and the manifest's own labels job.tasks[].leased_atjob.tasks[].log_bytesjob.tasks[].matrix- : the matrix cell's values, axis to value, so a client groups a task's cells; empty for a task without a matrix
job.tasks[].namejob.tasks[].no_eligible_worker- why a
queuedtask matches no online worker, counted per mismatch (os, arch, trust); absent once a worker could take it job.tasks[].prepared_atjob.tasks[].queued_at- the phase marks of the current attempt (Neon item 4,
Task::timeline): queued at submission;fit_atwhen an eligible member first existed for it;leased_at;prepared_atwhen the worker had the workspace ready;cold_starthow warm the member was at the lease job.tasks[].ready_at- when the task became leasable: its submission for a root task, the moment its last dependency succeeded for a dependant
job.tasks[].refusals- the members that handed the task back for a reason of their own, oldest first
job.tasks[].refusals[].atjob.tasks[].refusals[].reason- the worker's
infra_error.code job.tasks[].refusals[].worker- the member's registered name (
worker-6) job.tasks[].refusals[].worker_id- uuidv7 rendered as
wrk_<32 hex> job.tasks[].requeued_at- when a lease of it was last given back and it queued again: its next lease's wait starts here
job.tasks[].shardk/Njob.tasks[].slots- the worker slots the task's lease weighs,
ceil(resources.memory / memory_per_slot)on the worker that took it; absent until leased job.tasks[].started_atjob.tasks[].state- One of
queued,leased,running,succeeded,failed,cancelled,timed_out,infra_error,skipped job.tasks[].termination- why the task stopped short of its own exit, or why it went back to the queue:
oom,timeout,cancelled,worker_shutdown,lease_lost, or a host infra code; absent while nothing ended it. on aqueued,leasedorrunningtask it names the previous attempt's end job.tasks[].warnings- the warnings the worker collected from the task's log, bounded; present once the task reported
job.tasks[].warnings.by_kindjob.tasks[].warnings.first- at most 20, in the order they were seen
job.tasks[].warnings.total- every occurrence the collector saw, repeats included
job.tasks[].warnings.unique- distinct
(kind, file, lint)the collector kept, at most 200 per task job.tasks[].worker_id- uuidv7 rendered as
wrk_<32 hex> job.tree- the verified working tree the job runs on; absent for a delta submission
job.tree.bytesjob.tree.entriesjob.tree.root- the root digest of a working tree: sha-256 of the root directory manifest
job.tree_schema- the
TREE_SCHEMA_VERSIONtree.rootwas hashed under; absent when the client did not say job.trust- tiers, with no order on purpose (amendment 2026-10-27):
trusted_ciis protected-branch automation and the cache writer every tier reads,trusted_interactivea person's own work, and neither is "below" the other, so every rule over tiers names the tiers it meansOne ofuntrusted,trusted_ci,trusted_interactive job.urljob.verify_ms- milliseconds the cell spent verifying
treebefore the job transaction; absent for a delta submission or a cell older than the field next- the exact drill-down command or tool call
request_id- the
X-Request-Idthis answer was produced under tail- last
taillines of the first failed task tail_tasktaskstasks[].approval- : the task's approval gate; a gated task stays
queueduntil it is approved tasks[].approval.approversuser:<id>androle:<name>; empty means any person holdingci:approvals.approvetasks[].approval.commenttasks[].approval.decided_attasks[].approval.decided_bytasks[].approval.expires_attasks[].approval.reached- the task's dependencies have succeeded: an approval starts it at once
tasks[].approval.sod_exception- the requester decided their own gate under the policy's
approval_self: record tasks[].approval.state- One of
pending,approved,rejected,expired tasks[].artifact_counttasks[].blocked_by- on a
skippedtask, the dependency whose end skipped it (build,build[1/2]) tasks[].cache- how a task met the task cache: served without a run, looked up and run, recorded after the run,
or never keyed (
cache: false,cache: { results: false }or--no-cache)One ofhit,miss,write,none tasks[].cache_hit- the task did not run: its key matched a recorded success;
cached_fromnames it tasks[].cache_note- why the task was neither answered from the cache nor recorded in it, when the cell knows a reason
beyond "these inputs never passed": the manifest keeps it out, or the run changed a tracked path.
ciresk ci explain-misscompares a miss with the last recorded run of the task tasks[].cached_failure- the task did not run: its key failed cleanly in the named run and never passed, so it ended with that run's exit code, tests and first failure;
--no-cacheruns it tasks[].cached_failure.job_id- uuidv7 rendered as
job_<32 hex> tasks[].cached_failure.task_id- uuidv7 rendered as
tsk_<32 hex> tasks[].cached_from- the run a cache hit stands on: the job and task whose success was recorded under the key, so a hit names where its verdict, log, junit and artifacts come from
tasks[].cached_from.job_id- uuidv7 rendered as
job_<32 hex> tasks[].cached_from.task_id- uuidv7 rendered as
tsk_<32 hex> tasks[].cached_targets- a task split into per-target units: how many targets reused a recorded verdict
tasks[].cached_targets.hittasks[].cached_targets.oftasks[].cold_start- how warm the member was when it took the lease:
warmwas online before the job was submitted,startedcame online after it (the factory started it for the queue),first_after_bootwas online before but this is its first lease since its bootOne ofwarm,started,first_after_boot tasks[].cost_unitstasks[].duration_mstasks[].exit_codetasks[].expected_ms- how long the planner expects the task to run, from the repository's history or the kind default; shorter tasks lease first within a job
tasks[].finished_attasks[].first_failure- the first failing line the worker saw, present from the moment it was seen
tasks[].first_failure.at- the worker's clock when the line was seen
tasks[].first_failure.excerpttasks[].first_failure.kind- what the first failing line of a task's log was: a compiler diagnostic, a test
runner's failed case, a panic or uncaught exception, or nothing matched before a non-zero exitOne of
compiler,test,panic,exit tasks[].first_failure.line- the matched line, trimmed
tasks[].first_failure.locationpath:line[:col]when the line or its excerpt names onetasks[].first_failure.shardk/Nwhen the task is a shardtasks[].first_failure.task- the namespaced task name
tasks[].first_failure.tool- the detector rule that matched:
rustc,nextest,tsc,pytest,shellfor an exit,... tasks[].fit_attasks[].flaky_inputs- the targets (or the task's name for its whole key) whose identical inputs both passed and failed on record: reported, never quarantined
tasks[].has_junittasks[].labels- what the queue matches a worker on:
osandarchonly when the submit or the manifest set them,toolchains,workspace_warm, and the manifest's own labels tasks[].leased_attasks[].log_bytestasks[].matrix- : the matrix cell's values, axis to value, so a client groups a task's cells; empty for a task without a matrix
tasks[].nametasks[].no_eligible_worker- why a
queuedtask matches no online worker, counted per mismatch (os, arch, trust); absent once a worker could take it tasks[].prepared_attasks[].queued_at- the phase marks of the current attempt (Neon item 4,
Task::timeline): queued at submission;fit_atwhen an eligible member first existed for it;leased_at;prepared_atwhen the worker had the workspace ready;cold_starthow warm the member was at the lease tasks[].ready_at- when the task became leasable: its submission for a root task, the moment its last dependency succeeded for a dependant
tasks[].refusals- the members that handed the task back for a reason of their own, oldest first
tasks[].refusals[].attasks[].refusals[].reason- the worker's
infra_error.code tasks[].refusals[].worker- the member's registered name (
worker-6) tasks[].refusals[].worker_id- uuidv7 rendered as
wrk_<32 hex> tasks[].requeued_at- when a lease of it was last given back and it queued again: its next lease's wait starts here
tasks[].shardk/Ntasks[].slots- the worker slots the task's lease weighs,
ceil(resources.memory / memory_per_slot)on the worker that took it; absent until leased tasks[].started_attasks[].state- One of
queued,leased,running,succeeded,failed,cancelled,timed_out,infra_error,skipped tasks[].termination- why the task stopped short of its own exit, or why it went back to the queue:
oom,timeout,cancelled,worker_shutdown,lease_lost, or a host infra code; absent while nothing ended it. on aqueued,leasedorrunningtask it names the previous attempt's end tasks[].warnings- the warnings the worker collected from the task's log, bounded; present once the task reported
tasks[].warnings.by_kindtasks[].warnings.by_kind[].counttasks[].warnings.by_kind[].kindtasks[].warnings.first- at most 20, in the order they were seen
tasks[].warnings.first[].filetasks[].warnings.first[].kindtasks[].warnings.first[].linetasks[].warnings.first[].linttasks[].warnings.first[].message- the first line of the warning, trimmed, at most 512 bytes
tasks[].warnings.total- every occurrence the collector saw, repeats included
tasks[].warnings.unique- distinct
(kind, file, lint)the collector kept, at most 200 per task tasks[].worker_id- uuidv7 rendered as
wrk_<32 hex> timings- where a job's wall time went, each span absent until both of its ends
exist: submission to the first lease, lease to the first process start, start to the last
task's
ended_at(the worker's clock), and from there tojob.finished timings.prepare_mstimings.queued_mstimings.report_mstimings.run_msverdict- One of
succeeded,failed,cancelled,timed_out,infra_error,running warnings- every task's warnings, counted and the first 20
warnings.by_kindwarnings.by_kind[].countwarnings.by_kind[].kindwarnings.first- at most 20, in the order they were seen
warnings.first[].filewarnings.first[].kindwarnings.first[].linewarnings.first[].lintwarnings.first[].message- the first line of the warning, trimmed, at most 512 bytes
warnings.total- every occurrence the collector saw, repeats included
warnings.unique- distinct
(kind, file, lint)the collector kept, at most 200 per task
curl "$CIRESK_API/v1/ci/jobs/job_0109badfc220cd056b2c0e862ac73d40/summary" \
-H "Authorization: Bearer $CIRESK_KEY"Wait for a job
Block up to 55 s for a terminal state.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Required | The job's ID. |
return_on | string | Optional | |
timeout | string | Optional |
Response
approvals- the job's gates waiting for a person's decision
approvals[].actor- who asks, as a person reads it:
Claude Code · user:user_01J8... approvals[].approve- the command a person runs to approve it
approvals[].approversapprovals[].expires_atapprovals[].job- uuidv7 rendered as
job_<32 hex> approvals[].note- the submitter's one line for the person: untrusted text, shown and never interpreted
approvals[].reachedapprovals[].repoapprovals[].requested_atapprovals[].requester- the job's requester (
user:...,key:...,agent:...) approvals[].task- the task row's name:
deploy, or a matrix celldeploy[region=eu] cachecache.hitscache.missescache.public- the job's tasks' registry downloads answered by the workers' public cache; absent when no task reported any
cache.public.bytescache.public.hitscache.public.missescache.writescritical- the job's critical path from its task rows; absent until a worker ran a task, and from an older cell
critical.edge_mscritical.post_run_mscritical.prepare_mscritical.queue_mscritical.run_mscritical.tasks- the tasks on it, first to last,
nameorname[k/N]; a task the api completed is walked through critical.total_mscritical_path- the job's critical path as one line,
fmt → clippy-rust (4m 12s: edges 3.1s, queue 6.0s, prepare 9.2s, run 3m 50s, post-run 3.4s);criticalholds the numbers fail_fast- present once the cell's fail-fast cut the job: the task that triggered it and how many queued tasks never ran
fail_fast.cancelledfail_fast.taskfailing_tests- at most 20
failing_tests[].duration_msfailing_tests[].filefailing_tests[].linefailing_tests[].message- first 5 lines
failing_tests[].namefailing_tests[].shardfailing_tests[].stack- the first 20 frames of the failure, one per entry
failing_tests[].started_at- when the test started, where the runner's report says (nextest's testcase
timestamp); withduration_msthe run's timeline. absent from other runners and on rows ingested before it failing_tests[].status- One of
passed,failed,skipped,flaky failing_tests[].stderr_tail- only in
detailed failing_tests[].stdout_tail- only in
detailed failing_tests[].suite- the class, package or file the runner grouped the test under; absent on rows ingested before P5
failing_tests[].taskfailing_tests[].truncated- a message, stack or tail was cut at the ingestion bounds
failing_tests_totalfirst_failed_taskfirst_failure- the first failure seen so far, so a poller learns of it before the job ends
first_failure.at- the worker's clock when the line was seen
first_failure.excerptfirst_failure.kind- what the first failing line of a task's log was: a compiler diagnostic, a test
runner's failed case, a panic or uncaught exception, or nothing matched before a non-zero exitOne of
compiler,test,panic,exit first_failure.line- the matched line, trimmed
first_failure.locationpath:line[:col]when the line or its excerpt names onefirst_failure.shardk/Nwhen the task is a shardfirst_failure.task- the namespaced task name
first_failure.tool- the detector rule that matched:
rustc,nextest,tsc,pytest,shellfor an exit,... first_no_ms- milliseconds from submission to the first "no": the first
task.first_failureor the first task that ended other thansucceeded, else the verdict when it is not a success; absent while nothing failed job- without
tasks job.actorjob.affected- what expansion selected for the job and why, when the submission carried a tree
job.affected.changed_files- distinct changed paths between the reference root and the submitted one
job.affected.escalatedjob.affected.graph_root- the root whose recorded graph answered; absent when none was read
job.affected.reason- the condition column of's table, as
crates/ci/affectedwords it job.affected.reference_root- the root the diff was taken against; absent for a first submission
job.affected.selected- targets the tasks received through
targets_arg; 0 when escalated (the full set runs) job.affected.strategy- One of
cargo,pnpm,go,turbo,nx,files,none job.affected.total- nodes of the recorded graph, when one was read
job.base_digest- commit sha
job.base_ref- ref name as submitted
job.clientjob.cost_unitsjob.created_atjob.deduplicatedjob.diff_digest- sha-256 digest as
sha256:<64 hex> job.duration_msjob.exit_codejob.fail_fast- the cell cancels the job's queued tasks at the first task that ends other than
succeeded; a deduplicated job carries the first submitter's choice job.finished_atjob.fulljob.id- uuidv7 rendered as
job_<32 hex> job.kindcheck,test,build,lintor a manifest task idjob.no_cache--no-cache: no task is served from the task cache; successes still recordjob.principaljob.priorityjob.repojob.repo_id- uuidv7 rendered as
repo_<32 hex> job.request_id- the
X-Request-Idthis answer was produced under, so a--jsonenvelope can name it job.sessionjob.started_atjob.state- One of
queued,leased,running,succeeded,failed,cancelled,timed_out,infra_error job.superseded_by- the newer job of the same submitter, branch, kind and targets that cancelled this one under the
policy's
cancel_in_progress; absent otherwise job.targetsjob.tasks- absent on list rows and inside
Summary.job job.tasks[].approval- : the task's approval gate; a gated task stays
queueduntil it is approved job.tasks[].approval.approversuser:<id>androle:<name>; empty means any person holdingci:approvals.approvejob.tasks[].approval.commentjob.tasks[].approval.decided_atjob.tasks[].approval.decided_byjob.tasks[].approval.expires_atjob.tasks[].approval.reached- the task's dependencies have succeeded: an approval starts it at once
job.tasks[].approval.sod_exception- the requester decided their own gate under the policy's
approval_self: record job.tasks[].approval.state- One of
pending,approved,rejected,expired job.tasks[].artifact_countjob.tasks[].blocked_by- on a
skippedtask, the dependency whose end skipped it (build,build[1/2]) job.tasks[].cache- how a task met the task cache: served without a run, looked up and run, recorded after the run,
or never keyed (
cache: false,cache: { results: false }or--no-cache)One ofhit,miss,write,none job.tasks[].cache_hit- the task did not run: its key matched a recorded success;
cached_fromnames it job.tasks[].cache_note- why the task was neither answered from the cache nor recorded in it, when the cell knows a reason
beyond "these inputs never passed": the manifest keeps it out, or the run changed a tracked path.
ciresk ci explain-misscompares a miss with the last recorded run of the task job.tasks[].cached_failure- the task did not run: its key failed cleanly in the named run and never passed, so it ended with that run's exit code, tests and first failure;
--no-cacheruns it job.tasks[].cached_failure.job_id- uuidv7 rendered as
job_<32 hex> job.tasks[].cached_failure.task_id- uuidv7 rendered as
tsk_<32 hex> job.tasks[].cached_from- the run a cache hit stands on: the job and task whose success was recorded under the key, so a hit names where its verdict, log, junit and artifacts come from
job.tasks[].cached_from.job_id- uuidv7 rendered as
job_<32 hex> job.tasks[].cached_from.task_id- uuidv7 rendered as
tsk_<32 hex> job.tasks[].cached_targets- a task split into per-target units: how many targets reused a recorded verdict
job.tasks[].cached_targets.hitjob.tasks[].cached_targets.ofjob.tasks[].cold_start- how warm the member was when it took the lease:
warmwas online before the job was submitted,startedcame online after it (the factory started it for the queue),first_after_bootwas online before but this is its first lease since its bootOne ofwarm,started,first_after_boot job.tasks[].cost_unitsjob.tasks[].duration_msjob.tasks[].exit_codejob.tasks[].expected_ms- how long the planner expects the task to run, from the repository's history or the kind default; shorter tasks lease first within a job
job.tasks[].finished_atjob.tasks[].first_failure- the first failing line the worker saw, present from the moment it was seen
job.tasks[].first_failure.at- the worker's clock when the line was seen
job.tasks[].first_failure.excerptjob.tasks[].first_failure.kind- what the first failing line of a task's log was: a compiler diagnostic, a test
runner's failed case, a panic or uncaught exception, or nothing matched before a non-zero exitOne of
compiler,test,panic,exit job.tasks[].first_failure.line- the matched line, trimmed
job.tasks[].first_failure.locationpath:line[:col]when the line or its excerpt names onejob.tasks[].first_failure.shardk/Nwhen the task is a shardjob.tasks[].first_failure.task- the namespaced task name
job.tasks[].first_failure.tool- the detector rule that matched:
rustc,nextest,tsc,pytest,shellfor an exit,... job.tasks[].fit_atjob.tasks[].flaky_inputs- the targets (or the task's name for its whole key) whose identical inputs both passed and failed on record: reported, never quarantined
job.tasks[].has_junitjob.tasks[].labels- what the queue matches a worker on:
osandarchonly when the submit or the manifest set them,toolchains,workspace_warm, and the manifest's own labels job.tasks[].leased_atjob.tasks[].log_bytesjob.tasks[].matrix- : the matrix cell's values, axis to value, so a client groups a task's cells; empty for a task without a matrix
job.tasks[].namejob.tasks[].no_eligible_worker- why a
queuedtask matches no online worker, counted per mismatch (os, arch, trust); absent once a worker could take it job.tasks[].prepared_atjob.tasks[].queued_at- the phase marks of the current attempt (Neon item 4,
Task::timeline): queued at submission;fit_atwhen an eligible member first existed for it;leased_at;prepared_atwhen the worker had the workspace ready;cold_starthow warm the member was at the lease job.tasks[].ready_at- when the task became leasable: its submission for a root task, the moment its last dependency succeeded for a dependant
job.tasks[].refusals- the members that handed the task back for a reason of their own, oldest first
job.tasks[].refusals[].atjob.tasks[].refusals[].reason- the worker's
infra_error.code job.tasks[].refusals[].worker- the member's registered name (
worker-6) job.tasks[].refusals[].worker_id- uuidv7 rendered as
wrk_<32 hex> job.tasks[].requeued_at- when a lease of it was last given back and it queued again: its next lease's wait starts here
job.tasks[].shardk/Njob.tasks[].slots- the worker slots the task's lease weighs,
ceil(resources.memory / memory_per_slot)on the worker that took it; absent until leased job.tasks[].started_atjob.tasks[].state- One of
queued,leased,running,succeeded,failed,cancelled,timed_out,infra_error,skipped job.tasks[].termination- why the task stopped short of its own exit, or why it went back to the queue:
oom,timeout,cancelled,worker_shutdown,lease_lost, or a host infra code; absent while nothing ended it. on aqueued,leasedorrunningtask it names the previous attempt's end job.tasks[].warnings- the warnings the worker collected from the task's log, bounded; present once the task reported
job.tasks[].warnings.by_kindjob.tasks[].warnings.first- at most 20, in the order they were seen
job.tasks[].warnings.total- every occurrence the collector saw, repeats included
job.tasks[].warnings.unique- distinct
(kind, file, lint)the collector kept, at most 200 per task job.tasks[].worker_id- uuidv7 rendered as
wrk_<32 hex> job.tree- the verified working tree the job runs on; absent for a delta submission
job.tree.bytesjob.tree.entriesjob.tree.root- the root digest of a working tree: sha-256 of the root directory manifest
job.tree_schema- the
TREE_SCHEMA_VERSIONtree.rootwas hashed under; absent when the client did not say job.trust- tiers, with no order on purpose (amendment 2026-10-27):
trusted_ciis protected-branch automation and the cache writer every tier reads,trusted_interactivea person's own work, and neither is "below" the other, so every rule over tiers names the tiers it meansOne ofuntrusted,trusted_ci,trusted_interactive job.urljob.verify_ms- milliseconds the cell spent verifying
treebefore the job transaction; absent for a delta submission or a cell older than the field next- the exact drill-down command or tool call
request_id- the
X-Request-Idthis answer was produced under tail- last
taillines of the first failed task tail_tasktaskstasks[].approval- : the task's approval gate; a gated task stays
queueduntil it is approved tasks[].approval.approversuser:<id>androle:<name>; empty means any person holdingci:approvals.approvetasks[].approval.commenttasks[].approval.decided_attasks[].approval.decided_bytasks[].approval.expires_attasks[].approval.reached- the task's dependencies have succeeded: an approval starts it at once
tasks[].approval.sod_exception- the requester decided their own gate under the policy's
approval_self: record tasks[].approval.state- One of
pending,approved,rejected,expired tasks[].artifact_counttasks[].blocked_by- on a
skippedtask, the dependency whose end skipped it (build,build[1/2]) tasks[].cache- how a task met the task cache: served without a run, looked up and run, recorded after the run,
or never keyed (
cache: false,cache: { results: false }or--no-cache)One ofhit,miss,write,none tasks[].cache_hit- the task did not run: its key matched a recorded success;
cached_fromnames it tasks[].cache_note- why the task was neither answered from the cache nor recorded in it, when the cell knows a reason
beyond "these inputs never passed": the manifest keeps it out, or the run changed a tracked path.
ciresk ci explain-misscompares a miss with the last recorded run of the task tasks[].cached_failure- the task did not run: its key failed cleanly in the named run and never passed, so it ended with that run's exit code, tests and first failure;
--no-cacheruns it tasks[].cached_failure.job_id- uuidv7 rendered as
job_<32 hex> tasks[].cached_failure.task_id- uuidv7 rendered as
tsk_<32 hex> tasks[].cached_from- the run a cache hit stands on: the job and task whose success was recorded under the key, so a hit names where its verdict, log, junit and artifacts come from
tasks[].cached_from.job_id- uuidv7 rendered as
job_<32 hex> tasks[].cached_from.task_id- uuidv7 rendered as
tsk_<32 hex> tasks[].cached_targets- a task split into per-target units: how many targets reused a recorded verdict
tasks[].cached_targets.hittasks[].cached_targets.oftasks[].cold_start- how warm the member was when it took the lease:
warmwas online before the job was submitted,startedcame online after it (the factory started it for the queue),first_after_bootwas online before but this is its first lease since its bootOne ofwarm,started,first_after_boot tasks[].cost_unitstasks[].duration_mstasks[].exit_codetasks[].expected_ms- how long the planner expects the task to run, from the repository's history or the kind default; shorter tasks lease first within a job
tasks[].finished_attasks[].first_failure- the first failing line the worker saw, present from the moment it was seen
tasks[].first_failure.at- the worker's clock when the line was seen
tasks[].first_failure.excerpttasks[].first_failure.kind- what the first failing line of a task's log was: a compiler diagnostic, a test
runner's failed case, a panic or uncaught exception, or nothing matched before a non-zero exitOne of
compiler,test,panic,exit tasks[].first_failure.line- the matched line, trimmed
tasks[].first_failure.locationpath:line[:col]when the line or its excerpt names onetasks[].first_failure.shardk/Nwhen the task is a shardtasks[].first_failure.task- the namespaced task name
tasks[].first_failure.tool- the detector rule that matched:
rustc,nextest,tsc,pytest,shellfor an exit,... tasks[].fit_attasks[].flaky_inputs- the targets (or the task's name for its whole key) whose identical inputs both passed and failed on record: reported, never quarantined
tasks[].has_junittasks[].labels- what the queue matches a worker on:
osandarchonly when the submit or the manifest set them,toolchains,workspace_warm, and the manifest's own labels tasks[].leased_attasks[].log_bytestasks[].matrix- : the matrix cell's values, axis to value, so a client groups a task's cells; empty for a task without a matrix
tasks[].nametasks[].no_eligible_worker- why a
queuedtask matches no online worker, counted per mismatch (os, arch, trust); absent once a worker could take it tasks[].prepared_attasks[].queued_at- the phase marks of the current attempt (Neon item 4,
Task::timeline): queued at submission;fit_atwhen an eligible member first existed for it;leased_at;prepared_atwhen the worker had the workspace ready;cold_starthow warm the member was at the lease tasks[].ready_at- when the task became leasable: its submission for a root task, the moment its last dependency succeeded for a dependant
tasks[].refusals- the members that handed the task back for a reason of their own, oldest first
tasks[].refusals[].attasks[].refusals[].reason- the worker's
infra_error.code tasks[].refusals[].worker- the member's registered name (
worker-6) tasks[].refusals[].worker_id- uuidv7 rendered as
wrk_<32 hex> tasks[].requeued_at- when a lease of it was last given back and it queued again: its next lease's wait starts here
tasks[].shardk/Ntasks[].slots- the worker slots the task's lease weighs,
ceil(resources.memory / memory_per_slot)on the worker that took it; absent until leased tasks[].started_attasks[].state- One of
queued,leased,running,succeeded,failed,cancelled,timed_out,infra_error,skipped tasks[].termination- why the task stopped short of its own exit, or why it went back to the queue:
oom,timeout,cancelled,worker_shutdown,lease_lost, or a host infra code; absent while nothing ended it. on aqueued,leasedorrunningtask it names the previous attempt's end tasks[].warnings- the warnings the worker collected from the task's log, bounded; present once the task reported
tasks[].warnings.by_kindtasks[].warnings.by_kind[].counttasks[].warnings.by_kind[].kindtasks[].warnings.first- at most 20, in the order they were seen
tasks[].warnings.first[].filetasks[].warnings.first[].kindtasks[].warnings.first[].linetasks[].warnings.first[].linttasks[].warnings.first[].message- the first line of the warning, trimmed, at most 512 bytes
tasks[].warnings.total- every occurrence the collector saw, repeats included
tasks[].warnings.unique- distinct
(kind, file, lint)the collector kept, at most 200 per task tasks[].worker_id- uuidv7 rendered as
wrk_<32 hex> timings- where a job's wall time went, each span absent until both of its ends
exist: submission to the first lease, lease to the first process start, start to the last
task's
ended_at(the worker's clock), and from there tojob.finished timings.prepare_mstimings.queued_mstimings.report_mstimings.run_msverdict- One of
succeeded,failed,cancelled,timed_out,infra_error,running warnings- every task's warnings, counted and the first 20
warnings.by_kindwarnings.by_kind[].countwarnings.by_kind[].kindwarnings.first- at most 20, in the order they were seen
warnings.first[].filewarnings.first[].kindwarnings.first[].linewarnings.first[].lintwarnings.first[].message- the first line of the warning, trimmed, at most 512 bytes
warnings.total- every occurrence the collector saw, repeats included
warnings.unique- distinct
(kind, file, lint)the collector kept, at most 200 per task poll_after_msstate- One of
queued,leased,running,succeeded,failed,cancelled,timed_out,infra_error
curl "$CIRESK_API/v1/ci/jobs/job_0109badfc220cd056b2c0e862ac73d40/wait" \
-H "Authorization: Bearer $CIRESK_KEY"