You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Three bugs fixed in one commit:
1. **macOS path validation** (_path_validation.py)
validate_save_path() was silently accepting /etc/passwd and other
sensitive paths on macOS because os.path.realpath resolves /etc,
/var, /tmp to /private/etc, /private/var, /private/tmp via symlinks.
The blocked-prefix startswith check then missed them.
Fix: on darwin, add /private/-prefixed variants of every Linux
blocked prefix to BLOCKED_PREFIXES.
Tests: 5 previously-failing tests now pass, plus 2 new regression
tests (test_darwin_includes_private_variants,
test_linux_excludes_private_variants) pin the platform semantics.
2. **eject_robot state preservation** (scene_ops.py)
eject_robot_from_scene rebuilt the scene from scratch, silently
resetting surviving robots' joints to qpos=0 and snapping objects
back to their spawn pose. Agents calling remove_robot mid-scene
lost physics state with no warning.
Fix: snapshot per-joint (qpos, qvel) by fully-qualified name BEFORE
rebuild, restore by name AFTER fresh compile. Matches the 'Per-name
state copy, not flat index' rule from AGENTS.md — flat-index copy
is unsafe because body/joint indices shift when a robot is removed.
New helpers: _snapshot_joint_state, _restore_joint_state (both
module-private, name-based, width-checked per joint type).
Tests: 3 new regression tests
(test_surviving_robot_joint_state_is_preserved,
test_surviving_object_freejoint_pose_is_preserved,
test_ejected_robot_state_is_not_restored).
3. **mesh / peer_id explicit init** (simulation.py) — addresses
@sundargthb's approval nit.
mesh and peer_id constructor params were never assigned to self,
making hasattr(self, 'mesh') at L2006 permanently False and
masking the future PR #98 wire-up. Now explicitly initialised as
attributes so the guard becomes a plain truthy check.
Future-compatible: when PR #98 lands and replaces self.mesh with a
real mesh object, the cleanup path will start working without
further changes.
Tests: 1275 pass, 1 skipped, 0 failures (was 1255 pass + 5 fail).
Lint: ruff + mypy clean.
0 commit comments