> ## Documentation Index
> Fetch the complete documentation index at: https://docs.iearena.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Configuration

> Task configuration, metadata, and schema reference.

The **`task.toml`** file specifies the task configuration and metadata.

```toml theme={"system"}
schema_version = "1.3"

[task]
name = "apple/create-unix-os"
authors = [{ name = "Steve Jobs", email = "steve@apple.com" }]

[metadata]
difficulty_explanation = "Trivial task for demonstration"
category = "programming"

[verifier]
timeout_sec = 120.0
env = { API_KEY = "sk-test-123" }
user = "root"  # optional: run the verifier as this OS user

[agent]
timeout_sec = 120.0
user = "agent"  # optional: run the agent as this OS user

[solution]
env = { API_KEY = "sk-test-123" }

[environment]
network_mode = "allowlist"  # baseline; defaults to "public" when omitted
allowed_hosts = ["pypi.org"]
docker_image = "apple/unix-os:latest"
cpus = 1
memory_mb = 2048
storage_mb = 10240
```

## `[environment]` vs. `environment/`

By default, Harbor defers as much configuration as possible into the `environment/` spec rather than the `task.toml`. A lot of engineering effort has gone into designing `environment/` specs (like `Dockerfile`) and they provide conventions for common use cases.

Only when absolutely necessary does Harbor require configuration in the `task.toml`.

A few fields in `task.toml` are due to lack of convention or common pitfalls:

| Field                       | Explanation                                                                                                                                                            |
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `environment.docker_image`  | Specifies the Docker image to use for the environment. (If this is set, `environment/` can be omitted entirely)                                                        |
| `environment.network_mode`  | Sets the network isolation mode (e.g., `public`, `allowlist`).                                                                                                         |
| `environment.allowed_hosts` | Lists domains/IPs allowed for outbound network access when `network_mode` is `allowlist`.                                                                              |
| `environment.env`           | Defines environment variables to inject into the environment.                                                                                                          |
| `environment.healthcheck`   | Configuration for checking if the environment is healthy or ready.                                                                                                     |
| `environment.workdir`       | Sets the working directory for commands run in the environment. This was added by popular demand to retroactively set a `workdir` without having to rebuild the image. |

## Field reference

### General

<ParamField body="schema_version" type="string" default={'"1.3"'}>
  Version of the task configuration format.
</ParamField>

<ParamField body="multi_step_reward_strategy" type={'"mean" | "final" | null'} default="null">
  How to derive the trial-level reward from per-step verifier results. Only applies when \[\[steps]] is set; leave unset for single-step tasks (defaults to "mean" on multi-step). See [Multi-step tasks](/core-concepts/tasks/multi-step).
</ParamField>

### `[task]`

<ParamField body="task" type="PackageInfo | null" default="null">
  Optional \[task] section for registry package metadata. When present, task.name is required.
</ParamField>

<ParamField body="task.name" type="string">
  Package name in org/name format (e.g., "harbor/hello-world"). Required when \[task] is declared.
</ParamField>

<ParamField body="task.authors" type="list[Author]" default="[]">
  List of task authors. Each entry has a required name and optional email (for example, `[{ name = "Jane", email = "jane@example.com" }]`).
</ParamField>

<ParamField body="task.description" type="string" default={'""'}>
  Human-readable description of the task.
</ParamField>

<ParamField body="task.keywords" type="list[string]" default="[]">
  Keywords for search and categorization.
</ParamField>

### `[metadata]`

<ParamField body="metadata" type="object">
  Arbitrary metadata provided by the task author.
</ParamField>

### `[verifier]`

<ParamField body="verifier.timeout_sec" type="number" default="600">
  Timeout in seconds for the verifier.
</ParamField>

<ParamField body="verifier.network_mode" type={'"no-network" | "public" | "allowlist" | null'} default="null (no override)">
  Optional override during verify(). Applied only when set and different from the verifier baseline. See [Network policy](/core-concepts/tasks/network-policies).
</ParamField>

<ParamField body="verifier.allowed_hosts" type="list[string] | null" default="null">
  Allowlist hostnames when verifier.network\_mode is allowlist.
</ParamField>

<ParamField body="verifier.env" type="object" default="{}">
  Environment variables to set when running the verifier.
</ParamField>

<ParamField body="verifier.user" type="string | int | null" default="null">
  Username or UID to run the verifier as. When set, the environment's default user is configured accordingly before verification. If not set, the environment's container default (typically root) is used.
</ParamField>

<ParamField body="verifier.environment_mode" type={'"shared" | "separate" | null'} default="null">
  Where the verifier runs. "shared" (default when no \[verifier.environment] is declared) reuses the agent's container; "separate" launches a dedicated verifier container with its own image. Omitting this field while declaring \[verifier.environment] implies "separate". Declaring "shared" alongside \[verifier.environment] is a validation error.
</ParamField>

