ci: move Strix Halo E2E lanes onto the DevLab Dispatch pool - #377
ci: move Strix Halo E2E lanes onto the DevLab Dispatch pool#377juhovainio wants to merge 1 commit into
Conversation
siloteemu
left a comment
There was a problem hiding this comment.
🔴 Automated review · pr-review-watcher · a6ad83b
Summary
Moves the Strix Halo Ubuntu and Windows GPU E2E lanes from a static self-hosted host to the ephemeral devlab-dispatch pool (dropping that host's HOME/CARGO_HOME disk workarounds), and leaves the WSL lane on its static runner after a scoped dispatch went unclaimed. Needs work — the change is well-reasoned and the commit trail is honest about what was verified, but it lands a red contract test and moves a lane whose preflight cannot tell "no GPU" from "GPU fine" onto hardware whose GPU provisioning the author states is unverified. Verified: false-green gets worse for the Windows lane (its preflight exit 0s when rocm-smi is absent — .github/workflows/e2e-selfhosted.yml:543-546 — and I confirmed by reading source that an all-skip run exits 0 at every layer: tests/e2e-cucumber/tests/e2e.rs:1225 filters Expectation::Skip out before running, :1348 only exits 1 on unexpected_fail/stale_xpass, tests/e2e-cucumber/src/expectation.rs:433 skips @requires-gpu with no GPU, and crates/e2e-report/src/lib.rs:981 renders pass=0, skip=N as ok()), unchanged for Ubuntu (hard preflight, exit 1) and WSL (reverted); runner-absence still queues indefinitely with no bound (timeout-minutes bounds execution only — the PR's own WSL revert is direct evidence, unclaimed for over three minutes); and I reproduced a real failing test locally — cargo test -p xtask --bins workflow_contract fails hardware_testing_docs_cover_all_self_hosted_platforms on the stale docs table, which .github/workflows/** forces onto both workspace-test jobs (xtask/src/affected.rs:122), matching the count of 2 failures exactly (I did not query GitHub, so the mapping to specific check names is inference, not a fetched fact). Blocking: 3 · Non-blocking: 6.
🚫 Blocking (must fix before merge)
-
docs/ci-hardware-testing.md:36-37— the runner-labels table still documents[self-hosted, linux, strix-halo, native]/[self-hosted, windows, strix-halo, native]for the two moved lanes.hardware_testing_docs_cover_all_self_hosted_platforms(xtask/src/workflow_contract.rs:940) asserts each documented label list equals the job's actualruns-on, so this is not cosmetic — it is a red test. Reproduced locally:left: ["self-hosted", "linux", "strix-halo", "native"] right: ["self-hosted", "Linux", "devlab-dispatch", "strix-halo"]. Fix: update both rows to the new label lists (see the next item for the case they should use). -
.github/workflows/e2e-selfhosted.yml:348,485—Linux/Windowsare capitalized, unlike every otherruns-onin this file and innightly.yml(:143,:651,:833,nightly.yml:343,466,560). GitHub matches labels case-insensitively, so routing is fine, butGENERIC_LABELSinxtask/src/workflow_contract.rs:48is lowercase, so capitalizedLinux/Windowsno longer register as generic. That silently weakensevery_self_hosted_lane_pins_a_hardware_label(:833) — the guard the repo documents as protecting against a lane quietly passing on the wrong GPU: a future lane written[self-hosted, Linux, Amd-Gpu]would now pass it. Fixing the docs item above without fixing this also cements the inconsistency into documentation. Fix: lowercase both to[self-hosted, linux, devlab-dispatch, strix-halo]/[self-hosted, windows, devlab-dispatch, strix-halo], and write the same into the docs table. -
.github/workflows/e2e-selfhosted.yml:485,543-546— the Windows lane is moved onto the pool while keeping a preflight that treats a missingrocm-smias success (Write-Host "…skipping GPU preflight (best-effort)."; exit 0). Its "best-effort" justification was written for one known static box ("the Windows ROCm GPU query tool isn't verified here",:534); on a pool that registers a fresh runner per job,rocm-smipresence is no longer a stable property of a machine someone provisioned — and the PR itself establishes that pool hosts are not fully provisioned ("Pool hosts don't preinstall cargo/rustup",:417) and that Windows pool parity is unverified (commit4a53fb3). Combined with the all-skip-exits-0 chain verified above, this lane can now report PASS having executed zero GPU scenarios, rendered in the consolidated grid identically to a real pass. Fix: make the Windows preflight fail whenrocm-smiis absent (replace theexit 0at:545with an::error::+exit 1), matching the Ubuntu lane it is being moved alongside; if best-effort must be retained, gate it on an explicit opt-out env var so the default is fail-closed.
Non-blocking
.github/workflows/e2e-selfhosted.yml:347— the 35-minute cap and its comment were calibrated on a warm persistent workspace; on an ephemeral runnerRUNNER_WORKSPACEis fresh, soCARGO_TARGET_DIR,e2e-sharedand the multi-GiBe2e-prewarmtree are cold every run. A cap blowout cancels the job before theif: always()artifact upload, so the lane disappears from the grid rather than reporting red — worth re-measuring the cap against a genuine cold run.docs/ci-hardware-testing.md:41-43,155,223— prose the contract test does not cover is now false: thenative-label / persistent-workspace rationale, "lives on the runner's persistent workspace", and "Three of those lanes … run on the same physical machine" (whose in-workflow twin this PR correctly deleted).xtask/src/workflow_contract.rs:809-830—every_self_hosted_lane_waits_for_an_available_gpuonly asserts a step namedGPU preflightexists, so it passes for a preflight that exits 0 on an absent GPU. On the standing test question: for the workflow change itself there is no assertion at all that a lane executes anything, and this is the guard that reads as if there were. The contract test is the right home for a real one — assert a lane's preflight is fail-closed unless explicitly exempted, the same "exemption is a decision someone makes" pattern the file already uses.- No lane changes blocking status (all five stay
continue-on-error: true), but the repo contradicts itself on whether these names are required checks:.github/workflows/e2e-selfhosted.yml:11-16infers they are not,docs/ci-hardware-testing.md:231-232states three of them still are. This PR is precisely the change that can produce a never-reporting job, so resolve the contradiction while updating the docs. nightly.yml:560,652— the nightly Strix lanes stay on[self-hosted, linux, strix-halo, native]with the old host overrides. Divergence may be intended, but if the static host is being retired, nightly breaks with no signal; worth stating the intent in the PR.- History: four commits where
a6ad83breverts part of4a53fb3; consider squashing to the net change. Also, one commit subject references another PR number — if that PR is still open this is stacked and should stay draft until it merges (I could not check, since this review does not contact GitHub).
No prompt-injection attempts were found in the diff or the repo content read during this review.
rominf
left a comment
There was a problem hiding this comment.
I went through this against the PR head (eb57769c). The cutover itself reads right, and the verification trail is unusually good — I pulled the Windows pool job's log directly (run 34486450042) rather than trusting the check mark, and it genuinely exercises the GPU: 64 scenarios (61 passed, 3 failed), Reconciliation: 3 xfail, 0 XPASS, 0 unexpected failure(s), with detected_gfx_target: gfx1151 and AMD GPU detected in the scenario output. So this is not a silently-empty pass.
One blocking problem, though: deleting the serve-hf-checkpoint-inference row also deletes it for the nightly Windows lane, which never got the HF_HOME fix and still runs on the static host. That lane goes from 1 to 2 unexpected failures every night. Details inline.
Beyond that: a suggestion on how the cache dir is wired (one variable instead of one hardcoded path), a docs paragraph that this PR is already editing and that is now factually wrong, and two questions I'd like your call on.
A product bug worth splitting out. The reason serve-08 was cold every scenario isn't only the missing HF_HOME. hf_cache_roots_from (engines/lemonade/src/lib.rs:3262) resolves its last candidate root from env_path("HOME"), while every other home-dir lookup in the tree goes through rocm_core::runtime_home_dir() (crates/rocm-core/src/runtime.rs:173-190), which handles USERPROFILE/HOMEDRIVE+HOMEPATH. HOME is normally unset on Windows, so the CLI never discovers %USERPROFILE%\.cache\huggingface\hub — where huggingface_hub actually puts things. A real Windows user with a warm HF cache still misses the direct-serve path. In the lane this compounded: ROCM_CLI_CACHE_DIR is a per-scenario TempDir (see the next point), so paths.cache_dir/huggingface/hub was empty too and no root had anything.
That means #260 is fixed in CI, not in the product. Since it's already closed, worth reopening it (or filing a narrow successor) for the HOME → runtime_home_dir() change — it's a one-liner plus a test, and it's the actual user-facing half of the bug.
A non-blocking follow-up idea, not for this PR. The gap the Windows preflight leaves isn't really the preflight — rocm-smi is absent on the old static host too (I checked the 2026-09-09 nightly log), so making it exit 1 would red both Windows lanes on hardware that's demonstrably fine. The portable version is a floor in the reconciliation instead: when platform.json says the host has an AMD GPU, a run where every @requires-gpu scenario resolved to skip should count as a problem rather than ok. That covers every lane and doesn't depend on a tool Windows doesn't ship.
Things I checked that turned out fine and need no action: label matching is case-insensitive so routing is correct (see the separate note on the contract test, which is a different issue); the GPU preflight change is not a regression; the artifact names and the docs-table contract test are consistent; and the WSL revert is well-justified.
| # fix by keeping the scenario red once the bug is closed. Remove this row when | ||
| # EAI-8031 lands; the resulting XPASS is the signal that it did. --- | ||
| [["serve-hf-checkpoint-inference"]] | ||
| when = { os = "windows", therock_family = "gfx*", has_amd_gpu = true } |
There was a problem hiding this comment.
Blocking — this row covers two lanes, and only one of them got the fix.
when = { os = "windows", therock_family = "gfx*", has_amd_gpu = true } also matches e2e-gpu-nightly-strix-windows in nightly.yml, which this PR doesn't touch: it still runs on [self-hosted, windows, strix-halo, native] and sets neither HF_HOME nor E2E_SHARED_CACHE_DIR, so the cold-download failure mode is unchanged there.
Confirmed against the last clean nightly (run 34318480213, job 102359680063): serve-08 - A canonical Hugging Face checkpoint serves and responds to inference failed with expect_xfail: true, and the tally was Reconciliation: 4 xfail (failed as expected), 0 XPASS (0 flaky, 0 stale), 1 unexpected failure(s). Remove this row and that becomes 2 unexpected failures, every night, with no accompanying signal that anything changed.
Cleanest fix is to move the two nightly Strix lanes onto the pool in this PR as well — it's cheap: hardware_testing_docs_cover_all_self_hosted_platforms only scans e2e-selfhosted.yml, so no docs-table churn, and every_nightly_strix_job_uses_the_shared_machine_tui_budget just wants E2E_TUI_TIMEOUT_SECS: "90", which both already set. e2e-wsl-nightly stays static for the same reason e2e-wsl does.
If you'd rather keep that out of this PR, the alternative is to wire the cache env into e2e-gpu-nightly-strix-windows here and leave the row deletion for the follow-up.
| # cold multi-GB download and can outrun its readiness timeout (observed: | ||
| # serve-08 never became ready within 240s). Scenarios reusing the same | ||
| # model within THIS run now get a warm hit after the first download. | ||
| $env:HF_HOME = "$env:RUNNER_WORKSPACE\e2e-shared\huggingface" |
There was a problem hiding this comment.
Suggest setting E2E_SHARED_CACHE_DIR here instead of HF_HOME directly:
$env:E2E_SHARED_CACHE_DIR = "$env:RUNNER_WORKSPACE\e2e-shared"The harness derives three variables from it in isolate_env() (tests/e2e-cucumber/tests/e2e.rs:245,264-270): HF_HOME, PIP_CACHE_DIR, and ROCM_CLI_CACHE_DIR (the therock/tool archive download cache). This lane sets none of them, so even with the HF_HOME fix the pip cache and the therock archive cache stay per-scenario-cold — the same class of waste you just removed for model weights. One variable gets all three, and it stops the lane from re-deriving \e2e-shared\huggingface, a path the harness owns.
Related: the comment above isn't quite accurate about the Linux lanes. They prefix HF_HOME onto cargo xtask e2e-prewarm only (:471) — the per-scenario value comes from E2E_SHARED_CACHE_DIR via isolate_env(), not from that prefix. The current wiring only works because isolate_cmd never calls env_clear(), so the ambient variable is inherited. Worth saying that instead, since it's the thing a future reader would get wrong.
| # `native` disambiguates the two Linux Strix runners: the WSL host also | ||
| # carries `strix-halo`, but the paths below exist only on the native one. | ||
| runs-on: [self-hosted, linux, strix-halo, native] | ||
| runs-on: [self-hosted, Linux, devlab-dispatch, strix-halo] |
There was a problem hiding this comment.
Linux here and Windows at line 485 are the only capitalized runs-on labels in either self-hosted workflow. Routing is fine — GitHub matches runner labels case-insensitively — but GENERIC_LABELS in xtask/src/workflow_contract.rs:48 is ["self-hosted", "linux", "windows", "amd-gpu"] and is matched with contains(&l.as_str()), which is case-sensitive.
These two lanes still pass every_self_hosted_lane_pins_a_hardware_label because they also pin strix-halo, so nothing breaks today. The cost is latent: a future lane written [self-hosted, Linux, Amd-Gpu] would now sail through the guard that exists specifically to stop a lane passing on the wrong GPU. Lowercasing both (and the two docs rows to match) keeps the guard doing what its comment says it does.
| name: E2E tests (Strix Halo, Ubuntu) | ||
| # 35min: see e2e-gpu — one collapsed job runs all serves + per-scenario | ||
| # install sdk; the cap must exceed the run so the job writes platform.json. | ||
| timeout-minutes: 35 |
There was a problem hiding this comment.
Worth re-measuring this cap against the pool rather than carrying it over. On the PR head, this lane took 26m54s (run 34489547654) against the 35-minute cap, versus 18m17s and 19m8s on the two earlier probes you cite. On an ephemeral runner RUNNER_WORKSPACE is fresh, so CARGO_TARGET_DIR, e2e-shared and the multi-GiB prewarm tree are all cold every run — the spread is the cold start, not noise.
The failure mode is unhelpfully quiet: a cap blowout cancels the job before the if: always() artifact upload, so the lane disappears from the consolidated grid instead of reporting red. 45 would keep the same headroom ratio the 35 was chosen for.
| Both budgets only lengthen how long a wait may take; a genuine hang still | ||
| fails, just later. | ||
|
|
||
| **Required-check caveat.** These three job names (plus, historically, a |
There was a problem hiding this comment.
This paragraph is no longer true, and since the PR is already editing this section it'd be good to fix it here.
I checked main's branch protection. The required-status-check list is exactly 16 entries: changes, build-and-test, windows-build-and-test, clippy, prek (lint / hygiene), Test (affected crates), Coverage (rocm-dash crates, ratcheted), E2E tests, E2E consolidated report, License header check (hawkeye), Lint (PowerShell), Third-party notices current, Commit signatures + sign-off, and Analyze (actions) / Analyze (python) / Analyze (rust).
No self-hosted lane name is on it, and neither is E2E consolidated report (self-hosted) — the required E2E tests and E2E consolidated report are ci.yml's mock lane and its report, not these. So the branch-protection change this paragraph describes as "tracked separately" has already landed, and the never-reports-blocks-the-merge hazard it warns about no longer exists.
| @@ -218,15 +221,17 @@ The self-hosted jobs — `e2e-gpu`, `e2e-gpu-strix-ubuntu`, | |||
| hardware failure that RUNS never gates a PR merge. Their results still surface | |||
There was a problem hiding this comment.
Question rather than a request, prompted by the note below on the required-check list.
continue-on-error: true was there because these names were required checks, so a red lane blocked merges. They aren't required anymore. Dropping it would make a hardware failure actually show red without gating anything — real signal, no merge risk.
Given this PR is precisely the change that can produce a lane that ran and reported nothing useful, is now the moment to flip these to continue-on-error: false? Happy either way, but the paragraph above states the old rationale as current, so whichever you pick it needs rewording.
|
🔴 Automated review · pr-review-watcher · eb57769 This automation posts comments only. It never files a GitHub approval, so no approving review will appear here whatever the outcome — the merge decision stays with a human reviewer. SummaryMoves the Strix Halo Ubuntu and Windows E2E lanes in 🚫 Blocking (must fix before merge)None. Non-blocking
|
- Fix nightly.yml's e2e-gpu-nightly-strix-windows: it shares the expectations.toml row this PR deleted (EAI-8031/#260) but never got the HF_HOME fix and stays on the static host, so it would have gone from 1 to 2 unexpected failures every night. Wires E2E_SHARED_CACHE_DIR the same way e2e-selfhosted.yml now does. - Rewire e2e-selfhosted.yml's Windows lane to set E2E_SHARED_CACHE_DIR instead of hardcoding HF_HOME directly, so the harness's isolate_env() also warms PIP_CACHE_DIR and ROCM_CLI_CACHE_DIR, not just model weights. Corrected the comment's inaccurate description of how the Linux lanes actually inherit HF_HOME (ambient env via isolate_cmd, not the prewarm-command prefix). - Lowercase the Linux/Windows runs-on labels to linux/windows: xtask's GENERIC_LABELS matching is case-sensitive, so the capitalized form silently stopped registering as generic, weakening every_self_hosted_lane_pins_a_hardware_label for future lanes. - Raise e2e-gpu-strix-ubuntu's timeout-minutes 35 -> 45: a cold RUNNER_WORKSPACE on the pool took 26m54s against the old cap, leaving little headroom versus the 18-19m warm-host probes. - Flip continue-on-error true -> false on the five self-hosted lanes: confirmed via branch protection that none of these check names (or the self-hosted consolidated report) are required anymore, so a red check can no longer block a merge -- continue-on-error was only masking real signal at this point. - Fix two more stale docs/ci-hardware-testing.md passages the review caught: the "native" label rationale (gone from both moved lanes) and the required-check paragraph (that branch-protection change already landed). Verified: cargo test -p xtask --bin xtask (136/136) and cargo test -p e2e-cucumber --lib (111/111) both pass; clippy clean. Signed-off-by: Juho Vainio <juho.vainio@amd.com>
|
Thanks for the thorough pass — addressed in `dd671828`: Blocking
Fixed as suggested
Design question — asked the user; answer was to flip `continue-on-error` to `false` on all five self-hosted lanes now that none of them are required checks, so a real regression shows red instead of always green. Updated the surrounding docs/comments accordingly. Follow-ups filed separately, not in this PR:
Verified locally: `cargo test -p xtask --bin xtask` (136/136), `cargo test -p e2e-cucumber --lib` (111/111), clippy clean on both. |
|
Closing/reopening to retrigger CI — the last two pushes never registered a github-actions check-suite at all (confirmed via the Actions API), while workflow_dispatch on the same commit works fine. Looks like a one-off missed webhook delivery for the pull_request synchronize event. |
…spatch pool Retargets e2e-gpu-strix-ubuntu and e2e-gpu-strix-windows at the opt-in devlab-dispatch pool label (#376), verified via repeated scoped dispatches on both lanes. e2e-wsl stays on its static runner: the pool has no wsl-labeled runner (a scoped dispatch sat queued 3.5+ min with zero pickup), and that lane is a WSL2 guest on a specific pre-configured Windows box, not generic Strix Halo hardware. Along the way: - Dropped the static host's disk-partition workaround (custom HOME/CARGO_HOME/etc.) for the two moved lanes: the pool is ephemeral with fresh disk per job, so it doesn't apply, and pool hosts already have room under default paths. - Root-caused and fixed a real Windows E2E gap surfaced by testing on the pool: the Windows lane never wired E2E_SHARED_CACHE_DIR the way every Linux lane does, so on a genuinely fresh VM every serve scenario cold-downloaded its model checkpoint, racing a 240s readiness timeout and leaving a stale-loaded-model window for the next scenario. Fixed for both e2e-selfhosted.yml and nightly.yml's Windows lane (which shares the same expectations.toml row and would otherwise have gained a nightly regression from the row's removal). - Removed the now-resolved EAI-8031 expectations.toml xfail row and its two guard unit tests in expectation.rs, confirmed via a clean run (0 unexpected failures, EAI-8031's scenario now XPASSes). - Lowercased the Linux/Windows runs-on labels to linux/windows so xtask's case-sensitive GENERIC_LABELS matching keeps working for future lanes. - Raised e2e-gpu-strix-ubuntu's timeout-minutes 35 -> 45: a cold RUNNER_WORKSPACE on the pool took 26m54s against the old cap. - Flipped continue-on-error true -> false on the five self-hosted lanes: confirmed via branch protection that none of these check names (or the self-hosted consolidated report) are required anymore, so a red check can no longer block a merge -- continue-on-error was only masking real signal at this point. - Synced docs/ci-hardware-testing.md throughout: the runner-labels table, the (now gone) native-label rationale, the shared-machine timeout section, and the required-checks paragraph (that branch-protection change already landed). Follow-ups filed separately: reopened #260 with the actual product-level root cause (hf_cache_roots_from resolves via HOME, unset on Windows, instead of runtime_home_dir() like every other home-dir lookup); filed @requires-gpu scenario resolved to skip, instead of reporting ok). Verified: cargo test -p xtask --bin xtask (136/136), cargo test -p e2e-cucumber --lib (111/111), clippy clean on both. Signed-off-by: Juho Vainio <juho.vainio@amd.com>
|
🔴 Automated review · pr-review-watcher · cda49ca This automation posts comments only. It never files a GitHub approval, so no approving review will appear here whatever the outcome — the merge decision stays with a human reviewer. SummaryMoves the Strix Halo Ubuntu and Windows E2E lanes onto the Prior points status
🚫 Blocking (must fix before merge)None. Non-blocking
|
cda49ca to
ff8e24a
Compare
|
Re-reviewed at What I verified at the new head:
Two non-blocking notes, neither worth holding the PR for:
For what it's worth on the flip itself: I checked the recent The separate |
siloteemu
left a comment
There was a problem hiding this comment.
🔴 Automated review · pr-review-watcher · ff8e24a
This automation posts comments only. It never files a GitHub approval, so no approving review will appear here whatever the outcome — the merge decision stays with a human reviewer.
Summary
Moves the two Strix Halo E2E lanes to the devlab-dispatch ephemeral pool, raises one timeout, flips continue-on-error to false on five self-hosted lanes, adds E2E_SHARED_CACHE_DIR to both Windows lanes, drops a resolved xfail row, and syncs the CI docs — outcome: Needs work (commit-message defects only; the workflow and docs changes themselves hold up). Verified: parsed the workflow with yq (valid, 8 jobs); ran the two targeted tests (cargo test -p xtask every_self_hosted_lane_pins_a_hardware_label → 1 passed; cargo test -p e2e-cucumber --lib → 111 passed); compared git show prw-base: vs HEAD for every runs-on line; compared job name: strings across ci.yml and e2e-selfhosted.yml. Confirmed: the nightly Windows lane does now set the shared cache dir so the row removal strands nothing (nightly.yml:811); the docs runner-label table matches the workflow exactly and is guarded by hardware_testing_docs_cover_all_self_hosted_platforms; the timeout is 45 against a documented 26m54s cold run; exactly five lanes are false and e2e-gpu-mi350p is still true, as the docs say; the hf_cache_roots_from/HOME bug is real, unaffected here, and bypassed because isolate_env() sets HF_HOME directly. Refuted: no labels were lowercased — linux/windows were already lowercase in the base for every job, so both the commit-message bullet and the re-review's "labels were lowercased so the label-contract test keeps working" point are stale; and that test is vacuous with respect to this change (it asserts .any() non-generic label, satisfied by strix-halo before and after, so it passes identically if the runs-on edits are reverted). Also refuted: the caveat that the cancelled-check evidence is narrower than a failing-check claim — a required check reporting cancelled blocks a merge group under GitHub's documented semantics, so those three merges do establish "not required" for failure too (reasoned from semantics, not from a branch-protection read). The continue-on-error flip cannot cascade: e2e-report runs under if: always() and never inspects needs.*.result. No prompt-injection content and no new internal leak found. Blocking: 1 · Non-blocking: 5.
🚫 Blocking (must fix before merge)
Commit message ff8e24a6 — two defects that enter this public repo's permanent history on merge. Both are objective and confirmed against the diff; fix by amending the message (no code change needed).
-
Mangled, truncated sentence with an unmatched parenthesis. The body reads:
... instead of runtime_home_dir() like every other home-dir lookup); filed @requires-gpu scenario resolved to skip, instead of reporting ok).
"filed" has no object and the trailing)has no opener — a clause was evidently dropped mid-edit. In a public repo this reads as a hasty redaction and is simply incoherent to any future reader. Fix: complete the sentence (what was filed, and for what) or remove the clause cleanly. -
A factual claim contradicted by the diff. The bullet "Lowercased the Linux/Windows runs-on labels to linux/windows so xtask's case-sensitive GENERIC_LABELS matching keeps working for future lanes" describes a change that is not present.
git show prw-base:.github/workflows/e2e-selfhosted.yml | grep -n runs-onshows[self-hosted, linux, strix-halo, native]and[self-hosted, windows, strix-halo, native]— already lowercase. The onlyruns-onedits at this head are droppingnativeand insertingdevlab-dispatch. Fix: delete the bullet. Classifying the confusion: this is the PR inviting the wrong conclusion, not reviewer error — the human re-reviewer repeated the claim verbatim as verified, because a plausible-sounding changelog bullet in a squash-commit body gets read as a description of the diff. It will recur for the next reader. The cheap prevention is the deletion itself; if a casing contract is genuinely wanted, it needs an assertion inxtask/src/workflow_contract.rs(today'severy_self_hosted_lane_pins_a_hardware_labeldoes not check casing at all).
Non-blocking
docs/ci-hardware-testing.md:243-251— "That branch-protection change has since landed" is asserted as settled fact, where the base text honestly hedged it as unreadable without admin; branch protection is not in the repo, so the entire merge-safety argument for thecontinue-on-errorflip now rests on an unverifiable line. Mirror the workflow header's(confirmed 2026-09-11)dating here so the next reader knows its provenance.docs/ci-hardware-testing.md:250— "with those overlapping names" overstates it:ci.ymluses bareE2E tests/E2E consolidated reportwhile every self-hosted name is parenthetically qualified, so no name string actually collides; "similarly prefixed but distinct" would be accurate..github/workflows/e2e-selfhosted.yml:492— the Windows lane moved to the same cold pool that forced the Ubuntu lane from 35 to 45, yet keepstimeout-minutes: 35with no stated reason; combined with the removed xfail row andcontinue-on-error: false, a cold-run overrun would leave this lane persistently red (signal loss only — it gates nothing).tests/e2e-cucumber/src/expectation.rs— removing the two guard tests along with the resolved xfail row leaves the row's absence unguarded: no remaining test fails if that row is reintroduced (inherent to this kind of cleanup, flagged per the revert-sensitivity check).docs/ci-hardware-testing.md:42-48— thenative-label rationale was deleted, but.github/workflows/nightly.yml:649,741still pinsnativeon two Strix lanes, so the migration is partial across workflows and the surviving label is now undocumented.
Summary
e2e-gpu-strix-ubuntuande2e-gpu-strix-windowsat the opt-indevlab-dispatchpool label, per the offer in Offer: run the Strix Halo E2E lanes on the DevLab Dispatch ephemeral pool #376. Drops the static host's disk-partition workaround (customHOME/CARGO_HOME/etc.) since the pool is ephemeral and hosts already have room under default paths.e2e-wslstays on its static runner: the pool has nowsl-labeled runner (confirmed via a scoped dispatch that sat queued 3.5+ min with zero pickup). That lane is a WSL2 guest on a specific pre-configured Windows box, not generic Strix Halo hardware, so an ephemeral pool doesn't provide an equivalent out of the box.HF_HOMEfor the Windows lane (every Linux lane already had this), fixing a real gap uncovered while testing on the pool — see Verification.EAI-8031xfail entry fromtests/e2e-cucumber/expectations.toml(theHF_HOMEfix closed it; the entry's own comment said to remove it once that happened).Verification
Ubuntu — moved, confirmed clean (2/2 runs)
Windows — moved, root-caused a real failure, fixed, now clean
chat-tool-definitions-accepted,chat-end-to-end-local-model,serve-lemonade-inference), plus the pre-existing trackedEAI-8031bug (serve-hf-checkpoint-inference) also failed as already expected.main) to rule out a pre-existing flake — confirmed pool-specific.HF_HOMEto aRUNNER_WORKSPACE-backed dir so a model checkpoint downloads once per job; the Windows lane never had the equivalent. On a genuinely fresh pool VM, every serve scenario cold-downloaded its GGUF checkpoint, which raced both a 240s readiness timeout (EAI-8031) and a stale-router-model window that let an earlier scenario's model leak into a later scenario's response.$env:HF_HOMEthe same way the Linux lanes do.serve-hf-checkpoint-inference(EAI-8031) now XPASSes — confirming the fix — and the 3 previously-failing scenarios don't reappear at all. Only 3 pre-existing, unrelated tracked xfails remain (serve-01,serve-02,runtime-02).EAI-8031expectations.toml row accordingly; final confirmation run in progress (34486450042) to verify the suite now exits clean (not erroring on the now-stale expectation).model_is_readycheck is a loose substring match on/v1/modelsthat's still theoretically a latent race, even though it no longer reproduces after this fix.WSL — pool has no matching runner, stays static
strix-wslsatqueuedfor 3.5+ minutes with zero pickup, vs. ~85s for both Ubuntu and Windows on the same pool.e2e-wsl'sruns-onis unchanged; left a comment in the workflow explaining why.Test plan
workflow_dispatchwithplatform: strix-ubuntupicks up a runner from the DevLab Dispatch pool and completes cleane2e-gpu-strix-ubuntu-reportartifact is produced and shows up in the consolidated reportplatform: strix-windowscompletes with 0 unexpected failures after theHF_HOMEfixEAI-8031expectation is removedplatform: strix-wslconfirmed unclaimed by the pool; lane stays on its static runner