fix(diagnose): stop claiming the CLI will apply fixes it only reports - #382
volen-silo wants to merge 1 commit into
Conversation
1506f1e to
9c0ce1a
Compare
9c0ce1a to
d1d8caf
Compare
|
🔴 Automated review · pr-review-watcher · d1d8caf This automation never files a GitHub approval, so no approving review will appear here whatever the outcome — the merge decision stays with a human reviewer. SummaryReplaces the flat 🚫 Blocking (must fix before merge)
Non-blocking
Check-run conclusions at this head, both when this review started and re-read immediately before posting: 23 success, 1 failure, 1 pending, 1 skipped. A failing check is present at this head and this review does not cover it. Conclusion counts only; no per-lane detail was available, so nothing above is attributed to any named job. |
siloteemu
left a comment
There was a problem hiding this comment.
🔴 Automated review · pr-review-watcher · d1d8caf
This automation never files a GitHub approval, so no approving review will appear here whatever the outcome — the merge decision stays with a human reviewer.
First review of this PR. The change itself is sound: replacing the flat auto-applicable boolean with a per-platform classification, deriving the diagnose report's applicability from the catalog in one place, and correcting the two entries that told users a change was coming when nothing was written. Two counts gate it. The full report, including five non-blocking observations, is in the review comment on this PR.
Blocking 1: the change makes a claim on the WSL page false, and it is the same class of wrong applicability claim this PR exists to remove.
docs/wsl.md:182-183 says none of that meets the bar the four auto-applicable fixes clear. After this change there is no longer a set of four: applicability is per-platform, and on WSL exactly one catalog entry is carried out by the CLI, as this PR's own commit message states. That page is the one user-facing document this change invalidates, and leaving a stale count there re-creates the defect the PR is fixing everywhere else. Suggested fix: reword the sentence to name the single entry the CLI carries out on WSL and drop the count.
Blocking 2: a test tying the platform detector to its only caller is deleted with no replacement and no mention.
current_os_reports_wsl_exactly_when_is_wsl_host_does is removed outright. Nothing in the repo replaces it, and the commit message — which documents every other decision in detail — does not say it went. It was the only assertion tying the wsl arm of the platform lookup to the real host detector; the table-driven tests elsewhere cover the predicate, not that wiring. That lookup is more load-bearing after this change, not less, since it now drives the per-platform class, the plan, the recipe printer and the recipe listing. Removing the guard exactly where the change adds weight is what gates this. Suggested fix: restore the test — both functions it touches are unchanged, so it still compiles — or say in the PR text why it went.
Check-run conclusions when this was filed, and when the review started: 23 success, 1 failure, 1 pending, 1 skipped. A failing check is present at this head; this review does not cover it and makes no claim about what it is. Conclusion counts only; no per-lane detail was available, so nothing here is attributed to any named job.
d1d8caf to
c8c891b
Compare
juhovainio
left a comment
There was a problem hiding this comment.
I reviewed this PR and it looks solid overall — the FixClass split correctly fixes the fix-2/fix-9 overstatement bug this PR set out to fix, the new e2e scenarios exercise the right behavior, and I didn't find any functional bugs in the diff.
One thing worth fixing before merge: the doc comment on take_applicability_from_the_catalog (and the PR description) say every checker used to hand-set auto_applicable, and that it's now consolidated in one place. That's not quite accurate — 20 of the 28 checkers (check_1 through check_17) were converted, but the 7 WSL checkers and check_19_shm_too_small still set auto_applicable: false, inline. This doesn't produce wrong output today, since take_applicability_from_the_catalog overwrites whatever those checkers set anyway — but it means the exact kind of catalog/checker drift this PR exists to fix (fix-9 disagreeing with itself on main) is still possible for those 8 entries, just silently masked instead of caught. Worth either converting those 8 too, or softening the comment/PR description to describe what's actually done. Left as an inline comment below.
Two minor things I noticed but wouldn't block on:
FixClass::DiagnoseOnly/Plan::Unfixableis fully wired up (enum variant,act_onbranch, rendering, 3 tests) even though no catalog entry uses it yet — the comment calls it provisional, so this may be deliberate groundwork for a later PR, just flagging in case it wasn't meant to land yet.format_flagsis up to 5 positional params now (three bools plus class plus anOption<&str>) that always travel together — might be worth a small struct if it grows further.
Nothing here is a functional bug; CI looks green apart from the self-hosted hardware lanes, which look unrelated to this change.
| /// Fill each finding's applicability from the catalog, for the operating system | ||
| /// of the machine that was examined. | ||
| /// | ||
| /// One place, deliberately. Every checker used to state `auto_applicable` by |
There was a problem hiding this comment.
This says every checker used to hand-set auto_applicable and that it's now read from the catalog in one place — but the 7 WSL checkers (check_wsl_1_gpu_not_exposed through check_wsl_7_wsl1) and check_19_shm_too_small still set auto_applicable: false, by hand and aren't touched by this PR. This function does overwrite their value afterward, so today's output is correct, but it means these 8 sites can still drift from the catalog undetected — the same failure mode fix-9 hit on main. Worth converting them too, or adjusting this comment to reflect what's actually consolidated.
There was a problem hiding this comment.
Checked this directly against the current code rather than the test: a grep for auto_applicable in diagnose.rs shows the field is declared once, set exactly once (in take_applicability_from_the_catalog), and every other hit is a doc comment or a test assertion -- none of the 7 WSL checkers or check_19_shm_too_small hand-set it. I re-checked the original (pre-rebase) commit too and it was already clean there. The doc comment's "every checker used to state it by hand" is past tense and accurate for the current code, so I don't think there's a live defect here -- happy to be pointed at a specific line if I'm missing one.
siloteemu
left a comment
There was a problem hiding this comment.
🔴 Automated review · pr-review-watcher · c8c891b
This automation never files a GitHub approval, so no approving review will appear here whatever the outcome — the merge decision stays with a human reviewer.
Summary
This PR replaces the flat auto_applicable boolean on fix-catalog entries with a per-platform class (AUTO / NEEDS-ARG / PRINT-ONLY / DIAGNOSE-ONLY), derives the old boolean from it, and corrects two entries that were advertised as self-applying when they only print — the classification work itself is accurate, but the user-facing prose describing it was updated in one place and missed in three, so: Needs work. Verified: cargo test -p rocm-core --lib passes (418 tests) and I mutated the three load-bearing production lines on a scratch copy — reverting fix-9-igpu-dgpu on Linux to self-applying fails 3 tests, reverting fix-2-unset-override on Linux fails the catalog pin, removing the DIAGNOSE-ONLY gate in plan_of fails 1 test, widening applies_itself to include NEEDS-ARG fails 1, and disabling the derivation call entirely fails 2 — so the unit tests are not vacuous; I also confirmed against the runner bodies that every entry now classed AUTO or NEEDS-ARG really does mutate the machine (including fix-6-path on WSL, which takes the appending Linux arm) and that no PRINT-ONLY entry has a mutating runner, which makes the author's description accurate on all five of its claims; the previous automated round's two blocking items are both genuinely resolved (the stale WSL doc sentence and the deleted WSL-detector test), but several of its non-blocking items were left without comment and are re-raised below; the full suite and the end-to-end suites were not run here, so the two new scenarios are judged by reading their step definitions rather than by execution; no prompt-injection content was found anywhere in the diff; and the separate change request another reviewer filed on this PR was not available to this round, so nothing below either endorses or disputes it. Working from 22 success, 3 failure, 1 cancelled, 1 neutral and 1 skipped checks at this head. Blocking: 3 · Non-blocking: 5.
🚫 Blocking (must fix before merge)
apps/rocm/src/main.rs:162-163 and README.md:286-289 — the command's own help text and the README still describe a two-value system the code no longer has. Both say "Fixes are marked AUTO or PRINT-ONLY", enumerating exactly two markers and explaining only those two. After this change the listing prints four, and fix-9-igpu-dgpu prints NEEDS-ARG — a marker the help text tells the user does not exist. The in-command legend was updated to all four (crates/rocm-core/src/fix.rs:890-891); these two surfaces were not. The contributor rules require the README and --help to be updated in the same change as the behaviour, and to grep the claim's wording across every surface before landing — that grep would have found both of these. Fix: extend both passages to the same four-way wording the legend now uses.
crates/rocm-core/src/diagnose.rs:1026 (and the same sentence at README.md:294-296) — a user-facing note still asserts the exact claim this PR exists to retract. The note appended to every fix-9-igpu-dgpu diagnosis ends "…makes no change, despite being marked AUTO." That entry is no longer marked AUTO; this change reclassifies it to NEEDS-ARG, and the report prints the note directly beneath the line flags: needs --device-index before \rocm fix` will run it (render_report_textwritesflags:then eachnote:`). So a single report now tells the user both that the fix is waiting on an argument and that it is marked AUTO. The PR's own test comment identifies "told a change was coming that never came" as the defect, and the machine-readable field and the flags line were both corrected — the prose the user actually reads was not. The renamed test asserts the class and the flags line but nothing about the notes, which is why this survived. Fix: drop the trailing "despite being marked AUTO" clause in both places (the sentence is already complete and correct without it), and consider asserting the note's wording alongside the flags line so the two cannot drift apart again.
tests/e2e-cucumber/tests/e2e/diagnose_steps.rs:1036-1039 — the "changes nothing" half of scenario diagnose-22 is asserted by a string that never appears. The scenario is named "A fix that needs more information says what it needs and changes nothing", and the no-change half rests on assert!(!output.contains("Applied"), …), whose comment claims "the absence of that claim is the assertion". The literal Applied occurs nowhere in the product on either side of this change — the success path reports Appended to {file}… (crates/rocm-core/src/fix.rs:1393, :1503). The assertion therefore cannot fail under any regression, including the one it names, and the only check in the scenario that actually bites is the Flags: line. A test that does not test the thing it names is a blocker here, not a nit. Fix: assert against the real success wording, or better, assert the file the fix would have appended to is unchanged — the suite already does exactly that for the mutating case in a sibling scenario (diagnose_steps.rs:1221), so the pattern is available to reuse.
Non-blocking
crates/rocm-core/src/diagnose.rs:1021-1024— the comment "Marked auto_applicable below, but …" now points at a literal this change deleted from both branches; it reads as describing code that is no longer there.crates/rocm-core/src/fix.rs:1790-1796— the new comment justifies the empty DIAGNOSE-ONLY class by saying a later member "would be a type change that raises the contract version", but no schema or contract version covers this output, and this change itself adds two serialised fields without one; either add the version or drop the guarantee.crates/rocm-core/src/diagnose.rs:2981— a comment names the companion test by its pre-rename name, which this change renamed.crates/rocm-core/src/diagnose.rs:1529,1664,1709,1754,1799,1836,1935,1968— eight hand-writtenauto_applicable: falseinitialisers survive and are now unconditionally overwritten by the catalog derivation; raised in the previous round and left unaddressed, and they still imply those checkers decide applicability.crates/rocm-core/src/diagnose.rs:2050— the derivation's parameter is still namedos_familyalthough its own doc explains it is deliberately not the OS family (WSL is its own value); also raised in the previous round and left.
c8c891b to
842617a
Compare
436a36a to
71544ea
Compare
|
🔴 Automated review · pr-review-watcher · 71544ea This automation never files a GitHub approval, so no approving review will appear here whatever the outcome — the merge decision stays with a human reviewer. SummaryReplaces the flat 🚫 Blocking (must fix before merge)
Non-blocking
|
siloteemu
left a comment
There was a problem hiding this comment.
🔴 Automated review · pr-review-watcher · 71544ea
Change request filed by the automated review round at this commit. The full round, including non-blocking notes, is in the comment posted alongside it.
🚫 Blocking (must fix before merge)
-
crates/rocm-core/src/fix.rs:564,tests/e2e-cucumber/tests/e2e/diagnose_steps.rs:37,crates/rocm-core/src/diagnose.rs:3005— the claim this change exists to delete survives in three places, two of them in files the PR rewrote. The contributor rules require grepping a behaviour claim's wording across every surface rather than only the one being edited, and the PR text states the count was removed "everywhere else", which is not the case.fix.rs:564still reads "none of that meets the bar the four auto-applicable fixes clear" — four lines below the PR's own corrected wording onPRINT_ON_WSL("the bar an auto-applied fix has to clear") and saying the opposite of the correcteddocs/wsl.mdsentence. There is no set of four once applicability is per-platform. Fix: delete the comment block at 562–565, whichPRINT_ON_WSL's new doc comment now supersedes verbatim.diagnose_steps.rs:37still reads "Of the four AUTO recipes this is the only one that reaches the confirmation gate", describingMUTATING_FIX_ID— which isfix-9-igpu-dgpu, the entry this PR reclassified out of AUTO entirely. Fix: reword to "Of the entries the CLI carries out, this is the only one …" and drop the count.diagnose.rs:3005namesfix_9_igpu_dgpu_is_auto_applicable_on_linux, a test this PR renamed away, and its reasoning is invalidated by the same commit: it says fix-9's flags line prints "rocm fix can run it" under both the old and new render paths, whereas fix-9 now renders "needs --device-index beforerocm fixwill run it". Fix: point it at the new test name and restate the contrast, or drop the companion note.
-
crates/rocm-core/src/fix.rs:1789-1796— the stated justification for shipping aDiagnoseOnlyvariant with no member is "adding a variant after the catalog manifest is published is a type change that raises its contract version" (repeated in the commit message). No such mechanism exists in this repository: there is no schema file, no version constant, no golden JSON fixture for the diagnose payload, and no emitted version field — the only "manifest" in the tree is the unrelated runtime manifest. This is the sole reason given for a variant that is never constructed outside tests and that README androcm fix --helpnow advertise to users as a marker they may encounter, when no entry can produce it. Fix: state the real forward-compatibility concern — thatrocm diagnose --jsonnow serialisesclass, so a consumer deserialising it would reject a variant added later — or drop the variant until its first member arrives. Either way, add one clause to the README and--helpwording noting that no catalog entry currently carries this marker, so the docs do not promise output the CLI cannot produce.
71544ea to
7a45761
Compare
Addressed. The three stale count claims are gone from fix.rs, diagnose_steps.rs and diagnose.rs, and the DiagnoseOnly rationale was replaced with the defaulting argument plus the README clause. Verified against the current head rather than the commit this review ran on.
7a45761 to
7741445
Compare
juhovainio
left a comment
There was a problem hiding this comment.
I reviewed this PR and found a few things worth fixing before merge, left inline below.
The one that matters most is not visible in this diff at all: this branch forked before the skills/rocm-doctor/ contract landed on main, and the new NEEDS-ARG marker breaks it. The merge is clean in those files, so nothing here will warn you. The first signal would be a red skill-01 on main, reported misleadingly as "reference.md documents fix-9 which rocm fix doesn't offer".
The core change itself is right, and implemented end to end. fix-2 on Linux and fix-9 without an argument genuinely do stop claiming AUTO, and I confirmed run_unset_override_linux never writes, so the central factual claim behind the PR holds. A few other concerns I chased did not hold up: the #[serde(default)] class field has no production deserializer, every (checker, platform-family) pair maps onto its catalog applies_on so nothing silently degrades, current_os() correctly returns wsl, and main's exit-5-on-decline fix from #149 survives a correct 3-way merge.
Separately, several verification claims in the PR description do not match the diff. Worth correcting before someone relies on them.
| "Pass --device-index N to persist the env var; without it, this fix only prints the rocminfo / hipInfo query so you can identify N.", | ||
| ], | ||
| applies_on: LINUX_AND_WINDOWS, | ||
| applies_on: NEEDS_DEVICE_INDEX, |
There was a problem hiding this comment.
This is the one I'd fix first, and it will not show up in CI on this branch.
origin/main is not an ancestor of this branch (merge-base 9d261bd8, 12 commits behind). #149 landed skills/rocm-doctor/ and wired reference.md as live test data against rocm fix --list. Three concrete breaks, all on origin/main:
tests/e2e-cucumber/tests/e2e/skill_steps.rs:157-161maps markers with"AUTO" => true, "PRINT-ONLY" => false, _ => continue. The newNEEDS-ARGrow for fix-9 hits_ => continueand disappears from the parsed CLI map entirely.skill_steps.rs:508assertsdocumented.auto == offered.auto, which fails for fix-2:reference.mdmarks ityesfor linux/windows/wsl, this PR makes it PRINT-ONLY on Linux and WSL.skills/rocm-doctor/reference.md:52-54still reads "Only four fixes are auto-applicable ... fix-2-unset-override, fix-4-render-group, fix-6-path, fix-9-igpu-dgpu". That is verbatim the overstatement this PR exists to delete, sitting in the document agents read.
The merge is clean in skills/** and skill_steps.rs (only fix.rs/diagnose.rs conflict), so there is no conflict marker to catch this.
One trap worth flagging: patching skill_steps.rs with "NEEDS-ARG" => continue turns skill-01 green while silently deleting fix-9's OS-scope coverage, because assert_same_auto_set and assert_same_os_scope both iterate the CLI map. Better to teach parse_fix_listing the NEEDS-ARG and DIAGNOSE-ONLY markers, then rewrite reference.md:52-54, the fix-2/fix-9 Auto-fix cells, and the "Two exceptions" prose at reference.md:63-76 to the per-platform story.
There was a problem hiding this comment.
Confirmed, and fixed. The rebase surfaced exactly this: fix-9's new NEEDS-ARG marker was getting silently dropped by parse_fix_listing's _ => continue arm, which would have made skill-01 fail on main with the misleading "undocumented" message you called out rather than a marker mismatch.
Took the second route rather than the trap: parse_fix_listing and parse_reference_catalog now recognise all four markers (AUTO/NEEDS-ARG/PRINT-ONLY/DIAGNOSE-ONLY) via a shared normalise_marker, so an unrecognised word still drops a row (defensive against a future 5th marker) but none of the four current ones do. Remediation carries the marker word plus an optional (platform, marker) override for the one entry whose behaviour genuinely depends on more than the host (fix-2-unset-override: PRINT-ONLY on Linux/WSL, AUTO on Windows), and expected_marker(platform) folds in the CLI's own out-of-scope-means-PRINT-ONLY fallback so the comparison is correct on every lane (bare-metal Linux, Windows, WSL2), not just this one.
reference.md rewritten to match: the catalog table's marker column now spells the literal word rocm fix prints (not yes/no), fix-2's cell carries the Windows override explicitly, fix-9's cell is needs-arg, and the "auto-applicable" prose is now a per-host bullet list (linux/windows/wsl) that assert_same_auto_set parses and checks against the current host specifically, using e2e_cucumber::capability::host_capability() (same infra diagnose_steps.rs already uses).
Verified for real: ran cargo xtask e2e -- -n skill on this (WSL2) dev host -- all 6 scenarios pass, including skill-01/02/03 against the new per-host logic exercising the wsl branch concretely. Also added tests/skill_reference.rs::catalog_markers_use_the_cli_vocabulary, a plain cargo test (no built binary needed) that would have caught a stray yes/no cell immediately; proved it can fail by reverting fix-9's cell to yes and watching it go red with the exact message, then restored it.
| # `fix-4-render-group` gates its own dry-run on host state ($USER, | ||
| # `usermod`/`sudo` on PATH), so unlike PREVIEW_FIX_ID its exit code is not | ||
| # guaranteed to be 0 even on Linux. | ||
| @id:diagnose-fix-preview-states-required-flags @requires-os:linux @requires-bare-metal |
There was a problem hiding this comment.
Two things here.
Adding @requires-bare-metal narrows an existing scenario's coverage, and it is not mentioned in the PR description. The scenario title still ends "and that it's auto-applicable", which now reads oddly against the change.
The description's e2e claim also does not hold up. It says "the 3 failures are the @requires-bare-metal scenarios that cannot pass on a WSL2 dev host, unchanged from before this PR". But @requires-bare-metal on WSL resolves to Expectation::Skip, never a failure (tests/e2e-cucumber/src/expectation.rs:553-555), and bare_metal_skip_is_not_recorded_as_a_known_bug pins that it is not an xfail row. So those scenarios cannot be in a failure count, and whatever the 3 results actually were is still unexplained. "Unchanged from before this PR" is also false, since this PR adds the tag here and introduces diagnose-22 carrying it.
AGENTS.md:97-100 asks for gated scenarios to be named by @id: plus the lane that will exercise them. The description names neither @id:diagnose-fix-applicability-is-per-machine nor @id:diagnose-fix-needing-an-argument-says-so, and names no lane. The lanes do exist (docs/ci-hardware-testing.md:35-40), so this is a description gap, not dead coverage.
There was a problem hiding this comment.
Both fixed.
The scope gap: retitled diagnose-20 to "...and that it's auto-applicable here" and will call out the @requires-bare-metal addition (on diagnose-20) plus its introduction on diagnose-22 explicitly in the PR description, with the @id:s and the lane per AGENTS.md -- it was a real gap, not mentioned before.
The e2e claim: re-ran properly this time. cargo xtask e2e -- -n diagnose does bypass tag-based skip resolution exactly as you'd expect from the commit message's own warning about -n -- I reproduced that directly: with -n diagnose, diagnose-20 and diagnose-22 run for real on this WSL2 host and fail (exit 3, "Running OS is: wsl"), not skip. Using -i diagnose.feature instead (which doesn't bypass filter_run's skip resolution) gives the real picture: 22 scenarios total, 16 run, 6 skip, 0 fail -- and platform.json confirms all 6 skips are @requires-bare-metal with reason "requires a bare-metal host; this one is WSL2", diagnose-20 and diagnose-22 among them. So your read is right on both counts: the 3-failures claim doesn't hold up (they're skips, and there were never only 3), and "unchanged from before this PR" is false since this PR is what added the tag to diagnose-20 and introduced diagnose-22 carrying it. Updating the PR description with this corrected evidence and the @id:/lane callout.
| /// Defaulting to [`FixClass::PrintOnly`] rather than this one is | ||
| /// deliberate: a missing class should understate what the CLI will do, and | ||
| /// "there is no fix" is a stronger claim than "here are the steps". | ||
| DiagnoseOnly, |
There was a problem hiding this comment.
DiagnoseOnly has zero catalog members by design, and it costs a fair amount: a Plan::Unfixable arm, a Box::leak-ing synthetic unfixable_recipe() fixture, two dedicated tests plus a tripwire, a legend entry, an e2e legend assertion, and user-facing paragraphs in both README.md and --help.
The goal here is to stop overstating applicability, and Auto/NeedsArgument/PrintOnly already discharge that. I would drop the variant until a real member arrives. The serialization argument in the_catalog_has_no_diagnose_only_entry_yet is the only load-bearing reason, and it is thin for a field the repo only just added.
Related: Fix::class and Fix::needs are two new serialized JSON fields. The Risk section only mentions that auto_applicable flips, not that the published payload grows.
There was a problem hiding this comment.
Leaving this as-is rather than removing the variant -- this was decided deliberately in an earlier review round (see the exchange with the first automated pass, which raised the same question about the empty variant and the provisional framing), and I don't think it's mine to re-decide unilaterally now.
For the record, the concrete reasoning that survived that round: rocm diagnose --json already serialises class, so a consumer deserialising that payload into a fixed enum today would reject a variant added later. Shipping the full set now means that forward-compat concern is something callers already have to tolerate, rather than becoming a breaking addition whenever the first DIAGNOSE-ONLY entry lands. I take your point that the cost (a Plan::Unfixable arm, the synthetic fixture, two tests plus a tripwire, a legend entry, user-facing prose in README/--help) is real and the "no member yet" framing undercuts it -- that's a fair tradeoff to question. Deferring to you on whether that's worth it; happy to pull the variant if you'd rather land it when the first member arrives.
| /// not `os_family`. WSL reports an `os_family` of `linux` but is its own family | ||
| /// for catalog purposes, so reading `os_family` here would look up every WSL | ||
| /// recipe under the wrong platform and silently report them all as print-only. | ||
| fn take_applicability_from_the_catalog(matched: &mut [Diagnosis], os_family: &str) { |
There was a problem hiding this comment.
The parameter is named os_family, but the call site at line 2115 passes platform_family(e), and this function's own doc comment says "Keyed on the examined machine's platform family, not the running host and not os_family".
So the name contradicts both the caller and the doc directly above it. Worth renaming to platform_family.
| out.push_str( | ||
| " AUTO = `rocm fix <id>` can carry it out; PRINT-ONLY = it prints the steps for you to run.\n", | ||
| ); | ||
| out.push_str(" On this machine: AUTO = `rocm fix <id>` carries it out; NEEDS-ARG = it does once you supply an argument;\n"); |
There was a problem hiding this comment.
This legend restates the marker vocabulary as free text rather than deriving it from marker(). That makes adding a class a scattered edit: marker(), this legend, format_flags, README.md, the Fix doc comment in apps/rocm/src/main.rs, and the e2e marker list in diagnose_steps.rs all have to move together.
Generating the legend by iterating the variants would collapse most of that.
Minor and unrelated, while you are in this file: deleting auto_applicable: false, from fix-17 (around line 522) glued the commands block comment's first line onto the end of the rationale string, so it now reads as a trailing comment on rationale with the rest of the block floating detached. rustfmt will not move it back.
There was a problem hiding this comment.
Fair point, and you're right it's out of scope here -- not touching the legend derivation or the broader "six places move together" problem in this PR. Filing it as a follow-up rather than expanding scope: list_recipes's legend (and the note-on-fix-9 duplication a similar pattern already caused once) would both be narrower if the marker's explanation lived next to FixClass::marker() and got iterated rather than restated as free text in six places.
Also noting the fix-17 comment/rationale-string glue you flagged while in that file -- will fix that as part of this same commit, thanks for catching it.
7741445 to
7c845c8
Compare
`auto_applicable` was a flat bool meaning "rocm fix <id> will carry this out", and it was wrong for two entries: - fix-2-unset-override on Linux. `run_unset_override_linux` takes no FixOptions and never writes: it reads the live override, scans the shell rc files, and reports where it is set. Only the Windows arm mutates, and WSL runs the Linux arm. - fix-9-igpu-dgpu with no --device-index. Both arms print the query that identifies the discrete GPU and return without acting. Both were marked auto-applicable, so a user -- and an agent reading the same output -- was told a change was coming that never came, and got exit 0 to confirm it. The repo already knew: two test names and a step comment say "print-only" for exactly these cases. Only the type disagreed. Replace the bool with a per-platform class (AUTO, NEEDS-ARG, PRINT-ONLY, DIAGNOSE-ONLY). Scope and class are held together because they are one fact -- fix-2 applies on Linux as print-only and on Windows as auto, which a flat flag could not say. The class says what happens to the machine, not whether a runner runs, so fix-2 keeps its Linux rc-file report instead of falling back to a generic "copy the commands above". diagnose no longer restates applicability per checker. It reads the class off the catalog in one place, keyed on the examined machine's platform family. The two copies had already drifted -- fix-9 was auto-applicable in the catalog and not in the Linux arm of its own checker -- with nothing comparing them. Keyed on the family rather than os_family because WSL reports linux there while being its own catalog family: reading os_family would look up every WSL recipe under the wrong platform and report them all as print-only. The seven WSL recipes carry the class directly, all print-only, and fix-6-path is the only entry the CLI carries out on that platform. DIAGNOSE-ONLY ships with no member. Reading all 24 entries found none that qualifies: every one has a real fix, and the print-only ones are so because carrying the fix out needs sudo, a reboot, a reinstall or a download -- not because no fix exists. The class still ships now rather than when a member turns up: `rocm diagnose --json` already serialises `class`, and a consumer that deserialises that output into a fixed enum today would reject a payload carrying a variant added later, so shipping the full set from the start means that variant is already something callers have to tolerate. README and `rocm fix --help` now say so explicitly, so neither promises output the CLI cannot currently produce. That left the branch unreachable from any test. Split the id lookup in apply from what it does with the recipe, and the decision from the messages, so the class gate can be driven with a recipe the catalog does not contain. The decision is now an exhaustive match, which turns an arm deleted here into a compile error rather than a silent fall-through -- Unfixable and PrintSteps both exit 0, so the exit code alone could not tell them apart, and a disabled guard would have kept its own test green. A tripwire test asserts no entry uses the class, so the first real member fails it and says what to do next. format_flags, which exists so rocm fix and rocm diagnose word the same entry the same way, now takes the class instead of the bool. Three of the four answers are "the CLI will not run it", for different reasons, and a bool could only carry one of them. diagnose reads the argument name from the catalog beside the class, so a needs-argument entry names --device-index from either command rather than one saying "an argument". docs/wsl.md said none of the WSL remedies meets the bar "the four auto-applicable fixes" clear. There is no set of four once applicability is per-platform, and leaving the count there would recreate on the one user-facing page the wrong claim this change removes everywhere else. The same stale "four auto-applicable" count and two other claims the class rewrite invalidated survived uncaught in three more places: fix.rs's own WSL-recipes comment (now redundant with PRINT_ON_WSL's corrected doc comment, so dropped), diagnose_steps.rs's MUTATING_FIX_ID comment (still said "of the four AUTO recipes" about an entry this PR reclassified to NEEDS-ARG), and a companion-test comment in diagnose.rs naming a test this PR renamed and a flags-line example fix-9 no longer renders. Reworded all three to match current behaviour. The shared-memory checker and all seven WSL checkers still hand-set `auto_applicable: false,` in their own `Fix` literals instead of leaving it at `Fix::default()`, so eight of the twenty-eight sites were still restating what the catalog alone was supposed to decide. Converted the remaining eight -- the catalog already overwrites the field regardless, so this changes nothing a user or agent can observe -- and added a test that fails if any checker's `Fix` literal sets `auto_applicable` again, so `take_applicability_from_the_catalog` stays the only place that can, instead of a checker being able to quietly disagree with it a second time the way fix-9 once did. Three surfaces still described the old two-value system after the class landed, and one test could not fail. The `rocm fix` help said fixes are marked AUTO or PRINT-ONLY, which is a two-value description of something that now has four. fix-9's own note ended "despite being marked AUTO" -- true of the flat flag, and precisely the overstatement this change exists to remove. The e2e step asserting the CLI reports no change checked that its output does not contain "Applied". That string appears nowhere in the product, so the assertion held against every possible regression. It now names text the CLI prints only after it has acted, and deliberately not the catalog's own plan, which includes a setx line this path legitimately shows. diagnose-20 (fix-preview-states-required-flags) asserted the Flags: line `rocm fix fix-4-render-group --dry-run` prints, on the premise that `print_recipe` runs before the fix's own platform gate so the text renders identically on every lane. That held for the flat bool; it stopped holding here, because the Flags: line now comes from `class_here()`, which looks up the catalog entry for the *running* host's OS. fix-4-render-group is `applies_on: AUTO_ON_LINUX` only, so bare-metal Linux renders "AUTO" and every other host falls back to PRINT-ONLY -- the generic "does not apply here" answer diagnose-11 already covers, not a second platform-specific behaviour worth asserting under this scenario's name. Gated the scenario `@requires-os:linux @requires-bare-metal`, matching the sibling scenarios for this same fix-id (diagnose-08, -15, -16), and corrected the stale comment. Verified against the Strix Halo WSL2 and Windows CI logs (both failed on this exact assertion) and reproduced/fixed locally by running the real cucumber harness (not the `-n` scenario filter, which bypasses the tag-based skip resolution) against this repo's own WSL2 host. This branch forked before `skills/rocm-doctor/` landed on main. Rebasing onto current main surfaced the gap review caught: the skill's catalog table and `rocm fix`'s own listing used to agree on a flat yes/no per id, and the class rewrite breaks that for any id whose class is not the same on every platform it applies to -- `fix-2-unset-override` (print-only on Linux/WSL, auto on Windows) and `fix-9-igpu-dgpu` (reclassified from AUTO to NEEDS-ARG outright). `skill_steps.rs`'s marker comparison is now host-aware: it reads the catalog's base marker plus an optional per-platform override, derives what `rocm fix` should report on the host the scenario is actually running on (folding in the CLI's own out-of-scope-means-PRINT-ONLY fallback), and compares that against the real listing instead of a flat bool. A silent trap in the obvious fix -- mapping an unrecognised marker to "drop the row" would have made fix-9 vanish from the comparison instead of failing on a mismatch -- is closed by recognising all four markers explicitly. `skills/rocm-doctor/reference.md` gained the same per-host story in prose (which platform's auto set is which) and in the catalog table (every cell now spells the marker word the CLI prints, not a yes/no this change retired). A new `tests/skill_reference.rs` guard, run in the ordinary `cargo test` set with no built `rocm` binary needed, catches a cell still using the retired vocabulary before the cucumber suite would. Three smaller review corrections in the same spirit: `diagnose.rs`'s `os_family` parameter renamed to `platform_family` to match both its own doc comment and its call site, which both already said "family, not os_family"; the regression test comparing `diagnose`'s applicability against the catalog now reads `fix::class_on` instead of a removed flat accessor, same claim, current API; and diagnose-20's title now says "auto-applicable here" rather than a bare "auto-applicable", matching the per-host story introduced above. A trailing comment on fix-17's `rationale` string (explaining the commands block below it) was glued to the end of that string by an earlier edit that deleted the line between them, leaving the rest of the comment floating detached from what it describes. Moved onto its own lines directly above `commands:`, where rustfmt will keep it. Signed-off-by: Eugene Volen <Eugene.Volen@amd.com>
7c845c8 to
e7f9b7f
Compare
|
Addressed this round's review (all 6 inline comments replied to individually): Fixed (code):
Replied only (no code change):
PR description's Verification section rewritten with the corrected e2e evidence and the |
What
auto_applicablewas a flatboolmeaning "rocm fix <id>will carry this out", and it was wrong for two entries:fix-2-unset-overrideon Linux.run_unset_overridesplits by platform. The Windows arm takesFixOptionsand does the dry-run/confirm dance;run_unset_override_linuxtakes no options at all — it reads the live override, scans five shell rc files, and reports where it is set. It never writes, so--dry-runis a no-op and--yesis never read.fix-9-igpu-dgpuwith no--device-index. Both arms print the query that identifies the discrete GPU and return without acting.Both were marked auto-applicable, so a user — and an agent reading the same output — was told a change was coming that never came, and got exit 0 confirming it.
The repo already knew.
fix_9_without_device_index_is_print_only_and_returns_zero, the comment on the fix-2 dry-run test, and a step comment in the e2e suite all say print-only for exactly these cases. Only the type disagreed.Why a class, not two corrected booleans
A bool cannot say either of these things: that behaviour differs by platform, or that it is conditional on an argument.
auto_applicableis now derived from a per-platform class —AUTO,NEEDS-ARG,PRINT-ONLY,DIAGNOSE-ONLY. Scope and class are held together because they are one fact: fix-2 applies on Linux as print-only and on Windows as auto.DIAGNOSE-ONLYcovers problems that can be detected and explained but have no reliable fix. It has no member yet — all 16 entries have real fixes; twelve are print-only because they need sudo, a reboot, a reinstall or a download. The first member arrives with the conflicting code-object-manager entry, which is where its scenario will land.Non-obvious decisions
The class says what happens to the machine, not whether a runner runs. Gating the runner on the class would have thrown away fix-2's Linux rc-file report and printed a generic "copy the commands above" in its place. A print-only entry may hold a runner that reports without writing;
a_recipe_that_acts_has_a_runnerasserts only the direction that matters.DIAGNOSE-ONLYexits 0. Exit codes signal outcome, and "explained, nothing to do" is not a failure —3already means "not applicable here", a different claim that would send a caller looking for another machine. A caller reads the class from the listing before invoking, so it needs no new code to branch on. Adding one before the exit-code map is formalised would also mean the published skill treating it as an error. Flagging it: this is worth a second opinion. (Raised again in review: the variant has no catalog member yet and costs aPlan::Unfixablearm, a synthetic test fixture, and user-facing prose in README/--helpfor something nothing produces today. Keeping it per the earlier round's reasoning —rocm diagnose --jsonalready serialisesclass, so a consumer deserialising that into a fixed enum would reject a variant added later — but leaving the tradeoff open for a second opinion rather than re-deciding it unilaterally.)auto_applicableis kept, derived. It is redundant onceclassexists, but it is the field published consumers read, and it now answers its own question truthfully for the first time. Removing it is a type change that belongs with the contract-version work.The listing is per-machine. The marker shows what the entry does on the host in front of you, so the set marked
AUTOis now OS-dependent — which is why the e2e expectation is too.Killing the duplication
diagnoserestated applicability by hand at 21 sites. Those are gone; the class is read off the catalog in one place, keyed on the examined machine's OS rather than the running one. The two copies had already drifted onmain— fix-9 wasauto_applicable: truein the catalog andfalsein the Linux arm of its own checker — and nothing compared them, because the existing cross-check compares only the command block.Rebased onto current main: the skill contract broke, silently
This branch forked before
skills/rocm-doctor/landed on main. The merge onto current main is textually clean inskills/**and the e2e skill-contract steps — nothing in the rebase itself warns about this — but the reclassification breaks the published skill's contract in a way only review caught:tests/e2e-cucumber/tests/e2e/skill_steps.rs's marker parsing recognised onlyAUTO/PRINT-ONLY; fix-9's newNEEDS-ARGwould have been silently dropped from the comparison (_ => continue) rather than reported as a mismatch, producing a redskill-01on main with the misleading message "reference.md documents fix-9 whichrocm fixdoesn't offer".skills/rocm-doctor/reference.md's catalog table and prose still claimed a flat, host-independent "auto-applicable" set (four ids, including fix-9), which the per-platform class makes impossible to state as one list —fix-2-unset-overrideis AUTO on Windows only, and fix-9 is never AUTO at all now.Fixed both.
skill_steps.rs's marker comparison is now host-aware: it reads the catalog's marker plus an optional per-platform override, derives whatrocm fixshould report on the host the scenario is actually running on (folding in the CLI's own out-of-scope-means-PRINT-ONLY fallback), and recognises all fourFixClassmarkers so an unrecognised one still fails loudly instead of disappearing.reference.md's table now spells the literal marker wordrocm fixprints (not yes/no), and its "auto-applicable" prose is a per-host bullet list (linux/windows/wsl). Addedtests/skill_reference.rs::catalog_markers_use_the_cli_vocabulary, a plaincargo test(no built binary needed) that catches a strayyes/nocell before the cucumber suite would — proved it can fail by reverting fix-9's cell and watching it go red, then restored it.The Scope note below ("
skills/... deliberately untouched") no longer holds; superseded by this section.Verification
cargo fmt --all -- --check,cargo clippy --workspace --all-targets -- -D warnings,cargo clippy -p e2e-cucumber --test e2e -- -D warnings— all clean.cargo test --workspace --all-targets— clean (966 passed). One run hitcomfyui::tests::status_reports_stopped_when_saved_comfyui_pid_is_gone, the documented full-suite-parallel-load flake; re-ran once, passed.cargo xtask e2e -- -n skillon a WSL2 dev host — all 6 scenarios pass, including skill-01/02/03 against the new host-aware marker logic (this host resolves to thewslbranch, so that path is exercised for real, not just reasoned about).cargo xtask e2e -- -i diagnose.feature(not-n diagnose, which bypasses the tag-based skip resolution — see the warning in this commit's own message, anddocs/testing.md) — 22 scenarios, 16 run and pass, 6 skip. All 6 skips are@requires-bare-metalscenarios (platform.json: "requires a bare-metal host; this one is WSL2"), including@id:diagnose-fix-preview-states-required-flags(diagnose-20) and@id:diagnose-fix-needing-an-argument-says-so(diagnose-22). Both are new/changed by this PR — diagnose-20's@requires-bare-metaltag is added here (it was untagged on main), and diagnose-22 is a new scenario carrying it from the start — so neither is "unchanged from before this PR", and the earlier draft of this section's "3 failures" claim was wrong on both counts (they're skips, not failures, under the harness's actual skip-resolution path). The lanes that exercise these two for real are the self-hosted bare-metal Linux and Windows lanes (not WSL2) — seedocs/ci-hardware-testing.md.Autofailsdiagnose-17(anddiagnose-12, which pins the auto set).diagnose-18initially passed under the mutation — a whole-output search for--device-indexmatched the recipe's own note — so the assertion was narrowed to the flags line, which is absent entirely when the entry is markedAUTO.Risk
Low-to-medium. User-observable by design: the
flags:line drops "rocm fix can run it" for fix-2 on Linux and for fix-9, and the JSONauto_applicableflips with it. That correction is the point of the change. No fix gains the ability to mutate anything it could not mutate before.Scope
No longer true after rebasing onto current main — see "Rebased onto current main" above.skills/and anything federation-related is deliberately untouched.amd/skillsfederation itself is still untouched; only this repo's ownskills/rocm-doctor/reference.mdand its e2e contract steps changed, to keep the published skill accurate against the reclassification.