V1 runtime/taskset/harness refactor - #1559
Conversation
ApprovabilityVerdict: Needs human review 2 blocking correctness issues found. Diff is too large for automated approval analysis. A human reviewer should evaluate this PR. You can customize Macroscope's approvability policy. Learn more. |
| EnvRun.normalize_model(teacher) if teacher is not None else None | ||
| ) | ||
| self.states = list( | ||
| await asyncio.gather( |
There was a problem hiding this comment.
gather here has no return_exceptions=True. Most rollout errors are absorbed by run_lifecycle (via capture_error) and come back as states, which is great — but a failure raised before that try-block, e.g. the runtime failing to start or a toolset/user failing to enter in run_context, will propagate through this gather and fail the entire group with no partial credit. Is that intended? Two options worth discussing: (a) capture setup/runtime-acquisition failures into the state too, so one bad member can't sink its siblings, or (b) return_exceptions=True here with per-member handling. Also — since this waits for the slowest member before scoring, do we have a straggler policy at training scale, or is max_turns + runtime timeout the only backstop?
There was a problem hiding this comment.
Also: first failing rollout propagates while siblings keep running, then stop_env_scope() tears down servers under live rollouts. Use TaskGroup.
| state.capture_error(exc) | ||
| except Error as exc: | ||
| state.capture_error(exc) | ||
| except BaseException as exc: |
There was a problem hiding this comment.
Catching BaseException turns a failed rollout into recorded data, which I think is the intent. But it also swallows asyncio.CancelledError (and KeyboardInterrupt/SystemExit). On a timeout or shutdown this could prevent cancellation from propagating and leave work running. Should we re-raise CancelledError (catch Exception for the "error becomes data" path, and let cancellation through)? Same question for the except BaseException in interception.py's handler.
| "VF_PROMPT": prompt_text, | ||
| } | ||
|
|
||
| async def run_with_context(self, context: vf.Context) -> None: |
There was a problem hiding this comment.
The command harness wires the agent to the interception endpoint + task env, but not to any MCP tool servers — so external agents use their own built-in tools, and verifiers' @vf.tool(args/sets/extends) binding effectively does nothing on this path. That asymmetry vs the in-process base harness is subtle. Could we either document it loudly, or warn/error if a task declares bound toolsets but runs under a command harness, so an author doesn't think their sets/extends are taking effect?
| return | ||
| max_turns = self.max_turns(task) | ||
| turns = 0 | ||
| while max_turns <= 0 or turns < max_turns: |
There was a problem hiding this comment.
max_turns <= 0 means unlimited (bounded only by timeout). Worth a one-line doc on Task.max_turns / HarnessConfig.max_turns so 0 isn't mistaken for "no turns."
| def has_model_prompt(messages: Messages) -> bool: | ||
| return any(getattr(message, "role", None) != "system" for message in messages) | ||
|
|
||
| def max_turns(self, task: Task) -> int: |
There was a problem hiding this comment.
max_turns <= 0 means unlimited (bounded only by timeout). Worth a one-line doc on Task.max_turns / HarnessConfig.max_turns so 0 isn't mistaken for "no turns."
|
|
||
| def _validate_owner_bindings(self, owner: RuntimeOwnerMixin | None) -> None: | ||
| if owner is None: | ||
| async def stop(self) -> None: |
There was a problem hiding this comment.
Cleanup not cancellation-safe — contextlib.suppress(Exception) around await client.delete(sandbox_id) doesn't survive cancellation → leaked billed Prime sandboxes / orphaned Docker containers exactly when users interrupt. Shield cleanup awaits. Also SubprocessRuntime kills only the direct child (no process groups), and Docker/Prime timeouts abandon the remote command without killing it.
| result = await docker( | ||
| "run", | ||
| "--detach", | ||
| "--network", |
There was a problem hiding this comment.
Docker uses --network host — containers see every host-local service; also makes free_port()'s TOCTOU collisions real across concurrent rollouts.
| server: ServerConfig, name: str, *, in_runtime: bool = False | ||
| ) -> list[str]: | ||
| python = "python" if in_runtime else sys.executable | ||
| payload = { |
There was a problem hiding this comment.
Secrets in argv - full ServerConfig (incl. env/headers, the natural home for API keys) is serialized onto the command line, visible via ps. Pass over stdin.
| @property | ||
| def has_group_signals(self) -> bool: | ||
| return any(signal["stage"] == "group" for signal in self.signals) | ||
|
|
||
| def to_task(self, task: Task | JsonData) -> Task: |
There was a problem hiding this comment.
to_task bypasses task_type — taskset.py:218: the Task-instance path calls prepare_task(task) with default task_type=Task, so a taskset declaring a subclass silently accepts base Tasks. Should be prepare_task(task, self.task_type).
|
|
||
|
|
||
| def parse_anthropic_messages(body: JsonData) -> Messages: | ||
| messages: Messages = [] |
There was a problem hiding this comment.
Anthropic interception bugs — protocols.py:421 drops list-form system prompts (what Claude SDKs emit with cache_control) silently; protocols.py:484–509 reorders text before tool results, producing invalid assistant→user→tool sequences.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* chore: add v1 #1559-vs-#1576 comparison doc Feature parity, branch-unique features, and validation done for the two open v1 refactor PRs (#1559 codex/v1-nano-refactor-draft, #1576 feat/nano-as-v1). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: trim comparison (drop names, some #1559 items, validation section) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: scope the size row to the verifiers/ module diff Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Revert "docs: scope the size row to the verifiers/ module diff" This reverts commit 500bd30. --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* chore: final touches - harness configs no longer pin `id`; the caller supplies it (--harness.id / toml / a taskset's bundled harness), mirroring tasksets. Update the base HarnessConfig docstring and the `init` scaffold to match. - refine the v1 user guide (GUIDE.md, README.md) - register the reverse-text v0 env as an editable dep for the `eval --id reverse-text` legacy-bridge example Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: don't use auto-tracked num_turns as the @vf.metric example trace.num_turns is recorded by the framework; show a custom signal instead. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: move the load_tasks example into the Loading tasks section Keep the config code block focused on the config class. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: show full GSM8KTask construction in the load_tasks example Build typed task instances from the rows instead of stopping at the dataset load. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat: allow @reward to return dict[str, float] A reward can now report a family of named contributions, like @Metric already can; each entry is recorded under its own key and scaled by the function's weight before being summed into trace.reward. This aligns the reward/metric return contracts — the only remaining (and intended) differences are that rewards are summed and carry a weight. Documented in the v1 guide. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: drop the score/score_group override note Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: livelier scoring examples + reframe the notes heading Use an enthusiasm metric and a brevity (length-penalty) group reward instead of stubs, and reword "Notes that bite if missed" to "Good to know". Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: restructure the trace-reading table and reframe in-runtime scoring Group the trace members by area and fix the table: drop the nonexistent trace.messages (use trace.branches[-1].messages), add usage / has_response / id, and note trace.nodes. Reframe in-runtime scoring around when to use the runtime object (host-unsafe/heavy computation, or runtime-only information). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: separate scoring outputs from read inputs; say "host" not "eval process" The trace-reading table now lists only what a reward reads; reward/rewards/ metrics are called out as outputs you shouldn't read mid-scoring. Rename that group to "Carried state" (info/state). Use "host" instead of "eval process". Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: drop validate from the lifecycle-hooks table validate isn't part of the setup -> harness -> finalize -> scoring rollout loop (it's run only by `uv run validate`, documented in the CLI reference). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: give info its own section, contrasted with state Lift the trace.info paragraph into a "Persisted info" section beside "Per-rollout state", with a table contrasting the two per-rollout stores (persisted vs transient). Cross-link both ways. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: note that a Toolset wraps an MCP server @vf.tool methods are served as MCP tools the harness connects to. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: show the self-launching __main__ line in the tool/user examples Each tool/user server is its own self-launching module under servers/. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: merge own-host/own-sandbox into a single "own runtime" placement row Both are the same placement (a per-rollout runtime); subprocess on the host by default, a docker/prime sandbox when runtime.type is set. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: add the missing reference examples general-agent-v1 (per-task dynamic tools), tau2-bench-v1 (tools + user sim + bundled harness), and swebench-verified-v1 (SWE-bench on prebuilt images) were the only *_v1 envs absent from the example table. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: reframe the custom-harness intro and list mini-swe-agent/kimi-code Frame authoring a harness as "when you need rollout logic the built-ins can't express" rather than "you rarely need this", and add the mini-swe-agent and kimi-code built-ins to the table. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: surface the NEEDS_CONTAINER taskset capability flag Mention it in the taskset authoring intro alongside the generic params. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor: rename harness capability flag SUPPORTS_TASK_TOOLS -> SUPPORTS_MCP Rename the flag on the base Harness and every harness that sets it (built-ins + tau2/compact env harnesses), the Environment check, and align the user-facing error message and the README/GUIDE docs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: harness example configures via CLI args, drops max_steps Pass endpoint/secret/model as CLI args (as the built-in default harness does) instead of OPENAI_* env vars, which have footguns; note why. Drop the max_steps knob (turn limits are framework-enforced, not a harness concern) and the id pin (harness configs don't pin id), leaving a placeholder config. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: split the harness "Writing one" section into subsections Break the wall of bold-lead paragraphs into ### subsections (contract, launch, resolve_prompt, program styles, harness metrics), matching the taskset docs' ##/### structure. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: correct the tau2-bench-v1 example description tau2's taskset defines no vf.User/vf.Toolset; it bundles its own harness that runs the whole tau2 simulation in a subprocess and stores the result in trace.info. It's the bundled-harness example, not a tools+user-sim one. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore: drop internal bench/ scripts and COMPARE.md from v1 These are work-in-progress benchmarking scripts and a transient #1559-vs-#1576 comparison doc — not part of the public v1 surface. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * ci: restore taskset/harness PyPI publish workflows; bump to 0.2.0 Bring back publish-tasksets.yml / publish-harnesses.yml (dropped on the v1 branch). v1 versions packages statically in pyproject.toml rather than via __init__.py __version__, so the version-detection reads [project].version from pyproject. Bump both packages 0.1.0 -> 0.2.0: the v1 branch had reset them to 0.1.0, below what's already on PyPI (tasksets 0.1.5, harnesses 0.1.2), so a progression is required to publish. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: drop the experimental flag from the renderer client The renderer client is no longer marked experimental; keep the substantive caveat (per-model renderers cover a subset of models). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore: drop stale v1-runtime dependency comment Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore: tidy verifiers pyproject - drop the v0 reverse-text entry from the examples group - drop stale comments in [dependency-groups]/[tool.uv.sources] - drop the redundant [tool.ruff] line-length = 88 (88 is ruff's default) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * ci: exclude v1 envs from the auto env-publish for now publish-envs.yml matrixes over environments/*; skip the *_v1 packages and the compact harness example — the v1 envs aren't ready for the Environments Hub yet. Classic v0 envs still publish. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * ci: fix version-mismatch message to reference pyproject, not __init__.py The version is read from [project].version in pyproject.toml; the mismatch error still pointed at the old __init__.py source. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ison doc (PrimeIntellect-ai#1619) * chore: add v1 PrimeIntellect-ai#1559-vs-PrimeIntellect-ai#1576 comparison doc Feature parity, branch-unique features, and validation done for the two open v1 refactor PRs (PrimeIntellect-ai#1559 codex/v1-nano-refactor-draft, PrimeIntellect-ai#1576 feat/nano-as-v1). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: trim comparison (drop names, some PrimeIntellect-ai#1559 items, validation section) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: scope the size row to the verifiers/ module diff Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Revert "docs: scope the size row to the verifiers/ module diff" This reverts commit 500bd30. --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* chore: final touches - harness configs no longer pin `id`; the caller supplies it (--harness.id / toml / a taskset's bundled harness), mirroring tasksets. Update the base HarnessConfig docstring and the `init` scaffold to match. - refine the v1 user guide (GUIDE.md, README.md) - register the reverse-text v0 env as an editable dep for the `eval --id reverse-text` legacy-bridge example Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: don't use auto-tracked num_turns as the @vf.metric example trace.num_turns is recorded by the framework; show a custom signal instead. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: move the load_tasks example into the Loading tasks section Keep the config code block focused on the config class. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: show full GSM8KTask construction in the load_tasks example Build typed task instances from the rows instead of stopping at the dataset load. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat: allow @reward to return dict[str, float] A reward can now report a family of named contributions, like @Metric already can; each entry is recorded under its own key and scaled by the function's weight before being summed into trace.reward. This aligns the reward/metric return contracts — the only remaining (and intended) differences are that rewards are summed and carry a weight. Documented in the v1 guide. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: drop the score/score_group override note Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: livelier scoring examples + reframe the notes heading Use an enthusiasm metric and a brevity (length-penalty) group reward instead of stubs, and reword "Notes that bite if missed" to "Good to know". Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: restructure the trace-reading table and reframe in-runtime scoring Group the trace members by area and fix the table: drop the nonexistent trace.messages (use trace.branches[-1].messages), add usage / has_response / id, and note trace.nodes. Reframe in-runtime scoring around when to use the runtime object (host-unsafe/heavy computation, or runtime-only information). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: separate scoring outputs from read inputs; say "host" not "eval process" The trace-reading table now lists only what a reward reads; reward/rewards/ metrics are called out as outputs you shouldn't read mid-scoring. Rename that group to "Carried state" (info/state). Use "host" instead of "eval process". Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: drop validate from the lifecycle-hooks table validate isn't part of the setup -> harness -> finalize -> scoring rollout loop (it's run only by `uv run validate`, documented in the CLI reference). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: give info its own section, contrasted with state Lift the trace.info paragraph into a "Persisted info" section beside "Per-rollout state", with a table contrasting the two per-rollout stores (persisted vs transient). Cross-link both ways. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: note that a Toolset wraps an MCP server @vf.tool methods are served as MCP tools the harness connects to. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: show the self-launching __main__ line in the tool/user examples Each tool/user server is its own self-launching module under servers/. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: merge own-host/own-sandbox into a single "own runtime" placement row Both are the same placement (a per-rollout runtime); subprocess on the host by default, a docker/prime sandbox when runtime.type is set. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: add the missing reference examples general-agent-v1 (per-task dynamic tools), tau2-bench-v1 (tools + user sim + bundled harness), and swebench-verified-v1 (SWE-bench on prebuilt images) were the only *_v1 envs absent from the example table. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: reframe the custom-harness intro and list mini-swe-agent/kimi-code Frame authoring a harness as "when you need rollout logic the built-ins can't express" rather than "you rarely need this", and add the mini-swe-agent and kimi-code built-ins to the table. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: surface the NEEDS_CONTAINER taskset capability flag Mention it in the taskset authoring intro alongside the generic params. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor: rename harness capability flag SUPPORTS_TASK_TOOLS -> SUPPORTS_MCP Rename the flag on the base Harness and every harness that sets it (built-ins + tau2/compact env harnesses), the Environment check, and align the user-facing error message and the README/GUIDE docs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: harness example configures via CLI args, drops max_steps Pass endpoint/secret/model as CLI args (as the built-in default harness does) instead of OPENAI_* env vars, which have footguns; note why. Drop the max_steps knob (turn limits are framework-enforced, not a harness concern) and the id pin (harness configs don't pin id), leaving a placeholder config. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: split the harness "Writing one" section into subsections Break the wall of bold-lead paragraphs into ### subsections (contract, launch, resolve_prompt, program styles, harness metrics), matching the taskset docs' ##/### structure. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: correct the tau2-bench-v1 example description tau2's taskset defines no vf.User/vf.Toolset; it bundles its own harness that runs the whole tau2 simulation in a subprocess and stores the result in trace.info. It's the bundled-harness example, not a tools+user-sim one. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore: drop internal bench/ scripts and COMPARE.md from v1 These are work-in-progress benchmarking scripts and a transient PrimeIntellect-ai#1559-vs-PrimeIntellect-ai#1576 comparison doc — not part of the public v1 surface. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * ci: restore taskset/harness PyPI publish workflows; bump to 0.2.0 Bring back publish-tasksets.yml / publish-harnesses.yml (dropped on the v1 branch). v1 versions packages statically in pyproject.toml rather than via __init__.py __version__, so the version-detection reads [project].version from pyproject. Bump both packages 0.1.0 -> 0.2.0: the v1 branch had reset them to 0.1.0, below what's already on PyPI (tasksets 0.1.5, harnesses 0.1.2), so a progression is required to publish. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: drop the experimental flag from the renderer client The renderer client is no longer marked experimental; keep the substantive caveat (per-model renderers cover a subset of models). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore: drop stale v1-runtime dependency comment Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore: tidy verifiers pyproject - drop the v0 reverse-text entry from the examples group - drop stale comments in [dependency-groups]/[tool.uv.sources] - drop the redundant [tool.ruff] line-length = 88 (88 is ruff's default) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * ci: exclude v1 envs from the auto env-publish for now publish-envs.yml matrixes over environments/*; skip the *_v1 packages and the compact harness example — the v1 envs aren't ready for the Environments Hub yet. Classic v0 envs still publish. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * ci: fix version-mismatch message to reference pyproject, not __init__.py The version is read from [project].version in pyproject.toml; the mismatch error still pointed at the old __init__.py source. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary
This PR rewrites the v1 runtime/taskset/harness boundary around a strict, transcript-native contract while keeping v0 separate.
EnvRun, rolloutContext, and group lifecycle ownership for v1, including env-scope reuse, explicit close/cleanup, and group scoring.ToolsetandUserMCP-backed authoring surfaces with hidden bound args plussets/extendsupdates forstateandextras.Final Validation
GitHub CI is green on head
5d1ef09e1.Ruff: passTy: passSemgrep: passCodeQL/ analyzers: passCursor Bugbot: passMacroscope - Correctness Check: passVerifiers (3.10),(3.11),(3.12),(3.13): passEnvironments: passMacroscope - Approvability Check: skipped by the appLocal validation:
env PYTHONDONTWRITEBYTECODE=1 uv run pytest tests/test_v1_core.py -m 'not prime_sandbox' -qenv PYTHONDONTWRITEBYTECODE=1 uv run pytest tests/test_v1_core.py::test_env_user_startup_failure_closes_started_env_toolsets tests/test_v1_core.py::test_env_scope_startup_failure_closes_entered_env_user tests/test_v1_core.py::test_nemo_gym_task_row_preserves_explicit_task_fields -qenv PYTHONDONTWRITEBYTECODE=1 CHANGED_ENVS='wiki_search_v1,bfcl_v3_v1' uv run pytest tests/test_envs.py -vv -k 'wiki_search_v1 or bfcl_v3_v1'env PYTHONDONTWRITEBYTECODE=1 uv run pytest tests/test_wiki_search_v1.py -qenv PYTHONDONTWRITEBYTECODE=1 uv run --python 3.10 pytest tests/test_v1_core.py::test_v1_prime_runtime_run_honors_timeout -qenv PYTHONDONTWRITEBYTECODE=1 uv run --python 3.13 ty check verifiers/v1 packages/tasksets/tasksets packages/harnesses/harnessesenv PYTHONDONTWRITEBYTECODE=1 uv run --no-dev --group policy semgrep --metrics=off --disable-version-check --config .semgrep/verifiers.yml --error --quietenv PYTHONDONTWRITEBYTECODE=1 uv run python scripts/sync.py --checkgit diff --checkLive
prime evalsmoke matrix, default settings unless the package default had fewer eval examples. Commands were run withPYTHONPATHpinned to this worktree soprime evalloaded this PR branch:reverse-text-v1: 5 examples x 3 rollouts, average reward 0.948.alphabet-sort-v1: 5 examples x 3 rollouts, average reward 0.801.mcp-search-env-v1: 5 examples x 3 rollouts, average reward 1.000.math-python-v1: 5 examples x 3 rollouts, average reward 1.000.hello-group-reward-v1: 5 examples x 3 rollouts, average reward 0.645.sft-replay-v1: 1 example x 3 rollouts, structural replay completed with stopreplayed_messages.openenv-echo-v1: 5 examples x 3 rollouts, average reward 1.800; verified OpenEnv sandbox cleanup after run.openenv-textarena-v1: 5 examples x 3 rollouts, average reward 0.500; verified OpenEnv sandbox cleanup after run.tau2-bench-v1: 5 examples x 3 rollouts, average reward 0.533,tau2_num_errorsaverage 0; no Tau2 environment/tool errors.Review State