Repository navigation
fix(harness): a verifier that exits 0 without reward.txt errors the cell #695
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
napetrov
wants to merge
12
commits into
intel:main
Choose a base branch
from
napetrov:fsm687-verifier-no-reward
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+205
−41
Open
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
1fb962d
fix(harness): a verifier that exits 0 without reward.txt errors the cell
napetrov 81c4164
fix(harness): a docker reward.txt with no number in it errors the cell
xaleryb e5f4150
fix(harness): a failed or hung docker cp of reward.txt errors the cell
xaleryb bfdf48b
docs(harness): file the reward.txt rule under Changed and fix the fal…
xaleryb aa35664
Merge branch 'main' into fsm687-verifier-no-reward
xaleryb 62da132
fix(harness): a missing Docker socket is a failed docker cp, not a mi…
napetrov 3c143e6
Address review: four threads already fixed on this branch
napetrov 3841e25
Merge branch 'main' of https://github.com/intel/dokimi into fsm687-pr…
napetrov 23c11d2
fix(harness): podman's missing-file wording is still no reward file
napetrov 87f8d38
Address review: review-level claims already fixed on this branch
napetrov 74e61c6
docs(harness): the reward-file rule covers reward-file verifiers, not…
napetrov 97f70ef
Word the reward.txt error for the 0 to 1 range
antonwolfy File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
8 changes: 8 additions & 0 deletions
8
dokimi/changelog.d/20261113_120500_napetrov_fsm687-verifier.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| <!-- | ||
| Copyright (C) 2026 Intel Corporation | ||
| SPDX-License-Identifier: Apache-2.0 | ||
| --> | ||
|
|
||
| ### Changed | ||
|
|
||
| - **A `docker-*` reward-file verifier must write `reward.txt`: exit 0 alone is no longer a pass** — a Docker task (`task.toml` or `task.md`) whose verifier wrote no `/logs/verifier/reward.txt` used to score 1.0 on exit code 0. The cell is now errored, with no reward, and `run.log` names the missing file. A verifier that exits non-zero without a reward file still scores 0.0. A terminal-bench v1 task keeps its pytest summary as the verdict. A `reward.txt` with no number between 0 and 1 in it (`PASS`, empty, `75`) now errors the cell too, instead of scoring a fail, and so does a `docker cp` of it that fails or times out (the timeout used to score 0.0). Make such a verifier write `1` or `0` to `/logs/verifier/reward.txt`; pass rates of tasks whose verifier only set its exit code are not comparable with earlier runs. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,126 @@ | ||
| # Copyright (C) 2026 Intel Corporation | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| """A docker verifier's exit code is a verdict only with a reward file behind it.""" | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| from pathlib import Path | ||
|
|
||
| import pytest | ||
|
|
||
| from dokimi.harnesses import load_task | ||
|
|
||
|
|
||
| def _harbor(root: Path, name: str = "hb-task") -> Path: | ||
| task = root / name | ||
| for sub in ("environment", "solution", "tests"): | ||
| (task / sub).mkdir(parents=True) | ||
| (task / "solution" / "solve.sh").write_text("#!/bin/bash\n", encoding="utf-8") | ||
| (task / "tests" / "test.sh").write_text("#!/bin/bash\n", encoding="utf-8") | ||
| (task / "instruction.md").write_text("Fix it.", encoding="utf-8") | ||
| (task / "task.toml").write_text( | ||
| '[metadata]\ntags = ["onedal"]\n\n[environment]\nworkdir = "/app"\n', encoding="utf-8" | ||
| ) | ||
| return task | ||
|
|
||
|
|
||
| def test_docker_verify_exit_zero_without_a_reward_file_is_an_error_not_a_pass(tmp_path): | ||
| import io | ||
|
|
||
| from docker_cli_fake import DockerCLI | ||
| from dokimi.harnesses.docker_solver import DockerSolverHarness | ||
|
|
||
| out = tmp_path / "o" | ||
| out.mkdir() | ||
| task = load_task(_harbor(tmp_path)) | ||
| harness = DockerSolverHarness(harness_id="docker-oracle", mode="oracle", | ||
| runner=DockerCLI(reward=None)) | ||
| # The verifier exited 0 but never wrote reward.txt: no verdict, so the cell is errored. | ||
| with pytest.raises(RuntimeError, match="reward.txt"): | ||
| harness._verify(task, "c1", out, log=io.StringIO()) | ||
|
|
||
|
|
||
| def test_docker_verify_nonzero_exit_without_a_reward_file_stays_a_fail(tmp_path): | ||
| import io | ||
|
|
||
| from docker_cli_fake import DockerCLI, reply | ||
| from dokimi.harnesses.docker_solver import DockerSolverHarness | ||
|
|
||
| out = tmp_path / "o" | ||
| out.mkdir() | ||
| task = load_task(_harbor(tmp_path)) | ||
|
|
||
| def failing_verifier(call): | ||
| if "-lc" in call.argv: | ||
| return reply(returncode=1) | ||
| return None | ||
|
|
||
| harness = DockerSolverHarness(harness_id="docker-oracle", mode="oracle", | ||
| runner=DockerCLI(reward=None, answer=failing_verifier)) | ||
| assert harness._verify(task, "c1", out, log=io.StringIO()) == 0.0 | ||
|
|
||
|
|
||
| @pytest.mark.parametrize("exit_code", [0, 1]) | ||
| @pytest.mark.parametrize("text", ["PASS\n", ""]) | ||
| def test_docker_verify_a_reward_file_with_no_number_is_an_error(tmp_path, text, exit_code): | ||
| import io | ||
|
|
||
| from docker_cli_fake import DockerCLI, reply | ||
| from dokimi.harnesses.docker_solver import DockerSolverHarness | ||
|
|
||
| out = tmp_path / "o" | ||
| out.mkdir() | ||
| task = load_task(_harbor(tmp_path)) | ||
| verifier = (lambda call: reply(returncode=exit_code) if "-lc" in call.argv else None) | ||
| harness = DockerSolverHarness(harness_id="docker-oracle", mode="oracle", | ||
| runner=DockerCLI(reward=text, answer=verifier)) | ||
| # A reward file with no reward is no verdict, whatever the exit code (as in a command harness). | ||
| with pytest.raises(RuntimeError, match="reward.txt has no reward"): | ||
| harness._verify(task, "c1", out, log=io.StringIO()) | ||
|
|
||
|
|
||
| _NO_FILE = "Error response from daemon: Could not find the file /logs/verifier/reward.txt in container c1" | ||
|
|
||
|
|
||
| @pytest.mark.parametrize(("stderr", "exit_code", "outcome"), [ | ||
| (_NO_FILE, 1, 0.0), # docker's own "could not find the file": still a verifier that wrote none | ||
| (_NO_FILE, 0, "wrote no /logs/verifier/reward.txt"), | ||
| ("Error response from daemon: connection refused", 0, r"docker cp .* failed \(exit 1\)"), | ||
| ("Error response from daemon: connection refused", 1, r"docker cp .* failed \(exit 1\)"), | ||
| # podman's wording for a missing file (from memory; no podman on this box): still no reward file. | ||
| ('"/logs/verifier/reward.txt" could not be found on container c1: no such file or directory', 1, | ||
| 0.0), | ||
| ('"/logs/verifier/reward.txt" could not be found on container c1: no such file or directory', 0, | ||
| "wrote no /logs/verifier/reward.txt"), | ||
| # A missing Docker socket says "no such file or directory" but names no reward file. | ||
| ("dial unix /var/run/docker.sock: connect: no such file or directory", 1, | ||
| r"docker cp .* failed \(exit 1\)"), | ||
| ("dial unix /var/run/docker.sock: connect: no such file or directory", 0, | ||
| r"docker cp .* failed \(exit 1\)"), | ||
| ]) | ||
| def test_docker_verify_a_failed_reward_copy_is_not_a_missing_reward_file( | ||
| tmp_path, stderr, exit_code, outcome): | ||
| import io | ||
|
|
||
| from docker_cli_fake import DockerCLI, reply | ||
| from dokimi.harnesses.docker_solver import DockerSolverHarness | ||
|
|
||
| out = tmp_path / "o" | ||
| out.mkdir() | ||
| task = load_task(_harbor(tmp_path)) | ||
|
|
||
| def answer(call): | ||
| if "-lc" in call.argv: | ||
| return reply(returncode=exit_code) | ||
| if call.argv[1] == "cp" and call.argv[2].endswith(":/logs/verifier/reward.txt"): | ||
| return reply(stderr=stderr, returncode=1) | ||
| return None | ||
|
|
||
| harness = DockerSolverHarness(harness_id="docker-oracle", mode="oracle", | ||
| runner=DockerCLI(reward="1.0", answer=answer)) | ||
| if isinstance(outcome, float): | ||
| assert harness._verify(task, "c1", out, log=io.StringIO()) == outcome | ||
| else: | ||
| with pytest.raises(RuntimeError, match=outcome): | ||
| harness._verify(task, "c1", out, log=io.StringIO()) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.