Tasks
A job's tasks: one per manifest task and shard, with their lease, result and artifacts.
Get a task
One task with its lease and artifacts; ?warnings=1 pages its warning list.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Required | The job's ID. |
task | string | Required | The task's name, as the manifest names it (test, apps/web:test). |
cursor | string | Optional | |
limit | string | Optional | |
warnings | string | Optional |
Response
approval- : the task's approval gate; a gated task stays
queueduntil it is approved approval.approversuser:<id>androle:<name>; empty means any person holdingci:approvals.approveapproval.commentapproval.decided_atapproval.decided_byapproval.expires_atapproval.reached- the task's dependencies have succeeded: an approval starts it at once
approval.sod_exception- the requester decided their own gate under the policy's
approval_self: record approval.state- One of
pending,approved,rejected,expired artifact_countblocked_by- on a
skippedtask, the dependency whose end skipped it (build,build[1/2]) 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 cache_hit- the task did not run: its key matched a recorded success;
cached_fromnames it 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 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 cached_failure.job_id- uuidv7 rendered as
job_<32 hex> cached_failure.task_id- uuidv7 rendered as
tsk_<32 hex> 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
cached_from.job_id- uuidv7 rendered as
job_<32 hex> cached_from.task_id- uuidv7 rendered as
tsk_<32 hex> cached_targets- a task split into per-target units: how many targets reused a recorded verdict
cached_targets.hitcached_targets.ofcold_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 cost_unitsduration_msexit_codeexpected_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
finished_atfirst_failure- the first failing line the worker saw, present from the moment it was seen
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,... fit_atflaky_inputs- the targets (or the task's name for its whole key) whose identical inputs both passed and failed on record: reported, never quarantined
has_junitlabels- 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 leased_atlog_bytesmatrix- : the matrix cell's values, axis to value, so a client groups a task's cells; empty for a task without a matrix
nameno_eligible_worker- why a
queuedtask matches no online worker, counted per mismatch (os, arch, trust); absent once a worker could take it prepared_atqueued_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 ready_at- when the task became leasable: its submission for a root task, the moment its last dependency succeeded for a dependant
refusals- the members that handed the task back for a reason of their own, oldest first
refusals[].atrefusals[].reason- the worker's
infra_error.code refusals[].worker- the member's registered name (
worker-6) refusals[].worker_id- uuidv7 rendered as
wrk_<32 hex> requeued_at- when a lease of it was last given back and it queued again: its next lease's wait starts here
shardk/Nslots- the worker slots the task's lease weighs,
ceil(resources.memory / memory_per_slot)on the worker that took it; absent until leased started_atstate- One of
queued,leased,running,succeeded,failed,cancelled,timed_out,infra_error,skipped 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 warnings- the warnings the worker collected from the task's log, bounded; present once the task reported
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 worker_id- uuidv7 rendered as
wrk_<32 hex> artifactsartifacts[].digest- sha-256 digest as
sha256:<64 hex> artifacts[].expires_atartifacts[].media_typeartifacts[].nameartifacts[].size_bytesartifacts[].taskartifacts[].url- presigned
attemptinfra_errorinfra_error.codeinfra_error.messagelease- uuidv7 rendered as
lease_<32 hex> warnings_page- one page of the task's full warning list, only when asked
?warnings=1 warnings_page.next_cursorwarnings_page.totalwarnings_page.uniquewarnings_page.warningswarnings_page.warnings[].filewarnings_page.warnings[].kindwarnings_page.warnings[].linewarnings_page.warnings[].lintwarnings_page.warnings[].message- the first line of the warning, trimmed, at most 512 bytes
curl "$CIRESK_API/v1/ci/jobs/job_0109badfc220cd056b2c0e862ac73d40/tasks/test" \
-H "Authorization: Bearer $CIRESK_KEY"Report a task's first failure
The first failing line of a task, from its worker, ahead of the log.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Required | The job's ID. |
task | string | Required | The task's name, as the manifest names it (test, apps/web:test). |
Request body
atexcerpt- at most 40 lines around
line 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 lease_id- uuidv7 rendered as
lease_<32 hex> linelocationtool
Response
recorded- false when the task already had one: a repeat after a lost answer changes nothing
curl -X POST "$CIRESK_API/v1/ci/jobs/job_0109badfc220cd056b2c0e862ac73d40/tasks/test/first-failure" \
-H "Authorization: Bearer $CIRESK_KEY" \
-H "Content-Type: application/json" \
-d '{
"at": "2026-10-20T14:04:12Z",
"excerpt": [
"acme/platform"
],
"kind": "compiler",
"lease_id": "lease_01778d67b48ee630f44b3f03ab6254a8",
"line": "test manifest::parses_nested_manifests ... FAILED",
"location": "acme/platform",
"tool": "acme/platform"
}'Report a shard's passed tests
The tests a running shard of an archive task passed, from its worker.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Required | The job's ID. |
task | string | Required | The task's name, as the manifest names it (test, apps/web:test). |
Request body
lease_id- uuidv7 rendered as
lease_<32 hex> passedpassed[].binary_id- nextest's binary id:
ciresk-ci-core,ciresk-kepler-api::integration,xtask::bin/xtask passed[].signature- the standard base64 ed25519 signature of the worker's claim over these passes under the crate's test key
(
CacheClaimwithClaimed::passes): the api records passes only under a claim that verifies, and answers them only while it does; absent from older workers, whose passes are not recorded passed[].testsproducer- the worker build the claims name, which
ci.cache.revokerefuses by release or parser producer.parserproducer.release
Response
recorded- the tests recorded; a binary whose crate the plan does not test records nothing
curl -X POST "$CIRESK_API/v1/ci/jobs/job_0109badfc220cd056b2c0e862ac73d40/tasks/test/partials" \
-H "Authorization: Bearer $CIRESK_KEY" \
-H "Content-Type: application/json" \
-d '{
"lease_id": "lease_01778d67b48ee630f44b3f03ab6254a8",
"passed": [
{
"binary_id": "ciresk-ci-core",
"signature": "CacheClaim",
"tests": [
"manifest::parses_nested_manifests"
]
}
],
"producer": {
"parser": "acme/platform",
"release": "acme/platform"
}
}'Report a task's result
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Required | The job's ID. |
task | string | Required | The task's name, as the manifest names it (test, apps/web:test). |
Request body
artifactsartifacts[].digest- sha-256 digest as
sha256:<64 hex> artifacts[].media_typeartifacts[].nameartifacts[].sizecachecache.audited- the task-level key hit and the audit ran the task anyway
cache.flaky- the task's green stands on a flaky pass (CIR-722): a test of this run passed only on a retry, or the
task-level hit it reports was recorded so; a split task names its units in
units.flakytoo cache.from- on a
hit, the run the lookup named: the api copies its junit, warnings and artifacts onto this task and charges the hit rate cache.from.job_id- uuidv7 rendered as
job_<32 hex> cache.from.task_id- uuidv7 rendered as
tsk_<32 hex> cache.holes- what the run's key-hole detectors found; absent from older workers and from a run no detector looked at
cache.holes.detectorscache.holes.keyscache.holes.keys[].key- sha-256 digest as
sha256:<64 hex> cache.holes.keys[].paths- repository-relative, sorted, at most [
KeyHole::MAX_PATHS] cache.holes.keys[].sourcedep_info(rustc's dep-info files: no verdict is recorded under the key) ortrace(the audit's tracer: the verdict stands, the key's audit rate rises)cache.holes.keys[].target- the unit's target;
Nonefor the task-level key cache.holes.keys[].total- every path found, past the cap included
cache.key- sha-256 digest as
sha256:<64 hex> cache.namespacecache.outcome- 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 cache.producer- the worker build whose code decided what this report says about its keys, written on every row the report earns; absent from older workers
cache.producer.parsercache.producer.releasecache.public- what the task took from the worker's public registry cache; absent from older workers and from a worker whose cache is off
cache.public.bytescache.public.hitscache.public.missescache.signatures- the worker's signed verdict claim for each key the run passed: the api records a verdict row only under a key named here whose claim verifies; empty from older workers
cache.signatures[].key- sha-256 digest as
sha256:<64 hex> cache.signatures[].signaturecache.units- a task split into per-target units; absent from older workers and from a task that is one unit
cache.units.account- a failed run's account of the units that ran: which passed and which failed, when the worker could tell for every one of them; absent otherwise and from older workers, and the api then records no unit of a failed run
cache.units.account.failedcache.units.account.passedcache.units.account.source- what the account was read from:
nextest(the junit and the run'sStartingline) orunits_file(the command's ownCIRESK_UNITS_REPORT) cache.units.auditcache.units.flaky- the targets whose green stands on a flaky pass (CIR-722): a unit that ran and had a test pass only on
nextest's retry (junit
<flakyFailure>), or a hit served from a verdict recorded so. the api flags their verdict rows, observes them as flips and names them in the task'sflaky_inputs cache.units.hitcache.units.runcache.units.run[].key- sha-256 digest as
sha256:<64 hex> cache.units.run[].targetcost_units- the api recomputes from
workers.vcpus; a differing figure is logged duration_msended_atexit_codeinfra_errorinfra_error.codeinfra_error.messagejunit_digest- sha-256 digest as
sha256:<64 hex> lease_id- uuidv7 rendered as
lease_<32 hex> loglog.chunkslog.failed_rangeslog.failed_ranges[].endlog.failed_ranges[].labellog.failed_ranges[].startlog.total_bytesnext- the poll this report stands for: after the report commits the api leases for this worker
what fits and answers it in
ReportResponse::leases; absent from an older worker next.boot_to_online_ms- the worker's boot-to-online time, recorded on the lease for the cold start analysis
next.disk_free_bytesnext.first_lease_after_boot- no lease since boot (Neon item 4): the lease is
first_after_bootunless the member came online after the job next.free- see
HeartbeatRequest::free; a zero in cpus or memory answers204at once next.free.cpusnext.free.disk_bytesnext.free.memory_bytesnext.free.tmp_bytesnext.max_leases- how many leases one answer may carry, the worker's free slots; absent from an older worker: one
next.process_ended- the phase beat
process_ended: the leases this worker holds whose process exited and whose report has not landed; the api frees their slot, cpus and memory before it leases. absent from an older worker next.slots_freenext.wait_secsnext.warmnext.warm[].base_digestnext.warm[].repo_id- uuidv7 rendered as
repo_<32 hex> nextest- : the plan of a build row, or a shard's account; absent for every other task and from older workers
nextest.auditnextest.plan- sha-256 digest as
sha256:<64 hex> nextest.servednextest.unitsnextest.units[].build_key- sha-256 digest as
sha256:<64 hex> nextest.units[].piece- the crate's binaries as this run built them: a piece manifest the report names as an artefact, which
the api records as an
outputsrow with the target underbuild_key; absent when a recorded piece was reused nextest.units[].piece.bytes- the packed size of the piece's chunks, what its cache entry accounts under the quota
nextest.units[].piece.digest- sha-256 digest as
sha256:<64 hex> nextest.units[].targetnextest.units[].test_key- sha-256 digest as
sha256:<64 hex> nextest.role- One of
shard nextest.completenextest.failednextest.keys- the test keys of the plan the shard ran; the report's signatures carry a verdict claim for each, under the shard's own task, so the shard that merges the group can record every crate's verdict
observed_inputs- the files the task read, when the lease asked for
trace_inputsand a tracer ran; sorted, deduplicated, declared outputs excluded; empty from older workers observed_inputs[].digest- sha-256 digest as
sha256:<64 hex> observed_inputs[].pathoutcome- One of
succeeded,failed,timed_out,cancelled,infra_error outputs_content_digest- sha-256 of the outputs tar before compression: what a dependant's key
takes, so a compressor change keeps it;
outputs_digestnames the stored file. absent from older workers outputs_digest- sha-256 digest as
sha256:<64 hex> prepared_at- when the workspace was ready, the worker's clock; absent from older workers and from a task that failed before it
signalstarted_attermination- why the task did not run to its own exit, when the worker knows:
oom(the kernel killed a process of the task's cgroup),timeout,cancelled,worker_shutdown; absent from older workers and from a task that ended by itself timings_digest- sha-256 digest as
sha256:<64 hex> toolchains_resolvedtracer- the tracer and its format version,
fanotify/1orstrace/1; part of the key usage- the cgroup's measurement of the run; absent from older workers and from a plain launcher
usage.cpu_secondsusage.memory- the cgroup's memory counters at the last reading: what tells a task stalled at its
memory.highfrom a slow one; absent from older workers and from a plain launcher usage.memory.frozen_ms- how long the member's freezer held the task under host memory pressure;
the report's
duration_msleaves it out usage.memory.high_bytesusage.memory.high_eventsmemory.eventshigh: how often the task went overmemory.highand was throttledusage.memory.max_eventsmemory.eventsmax: how often it hitmemory.maxusage.memory.oom_killsusage.memory.pressure_full_avg10usage.memory.pressure_full_total_ususage.memory.pressure_some_avg10- psi: the percent of the last 10 s some, or every, running process of the task waited on memory
usage.memory.pressure_some_total_us- psi: the microseconds some, or every, running process waited on memory since the task began
usage.peak_anon_bytes- the largest
memory.statanonthe worker sampled: what the task needed.memory.peakcounts the page cache too, which fills a cgroup to itsmemory.highwhatever the task needs (eu1, 2026-10-25: a one-crate test-rust peaked at 21.6 GiB under a 24 GiB ask), so asks are learnt from this; absent from older workers usage.peak_memory_byteswarnings- what the warnings collector kept: the unique list, at most 200, and the count of every occurrence; absent from older workers and from a task with none
warnings.totalwarnings.warningswarnings.warnings[].filewarnings.warnings[].kindwarnings.warnings[].linewarnings.warnings[].lintwarnings.warnings[].message- the first line of the warning, trimmed, at most 512 bytes
workspaceworkspace.base_digestworkspace.id- uuidv7 rendered as
ws_<32 hex> workspace.slot- the warm slot the task ran in, so the slot reuse of sticky routing is measurable from task rows; absent from older workers
workspace.state- One of
ready,in_use,dirty,evicting,gone
Response
job_state- One of
queued,leased,running,succeeded,failed,cancelled,timed_out,infra_error leases- the leases
ReportRequest::nextfound for this worker; absent when it asked for none, from a repeated report and from an older api leases[].jobleases[].job.actorleases[].job.base_digestleases[].job.base_refleases[].job.diff- a content-addressed blob the receiver fetches by presigned url
leases[].job.diff.digest- sha-256 digest as
sha256:<64 hex> leases[].job.diff.download- a presigned get
leases[].job.diff.sizeleases[].job.graph- the cell holds no graph for this root and the manifest has a task with this strategy: record one after the run, once per job
leases[].job.graph.dir- where the tool runs, repository-relative,
""for the root leases[].job.graph.root- the root digest of a working tree: sha-256 of the root directory manifest
leases[].job.graph.strategy- One of
cargo,pnpm,go,turbo,nx,files,none leases[].job.graphs- every graph the cell lacks for this root, one request per strategy the manifest declares (
cargo,pnpm,go);graphcarries the first of them for a worker from before this field leases[].job.graphs[].dir- where the tool runs, repository-relative,
""for the root leases[].job.graphs[].root- the root digest of a working tree: sha-256 of the root directory manifest
leases[].job.graphs[].strategy- One of
cargo,pnpm,go,turbo,nx,files,none leases[].job.id- uuidv7 rendered as
job_<32 hex> leases[].job.kindcheck,test,build,lintor a manifest task idleases[].job.manifest_digest- sha-256 digest as
sha256:<64 hex> leases[].job.manifest_path- the governing manifest's repository-relative path; absent means
<cwd>/.ciresk/ci.yaml leases[].job.org_idtenants.org_idoftenant, the organisation dev names its sessions by: the worker records it on the warm root, so a dev session only ever pins or indexes its own org's generations; absent from an older api, and a root without it is never handed to a sessionleases[].job.repoleases[].job.repo.default_branch- the registration's default branch (
ci.repos.create): a lease whosebase_refnames it is what an overlay member's trunk follows; absent from an older api leases[].job.repo.id- uuidv7 rendered as
repo_<32 hex> leases[].job.repo.slugleases[].job.repo.urlleases[].job.seed_pack- the repository's seed pack, offered only to a job with a tree and no view; absent when the cell has none and from an older api
leases[].job.seed_pack.bytesleases[].job.seed_pack.download- a presigned get
leases[].job.seed_pack.entriesleases[].job.seed_pack.root- the tree the pack was built from; its root manifest is the pack's last entry, so a cas that holds the root was seeded already
leases[].job.sessionleases[].job.targetsleases[].job.tenant- the owner of the tree's blobs, the partition of the worker's local cas
leases[].job.toolchainsleases[].job.tree- the tree to materialise;
diffstays until every worker readstree leases[].job.tree.bytesleases[].job.tree.entriesleases[].job.tree.root- the root digest of a working tree: sha-256 of the root directory manifest
leases[].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 leases[].job.view- the requester's path view when it hides a prefix: the task runs in a fresh namespace on a tree of the readable paths only; absent for every other job
leases[].job.view.digestViewSpec::digest: the entries only, so every key that carries it also carries the tenantleases[].job.view.entriesleases[].job.view.policy_versionleases[].job.workspaceleases[].job.workspace.keepleases[].job.workspace.kind- One of
warm,ephemeral leases[].job.workspace.prewarm- the manifest's
workspace.prewarm: an idle worker may refresh the repo's trunk leases[].job.workspace.sparseleases[].leaseleases[].lease.cold_start- how warm this member was for the queue (Neon item 4); absent from an older control planeOne of
warm,started,first_after_boot leases[].lease.expected_ms- the task's expected run: on a spot notice a lease whose remainder fits is finished, not handed back; absent from an older control plane
leases[].lease.expires_atleases[].lease.fencing- equals
tasks.attempt; a report with an older fence is409 lease_not_held leases[].lease.heartbeat_secsleases[].lease.id- uuidv7 rendered as
lease_<32 hex> leases[].lease.warm_wait_ms- the task's warm wait: 0 means a warm slot pays nothing, so the task never waits for a restore. absent without both p50s and from an older control plane, which waits as before
leases[].lease.weight- how many of the worker's slots this lease holds:
ceil(resources.memory / memory_per_slot), at least one; an older control plane sends none, which is one leases[].taskrunarrives withtargets_argalready substitutedleases[].task.artifactsleases[].task.attemptleases[].task.cache- the namespaces this task reads and the one it may write, with the hmac write token
leases[].task.cache.bypass- why the worker computes the key but skips the lookup:
no_cachefor the job's--no-cache,results_offfor the task'scache: { results: false }; absent means look up leases[].task.cache.enabledleases[].task.cache.readleases[].task.cache.submit_missed- the submit key the api looked up when the task became ready and found no recorded success under: the worker reads no early key and asks once after the materialise. absent from an older api and whenever the api did not look up or found a row, which means as before
leases[].task.cache.writeleases[].task.cache.write_tokenleases[].task.cwdleases[].task.depends_onleases[].task.depends_on[].content_digest- sha-256 of the outputs tar before compression: what the task's key takes for this dependency, and what
the restore checks; absent from an older api and for a dependency recorded before it, where the key
takes
outputs_digest leases[].task.depends_on[].download- a presigned get
leases[].task.depends_on[].nameleases[].task.depends_on[].outputs_digest- sha-256 digest as
sha256:<64 hex> leases[].task.depends_on[].task_id- uuidv7 rendered as
tsk_<32 hex> leases[].task.egress_strict- decision 10: the manifest's
egress: strict; the worker runs the task strict when this or the tenant's policy says so. absent from older control planes, which means the tenant's mode alone leases[].task.envleases[].task.global_inputs- the manifest's
globals.inputs: in every task's key whether or not the task declaresinputs, so a lockfile change never hits a stale verdict; absent from older control planes, which means none leases[].task.id- uuidv7 rendered as
tsk_<32 hex> leases[].task.id_token- : the task's id token; absent when it asks for none, its job is untrusted, or from older apis
leases[].task.id_token.audienceleases[].task.id_token.expires_atleases[].task.id_token.token- the signed jwt the task hands a relying party
leases[].task.id_token_refused- : why the token the task asks for was refused; the worker fails the task before it runs
leases[].task.inputsleases[].task.knobs- what the derived tool knobs come from when the api trimmed the grant's memory below the manifest's from this run's history: the untrimmed request, so a trim moves the scope's caps and the fit, never a tool's parallelism or heap. absent when the grant is untrimmed and from older control planes: the knobs follow it
leases[].task.knobs.cpus- whole cpus,
CPUQuotaof the scope and the-jevery tool is handed leases[].task.knobs.disk- space the task writes to its workspace (a build directory); fitted against the data volume
leases[].task.knobs.memoryMemoryMaxof the scopeleases[].task.knobs.tmp- scratch space the task needs under
TMPDIR; the worker refuses the run when the data volume has less than this free leases[].task.log- the log token path of; absent from older control planes, which means the worker token
leases[].task.log.direct- : the worker puts sealed segments into the store itself (
ci.logs.segment_url, thenci.logs.segment_commit) and sends no log bytes to the api; absent from an older control plane, which means every chunk throughci.logs.append leases[].task.log.max_bytesleases[].task.log.tokenleases[].task.nameleases[].task.nextest- : the row is one half of a task that builds once and tests on shards; absent for every other task and from older control planes
leases[].task.nextest.role- which half of an
archivetask a row isOne ofarchive,shard leases[].task.nextest.taskleases[].task.outputsleases[].task.pass_envleases[].task.pass_env_refused- the
pass_envnames whose secret scope this job is outside of: never inpass_env, and the worker fails the task naming each one instead of running it without them. absent from older control planes, which means none leases[].task.pass_env_refused[].nameleases[].task.pass_env_refused[].reasonleases[].task.priorities- the tests to start first, for a task with a junit report the cell has results of (CIR-722); absent from older control planes and for every other task
leases[].task.priorities.first- failed or flaky in a recent run and not passed since, most recent first
leases[].task.priorities.slow- the slowest seen, slowest first
leases[].task.reportleases[].task.report.junitleases[].task.report.timingsleases[].task.resources- the grant: the manifest's
resourceswith what it left unsaid filled from the task's history or the kind defaults; the scope's caps and the derived tool knobs come from it. absent from older control planes, which means the worker's limits leases[].task.resources.cpus- whole cpus,
CPUQuotaof the scope and the-jevery tool is handed leases[].task.resources.disk- space the task writes to its workspace (a build directory); fitted against the data volume
leases[].task.resources.memoryMemoryMaxof the scopeleases[].task.resources.tmp- scratch space the task needs under
TMPDIR; the worker refuses the run when the data volume has less than this free leases[].task.runleases[].task.services- : the services the task runs beside it, by name, started before it in its own network namespace;
leased only to a member labelled
services: podman, absent for every other task and from older control planes leases[].task.shard- a 1-based shard of a sharded task; rendered as
k/Nwhere the wire asks for a string leases[].task.shard.countleases[].task.shard.indexleases[].task.timeout_secsleases[].task.toolchains- : a matrix cell's toolchains when an axis pins one, replacing the job's
toolchainsfor this task; absent for every other task and from older control planes leases[].task.trace_inputs- : the worker traces the task's file reads and reports them as
observed_inputs; absent from older control planes, which means off remaining_taskstask_state- One of
queued,leased,running,succeeded,failed,cancelled,timed_out,infra_error,skipped
curl -X POST "$CIRESK_API/v1/ci/jobs/job_0109badfc220cd056b2c0e862ac73d40/tasks/test/report" \
-H "Authorization: Bearer $CIRESK_KEY" \
-H "Content-Type: application/json" \
-d '{
"artifacts": [
{
"digest": "sha256:c21fa32a40d82233c44e76e6ae776b4d403ac1a564ca26de95a14c6bb47eaf49",
"media_type": "application/zstd",
"name": "target/dist/platform-api.tar.zst",
"size": 18432000
}
],
"cache": {
"audited": true,
"flaky": true,
"from": {
"job_id": "job_0109badfc220cd056b2c0e862ac73d40",
"task_id": "tsk_011ec0cc99550d0e90bc9fed5781decd"
},
"holes": {
"detectors": [
"acme/platform"
],
"keys": [
{
"key": "sha256:11e0184e1acaf0c0f4c3a5e7be84998835bca8fed12b2d226b82a64811f0bd21",
"paths": [
".ciresk/ci.yaml"
],
"source": "tenant",
"target": "platform-api",
"total": 1
}
]
},
"key": "sha256:11e0184e1acaf0c0f4c3a5e7be84998835bca8fed12b2d226b82a64811f0bd21",
"namespace": "acme/platform",
"outcome": "hit",
"producer": {
"parser": "acme/platform",
"release": "acme/platform"
},
"public": {
"bytes": 18432000,
"hits": 2,
"misses": 1
},
"signatures": [
{
"key": "sha256:11e0184e1acaf0c0f4c3a5e7be84998835bca8fed12b2d226b82a64811f0bd21",
"signature": "acme/platform"
}
],
"units": {
"account": {
"failed": [
"acme/platform"
],
"passed": [
"acme/platform"
],
"source": "tenant"
},
"audit": [
"acme/platform"
],
"flaky": [
"acme/platform"
],
"hit": [
"acme/platform"
],
"run": [
{
"key": "sha256:11e0184e1acaf0c0f4c3a5e7be84998835bca8fed12b2d226b82a64811f0bd21",
"target": "platform-api"
}
]
}
},
"cost_units": 1296,
"duration_ms": 83000,
"ended_at": "2026-10-20T14:12:41Z",
"exit_code": 0,
"infra_error": null,
"junit_digest": "sha256:3a4023b488227ad5836b17135ab100254dba3d78ac557d2ff5f6fad1d131b1a9",
"lease_id": "lease_01778d67b48ee630f44b3f03ab6254a8",
"log": {
"chunks": 1,
"failed_ranges": [
{
"end": 1,
"label": "linux",
"start": 1
}
],
"total_bytes": 18432000
},
"next": {
"boot_to_online_ms": 83000,
"disk_free_bytes": 18432000,
"first_lease_after_boot": true,
"free": {
"cpus": 1,
"disk_bytes": 18432000,
"memory_bytes": 68719476736,
"tmp_bytes": 18432000
},
"max_leases": 1,
"process_ended": [
"lease_01d50b6f005647a6f46cd8e6ccc4a47a"
],
"slots_free": 1,
"wait_secs": 300,
"warm": [
{
"base_digest": "feef45d804737fdf7a297e27e443d914551629de",
"repo_id": "repo_0129354d7b6b4146ad16c315d960365b"
}
]
},
"nextest": {
"audit": [
"acme/platform"
],
"plan": "sha256:cc297ca49b911f870d7248af6418404d1405442c9c5606c92f3afaddf54c5f7e",
"served": [
"acme/platform"
],
"units": [
{
"build_key": "sha256:f83f356cc2d6be112610d11a740763a25591d8ecfb25fcfd31feb9d471110b96",
"piece": {
"bytes": 18432000,
"digest": "sha256:c21fa32a40d82233c44e76e6ae776b4d403ac1a564ca26de95a14c6bb47eaf49"
},
"target": "platform-api",
"test_key": "sha256:557e7166fb6de8fbb6f4dd67eb058ff75b0961bd090d0da76be1a376fbbe72af"
}
],
"role": "archive"
},
"observed_inputs": [
{
"digest": "sha256:c21fa32a40d82233c44e76e6ae776b4d403ac1a564ca26de95a14c6bb47eaf49",
"path": ".ciresk/ci.yaml"
}
],
"outcome": "succeeded",
"outputs_content_digest": "sha256:768e5e03075620e8f68c621b8e19b0bb62dcf536a2e9e351439f581b4c282514",
"outputs_digest": "sha256:7cf9d095df466528c49ea6cab229fb433ce465de3fd7407f998773542f070110",
"prepared_at": "2026-10-20T14:04:12Z",
"signal": 1,
"started_at": "2026-10-20T14:04:19Z",
"termination": "oom",
"timings_digest": "sha256:2e117fc44cf3311c46b44aae4d21fbff16dd8f293c634912f5e2f731fdd8508c",
"toolchains_resolved": {
"rust": "acme/platform"
},
"tracer": "fanotify/1",
"usage": {
"cpu_seconds": 1.5,
"memory": {
"frozen_ms": 83000,
"high_bytes": 18432000,
"high_events": 1,
"max_events": 1,
"oom_kills": 1,
"pressure_full_avg10": 1.5,
"pressure_full_total_us": 1,
"pressure_some_avg10": 1.5,
"pressure_some_total_us": 1
},
"peak_anon_bytes": 18432000,
"peak_memory_bytes": 18432000
},
"warnings": {
"total": 1,
"warnings": [
{
"file": "crates/core/src/manifest.rs",
"kind": "check",
"line": 212,
"lint": "acme/platform",
"message": "assertion failed: nested manifests merge root first"
}
]
},
"workspace": {
"base_digest": "feef45d804737fdf7a297e27e443d914551629de",
"id": "ws_012011c5add7f80ffb87fb5416d433f9",
"slot": 1,
"state": "ready"
}
}'