Skip to main content

Overview

Worker-tier steps run in the agent’s sandbox and are capped at 10 minutes. A step declared with tier: 'job' runs instead in its own Kubernetes Job: an isolated container with a mounted workspace volume, a checkpoint every few hours, and - for agent steps - a full coding session driven by a harness such as Claude Code. Use the Job tier for anything that needs a repository checkout, a long test suite, or an agent that reads and edits files and runs commands.
$ is the Job image’s shell helper; a plain child_process spawn also works in a Job-tier code step.

Declaring a Job-tier step

The workspace

Declare the volume once on createWorkflow:

Mounting

  • The first Job-tier step of a run must mount rw - the clone happens on the first rw mount, and an ro mount on an empty volume is refused.
  • mount: 'ro' drops the write, edit and git tools from a coding turn.
  • Each run works on its own branch, lua/wf-<lineageId>. When a turn completes (and at each checkpoint) the harness commits and pushes that branch; a diff that contains a secret is refused before the push (secret_in_diff).
  • A child workflow started with { workspace: 'inherit' } uses the parent’s volume; the parent’s volume is released while the child waits.
  • lua workflows workspace <runId> shows the repo, branch, head, size and TTL; --release frees the volume early.

Parallel worktree arms

Several coding turns can work on the same checkout at once. Each arm gets its own worktree and branch (lua/wf-<lineageId>/<armId>) and a merge row folds them back:
merge.strategy is 'rebase' or 'merge'; onConflict: 'agent' lets one resolver turn fix conflicts, 'fail' fails the merge. At most 8 arms.

Coding turns

An agent step on the Job tier is a coding session on the mounted checkout:
  • Harness. claude-code runs the turn as a Claude Code session with the step’s prompt, the agent’s persona and the tool allowlist. generic is the other harness; it does not support the schema-repair pass a claude-code turn gets when its reply misses outputSchema.
  • Tool scope. toolScope.jobTools picks from shell, read, write, edit, glob, grep, git, gh and fetch. Leave out gh when a code step opens the PR instead.
  • Output schema. The turn’s final reply is validated against outputSchema; a mismatch fails the attempt, so give the turn retry: { maxAttempts: 2 }. The workspace persists across attempts, so a retry continues rather than restarts.
  • Segments. A long turn is split into 4-hour segments. At each boundary the harness commits, pushes and checkpoints; the next segment resumes from the checkpoint on the same attempt.
  • Model. Leave model unset to use the organisation default for Job turns.

Size classes

A container that exceeds its memory limit is killed and the step fails with job_oom_killed. Keep test suites inside the class (for example --maxWorkers=2 on a memory-hungry suite) or pick a larger one.

Credentials

The Job container never holds a credential.
  • workspace.credentialsRef names a GitHub connection. At spawn the platform mints a short-lived token scoped to that one repository and the permissions the step needs, and hands it to a sidecar next to the container - not to the container itself.
  • Inside the container the git remote is a local proxy. git fetch, git pull and git push work normally; the proxy adds the credential on the way out.
  • A push is admitted only to the run’s own branch (or the arm’s branch): no other refs, no deletes, no force-push over a moved ref. A pod spawned without an exact ref refuses every push.
  • gh (when granted in jobTools / toolScope.jobTools) goes through the same proxy and is limited to reading the pinned repository and three writes: create a pull request, edit a pull request’s title/body/draft state, and comment on an issue or PR. Merging, other repositories and organisation-level calls are refused.
  • Tokens are never written to a row, an event, a log or the journal. If the connection cannot mint a token the step fails with credentials_revoked (not retried).
  • The model provider key is likewise held only by the sidecar; the container talks to the provider through a metered local proxy.
Steps that need other services use requiredConnections and the usual Integrations.passthrough from a worker-tier code step - the pattern in the shipped examples is to open the PR from a worker step under ctx.once after the coding turns finish.

What the run page shows

On the desktop run page, select a Job-tier step to see:
  • the Job’s name, phase, size class and harness, with spawned / claimed / last-heartbeat times;
  • elapsed time against the timeout, and the segment strip for a multi-segment turn;
  • What the agent is doing: the turn’s latest activity, newest first - every tool call with its input and, once it returns, whether it succeeded and its output; and the model’s own notes between calls;
  • the workspace panel: branch, head, size used and files changed.
The Log tab lists the same activity for the whole run with filters for Tool calls, Agent notes and Step events, and a Follow switch that keeps the newest line in view. From the CLI:

Limits