Skip to content

fix(tasks): honor reset(states=) contract in eight Tier-1 task overrides - #809

Merged
geng-haoran merged 1 commit into
mainfrom
fix/task-reset-states-contract
Sep 3, 2026
Merged

fix(tasks): honor reset(states=) contract in eight Tier-1 task overrides#809
geng-haoran merged 1 commit into
mainfrom
fix/task-reset-states-contract

Conversation

@geng-haoran

Copy link
Copy Markdown
Collaborator

BaseTaskEnv.reset(states=None, env_ids=None, seed=None) is the contract every task must be
substitutable for, but eight Tier-1 overrides dropped states: the two legged-robot bases
(humanoid, beyondmimic) reimplemented reset without it, and the six SimplerEnv tasks took
options in its place.

The IL and VLA evaluation runners pass states unconditionally — default_runner calls
env.reset(states=init_states[...]) to replay a demo's initial states, and the OpenVLA, SmolVLA
and pi0 eval loops do the same. Because --task is a free-form string, nothing stopped a user
from pairing a VLA with a SimplerEnv task — the canonical pairing for that benchmark — and doing
so died immediately with TypeError: reset() got an unexpected keyword argument 'states'. The
same TypeError hit any IL evaluation on the humanoid or beyondmimic bases.

All eight now accept states/env_ids/seed in the base's order. The legged-robot bases apply
caller-supplied states in place of their scripted initial states. The SimplerEnv tasks keep
options — it carries the episode spec (object/robot init options, episode id) that the gym
adapter feeds them, so dropping it would have silently discarded per-episode setup — but it
moves after the contract's three parameters and keeps its default. External states are applied
on top of the scripted layout, and the settle-derived quantities the success checkers key off
(object height, object poses, bbox extents) are re-derived from the applied states rather than
left describing a layout that was overwritten.

The guardrail that should have caught this (tests/test_task_reset_seed_contract.py) only looked
for a seed parameter, so all eight sailed through it — that is why they rotted. It now checks
full substitutability: every contract parameter is accepted, positional order matches the base
(a swapped positional binds the wrong value, which corrupts rather than raises), and an override
may not add a required parameter of its own. Extra parameters like SimplerEnv's options remain
allowed after the contract's three, with defaults. The ratchet is zero-tolerance, so this class
of drift cannot recur.

Review: independently reviewed against current main (verdict MERGE AS-IS); rebased, re-verified: 14 passed in 6.72s

🤖 Generated with Claude Code

https://claude.ai/code/session_017i6VtKoovBNed815mWFqxw

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Sep 3, 2026

Copy link
Copy Markdown

Deploying roboverse-release with  Cloudflare Pages  Cloudflare Pages

Latest commit: 09720eb
Status:⚡️  Build in progress...

View logs

BaseTaskEnv.reset(states=None, env_ids=None, seed=None) is the contract every task must be
substitutable for, but eight Tier-1 overrides dropped `states`: the two legged-robot bases
(humanoid, beyondmimic) reimplemented reset without it, and the six SimplerEnv tasks took
`options` in its place.

The IL and VLA evaluation runners pass `states` unconditionally — default_runner calls
env.reset(states=init_states[...]) to replay a demo's initial states, and the OpenVLA, SmolVLA
and pi0 eval loops do the same. Because `--task` is a free-form string, nothing stopped a user
from pairing a VLA with a SimplerEnv task — the canonical pairing for that benchmark — and doing
so died immediately with `TypeError: reset() got an unexpected keyword argument 'states'`. The
same TypeError hit any IL evaluation on the humanoid or beyondmimic bases.

All eight now accept states/env_ids/seed in the base's order. The legged-robot bases apply
caller-supplied states in place of their scripted initial states. The SimplerEnv tasks keep
`options` — it carries the episode spec (object/robot init options, episode id) that the gym
adapter feeds them, so dropping it would have silently discarded per-episode setup — but it
moves after the contract's three parameters and keeps its default. External states are applied
on top of the scripted layout, and the settle-derived quantities the success checkers key off
(object height, object poses, bbox extents) are re-derived from the applied states rather than
left describing a layout that was overwritten.

The guardrail that should have caught this (tests/test_task_reset_seed_contract.py) only looked
for a `seed` parameter, so all eight sailed through it — that is why they rotted. It now checks
full substitutability: every contract parameter is accepted, positional order matches the base
(a swapped positional binds the wrong value, which corrupts rather than raises), and an override
may not add a required parameter of its own. Extra parameters like SimplerEnv's `options` remain
allowed after the contract's three, with defaults. The ratchet is zero-tolerance, so this class
of drift cannot recur.
@geng-haoran
geng-haoran force-pushed the fix/task-reset-states-contract branch from 7ee6127 to 09720eb Compare September 3, 2026 19:23
@geng-haoran
geng-haoran merged commit 55a5f87 into main Sep 3, 2026
5 of 7 checks passed
@geng-haoran
geng-haoran deleted the fix/task-reset-states-contract branch September 3, 2026 19:23
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.

1 participant