From db6191f1e36d884f7005ff163851c27a6fda07e9 Mon Sep 17 00:00:00 2001 From: Sandy Chapman Date: Mon, 10 Aug 2026 12:39:32 -0300 Subject: [PATCH 1/3] feat(evaluator): pre-flight Gym config with `gym env validate` and take overrides as a dict MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three changes to the Gym runner, all about making its preconditions checkable before a run commits to anything. **Validate before starting.** `_run_two_step` now runs `gym env validate` with the identical selection arguments it is about to pass to `gym env start`, and fails with Gym's own report if the config is rejected. Gym does not publish what configuration an environment requires — the typed `*ResourcesServerConfig` classes cover behavioural knobs, while model wiring lives in each environment's YAML under names that vary per environment — so validate is the only way to find out short of running. It merges configs, flags, and overrides and reports unset `???` values, bad paths, and dangling cross-references without Ray and without starting a server, in about a second. The alternative is what we had: a config mistake surfaces after a Ray cluster and several uvicorn servers are up, as a readiness timeout of up to `startup_timeout_s` (240s) whose message says nothing about the cause. Sweeping five environments found two real problems this way in under a minute, one of them in this runner: `gdpval` registers its resources-server as `gdpval_resources_server`, not `gdpval`, so `bind_resources_server`'s assumption that the two names match does not hold for it. **`env_overrides` becomes a nested dict.** It was `list[str]` of pre-serialized Hydra arguments. These runner configs become serialized job specs when Gym runs as a governed platform job, and `"+a.b.c=${d}"` is a string that only means something to Hydra, whereas `{"a": {"b": {"c": "${d}"}}}` is JSON. Flattening to Hydra's grammar now happens at invocation. Leaf rendering is explicit about `None` -> `null` and booleans -> `true`/`false`, which naive `str()` would have written as the literal strings `"None"` and `"True"`; interpolations pass through untouched. Redaction moved with it and now matches on the full dotted path, so nesting cannot hide a credential behind an innocuous leaf name. **Hydra run directories are redirected.** Gym is a Hydra app and writes a timestamped run directory per invocation, defaulting to `outputs//