Skip to content

feat(v1): support Harbor's separate verifier environments#2067

Open
xeophon wants to merge 16 commits into
mainfrom
feat/harbor-separate-verifier
Open

feat(v1): support Harbor's separate verifier environments#2067
xeophon wants to merge 16 commits into
mainfrom
feat/harbor-separate-verifier

Conversation

@xeophon

@xeophon xeophon commented Jul 18, 2026

Copy link
Copy Markdown
Member

Overview

Adds Harbor v1 support for tasks that grade in a separate verifier environment. Shared tasks keep grading in the agent runtime; separate tasks run their verifier in a fresh runtime on the same provider, using the task's Harbor configuration without adding new run-time knobs.

Details

  • Resolves shared vs. separate mode from [verifier].environment_mode and [verifier.environment].
  • Derives the verifier runtime from the resolved agent runtime while applying the verifier image, resources, environment variables, and workdir.
  • Stages the packaged verifier tests before restoring /logs/artifacts and declared main-service artifacts at their original paths, including per-artifact exclude patterns.
  • Runs an optional task-root pre_artifacts.sh capture hook before artifact transfer.
  • Reads separate-verifier rewards from numeric reward.json values or numeric metric maps, then falls back to reward.txt; shared-mode reward behavior remains unchanged.
  • Fails clearly for unsupported subprocess runtimes, Dockerfile-only verifier builds, compose-sidecar artifacts, and collect hooks. Declared verifier network policies emit a warning because they are not yet enforced.

This enables Harbor datasets with isolated grading environments, including fresh-copy and dedicated verifier-image configurations, while preserving the explicit artifact boundary between agent work and grading.

Note

Overview

Adds Harbor v1 support for tasks that grade in a separate verifier environment. Shared tasks keep grading in the agent runtime; separate tasks run their verifier in a fresh runtime on the same provider, using the task's Harbor configuration without adding new run-time knobs.

Details

  • Resolves shared vs. separate mode from [verifier].environment_mode and [verifier.environment].
  • Derives the verifier runtime from the resolved agent runtime while applying the verifier image, resources, environment variables, and workdir.
  • Stages the packaged verifier tests before restoring /logs/artifacts and declared main-service artifacts at their original paths, including per-artifact exclude patterns.
  • Runs an optional task-root pre_artifacts.sh capture hook before artifact transfer.
  • Reads separate-verifier rewards from numeric reward.json values or numeric metric maps, then falls back to reward.txt; shared-mode reward behavior remains unchanged.
  • Fails clearly for unsupported subprocess runtimes, Dockerfile-only verifier builds, compose-sidecar artifacts, and collect hooks. Declared verifier network policies emit a warning because they are not yet enforced.

This enables Harbor datasets with isolated grading environments, including fresh-copy and dedicated verifier-image configurations, while preserving the explicit artifact boundary between agent work and grading.

Changes since #2067 opened

  • Refactored artifact handling in separate verifier mode within tasksets.harbor.HarborTask [32de5e2]
  • Fixed reward value parsing in tasksets.harbor.HarborTask._read_reward method [32de5e2]
  • Refactored path resolution in tasksets.harbor.HarborTask._transfer_artifacts method [32de5e2]
  • Inlined network policy detection logic in tasksets.harbor.parse_verifier function [32de5e2]
  • Updated docstrings across tasksets.harbor pydantic models and methods [32de5e2]
  • Modified tar command argument construction in HarborTask._grade method to insert end-of-options marker and handle empty path strings [0d20fa0]
  • Implemented two-phase scoring for Harbor tasks with separate verifier environments [845cd50]
  • Modified scoring phase orchestration in rollout to support optional separate scoring runtime configurations [845cd50]
  • Added confirmed teardown capability to runtime implementations [845cd50]
  • Added scoring runtime configuration support to task interface [845cd50]
  • Updated runtime type validation for verifier environments [845cd50]
  • Modified solved reward to stage tests when no separate verifier is configured [845cd50]
  • Modified parse_verifier function to use top-level configuration environment as fallback [adff2dc]

Note

Medium Risk
Changes rollout scoring order and lifecycle for tasks that return a scoring runtime config, and adds multi-runtime Harbor flows that depend on confirmed teardown and artifact tar/restore correctness.

Overview
Adds Harbor “separate verifier” grading: tasks can score in a fresh docker/prime runtime instead of reusing the agent sandbox, with artifacts copied across after confirmed agent teardown.

Rollout / task plumbing: Task.scoring_runtime_config() lets a task opt into a replacement scoring runtime. When set, rollout scores the harness on the live agent runtime first, then runs task scoring (which may swap runtimes) instead of parallel gather. Scoring timeouts use asyncio.timeout instead of wait_for around gather.

