Repository navigation
Conversation
The exit-code fallback scored such a verifier 1.0. A missing reward file is now no verdict: the cell is errored. Non-zero exit without a reward file stays 0.0. Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues remain for the change preventing Docker verifiers from passing without a reward file.
No open issues 🎉
What changed in this PR
0 new findings; nothing to fix.
This PR addresses the false-pass defect in #687: Docker verifiers that exit successfully without writing reward.txt now error the cell instead of receiving a passing score.
Changes:
- Add a missing-reward verdict helper that raises on exit code 0 and preserves a 0.0 score for non-zero exits.
- Add regression tests and update existing Docker fixtures to supply reward files.
- Document the behavior change and lower the Docker solver’s growth baseline.
| File | Description |
|---|---|
dokimi/tests/test_docker_verify_reward.py |
Tests missing-reward behavior for zero and non-zero exits. |
dokimi/tests/test_docker_task_md.py |
Updates fixtures to provide the fake verifier’s reward file. |
dokimi/scripts/growth_baseline.json |
Lowers the Docker solver baseline to 896 lines. |
dokimi/dokimi/harnesses/docker_solver.py |
Uses the new helper when no reward is available. |
dokimi/dokimi/harnesses/command.py |
Adds explicit missing-reward exit-code handling. |
dokimi/changelog.d/20261113_120500_napetrov_fsm687-verifier.md |
Documents the corrected verifier behavior. |
Review effort: Balanced
|
✅ OpenCodeReview: Review complete: 0 finding(s) across 4 selected item(s). CI at Review details
|
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #695 +/- ##
==========================================
+ Coverage 95.71% 95.73% +0.01%
==========================================
Files 415 415
Lines 55346 55376 +30
Branches 9514 9519 +5
==========================================
+ Hits 52977 53012 +35
+ Misses 1466 1463 -3
+ Partials 903 901 -2
🚀 New features to boost your workflow:
|
vlad-perevezentsev
left a comment
There was a problem hiding this comment.
Review at 1fb962d. The fix is right for the case it targets: a Docker verifier that exits 0 without reward.txt now errors the cell and leaves pass_rate, and a non-zero exit still scores 0. A reward file with no number in it is still scored as a fail, and two docs still describe the old fallback; details are in the line comments.
What I ran, at 1fb962d:
make ci-local --offline: 0 failed, 21 passed, 19 skipped (network-only jobs); the test suite: 18,933 passed, 72 skipped.- The CI smoke (
docker-oracleanddocker-probeononetbb-histogram-local-aggregation, real Docker): 1/1 pass each, the reward read fromreward.txt. - Real Docker,
docker-oracleon two copies of that task:test.shthat only exits 0 gives an errored cell (RuntimeError: verifier exited 0 but wrote no /logs/verifier/reward.txt, docker's "Could not find the file" in run.log);test.shthat writesPASSgives reward None with no error, counted asscored: 1, pass_rate: 0.0. - Through
run()with the fake docker: exit 0 with no file is errored in oracle mode (raised to the runner's_error_result); exits 1, 127 and 137 with no file score 0.0.
Checked, no issues
- Error path: in oracle mode without a sandbox
run()re-raises and the runner recordsmetrics.error; with a sandbox or an agent,run()records it itself. Both rows are errored and leave the pass_rate denominator. - Non-zero exits: keeping 0.0 for 126/127/137 is right here, unlike the command harness:
test.shoften ends with the solution's own binary, so a crash or a missing build is the solution's fail. - Tests: the exit-0 test fails on the base (
_verifyreturned 1.0); the_capture/_host_clichanges only let the fake write itsreward.txt, so the existing tests still verify through a reward file. - Growth gate:
_exit_code_verdictlives incommand.pyand the tests in a new file becausedocker_solver.pyandtest_task_formats.pyare at their baselines.
vchamarthi
left a comment
There was a problem hiding this comment.
Reviewed head 1fb962d. Nothing new to fix; 4 threads from vlad-perevezentsev are still open. 0 new findings. The exit-0 path errors the cell and non-zero exits still score 0.0, as the changed tests pin. Four open threads from vlad-perevezentsev still stand, so the PR is not ready to approve.
Verified
- Exit 0 without reward: A
docker-*verifier that exits 0 with no/logs/verifier/reward.txtraisesRuntimeErrornamingreward.txtfrom_verify, and the changed test asserts that raise. - Exit 0 without reward on main: On main the same exit-0 verifier with no reward file does not raise, so the changed test fails there with
DID NOT RAISE. - Non-zero exit without reward: Exit codes 1, 126, 127 and 137 with no reward file score 0.0 on the head, and 0.0 on main.
- Run.log message: The missing-reward error writes
/logs/verifier/reward.txtinto the run log, as the changelog fragment says; main does not raise there. - Exit-0 test pins the verdict: Reverting the verdict in
docker_solver.pyto1.0 if exit 0makes the exit-0 test intest_docker_verify_reward.pyfail. - Existing task verify tests: All 68 changed tests pass on the head, including the
test_docker_task_md.pyfixtures whosedocker cpnow falls through to a reward file. - Full test run: With main merged in, the full test run has no failure that main lacks, and the file-length step passes with
docker_solver.pyat 896 lines. - Merge: The PR merges onto the current main with no conflict.
Open threads from other reviewers:
- still holds on this head: #695 (comment): A
reward.txtcontainingPASSmakes_verifyreturn None on the head, sorun()records no reward and no error, and main does the same. - still holds on this head: #695 (comment):
docs/contributing-terminal-bench-task.mdstill says a missingreward.txtfalls back to the exit code, anddocs/coding-harnesses.mdsays adocker-*cell does too, while the head errors such a cell on exit 0. - still holds on this head: #695 (comment): The fragment files the change under
### Fixed, butdokimi/changelog.d/README.mdputs anything that moves scores for the same inputs underChanged. - still holds on this head: #695 (comment): A
docker cpthat exits 1 after the verifier wrotereward.txtraisesverifier exited 0 but wrote no /logs/verifier/reward.txt, and adocker cptimeout raisesTimeoutExpired, whichrun()records as reward 0.0.
|
PASS or an empty file parsed to reward None with no error, so the summary scored the cell as a fail. It is no verdict, as in a command harness's reward file (command.py _exit_code_reward): the cell is errored whatever the exit code. Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
A cp that failed for a daemon error was reported as 'wrote no reward.txt' (or scored 0.0 on a non-zero exit), and a cp timeout raised TimeoutExpired, which run() scores 0.0. Both lost the verdict: they now error the cell with their own message, the cp exit code in it. Only docker's own no-such-file stays no reward. Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
…lback docs A docker-* verifier's exit code alone is no longer a pass, which moves scores for the same tasks: the fragment moves to Changed and says what a task author does. The task contract, the artifact docs and the self-test reference stop describing the exit-code fallback for docker-* cells. Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
|
Pushed 4 commits (
On the merged tree: full suite (19942 passed), ruff, mypy, bandit, check_growth, |
xaleryb
left a comment
There was a problem hiding this comment.
Re-checked at aa35664 (our three fixes for the four review threads plus a merge of main): a reward.txt with no number and a failed or timed-out docker cp error the cell, a dead container still reports 'not running at verify time', the fragment is under Changed and the docs describe the docker-* rule; the full suite (19942 passed), ruff, mypy, bandit, check_growth and the docs gate pass, a real docker-oracle run matches, and CI is green.
antonwolfy
left a comment
There was a problem hiding this comment.
Review at aa35664. The exit-0, no-number and cp-failure rules hold, and the earlier threads are fixed. One point to fix before merge: the missing-file pattern for docker cp is too broad.
What I ran, on a Linux review host at aa35664:
make ci-local --with-docker: 0 failed, 37 passed, 14 skipped; 19,961 tests passed, 19 skipped; changed-line coverage met- A reproduction of the inline finding, with the Docker CLI faked: socket stderr with verifier exit 1 returns 0.0, with exit 0 raises the wrong message.
- Mutants of the new branches (cp timeout, copy failure,
_check_reward_copycall,runninginspect, each regex alternative): the reward-file tests kill them all except theno such filealternative. The cp timeout and the dead-container branch are pinned bytest_cleanup_timeouts.pyandtest_container_agent.py.
Checked, no issues
- Commits: all four non-merge commits carry a
Signed-off-by. - Docs:
coding-harnesses.md, the task contract, the self-test reference and theChangedfragment match_verify; no other doc still describes the exit-code fallback fordocker-*cells (the remaining mentions are about thecommandharness). - Verdicts: exit 0 without a file errors, a non-zero exit scores 0.0,
PASSor an empty file errors for both exit codes, and a cp timeout errors.
…ssing reward The third alternative of the docker cp no-file pattern was a bare "no such file", which matches a missing Docker socket. A failed cp was then read as "verifier wrote no reward.txt", scoring a verifier that exited 1 as 0.0 and blaming a verifier that exited 0. Keep Docker's own no-file wordings only. Thread: PRRT_kwDOVBg7g863cHuu Thread: PRRT_kwDOVBg7g863finG Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…695-work Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
The regex lost its bare "no such file" alternative in the previous commit, which the comment above it says covered podman. Match podman's own "could not be found on container" wording instead, so a missing file still scores 0.0 or the no-reward error, and a socket error stays a failed cp. The wording is from memory: podman is not installed here. Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
Thread: PRR_kwDOVBg7g88AAAABXxKgQw: already fixed in 3c143e6 Thread: PRR_kwDOVBg7g88AAAABX67UcQ: already fixed in 3c143e6 Thread: PRR_kwDOVBg7g88AAAABX_tPZg: already fixed in 62da132 Thread: IC_kwDOVBg7g88AAAABmaYJNA: already fixed in 3c143e6 Thread: IC_kwDOVBg7g88AAAABmcuxrQ: already fixed in 3c143e6 Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
|
Re: review by vlad-perevezentsev
|
|
|
|
Re: vchamarthi's "not approving yet": the four vlad-perevezentsev threads are checked on head, and each is answered in its thread. |
… terminal-bench v1 A terminal-bench v1 task (task.yaml) is graded by its pytest summary before the reward file is read, so exit 0 without reward.txt is not an error there. The coding-harnesses doc, the task contract and the changelog said it for every docker-* verifier. Thread: PRRT_kwDOVBg7g863iPHE Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
antonwolfy
left a comment
There was a problem hiding this comment.
LGTM. The socket-error point from my earlier review is fixed: a missing Docker socket is now a failed docker cp, for either verifier exit code, and the two socket cases are pinned in the parametrization. The terminal-bench v1 carve-out in the docs now matches _verify. One nit inline.
What I ran, on a Linux review host at 74e61c6:
make ci-local --with-docker: 0 failed, 38 passed, 14 skipped; 20,447 tests passed, 19 skipped; changed-line coverage 100% (19 lines)._reward_file_verdicton75,1.5,100%,1,0.75, with no model or network involved.
Checked, no issues
- Commits: all nine non-merge commits carry a
Signed-off-by. - Socket pattern:
_CP_NO_FILE_REno longer has the bareno such filealternative. The socket, daemon andNo such container: c1stderr all raisedocker cp ... failed (exit 1); Docker's and podman's missing-file wordings still reach the exit-code verdict. - Docs:
coding-harnesses.md, the task contract, the self-test reference and theChangedfragment agree with_verify: exit 0 without a file errors, a non-zero exit scores 0.0, and a terminal-bench v1 task keeps its pytest summary. - Growth gate:
docker_solver.pyis under its baseline andtests/test_growth_ratchet.pypasses.
Signed-off-by: Anton Volkov <antonwolfy@gmail.com>
antonwolfy
left a comment
There was a problem hiding this comment.
LGTM. I pushed a commit per nit, up to 97f70ef, which fix the nit from my review:
97f70ef:dokimi/dokimi/harnesses/command.py:464: the error now readshas no reward between 0 and 1 in it, and the changelog fragment and both docs sayno number between 0 and 1 in it (PASS, empty, 75).
make ci-local at 97f70ef: 35 passed, 3 failed (host), 14 skipped.
Part of #687 (verifier no-reward, High).
Summary
_exit_code_verdictlives inharnesses/command.py, sodocker_solver.pyshrinks from 897 to 896 lines;scripts/growth_baseline.jsonis lowered to match (no baseline bump).Evidence
test_docker_verify_exit_zero_without_a_reward_file_is_an_error_not_a_passfails on intel/main: a verifier that exits 0 and writes no reward is scored as a pass.tests/test_docker_verify_reward.pypass (exit 0 without reward -> error,non-zero exit without reward -> still a fail).tests/test_docker_task_md.pyfixtures now answer thedocker cpcalls the verifier makes, since they relied on exit 0 = pass.make ci-local: growth ratchet and all other steps pass; the only failure istests/test_process.py::test_sighup_kills_the_live_groups_too, a 30 s timeout under box load. It passes alone (1 passed).Merge Danger
Door: two-way
Behaviour change: a task whose verifier exits 0 without writing a reward now errors the cell instead of scoring it as a pass. Tasks that relied on that silent pass will show as errors until their verifier writes
reward.txt.Blast Radius: medium
Affects every docker-solver task run. Expect a rise in error cells on any task whose verifier does not write a reward file; the fix is the verifier, not this check.