Log inGet started

jobs

Updated 5 September 2026

The jobs namespace — 10 functions.

globals/jobs/find

jobs.find(name: string) -> JobHandle?

Look up a registered job by name. Returns a JobHandle or nil for anonymous / unknown names. Single FFI crossing — returns the id directly, no registry snapshot.

Parameters

  • name string — Job name supplied to jobs.register.

Returns JobHandle? — JobHandle or nil.

local job = jobs.find("animation_blend_main")

globals/jobs/inspect

jobs.inspect(target: JobHandle | string) -> JobInfo?

Return a snapshot row by job handle or by name without retrieving a full handle. Single FFI crossing — pulls only the matching row.

Parameters

  • target JobHandle | string — JobHandle, or job name string.

Returns JobInfo? — Snapshot row or nil.

local info = jobs.inspect("animation_blend_main")

globals/jobs/list

jobs.list(phase: string?) -> { JobInfo }

List registered job summaries. Pass a phase name to filter to a single phase. Single FFI crossing — only the requested rows cross the bridge.

Parameters

  • phase string (optional) — Optional phase filter — nil returns every job.

Returns { JobInfo } — Array of JobInfo rows.

local rows = jobs.list("main")

globals/jobs/register

jobs.register(descriptor: table) -> JobHandle?

Register a substrate job. Returns a JobHandle on success, nil on validation failure. Dispatches by executor.kind:\n - "kernel" / "stub" → standard __jobs.register (JSON-only descriptor).\n - "luau"__jobs.register_luau(descriptor, executor.run) so the Luau function survives the JSON crossing as a stable registry ref. The dispatcher invokes the run closure once per frame; the closure captures any bindings/buffers it needs.\n - "compute" → the shader reference resolves to its registration key, and the job queues one dispatch per frame.\n\norigin is auto-filled with the VFS path of the calling script unless the descriptor already supplies one — surfaced under /zero/runtime/jobs/<phase>/<key>/origin.txt for agent traceability. Single FFI crossing — auto-origin runs Rust-side via lua_getinfo, no separate stack-inspection trip.

Parameters

  • descriptor table — Job declaration with the JobDescriptor shape — name?, phase, reads?, writes?, executor, ordering?, pure?, origin?, metadata?. Param is typed as table rather than JobDescriptor because the LSP doesn't yet narrow string literals to their literal types in record fields, so a JobDescriptor annotation rejects the tagged-union executor discriminator on every call site (literal kind = "kernel" infers as kind: string, doesn't subtype KernelExecutor.kind: "kernel"). Runtime validation in __jobs.register enforces the actual structure; see the JobDescriptor type alias above for the canonical shape.

Returns JobHandle? — JobHandle or nil.

local job = jobs.register({ phase = "main", executor = { kind = "kernel", kernel = "copy_buffer" }, reads = {{resource={kind="buffer",id=src.id},mode="r"}}, writes = {{resource={kind="buffer",id=dst.id},mode="w"}} })
local job = jobs.register({ phase = "main", executor = { kind = "luau", run = function() print("tick") end } })
local job = jobs.register({ phase = "main", executor = { kind = "compute", shader = asset.resolve("carve", "computeShader"), buffers = { "heights" }, workgroups = { 64 } } })

typed/builtin//modules/jobs/jobhandle_cancel

jobhandle_cancel(self: JobHandle) -> boolean

Cancel the job — drops one refcount, last drop unregisters and the dispatcher stops invoking it. Symmetric with vfs.remove("/runtime/jobs/<phase>/<id>").

Parameters

  • self JobHandle — JobHandle returned by jobs.register.

Returns boolean — True if the substrate still tracked the job at call time.

job:cancel()

typed/builtin//modules/jobs/jobhandle_info

jobhandle_info(self: JobHandle) -> JobInfo?

Latest snapshot row for this job (id, name, phase, status, origin, metadata, reads, writes…). Single FFI crossing — pulls only this job's row, not the full registry.

Parameters

  • self JobHandle — JobHandle returned by jobs.register.

Returns JobInfo? — Snapshot row or nil if the job is no longer tracked.

local info = job:info(); print(info.origin)

typed/builtin//modules/jobs/jobhandle_pause

jobhandle_pause(self: JobHandle) -> boolean

Pause the job — skipped on subsequent ticks but stays registered.

Parameters

  • self JobHandle — JobHandle returned by jobs.register.

Returns boolean — True if the substrate still tracked the job.

local job = jobs.register({...}); job:pause()

typed/builtin//modules/jobs/jobhandle_resume

jobhandle_resume(self: JobHandle) -> boolean

Resume a paused or errored job (clears ErroredPending).

Parameters

  • self JobHandle — JobHandle returned by jobs.register.

Returns boolean — True if the substrate still tracked the job.

job:resume()

typed/builtin//modules/jobs/jobhandle_status

jobhandle_status(self: JobHandle) -> JobStatus?

Read the job's current scheduler status.

Parameters

  • self JobHandle — JobHandle returned by jobs.register.

Returns JobStatus? — "pending" / "running" / "errored", or nil if the id is no longer tracked.

local s = job:status() -- "pending"

typed/builtin//modules/jobs/jobhandle_valid

jobhandle_valid(self: JobHandle) -> boolean

Whether the substrate still tracks this job (false after :cancel/:destroy).

Parameters

  • self JobHandle — JobHandle returned by jobs.register.

Returns boolean — True if the underlying job is still registered.

if not job:valid() then return end
  • api
  • reference