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
**Status:** Shipped; unit-verified end-to-end. Empirical "abort in <2s on unreachable URL" check still recommended on first user-driven run.
5
+
**Status:** Shipped + follow-up fold for peer.yml fallback. The G4 Roy-0 re-run on 2026-05-11 surfaced that the original probe was a no-op for the standard peer-with-peer.yml setup (env vars are exported by `apply_peer_config_to_env` only at lane resolution, which happens AFTER `_preflight_llm`); the follow-up reads `~/.config/maxim/peer.yml` directly when env vars are absent.
6
6
**Companion:**[G4 — substrate-primary cluster_id reward wire](15_g4_cluster_reward_wire.md) (the substrate-primary closure that motivated splitting these as paired PRs).
7
7
8
8
## What was caught
@@ -31,6 +31,20 @@ Test seam: production path (no fake `sim_runner`) defaults to `_preflight_llm`.
31
31
| Pre-existing flake |`test_context_index.py::test_similar_text_found` (unrelated; documented as load-order-dependent) |
32
32
| Failure window | Probe budget ≤ ~3.3s on standard health_check timeouts (first 0.8s + retry 2.5s) |
33
33
34
+
## Follow-up fold: peer.yml fallback (post-Roy-0)
35
+
36
+
The 2026-05-11 Roy-0 re-run (G4 empirical validation) revealed that the original probe was silently skipping under the canonical peer-leader setup. `apply_peer_config_to_env` in [runtime/lane_backends.py:1073](../../src/maxim/runtime/lane_backends.py) reads `~/.config/maxim/peer.yml` and exports `MAXIM_LANE_LARGE_REMOTE_*` env vars — but only at lane resolution, which fires AFTER `_preflight_llm`. Operator who runs `maxim roy run` with no env vars exported but a valid `peer.yml` got `result.preflight = {"skipped": True, "reason": "MAXIM_LANE_LARGE_REMOTE_URL not set"}`, leaving the broken-leader failure mode uncaught.
37
+
38
+
The fix: `_preflight_llm` now reads `peer.yml` directly when env vars are absent, falling back to that config source before deciding to skip. Resolution order:
39
+
40
+
1.`MAXIM_LANE_LARGE_REMOTE_URL` / `_API_KEY` / `_MODEL` env vars (explicit per-session override).
41
+
2.`~/.config/maxim/peer.yml` via `read_peer_config()` (the canonical peer-leader setup).
42
+
3. Otherwise: skip the probe (local-LLM / cloud-only setups don't have the 10-min grind failure mode).
43
+
44
+
`result.preflight.source` field records which path was used (`"env"` or `"peer.yml"`) so operators can verify their config was picked up. Env always wins when both are present.
45
+
46
+
Regression guards: `TestPreflightHelper::test_peer_yml_fallback_when_env_not_set` (asserts URL/key/model are read from peer.yml when env is absent) + `TestPreflightHelper::test_env_takes_precedence_over_peer_yml` (env wins when both present).
47
+
34
48
## What this does NOT prove
35
49
36
50
- That a real `maxim roy run` against an intentionally unreachable URL actually aborts in <3s. Unit-verified, not empirically verified. **Recommended first check:**`MAXIM_LANE_LARGE_REMOTE_URL=https://wrong.example.com maxim roy run docs/plans/roy/roy_0_smoke.yaml` against a known-bad URL — should print `aborted_at="preflight"` and exit quickly.
|`TestRoyPreflight::test_preflight_raising_treated_as_failure`|`preflight_fn` raises → treated as preflight failure (no crash), `preflight.outcome="preflight_raised"`. |
31
-
|`TestPreflightHelper::test_skips_when_no_remote_url_configured`| No `MAXIM_LANE_LARGE_REMOTE_URL` → returns `(True, {skipped: True})`. |
32
-
|`TestPreflightHelper::test_probes_when_remote_url_configured`| URL + key + model env vars → helper calls `_MaximPeerBackend.for_url(url, api_key=k, model=m).health_check()` and surfaces the outcome. |
31
+
|`TestPreflightHelper::test_skips_when_no_remote_url_configured`| No env var AND no peer.yml → returns `(True, {skipped: True})`. |
32
+
|`TestPreflightHelper::test_probes_when_remote_url_configured`| URL + key + model env vars → helper calls `_MaximPeerBackend.for_url(url, api_key=k, model=m).health_check()` and surfaces the outcome. `info.source == "env"`. |
|`TestPreflightHelper::test_peer_yml_fallback_when_env_not_set`| No env vars but peer.yml present → reads URL/key/model from peer.yml; `info.source == "peer.yml"`. (Roy-0 re-run fold.) |
35
+
|`TestPreflightHelper::test_env_takes_precedence_over_peer_yml`| Both env and peer.yml present → env wins; `info.source == "env"`. |
0 commit comments