Core concepts

Harnesses

Multi-harness agent council: Codex, OpenCode, Hermes, OpenClaw, Grok Build, and Pi around the Anvil controller core
Multi-harness agent council: Codex, OpenCode, Hermes, OpenClaw, Grok Build, and Pi around the Anvil controller core

One AgentRun creates one Job and selects one harness. Install-wide runnerImages values provide defaults; the source chart uses local :dev names and a packaged chart uses its matching vVERSION. An AgentHarnessProfile selects the adapter, image, provider configuration, workload identity, credentials, storage, and resource envelope. A run can atomically select a different harness profile and can apply explicit inline runtime overrides. Production installations should use image digests.

KindRuntimeProvider fieldsDurable home recommended
codexOpenAI Codex CLICodex model, reasoning, approval settingsyes
openCodeOpenCode CLIprovider-qualified model, agent, variant, auto/pure modeyes
hermesAgentHermes Agentprovider, auth mode, modelyes
openClawOpenClawprovider, agent ID, model, thinkingyes
grokBuildGrok BuildxAI model, profile, service tieryes
piAgentPi coding agentprovider, model, thinking, modeyes
customoperator-supplied imagecommand and argsimage-defined

The shared model-provider enum currently covers OpenAI/Codex and xAI integrations. OpenCode keeps its broader provider catalog native by accepting a provider-qualified openCode.model value and provider credential environment variables rather than narrowing it to that enum. Remote issue context and remote skill files are currently GitHub adapters. They are optional integration surfaces, not requirements for custom harnesses.

Common Contract

Every built-in runner receives:

  • ANVIL_AGENT_RUN_PROMPT_FILE: complete generated prompt.
  • ANVIL_AGENT_RUN_CONTEXT_FILE: structured run and source context.
  • ANVIL_AGENT_RUN_TOOL_SETUP_FILES: newline-separated executable setup files.
  • ANVIL_AGENT_RUN_TOOLS_JSON: names, descriptions, setup paths, and checks.
  • ANVIL_AGENT_RUN_STATUS_LOG_PREFIX: prefix for JSON status log records.
  • provider and backend-specific environment variables.

Setup scripts run after repository preparation and before the runtime starts. They execute as the container user in the configured workdir. Keep them idempotent, install only into writable paths, pin downloaded artifacts, and pass credentials through the selected harness profile's envSecretRefs rather than inline YAML. Tool contracts normally live in AgentToolSet; the skill that teaches an agent when to use them remains in AgentSkillSet. Selecting a tool set does not grant the credentials that its tool may need.

Run profiles created before the composition API may still contain inline backend and execution settings. When a run selects a different harnessProfileRef, those profile-inline runtime fields are deliberately not carried into the replacement. Move all provider credentials and durable homes into AgentHarnessProfile before offering runtime swaps. See Agent Composition.

OpenCode On Kubernetes

The built-in OpenCode image pins the upstream standalone binary and verifies its release checksum at build time. It uses the supported non-interactive opencode run command, pipes the combined AgentRun prompt on stdin, defaults to JSON event logs, disables auto-updates, and uses --pure unless the backend explicitly opts out. See the OpenCode CLI documentation and the image README.

Select a provider-qualified model such as openai/gpt-5.4. Supply provider API keys through envSecretRefs, or seed an existing credential store with OPENCODE_AUTH_JSON. OpenCode's standard auth file lives below the runner's XDG data directory and is included in the /opt/anvil/opencode durable-home layout. Do not start interactive login inside an AgentRun Job.

openCode.auto: true enables OpenCode's explicit auto-approval mode for permission requests not denied by configuration. It is intentionally false by default. OpenCode's own permission rules and the Pod's ServiceAccount, Secret, mount, egress, and security boundaries must agree with the run intent.

Workload Sizing And Placement

Harness profiles are also reusable machine profiles for heavy work. Set CPU, memory, and ephemeral-storage requests so Kubernetes can place builds, test suites, indexing, and analysis on a node that can complete them. Use limits to bound one run, and use nodeSelector, affinity, and tolerations to route specialized harnesses to dedicated pools.

Keep distinct profiles for materially different envelopes, such as a small review lane, a large Rust build lane, and a custom GPU analysis lane. They can all be selected by the same provider-neutral run profile and skill sets. This avoids hard-coding one machine class into the agent's role.

Each harness Pod occupies one node. Run multiple independent AgentRuns to use multiple machines; a single run is not split across nodes by the controller. Local or ReadWriteOnce data volumes may constrain placement and parallel mounts. See Distributed Workloads before sharing a durable home across concurrent lanes.

Codex Sandbox On Kubernetes

Codex read-only and workspace-write sandbox modes depend on unprivileged user namespaces and their OS sandbox helper. Hardened Kubernetes nodes often disable that kernel capability, which causes the CLI to fail before the model run starts. Test the selected mode on every worker pool used by the harness.

When those nodes cannot support the inner Codex sandbox, the danger-full-access Codex mode can run inside a deliberately hardened Pod. In that configuration the name applies to the process inside its container; it does not grant Kubernetes or node authority by itself. The Pod boundary must carry the security policy: non-root user, dropped capabilities, seccomp, read-only root filesystem where supported, narrow ServiceAccount/RBAC, bounded mounts and Secrets, controlled egress, namespace isolation, and immutable images. Do not use this fallback as a substitute for those controls.

Custom Harness

A custom image should read the prompt and context files, perform one bounded task, print useful logs, exit nonzero on failure, and emit status JSON. The small image under examples/quickstart is the executable reference contract. A status line looks like:

ANVIL_AGENT_RUN_STATUS_JSON={"type":"decision","action":"inspect","summary":"completed","residualRisk":"none"}

The controller also treats Kubernetes Job success or failure as terminal evidence. Structured reports enrich status; they do not override a failed Job.

Source Preparation

The built-in images honor their documented repository environment variables, but v0.1 does not have a provider-neutral repository source object. Supply repository URL/ref variables through a profile or Secret, or build source preparation into a custom image. Do not assume that applicationRef clones a repository; it is only scope metadata. When a built-in image is asked to clone or check out a repository, clone, fetch, and ref-resolution failures terminate the Job instead of silently running against an empty or wrong workspace.

Use credential helpers or provider-specific token Secrets where possible. If an HTTP(S) repository URL contains userinfo, a query, or a fragment, the runner uses it only for transport and persists a sanitized origin URL. Credential- bearing URLs using other URI schemes are rejected; use a normal SSH username or credential helper instead. This prevents a durable workspace from retaining the inline credential, but it does not make inline URL credentials the preferred authentication mechanism.

Remote skill content is a separate controller-side fetch. Its source must name a full immutable commit. Private-source tokens are mapped by exact API host in the trusted harness execution envelope; they cannot be selected by an AgentSkillSet or skill override.