Problem
When running an evaluation with --hardened (strict defense profile), the target container attaches to the cybergym-internal network (172.18.0.0/16) rather than the default Docker bridge. The controller, however, is bound to the default bridge gateway (172.17.0.1) via controller_url in the generated config. This makes the controller unreachable from inside hardened-profile containers specifically, not the default profile.
Reproduction
A hardened-profile run's config.json shows controller_url: "http://172.17.0.1:8666", but the container's only route is to 172.18.0.0/16. The agent's attempt to reach 172.17.0.1:8666 fails with "network unreachable," and 172.18.0.1:8666 (the correct internal gateway) is refused, since the controller isn't listening there. The evaluation still exits cleanly (it doesn't crash), so this can look like a normal completed run unless you check what the agent actually said about why it stopped.
Fix
This PR updates pre_run.py to bind the controller to the internal network gateway (172.18.0.1) that hardened-profile containers actually have a route to, while leaving the firewall/proxy setup unchanged.
Testing
uv run python -m py_compile scripts/setup/pre_run.py passes
A disposable container on cybergym-internal successfully reached http://172.18.0.1:8666/ (received a 404, confirming TCP-level connectivity to the controller rather than a network failure)
Re-ran a full hardened-profile evaluation afterward and confirmed the agent could reach the controller for the full run duration
Problem
When running an evaluation with --hardened (strict defense profile), the target container attaches to the cybergym-internal network (172.18.0.0/16) rather than the default Docker bridge. The controller, however, is bound to the default bridge gateway (172.17.0.1) via controller_url in the generated config. This makes the controller unreachable from inside hardened-profile containers specifically, not the default profile.
Reproduction
A hardened-profile run's config.json shows controller_url: "http://172.17.0.1:8666", but the container's only route is to 172.18.0.0/16. The agent's attempt to reach 172.17.0.1:8666 fails with "network unreachable," and 172.18.0.1:8666 (the correct internal gateway) is refused, since the controller isn't listening there. The evaluation still exits cleanly (it doesn't crash), so this can look like a normal completed run unless you check what the agent actually said about why it stopped.
Fix
This PR updates pre_run.py to bind the controller to the internal network gateway (172.18.0.1) that hardened-profile containers actually have a route to, while leaving the firewall/proxy setup unchanged.
Testing
uv run python -m py_compile scripts/setup/pre_run.pypassesA disposable container on cybergym-internal successfully reached http://172.18.0.1:8666/ (received a 404, confirming TCP-level connectivity to the controller rather than a network failure)
Re-ran a full hardened-profile evaluation afterward and confirmed the agent could reach the controller for the full run duration