Skip to navigation

nemo_gym.data.tasks.harbor.verifier_env

View as Markdown

Harbor’s separate-verifier rules.

Which environment the verifier runs in, the verifier table or a copy of the task environment, whether tests/ is a build context of its own, which top-level keys, sidecars and main-service keys a tests/docker-compose.yaml may declare (and which such files cannot be read at all), and the two refusals the loader raises when a separate verifier has no image and no definition. The loader and the build planner both read these rules.

Module Contents

Functions

NameDescription
_verifier_build_requiredroot is the dataset folder whose built-images.json the loader read (see _build_required).
_verifier_compose_servicesThe services mapping of the task’s tests/docker-compose.yaml; {} without the file, or for one that
_verifier_definition_requiredHarbor’s refusal of a separate verifier environment with nothing to run: its environment dir is always
effective_verifier_environmentThe environment a separate verifier runs in, as Harbor resolves it, or None in shared mode.
step_verifier_build_contextThe folder Harbor starts a step’s separate verifier environment from (_verifier_env_build_context with a
step_verifier_environmentThe environment a step’s separate verifier runs in, as Harbor’s resolve_effective_verifier_env_config
step_verifier_mode"separate" or "shared" for one step, as Harbor’s resolve_step_verifier_mode (verifier_mode.py at
verifier_build_contextThe folder Harbor builds the separate verifier’s image from, tests/, when it builds one; else None.
verifier_build_environmentThe effective verifier environment whose settings Harbor’s build of tests/Dockerfile sees, or None
verifier_compose_main_overridesThe keys of main in the task’s tests/docker-compose.yaml other than VERIFIER_MAIN_KEYS (other
verifier_compose_refusalWhy the task’s tests/docker-compose.yaml is not the file verifier_compose_sidecars and
verifier_compose_sidecarsThe services other than main that the task’s tests/docker-compose.yaml declares, in file order; []

Data

BUILD_PULL_POLICY

COMPOSE_EXTENSION_PREFIX

PREBUILT_VERIFIER_MAIN_KEYS

TESTS_COMPOSE_FILE

TESTS_DOCKERFILE

VERIFIER_COMPOSE_TOP_LEVEL_KEYS

VERIFIER_MAIN_KEYS

API

nemo_gym.data.tasks.harbor.verifier_env._verifier_build_required(
task_folder: pathlib.Path,
root: pathlib.Path

root is the dataset folder whose built-images.json the loader read (see _build_required).

nemo_gym.data.tasks.harbor.verifier_env._verifier_compose_services(
task_folder: pathlib.Path
) -> dict[typing.Any, typing.Any]

The services mapping of the task’s tests/docker-compose.yaml; {} without the file, or for one that does not parse or has no services mapping (a file the loader refuses first, verifier_compose_refusal).

nemo_gym.data.tasks.harbor.verifier_env._verifier_definition_required(
task_folder: pathlib.Path

Harbor’s refusal of a separate verifier environment with nothing to run: its environment dir is always tests/ (_verifier_env_build_context in trial.py), checked by require_agent_environment_definition.

nemo_gym.data.tasks.harbor.verifier_env.effective_verifier_environment(

The environment a separate verifier runs in, as Harbor resolves it, or None in shared mode.

Harbor’s resolve_effective_verifier_env_config (verifier_mode.py at v0.22.0) for a single-step task: [verifier.environment] when the task declares one, else a copy of [environment], so a task that only says environment_mode = "separate" grades in an environment shaped like the agent’s, docker_image included.

nemo_gym.data.tasks.harbor.verifier_env.step_verifier_build_context(
task_folder: pathlib.Path,
) -> pathlib.Path

The folder Harbor starts a step’s separate verifier environment from (_verifier_env_build_context with a step in trial.py at v0.22.0): steps/<name>/tests/ when that folder exists, else the task’s tests/.

The environment a step’s separate verifier runs in, as Harbor’s resolve_effective_verifier_env_config resolves it with a step: [steps.verifier.environment], else [verifier.environment], else a copy of [environment]; None when the step verifies in shared mode.

nemo_gym.data.tasks.harbor.verifier_env.step_verifier_mode(
) -> str

"separate" or "shared" for one step, as Harbor’s resolve_step_verifier_mode (verifier_mode.py at v0.22.0) resolves it: the step’s explicit [steps.verifier].environment_mode, else separate when the step declares a [steps.verifier.environment], else the task’s own mode (HarborTaskConfig.is_shared_verifier). Steps of one task may resolve differently.

nemo_gym.data.tasks.harbor.verifier_env.verifier_build_context(
task_folder: pathlib.Path,
) -> pathlib.Path | None

The folder Harbor builds the separate verifier’s image from, tests/, when it builds one; else None.

Harbor starts the separate verifier’s environment with tests/ as its environment dir (_verifier_env_build_context in trial.py at v0.22.0) and the effective verifier environment as its config (effective_verifier_environment). Its Docker environment then uses the config’s docker_image when there is one and otherwise runs docker compose build on tests/Dockerfile (should_use_prebuilt_docker_image, start in docker.py), whatever that Dockerfile holds: a FROM plus RUN file is built, not overlaid. So: shared mode, a declared or inherited docker_image, or no tests/Dockerfile means no build. Without the file and without an image Harbor refuses the task (require_agent_environment_definition on tests/, which is always its verifier environment dir: there is no fallback to environment/), and so does load_task. Prepare plans one build entry per returned context (nemo_gym.data.tasks.harbor.image_build.plan_builds) and the loader reads its record. A multi-step task whose steps verify separately builds tests/ for the steps that declare no image and start from it (verifier_build_environment), whatever the task’s own mode.

nemo_gym.data.tasks.harbor.verifier_env.verifier_build_environment(
task_folder: pathlib.Path,

The effective verifier environment whose settings Harbor’s build of tests/Dockerfile sees, or None when nothing builds from tests/: the task’s own (effective_verifier_environment) when it declares no docker_image, else the first step’s whose separate verifier declares none and starts from tests/ (step_verifier_build_context; a step with a tests/ folder of its own starts from that folder, which this server does not build, and the loader refuses such a step). Steps that would build tests/ under different environments share the first one’s settings here, where Harbor builds once per step.

nemo_gym.data.tasks.harbor.verifier_env.verifier_compose_main_overrides(
task_folder: pathlib.Path,
prebuilt: bool
) -> list[str]

The keys of main in the task’s tests/docker-compose.yaml other than VERIFIER_MAIN_KEYS (other than PREBUILT_VERIFIER_MAIN_KEYS when prebuilt: the effective verifier environment names a docker_image, so nothing builds from tests/, and a pull_policy of build counts too), in file order; [] without the file or without a main mapping.

Harbor stacks that file on its verifier template for the build and for up (_docker_compose_paths in docker.py at v0.22.0), so environment, env_file, volumes, command and every other runtime key of main reach the verifier’s container: a test.sh that reads CHECK_MODE from main.environment sees it there, an image beside a prebuilt verifier replaces the declared image Harbor’s template names (${PREBUILT_IMAGE_NAME}), and a build section there has Harbor’s up build tests/Dockerfile under the declared name, always with pull_policy: build (see VERIFIER_MAIN_KEYS). This server starts the separate verifier as a single sandbox from the effective verifier environment of task.toml and the verifier image alone, and reads the file for the build section and pinned image of a main it builds only, so such a task would grade differently from Harbor without a word. It is refused instead, like one with verifier sidecars: by load_task and, before any build, by ImageBuilder.build_many.

nemo_gym.data.tasks.harbor.verifier_env.verifier_compose_refusal(
task_folder: pathlib.Path
) -> str | None

Why the task’s tests/docker-compose.yaml is not the file verifier_compose_sidecars and verifier_compose_main_overrides read, as the loader’s message, or None when it is (or there is none).

Those readers see the file’s own services mapping and nothing else, so what they cannot see must not reach Harbor’s verifier either. Harbor stacks the whole file on its verifier template (_docker_compose_paths in docker.py at v0.22.0) and compose up applies every top-level key of it to the verifier’s project, so only the keys this server reads or that cannot shape the verifier’s container pass (VERIFIER_COMPOSE_TOP_LEVEL_KEYS and x- extension fields) and any other is refused by name. A top-level include merges the included files’ services into the project before the stacking, so main.environment or a build section written in an included file reaches Harbor’s verifier container as if written here, while this server reads services: {} and grades in the declared image without a word (validate_task_compose refuses include for a Dockerfile build the same way; this is the loader’s refusal, for every separate verifier, prebuilt ones, which that validator never sees, included). A top-level networks reconfigures the project’s default network, the one Compose attaches main to because neither of Harbor’s templates gives it a networks or network_mode key and, under Harbor’s default public policy, no egress overlay does either: default: {internal: true} grades Harbor’s verifier without egress (driver_opts, ipam, enable_ipv6 likewise) while this server’s single sandbox grades with it. Top-level volumes, configs and secrets are inert until a service references them, and a reference on main is a key verifier_compose_main_overrides refuses, but the class is closed rather than judged key by key, since each is a project setting the readers never see. A file that is not valid YAML or not a mapping, or whose services is not one, fails Harbor’s compose up (and Harbor’s own reader of the file, _egress_controlled_service_names in docker.py, parses it with yaml.safe_load), so the trial errors under Harbor where the readers above would see {}; refused as validate_task_compose refuses it. An empty file is an empty mapping, as it is there.

nemo_gym.data.tasks.harbor.verifier_env.verifier_compose_sidecars(
task_folder: pathlib.Path
) -> list[str]

The services other than main that the task’s tests/docker-compose.yaml declares, in file order; [] without the file, or for one that does not parse or has no services mapping (verifier_compose_refusal names such a file, and a top-level key other than services, first).

Harbor’s separate verifier is a whole Docker environment over tests/: it stacks that Compose file on its build or prebuilt template (_docker_compose_paths in docker.py at v0.22.0), builds every service with a build section and starts them all with up, image or built, prebuilt main or not. This server starts the separate verifier as a single sandbox, so a task that declares any such service is refused: by load_task and, before any build, by ImageBuilder.build_many. A main-only file (cadir’s and arc-crm-6’s shape) is read for main’s build section, and its image when prepare builds the verifier; a runtime setting on main (every key of arc-crm-6’s file: network_mode, pids_limit, security_opt, cap_drop) is refused the same way (verifier_compose_main_overrides).

nemo_gym.data.tasks.harbor.verifier_env.BUILD_PULL_POLICY = 'build'
nemo_gym.data.tasks.harbor.verifier_env.COMPOSE_EXTENSION_PREFIX = 'x-'
nemo_gym.data.tasks.harbor.verifier_env.PREBUILT_VERIFIER_MAIN_KEYS = frozenset({'pull_policy'})
nemo_gym.data.tasks.harbor.verifier_env.TESTS_COMPOSE_FILE = Path('tests') / 'docker-compose.yaml'
nemo_gym.data.tasks.harbor.verifier_env.TESTS_DOCKERFILE = Path('tests') / 'Dockerfile'
nemo_gym.data.tasks.harbor.verifier_env.VERIFIER_COMPOSE_TOP_LEVEL_KEYS = frozenset({'services', 'name', 'version'})
nemo_gym.data.tasks.harbor.verifier_env.VERIFIER_MAIN_KEYS = frozenset({'image', 'build', 'pull_policy'})