The runner exposes the same request/result contract through the Rust library, CLI, and HTTP API.
Important fields:
job_id: optional. The runner assignsjob_<uuid>when omitted.trace: generic metadata with optional known fields such astrace_id,task_id,agent_id, andworkspace_id.workspace.source: currentlylocal_path.workspace.path: host path to snapshot.workspace.includeandworkspace.exclude: glob lists. Default exclusions always skip.git, virtualenvs,target,node_modules, common dependency caches, and common secret paths such as.env*, private keys, andsecrets/.command.argv: required non-empty array. Shell strings are not the primary API.command.cwd: relative path inside the copied snapshot.command.env: explicit additions only; the local backend starts from an empty child environment. Keys are denied unless listed inpolicy.allowed_envor allowed by runner configuration.policy.allowed_commands: command basenames or detailed executable policy.policy.allowed_env: explicit environment keys allowed for this request. Omit or use an empty list to deny all request-provided environment variables.policy.allow_shell: defaults tofalse.policy.network: recorded policy intent. The local backend cannot enforce network isolation.limits: timeout, output caps, artifact caps, and record-size caps.backend.kind:local_processorfirecracker.
Detailed command policy can pin a path and optional executable digest:
{
"allowed_commands": [
{
"basename": "python",
"path": "/usr/bin/python3",
"sha256": "..."
}
]
}Terminal statuses:
completedfailedtimed_outpolicy_deniedsetup_failedbackend_unavailablecanceled
Queue-oriented future HTTP states:
queuedrunning
Every result includes:
- command argv/cwd echo;
- exit code when available;
- capped stdout/stderr plus truncation flags and SHA-256 hashes;
- artifact records with safe relative paths, sizes, hashes, and local storage URIs;
- replay hashes for request, workspace snapshot, and result;
- policy decision and version hash;
- optional stable error object.
{
"code": "policy.command_denied",
"message": "command is not allowed by policy",
"details": {
"argv0": "bash"
}
}Implemented codes include:
validation.invalid_requestvalidation.path_escapejob.not_foundqueue.fullqueue.closedpolicy.command_deniedpolicy.shell_deniedpolicy.env_deniedpolicy.artifact_deniedbackend.unavailablebackend.setup_failedrun.timed_outrun.spawn_failedrun.io_failedrun.artifact_collection_failedrun.exit_nonzero
Start the service:
agent-runner serve --addr 127.0.0.1:3000 --store-dir ./agent-runner-runsRoutes:
GET /healthreturns200with{ "status": "ok" }.POST /v1/jobsreturns202with{ "job_id": "...", "status": "queued" }.GET /v1/jobs/{job_id}returns current status and, once terminal, the fullRunJobResult.GET /v1/jobs/{job_id}/artifactsreturns artifact metadata for terminal jobs.- Validation errors return
422. - Policy denials return terminal result objects, not HTTP 500.
- Queue full returns
503.
HTTP job state is indexed in memory while the service runs. Status files are
written to runs/<job_id>/status.json, and terminal results are written to
runs/<job_id>/result.json. If the process restarts, terminal results can still
be read by GET /v1/jobs/{job_id} from the run store.