Runtimes: Docker and Prime implement stop_confirmed() so Harbor can tear down the agent environment only after deletion is verified before starting the verifier.

Harbor: Parses [verifier].environment_mode, [verifier.environment], and [[artifacts]] into VerifierConfig / Artifact on HarborData. Separate mode runs optional pre_artifacts.sh, tars /logs/artifacts and declared paths (with exclude patterns), stop_confirmed() on the agent, boots a derived verifier runtime, restores archives, stages tests/, and runs test.sh. Rewards prefer numeric reward.json in separate mode; shared mode still uses reward.txt. Unsupported cases (subprocess runtimes, Dockerfile-only verifier builds, compose sidecars, collect hooks) fail clearly; declared verifier network policies only warn.

Reviewed by Cursor Bugbot for commit adff2dc. Bugbot is set up for automated code reviews on this repo. Configure here.

Fixes RES-1093

Honor `[verifier].environment_mode = "separate"` / `[verifier.environment]`
in the v1 Harbor taskset: grade in a fresh container/sandbox on the same
provider (docker/prime/modal), derived from the agent runtime's resolved
config. Mirrors Harbor semantics: mode resolution and validation, artifact
transfer (/logs/artifacts + top-level artifacts, main service only) at
identical absolute paths, reward.json-first read order in separate mode,
and the pre_artifacts.sh capture hook used by Pier-style datasets (e.g.
DeepSWE v1.1). Shared-mode behavior is unchanged; no new config knobs.
Comment thread verifiers/v1/tasksets/harbor/taskset.py
Comment thread verifiers/v1/tasksets/harbor/taskset.py
Comment thread verifiers/v1/tasksets/harbor/taskset.py Outdated
Comment thread verifiers/v1/tasksets/harbor/taskset.py Outdated
@macroscopeapp

macroscopeapp Bot commented Jul 18, 2026

Copy link
Copy Markdown

Approvability

Verdict: Needs human review

This PR adds a substantial new feature for separate verifier environments, introducing new runtime lifecycle methods, modified scoring flow, and artifact transfer logic between runtimes. The scope of new capability and runtime behavior changes warrants human review.

You can customize Macroscope's approvability policy. Learn more.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 662b48db5b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread verifiers/v1/tasksets/harbor/taskset.py Outdated
Comment thread verifiers/v1/tasksets/harbor/taskset.py Outdated
xeophon added 2 commits July 18, 2026 18:46
- move verifier.start() inside the try so a failed/cancelled start still
  reaches the finally's stop() (no leaked sandbox/container)
- _read_reward: catch TypeError too (non-object reward.json, null reward)
  so it falls back to reward.txt instead of aborting scoring
- _transfer_artifacts: check both tar exit codes and raise SandboxError
  instead of grading against silently incomplete artifacts
Comment thread verifiers/v1/tasksets/harbor/taskset.py

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 61beb0b5b6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread verifiers/v1/tasksets/harbor/taskset.py Outdated
Comment thread verifiers/v1/tasksets/harbor/taskset.py Outdated
- _grade wipes /tests before extracting the staged tests tarball, so files
  baked into a verifier image can't linger and contaminate grading
