Harbor Tasks
Harbor Tasks
NeMo Gym runs datasets written in the Harbor task format directly: a
folder of task folders is both the dataset and the input to gym eval run. Harbor is the input format; Gym owns
execution (sandboxes, agents, verification). This page covers the dataset layout, the dataset-level settings Gym
reads, and the three commands that work on such a dataset.
Dataset layout
task.toml belongs to the task author and is read-only once fetched. A task runs in a sandbox when it declares
[environment].docker_image, or a Dockerfile Gym can run without a build (FROM plus WORKDIR, ENV, USER,
LABEL, and RUN lines that Gym applies in the pulled base image at seed). Each task’s rows are materialized
with a digest of the task folder plus the dataset settings applied to it, and the environment server refuses a
task whose digest no longer matches, so edits after materialization are caught rather than silently run.
dataset.toml and the [gym] table
Harbor’s own tables ([dataset]) are left to Harbor. What a dataset needs on top of its tasks goes in a [gym]
table, as data: defaults that scale every task, and per-task overrides written with Harbor’s own
[environment] fields.
Deployment settings (which sandbox provider, registry credentials, image mirrors) do not belong here: a dataset
must run unchanged on every deployment. Those live in the sandbox provider block of the run configuration. See
OpenSandbox for the provider’s images and setup blocks.
Harbor round trip. harbor add, harbor remove and harbor sync rewrite dataset.toml from Harbor’s
manifest model, which serializes only Harbor’s own tables. The [gym] table is dropped, so a round trip resets
the multipliers and per-task overrides to their defaults without an error. Keep the dataset in git and restore the
table from there after running one of these commands.
gym dataset init
Scaffolds a dataset in exactly the shape the loader accepts: dataset.toml with a [gym] table and one task
(hello) with an instruction, a verifier and a reference solution. Harbor requires org/name in the manifest,
so a bare name is written as local/<name> (and the task as local/hello); give org/name to choose the org.
The folder is the name without the org, as harbor task init does for a task.
gym dataset validate
Runs each task’s reference solution (solution/solve.sh) through the task’s verifier with an oracle harness and
reports the rewards. Every solution must score 1; the command exits non-zero otherwise. Tasks without a
solution are listed as unvalidated. Validation outputs never share inputs, configs or cached results with an
evaluation run.
gym eval run with a task target
gym eval run takes the same targets in place of a benchmark name. Gym prepares the dataset (recording the base
images the Dockerfiles resolve against, loading every task, writing the rows and the per-taskset environment
server configuration), then starts the servers and collects rollouts as for any benchmark.
A task folder that does not load is left out of the prepared rows and recorded in skipped.json next to them
with the reason; the rest of the dataset still prepares. By default gym eval run then lists every task left
out and stops before starting servers. Pass --skip-unloadable to run the loadable subset instead; the omitted
tasks stay listed in skipped.json. Tasks that declare GPUs run on the environment server’s gpu_sandbox_provider
block when one is configured. The run’s rows, generated configuration and outputs are the same artifacts every
other gym eval run produces, so gym eval aggregate, gym eval export and the health check apply unchanged.