<ParamField body="verifier.environment" type="EnvironmentConfig | null" default="null">
  Optional \[verifier.environment] section (same schema as the top-level \[environment]). Defines a dedicated container the verifier runs in. When set, the task's tests/ directory becomes the verifier image's build context — the image must provide /tests/test.sh (Linux) or /tests/test.bat (Windows) at runtime; Harbor does not upload tests for separate envs. When environment\_mode="separate" is declared without this section, a fresh copy of the top-level \[environment] is used.
</ParamField>

<ParamField body="verifier.environment.network_mode" type={'"no-network" | "public" | "allowlist"'} default={'"public"'}>
  Separate verifier env baseline when \[verifier.environment] is set. Same modes as environment.network\_mode.
</ParamField>

<ParamField body="verifier.environment.allowed_hosts" type="list[string] | null" default="null">
  Allowlist hostnames when verifier.environment.network\_mode is allowlist.
</ParamField>

### `[agent]`

<ParamField body="agent.timeout_sec" type="number | null" default="null">
  Timeout in seconds for the agent. If not set, no timeout is enforced.
</ParamField>

<ParamField body="agent.network_mode" type={'"no-network" | "public" | "allowlist" | null'} default="null (no override)">
  Optional override during agent.run(). Applied only when set and different from \[environment]. See [Network policy](/core-concepts/tasks/network-policies).
</ParamField>

<ParamField body="agent.allowed_hosts" type="list[string] | null" default="null">
  Allowlist hostnames when agent.network\_mode is allowlist.
</ParamField>

<ParamField body="agent.user" type="string | int | null" default="null">
  Username or UID to run the agent as. When set, the environment's default user is configured accordingly before agent setup and execution. If not set, the environment's container default (typically root) is used.
</ParamField>

### `[solution]`

<ParamField body="solution.env" type="object" default="{}">
  Environment variables to set when running the solution.
</ParamField>

### `[environment]`

<ParamField body="environment.build_timeout_sec" type="number" default="600">
  Timeout in seconds for environment build.
</ParamField>

<ParamField body="environment.network_mode" type={'"no-network" | "public" | "allowlist"'} default={'"public"'}>
  Agent env baseline. Also the shared verifier baseline when no separate verifier env overrides it. See [Network policy](/core-concepts/tasks/network-policies).
</ParamField>

<ParamField body="environment.allowed_hosts" type="list[string] | null" default="null">
  Allowlist hostnames when environment.network\_mode is allowlist.
</ParamField>

<ParamField body="environment.docker_image" type="string | null" default="null">
  A pre-built Docker image to use for the environment. When set, environment/Dockerfile is optional for supported environment types.
</ParamField>

<ParamField body="environment.os" type={'"linux" | "windows"'} default={'"linux"'}>
  Target operating system for the task container. "linux" (default) or "windows". When "windows", Harbor uses Windows-style paths, cmd.exe execution, tar-over-exec file transfer, and filters script discovery to .bat only. The Docker daemon mode and image OS are validated against this value at start; mismatches fail fast.
</ParamField>

<ParamField body="environment.cpus" type="integer | null" default="null">
  Number of CPUs requested by the task. When omitted, Harbor leaves CPU sizing to the selected provider.
</ParamField>

<ParamField body="environment.memory_mb" type="integer | null" default="null">
  Amount of RAM requested by the task in megabytes. When omitted, Harbor leaves memory sizing to the selected provider.
</ParamField>

<ParamField body="environment.storage_mb" type="integer | null" default="null">
  Amount of storage requested by the task in megabytes. When omitted, Harbor leaves storage sizing to the selected provider.
</ParamField>

<ParamField body="environment.gpus" type="integer | null" default="null">
  Number of GPUs requested by the task. When omitted, Harbor does not request GPUs.
</ParamField>

<ParamField body="environment.gpu_types" type="list[string] | null" default="null">
  List of acceptable GPU types (e.g., \['H100', 'A100', 'T4']). None means any GPU type is acceptable.
</ParamField>

<ParamField body="environment.tpu" type="TpuSpec | null" default="null">
  TPU slice specification (type + topology). When set, the environment requests a TPU node matching this spec; per-pod chip count is derived from the topology. Singular because a task allocates exactly one TPU slice per pod. Only supported on TPU-capable environments (currently GKE).
</ParamField>

<ParamField body="environment.tpu.type" type="string">
  TPU accelerator type. Accepts either a user-friendly alias (e.g., 'v6e', 'trillium', 'v4') or a canonical GKE label (e.g., 'tpu-v6e-slice', 'tpu7x').
</ParamField>

<ParamField body="environment.tpu.topology" type="string">
  TPU topology as 'NxM' or 'NxMxK' (e.g., '2x4', '2x2x1'). Required — GKE's implicit default topology is not part of a stable contract, so omitting it would make Harbor runs non-reproducible across GKE versions. Per-pod TPU chip count is computed as the product of dimensions (e.g. '2x2x1' → 4 chips, '2x4' → 8 chips). Each dimension must be a positive integer (no leading zeros).