- parse_verifier fails fast on separate-mode tasks declaring
  [[verifier.collect]] hooks (compose sidecars aren't supported) instead of
  silently grading without the collected evidence

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e8c5eeb62b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread verifiers/v1/tasksets/harbor/taskset.py Outdated
A separate-mode task whose artifacts entries target a compose service can't
be graded faithfully without the sidecar's files — fail fast like the
collect-hook guard instead of warn-and-skip.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 789a40d02e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread verifiers/v1/tasksets/harbor/taskset.py Outdated
Comment thread verifiers/v1/tasksets/harbor/taskset.py Outdated
Comment thread verifiers/v1/tasksets/harbor/taskset.py Outdated
Comment thread verifiers/v1/tasksets/harbor/taskset.py Outdated
Comment thread verifiers/v1/tasksets/harbor/taskset.py Outdated
- HarborData.verifier: VerifierConfig | None (image/resources/workdir) —
  None grades shared; replaces the flat verifier_* fields (review)
- TODO to port the separate verifier runtime into a judge env once
  multi-agent lands (review)
- separate-mode reward.json without a 'reward' key but with an all-numeric
  mapping (Harbor's multi-metric form) is returned as keyed rewards instead
  of falling through to 0.0
- warn at load when [verifier]/[verifier.environment] declares a network
  policy (not enforced; rejecting would break DeepSWE's uniform
  allow_internet=false, which its graders don't depend on)
Comment thread verifiers/v1/tasksets/harbor/taskset.py Outdated
Comment thread verifiers/v1/tasksets/harbor/taskset.py
Comment thread verifiers/v1/tasksets/harbor/taskset.py Outdated
xeophon added 2 commits July 18, 2026 22:45
The probe always exits 0 when it runs, so a nonzero exit means the agent
runtime is gone (e.g. dead container) — raise SandboxError instead of
skipping the transfer and grading a clean verifier.
Harbor applies excludes per entry, relative to the artifact root (-C <src> .);
the single combined transfer tar can't reproduce that scoping, so fail fast
at load instead of materializing files the task explicitly excluded.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b7caabea43

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread verifiers/v1/tasksets/harbor/taskset.py
xeophon added 2 commits July 18, 2026 23:24
Structured artifacts entries may declare exclude patterns; apply them the
way Harbor does — per entry, relative to the artifact's root, and to
directory artifacts only. Plain entries still share one combined tar; an
entry with excludes gets its own tar (-C <source> .) so the patterns scope
correctly. File artifacts with excludes travel with the combined tar
(Harbor ignores excludes on files too).
A present [verifier.environment] replaces the task's [environment]
wholesale (Harbor): resource fields it omits are no longer inherited from
the agent task. Fields whose value matches the task's declared resources
(task-set) reset to the runtime default; cli/toml overrides (mismatches)
keep winning. Mode-only separate stays a fresh copy and keeps inheriting.
Comment thread verifiers/v1/tasksets/harbor/taskset.py Outdated
Comment thread verifiers/v1/tasksets/harbor/taskset.py

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 48ed242ed9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread verifiers/v1/tasksets/harbor/taskset.py Outdated
Comment thread verifiers/v1/tasksets/harbor/taskset.py
…envs

- keyed reward.json values must be int/float by exact type (JSON booleans
  are not rewards; fall back to reward.txt)
- relative artifact sources resolve against the agent runtime's workdir
  before probing/archiving, so the combined tar packs and re-materializes
  the right absolute path
- an explicit [verifier.environment] without docker_image is rejected even
  without tests/Dockerfile (Harbor would build or fail; the agent image is
  not a faithful fallback unless ignore_dockerfile opts in)
Comment thread verifiers/v1/tasksets/harbor/taskset.py Outdated
A failed hook doesn't invalidate /logs/artifacts (also the agent's own
publish directory), so partial artifacts still transfer — say that instead
of claiming the base state is graded.
Comment thread verifiers/v1/tasksets/harbor/taskset.py

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e83057ab44

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread verifiers/v1/tasksets/harbor/taskset.py
Comment thread verifiers/v1/tasksets/harbor/taskset.py Outdated
@xeophon
xeophon requested a review from mikasenghaas July 19, 2026 14:13

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0d20fa0fc8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread verifiers/v1/tasksets/harbor/taskset.py Outdated

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 845cd50. Configure here.

Comment thread verifiers/v1/tasksets/harbor/taskset.py

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 845cd5033b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread verifiers/v1/tasksets/harbor/taskset.py Outdated
Comment thread verifiers/v1/tasksets/harbor/taskset.py

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: adff2dcc3b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +270 to +271
["tar", "-czf", ARTIFACTS_TAR, "-C", "/", "--"]
+ [(path.lstrip("/") or ".") for path in combined],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep artifact archives outside collected directories

When a separate-mode task declares a plain directory artifact that contains /tmp/.vf-artifacts.tgz — for example artifacts = ["/tmp"] or a relative artifact resolving under /tmp — this command writes the archive inside the tree being archived. GNU tar exits nonzero in that shape (file changed as we read it), so _archive_tar() raises and the verifier never runs even though Harbor allows directory artifacts at their original paths; create the temporary archive outside any collected source or exclude the archive path.

Useful? React with 👍 / 👎.

f"{task_dir.name}: [verifier.environment] requires a separate verifier "
'(environment_mode = "separate", or no explicit mode, which it implies)'
)
fields: dict[str, Any] = {"verifier_env": verifier.get("env", {})}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject unsupported verifier user overrides

When a separate Harbor task sets [verifier].user to a user different from the verifier image default, this parser preserves only verifier.env and never applies or rejects the requested user. Harbor’s task schema documents this field for verifier execution, but Docker/Prime will run bash test.sh as the image/default user here, so permission-sensitive graders can pass or fail differently from Harbor; thread the user through runtime execution or fail fast for separate mode when it is set.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants