Skip to content

Latest commit

 

History

History
128 lines (105 loc) · 3.61 KB

File metadata and controls

128 lines (105 loc) · 3.61 KB

API Contract

The runner exposes the same request/result contract through the Rust library, CLI, and HTTP API.

RunJobRequest

Important fields:

  • job_id: optional. The runner assigns job_<uuid> when omitted.
  • trace: generic metadata with optional known fields such as trace_id, task_id, agent_id, and workspace_id.
  • workspace.source: currently local_path.
  • workspace.path: host path to snapshot.
  • workspace.include and workspace.exclude: glob lists. Default exclusions always skip .git, virtualenvs, target, node_modules, common dependency caches, and common secret paths such as .env*, private keys, and secrets/.
  • 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 in policy.allowed_env or 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 to false.
  • 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_process or firecracker.

Detailed command policy can pin a path and optional executable digest:

{
  "allowed_commands": [
    {
      "basename": "python",
      "path": "/usr/bin/python3",
      "sha256": "..."
    }
  ]
}

RunJobResult

Terminal statuses:

  • completed
  • failed
  • timed_out
  • policy_denied
  • setup_failed
  • backend_unavailable
  • canceled

Queue-oriented future HTTP states:

  • queued
  • running

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.

Error Shape

{
  "code": "policy.command_denied",
  "message": "command is not allowed by policy",
  "details": {
    "argv0": "bash"
  }
}

Implemented codes include:

  • validation.invalid_request
  • validation.path_escape
  • job.not_found
  • queue.full
  • queue.closed
  • policy.command_denied
  • policy.shell_denied
  • policy.env_denied
  • policy.artifact_denied
  • backend.unavailable
  • backend.setup_failed
  • run.timed_out
  • run.spawn_failed
  • run.io_failed
  • run.artifact_collection_failed
  • run.exit_nonzero

HTTP API

Start the service:

agent-runner serve --addr 127.0.0.1:3000 --store-dir ./agent-runner-runs

Routes:

  • GET /health returns 200 with { "status": "ok" }.
  • POST /v1/jobs returns 202 with { "job_id": "...", "status": "queued" }.
  • GET /v1/jobs/{job_id} returns current status and, once terminal, the full RunJobResult.
  • GET /v1/jobs/{job_id}/artifacts returns 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.