</ParamField>

<ParamField body="environment.allow_internet" type="boolean | null" default="null">
  Deprecated compatibility field. Prefer \[environment].network\_mode. When set and \[environment].network\_mode is omitted, false maps to no-network and true maps to public.
</ParamField>

<ParamField body="environment.env" type="object" default="{}">
  Environment variables required for the task, resolved from the host at runtime. Supports `${VAR}` and `${VAR:-default}` template syntax.
</ParamField>

<ParamField body="environment.mcp_servers.name" type="string">
  Unique name for each MCP server entry (declare servers as \[\[environment.mcp\_servers]] in TOML). Compatible agents register them automatically. See [Environment — MCPs](/core-concepts/tasks/environment#mcps).
</ParamField>

<ParamField body="environment.mcp_servers.transport" type={'"stdio" | "sse" | "streamable-http"'} default={'"sse"'}>
  How the agent connects to the server. "sse" and "streamable-http" require url; "stdio" requires command. Legacy value "http" is normalized to "streamable-http".
</ParamField>

<ParamField body="environment.mcp_servers.url" type="string | null" default="null">
  Endpoint URL when transport is "sse" or "streamable-http" (e.g. [http://mcp-server:8000/mcp](http://mcp-server:8000/mcp) for a Compose sidecar). Required for those transports.
</ParamField>

<ParamField body="environment.mcp_servers.command" type="string | null" default="null">
  Executable to spawn when transport is "stdio". Required for stdio.
</ParamField>

<ParamField body="environment.mcp_servers.args" type="list[string]" default="[]">
  Arguments passed to command when transport is "stdio".
</ParamField>

<ParamField body="environment.skills_dir" type="string | null" default="null">
  Path to a skills directory in the environment. Contents are copied to the agent's skills config directory.
</ParamField>

<ParamField body="environment.healthcheck" type="HealthcheckConfig | null" default="null">
  Optional healthcheck block run after environment start (omit the whole \[environment.healthcheck] section to disable). When set, command is required; other fields use the defaults below.
</ParamField>

<ParamField body="environment.healthcheck.command" type="string">
  Shell command to run as a healthcheck after environment start. Exit 0 means healthy. Required when \[environment.healthcheck] is present.
</ParamField>

<ParamField body="environment.healthcheck.interval_sec" type="number" default="5">
  Time in seconds between healthcheck attempts.
</ParamField>

<ParamField body="environment.healthcheck.timeout_sec" type="number" default="30">
  Maximum time in seconds for a single healthcheck command.
</ParamField>

<ParamField body="environment.healthcheck.start_period_sec" type="number" default="0">
  Grace period in seconds after environment start during which failures don't count.
</ParamField>

<ParamField body="environment.healthcheck.start_interval_sec" type="number" default="5">
  Interval in seconds between checks during the start period.
</ParamField>

<ParamField body="environment.healthcheck.retries" type="integer" default="3">
  Number of consecutive failures before the healthcheck is considered failed.
</ParamField>

<ParamField body="environment.workdir" type="string | null" default="null">
  Default working directory for command execution in the environment. Overrides the container WORKDIR when set.
</ParamField>

### Artifacts

<ParamField body="artifacts" type="list[string | ArtifactConfig]" default="[]">
  Root-level paths to snapshot from the environment into the trial artifacts directory. Single-step: collected once after verification. Multi-step: included in every step's collection pass (step-level paths use \[\[steps]].artifacts — see [Multi-step tasks](/core-concepts/tasks/multi-step)). Each entry is a container path string or a table with source / destination / exclude.
</ParamField>

<ParamField body="artifacts.source" type="string">
  Container path to download (file or directory). Required for table entries; a bare string in the artifacts list is shorthand for source only.
</ParamField>

<ParamField body="artifacts.destination" type="string | null" default="null">
  Relative path under the trial artifacts directory. When omitted, Harbor derives the host path from source.
</ParamField>

<ParamField body="artifacts.exclude" type="list[string]" default="[]">
  Glob patterns to exclude when source is a directory (passed as tar --exclude flags).
</ParamField>

### Provenance

<ParamField body="source" type="string | null" default="null">
  Optional source string for task provenance.
</ParamField>

## Multi-step configuration

The field reference above covers single-step and shared task-root settings. Multi-step tasks add `[[steps]]` entries with per-step `agent`, `verifier`, `healthcheck`, `min_reward`, and `artifacts` overrides. Step fields, `workdir/setup.sh`, and trial-level reward rollup are documented on [multi-step tasks](/core-concepts/tasks/multi-step).

## TOML templates

During task creation, you can pass a `--metadata-template` flag with a path to a TOML file to pre-populate `task.toml` with metadata fields and config defaults:

```bash theme={"system"}
harbor task init [org]/[name] --metadata-template task-template.toml
```

Sections in the template override Harbor's built-in defaults. Anything not specified falls back to the defaults listed above.
