Repository navigation
ROCMAI-759: move the remaining command clusters out of main.rs - #840
Conversation
There was a problem hiding this comment.
🔵 Needs a closer look
Missing main.rs and service_records.rs diffs prevent verification of the broad CLI relocation, and maintainer confirmation is needed for move equivalence and full-workspace, end-to-end, and Windows validation on the rebased head.
No open issues 🎉
What changed in this PR
This PR continues the CLI modularization by moving command handlers and supporting helpers out of main.rs, leaving it focused on CLI definitions, dispatch, and glue. The changes are intended to preserve behavior; the ComfyUI dispatch extraction remains a separate follow-up.
Changes:
- Relocates command handlers, audit logging, model-fit assessment, and bridge helpers into focused modules alongside their existing tests.
- Extracts the update and chat dispatch bodies into functions, keeping chat orchestration separate to avoid a circular module dependency.
- Updates imports, visibility, source-path assertions, and architecture documentation to follow the relocated code.
| File | Description |
|---|---|
xtask/src/ascii_output_contract.rs |
Retargets the spinner-literal exemption to its new module. |
docs/testing.md |
Updates the service-pruning test location. |
docs/architecture.md |
Documents extracted modules and revised dependencies. |
crates/rocm-dash-tui/src/ui/examine_manager.rs |
Updates a comment identifying the refusal-text source. |
apps/rocm/src/update_cmd.rs |
Receives the update command handler. |
apps/rocm/src/setup_cmd.rs |
Houses setup handlers, rendering, and existing tests. |
apps/rocm/src/services_text.rs |
Updates helper imports and module documentation. |
apps/rocm/src/services_cmd.rs |
Houses service dispatch and approval-gated actions. |
apps/rocm/src/service_launch.rs |
Updates comments describing relocated service helpers. |
apps/rocm/src/service_hints.rs |
Receives service-action label and tool-mapping helpers. |
apps/rocm/src/serve_cmd.rs |
Receives serve-warning collection and its tests. |
apps/rocm/src/runtime_install_finalize.rs |
Updates the documented install-handler location. |
apps/rocm/src/model_fit.rs |
Houses model-fit assessment, platform gates, and tests. |
apps/rocm/src/managed_service_status.rs |
Updates documentation of callers. |
apps/rocm/src/install_cmd.rs |
Houses install handlers, SDK request mapping, and tests. |
apps/rocm/src/gpu_policy.rs |
Updates documentation references to moved helpers. |
apps/rocm/src/freeform_answer.rs |
Houses read-only freeform answer rendering. |
apps/rocm/src/examine_report_text.rs |
Updates module documentation for relocated callers. |
apps/rocm/src/examine_cmd.rs |
Houses examine dispatch and JSON document types. |
apps/rocm/src/driver_install.rs |
Updates comments identifying the install caller. |
apps/rocm/src/diagnose_cmd.rs |
Houses diagnose, fix, report delivery, and existing tests. |
apps/rocm/src/config_cmd.rs |
Houses configuration commands, rendering, and tests. |
apps/rocm/src/cli_audit.rs |
Houses audit and lifecycle logging with existing tests. |
apps/rocm/src/chat.rs |
Removes SDK request mapping and tests relocated to install. |
apps/rocm/src/chat_cmd.rs |
Houses chat orchestration separately from chat internals. |
apps/rocm/src/bridge_snapshot.rs |
Houses bridge snapshot and engine-inventory builders. |
apps/rocm/src/advised_commands.rs |
Updates source-path assertions for moved command text. |
AGENTS.md |
Updates the setup-test documentation link. |
Review effort: Balanced
nowycondro
left a comment
There was a problem hiding this comment.
🤖 Automated review (Claude Code) · b7776c4
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.
Review — no blocking findings
Full review of the whole change. Implements PRs 1–15 of ROCMAI-759 (Phase 8.1-G): mechanically moving 13 command-handler/helper clusters, plus the Update and Chat dispatch-arm bodies, out of apps/rocm/src/main.rs into their own modules. PR 16 of that ticket (moving the comfyui dispatch function) is explicitly deferred to ROCMAI-833, consistent with the ticket's own "Open decision" section requiring a maintainer call on where the clap definition lives before that move happens. The ticket's own automation note says only the terminating PR for its scope may name the ticket key in its body (earlier PRs must not, or automation closes the ticket early) — this PR does name it, which is consistent with it being the last PR against the (now comfyui-excluded) scope of ROCMAI-759, not a premature auto-close risk.
Blocking
None.
Non-blocking
cli_audit.rs's own module doc comment is stale about its caller list —apps/rocm/src/cli_audit.rs:14-19
The doc comment (added verbatim by this PR's first commit,f622129, and never touched by any later commit in this PR) enumerates the external callers ofrecord_cli_audit_eventasmain.rs, chat.rs, engines_cmd.rs, runtime_install_finalize.rs, runtimes_cmd.rs, service_launch.rs, storage.rs. At the PR's actual head,git grep -l 'record_cli_audit_event' apps/rocm/srcalso showsconfig_cmd.rs,install_cmd.rs,service_records.rs,services_cmd.rs, andupdate_cmd.rsas callers — all five added by this same PR's own later commits, none reflected back into this list. By contrast,service_hints.rs's equivalent doc comment was correctly updated by a later commit (dc4625a) when its caller moved — so the project clearly treats this kind of caller-list accuracy as something each PR in this stack is expected to maintain, and this one instance slipped through.
Confidence 85 · mechanical · Fix: extend the caller list (or genericize the wording, the way thedocs/architecture.mdentry for the same module already does) to include the five newer callers.
Decisions for the author
- Giving the
Chatarm its ownchat_cmd.rsinstead of folding it intochat.rs— tradeoff
The ticket's own plan (ROCMAI-759 PR 15) called for moving theCommand::Chatarm body into a function inside the existingchatmodule. The PR deviates and creates a newchat_cmd.rsinstead, becausechat_cmd's handler calls bothchat::anddash::, anddash.rsalready calls intochat.rs— folding it intochat.rswould create achat↔dashcycle. Verified directly:chat.rshas nouse/call intodash,dash.rscalls intochat.rs, andchat_cmd.rsimports both. This is a reasonable, disclosed deviation from the ticket's plan that avoids a real cycle, at the cost of one more small dispatch-only file in an already large (13-new-file) module count for this single ticket. Worth the author/maintainers confirming they're comfortable with the module count this stacked ticket is producing, versus, e.g., folding some of the smallest dispatch-only modules together.
Positive signals
- Every one of the 15 commits was independently verified byte-identical between its pre-move location (diffed against that specific commit's own parent, not a looser
main-relative diff) and its new module, modulo only the documentedpub(crate)visibility widenings — across all clusters, including the two that are a real code-shape change rather than a textual move (update()/run_chat_command, extracted from inlinedispatch()match arms into standalone functions with the same body, same parameter order, and narrowly-scoped#[allow(clippy::...)]attributes matched to the exact lint each longer signature triggers). - The stated rationale for
chat_cmd.rsavoiding achat↔dashmodule cycle checks out against the actualusestatements, not just the commit prose. - The correctness-critical
FixExitCodeerror-chaining detail (an explicit code comment warns that re-stringifying the error would silently break its exit-code-carrying downcast) is preserved exactly in the movedfix(), and the regression test exercising that exact path was deliberately left inmain.rsrather than moved, so it still proves the chain end-to-end. - A subtle test-portability hazard — a subprocess test that re-invokes itself by a hardcoded test-path string (
model_fit::tests::docker_unreachable_subprocess_helper) — was correctly updated for the module's new location, with no stale"tests::..."string left anywhere in the tree. docs/architecture.mdis updated in the same commit as each move (never deferred), and its new/updated entries were independently verified against the code (callers,pub(crate)rationale, dependency direction, exact test counts) rather than taken on faith — including entries for files this PR didn't even touch directly, corrected because the move made their existing text false.- All 15 commits carry DCO sign-off from a real company identity and no AI-attribution footers, consistent with this repo's OSS-contribution requirements.
- The one bot-review concern on this PR ("missing main.rs and service_records.rs diffs prevent verification") does not hold up: both files are fully present in the diff fetched directly via git (
main.rs1,464+/6,075-,service_records.rsa new 1,759-line file) and were fully reviewed; this looks like a diff-rendering limitation of whatever surfaced that bot's view, not a gap in the actual PR contents.
Deployment notes
- The PR description itself names several other open PRs (#817, #799, #709, #826, #837) that touch code relocated here and will need rebasing after this merges — a coordination point for whoever merges next, not a defect in this change.
- CI for the reviewed head (
b7776c4a) is green on every lane that ran: clippy, the main build-and-test/affected-crates lanes, Windows build-and-test, the E2E suite and its consolidated report, Strix Halo (Ubuntu current, WSL2), commit-signatures+sign-off, markdown-links (lychee), license headers, coverage (ratcheted), and CodeQL. Four hardware-gated E2E lanes (Strix Halo Ubuntu nightly, Strix Halo Ubuntu release, W7900, MI300X) showqueuedrather than completed for this head — not a failure, but hardware-only verification on those specific lanes isn't confirmed either way from CI alone.
What this covered
Every one of the 15 commits in 6eeec62...b7776c4 (the PR's full range against origin/main, fetched read-only via pull/840/head), read in full via 8 independent fan-out workers grouped by cluster coupling, each diffing the moved code against that specific commit's own parent (not a single main-relative diff, to avoid misattributing earlier stacked commits' changes). This includes apps/rocm/src/main.rs's full diff and the new service_records.rs (1,765 lines) in their entirety, despite a prior bot review's claim that these were unavailable for review — both were fetched and read completely via git. Also covered directly by the reviewing driver: CI status for the head commit, commit metadata (DCO sign-off, no AI footers) for all 15 commits, the full docs/architecture.md/AGENTS.md/docs/testing.md diffs, the final main.rs structure (confirming only the ticket's "stays" list of functions remains before its test module), the chat/dash/chat_cmd import graph, and the named ticket ROCMAI-759 (retrieved directly by key, not via a link in the PR body).
Did not run: a local cargo build/cargo test/cargo clippy (no Rust toolchain available in this review environment) — relied on the PR's own green CI for that verification instead, per the above. History and prior-changes passes were folded into each worker's per-commit diffing rather than run as separate passes, since the "history" here is the commit stack itself. Not reconciled against this PR's own review discussion or existing comments here — this review was produced blind to that, by design.
🤖 Generated with Claude Code
juhovainio
left a comment
There was a problem hiding this comment.
I went through the diff and found nothing blocking. The moves look behaviour-preserving: the removed and added lines differ only in pub(crate) widening, rustfmt re-wraps, use blocks and doc text. The test count is unchanged (75 moved), the Update and Chat arm bodies are identical to before, and the architecture doc and path pins are updated.
Things worth a look before or after merge (none blocking):
- The PR is currently conflicting with main and needs a rebase. After that, check that nothing #817/#799/#709/#826/#837 added to
main.rswas dropped or re-added. - The PR says it completes ROCMAI-759, but the ticket still lists the
comfyuidispatch move and "main.rsholds only the stays list". That move is deferred to ROCMAI-833, so the ticket text should be amended before the key auto-closes it. - The four
command_chat_*source-text tests stay inmain.rsbut readchat_cmd.rs. They would sit more naturally inchat_cmd.rs's own tests. - The ticket asks for each new module's
use crate::edges in the PR body; the body only says a scan found no new two-module cycle. - The two Strix Halo Ubuntu E2E jobs (release, nightly) hit the 45m limit with the step cancelled and no assertion failure visible. The same hardware passes on WSL2 and Windows, so this looks like infrastructure, but a rerun would confirm it.
This is a diff-only read; it doesn't replace CI or a local run.
| //! re-imported via `use crate::examine_report_text::{...};`; `examine_cmd.rs`'s | ||
| //! `examine()`, which the `Command::Examine` arm calls, imports and calls | ||
| //! `examine_human_report` itself. `main.rs`'s own `launch_default` calls | ||
| //! `render_launch_summary` directly, also re-imported there. `render_examine_text`, `render_examine_text_with_paths`, and |
There was a problem hiding this comment.
Nit: this doc line was joined rather than re-wrapped after the edit and now runs well past the surrounding width; re-wrap it like the neighbouring lines.
There was a problem hiding this comment.
Re-wrapped in 5f1694d: the sentence now breaks after "also re-imported there." so the lines match their neighbours.
…nto cli_audit.rs Moves record_cli_audit_event and its helpers (the lifecycle and per-action log writers, their path builders and the two sanitizers) verbatim into a new cli_audit.rs, together with the two tests that exercise only them. Other modules keep reaching the items as crate::<name> through a re-import in main.rs. Edits beyond the relocated lines, module and import wiring: - cli_lifecycle_log_path and sanitize_log_value become pub(crate) (callers in services_text.rs, runtime_install_finalize.rs and update_cmd.rs) - main.rs drops two rocm_core imports that only the moved code used - the comment above main.rs's re-import block gains a sentence for the new re-import - the module doc in examine_report_text.rs no longer lists the two moved tests as living in main.rs - docs/architecture.md gains the cli_audit.rs entry, loses the audit log from the main.rs paragraph, and corrects the examine_report_text.rs entry, which still said the two audit-log tests stayed in main.rs Signed-off-by: Jussi Elo <jussi.elo@amd.com>
…into service_hints.rs Moves service_action_command, service_action_verb, service_action_past_tense and sandbox_tool_arg_from_service_tool into service_hints.rs, verbatim. They have to land before the services command and the service-record cluster move, because services_text.rs reads service_action_past_tense and a later move of the services cluster would otherwise make services_text.rs and the new module depend on each other. Edits other than relocated lines and module/import wiring: - the four functions widen from private to pub(crate). - services_text.rs now imports service_action_past_tense from service_hints instead of through the crate root. - the intra-doc link in service_hints.rs to crate::service_action_command is rewritten to point at the function in the same module. - the service_hints.rs module doc gains a paragraph describing the four helpers. - the comment above main.rs's re-import block gains a sentence for the new import. - docs/architecture.md extends the service_hints.rs entry. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
…s into service_records.rs Moves the cluster behind `rocm services remove` and `rocm services prune` into a new service_records.rs: ServiceRecordArtifacts and the artifact helpers, managed_service_record_is_in_use, remove_managed_service_record, the prune plan, render and apply steps, the age-gate helpers and prune_managed_service_records. The 20 tests that exercise only those items move with them, along with parse_services_prune_args, the helper they share. The function bodies and the tests are relocated verbatim. main.rs re-imports the four items its clap definition and services() use. Edits other than relocated lines and module/import wiring: - DEFAULT_SERVICE_PRUNE_MIN_AGE_HOURS, remove_managed_service_record, service_prune_min_age_hours, prune_managed_service_records and ServicePruneOutcome (with its text, removed_records, removed_files and failures fields) widen from private to pub(crate), since main.rs reads them; rustfmt re-wraps the remove_managed_service_record signature as a result. - plant_service_record and plant_service_record_without_its_key, the test fixtures that stay in main.rs, widen to pub(crate) so the moved tests reach them through crate::tests. - the remaining main.rs tests now import ManagedServiceRecord and load_managed_service themselves instead of through the crate-root imports that production code no longer needs. - the section-divider comment above the cluster in main.rs is not carried over. - path pins follow the code: the exempt-literal entry for the prune spinner label in xtask's ASCII contract, the two labelled-line assertions in the advised-command checker, and the test path named in docs/testing.md (now a link). - doc references follow the code: gpu_policy.rs's intra-doc link to prune_managed_service_records and services_text.rs's module doc. - the comment above main.rs's re-import block gains a sentence for the new import, and docs/architecture.md gains the service_records.rs entry and updates the main.rs, service_launch.rs, managed_service_status.rs and services_text.rs entries. - managed_service_status.rs's module doc named main.rs as the caller of the liveness helpers for service-record removal and pruning; it now names service_records.rs. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
…s_cmd.rs Moves services() and run_approved_service_action into a new services_cmd.rs, together with the one test that exercises them. The function bodies and the test are relocated verbatim, and the dispatch() call site is untouched. main.rs re-imports services for dispatch() and, under cfg(test) only, run_approved_service_action, which advised_commands.rs's test reaches as super::run_approved_service_action. Edits other than relocated lines and module/import wiring: - services and run_approved_service_action widen from private to pub(crate). - main.rs stops importing the service_records and service_hints items and the services_text items that only the moved code used; services_cmd.rs imports them directly. - doc references follow the code: the module docs of service_records.rs, service_hints.rs, services_text.rs and service_launch.rs named main.rs's services() and run_approved_service_action, and the last also described where record_cli_audit_event, existing_live_managed_service and the record removal and pruning live; those sentences are rewritten to the current locations. - docs/architecture.md gains the services_cmd.rs entry and updates the main.rs, service_launch.rs, service_records.rs and services_text.rs entries. - the service_hints.rs entry in docs/architecture.md lists the modules that now use it, in place of main.rs. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
…d.rs Moves config(), read_provider_key_from_user, render_config_text and telemetry_policy_summary into a new config_cmd.rs, together with the two render_config_text tests. The function bodies and the tests are relocated verbatim, and the dispatch() call site is untouched. main.rs re-imports config and render_config_text, so chat.rs keeps reaching render_config_text as crate::render_config_text. Edits other than relocated lines and module/import wiring: - config widens from private to pub(crate) for dispatch(). - main.rs drops the active_runtime_marker_path and std::io::Read imports that only the moved code used, and the moved tests import TELEMETRY_MODE_OFF themselves. - the pin in the advised-command checker that exempts the `rocm config` report heading now names config_cmd.rs. - the examine_report_text.rs module doc, which said render_config_text and telemetry_policy_summary were left in main.rs, now says they live in config_cmd.rs. - docs/architecture.md gains the config_cmd.rs entry and updates the main.rs and examine_report_text.rs entries. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
…el_fit.rs Moves assess_model_on_this_host, assess_model_with_host_paths, assess_model_for_host, host_accelerator_memory, classify_accelerator_memory, examination_reports_amd_gpu, PlatformRuleOut, engine_ruled_out_by_platform and unsupported_here_for into a new model_fit.rs, together with the 18 tests (and the engine_selection_hosts helper) that exercise only them. It is a module of its own rather than part of the diagnose handler so examine_report_text.rs, which reads PlatformRuleOut and engine_ruled_out_by_platform, does not depend on a command module. The function bodies and the tests are relocated verbatim, and main.rs re-imports the three items other code reaches as crate::<name>. Edits other than relocated lines and module/import wiring: - assess_model_on_this_host, PlatformRuleOut and engine_ruled_out_by_platform widen from private to pub(crate). - the moved engine_ruled_out_by_platform_gates_aim_on_docker_reachability re-runs the test binary on its helper by full test path; the string now reads model_fit::tests::docker_unreachable_subprocess_helper instead of tests::docker_unreachable_subprocess_helper. The old path would match no test and the parent would pass without running the helper, so it was checked by breaking the helper's assertion and confirming the parent goes red. - main.rs drops the select_serve_engine, gpu_policy and rocm_core imports that only the moved code used, and the sentence in the comment above the re-import block that said select_serve_engine is re-imported for assess_model_for_host. - doc references follow the code: the module docs of serve_cmd.rs and examine_report_text.rs and the module doc in gpu_policy.rs named main.rs as the home of these items, and now name model_fit.rs; gpu_policy.rs's intra-doc link to host_accelerator_memory, which did not resolve before either, becomes a plain code reference. - docs/architecture.md gains the model_fit.rs entry and updates the main.rs, gpu_policy.rs, serve_cmd.rs and examine_report_text.rs entries. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
… into diagnose_cmd.rs Moves diagnose(), established_entry, perform_delivery, show_prepared_report and fix() into a new diagnose_cmd.rs, together with the five tests and the RecordingOpener fixture that exercise only them. FixExitCode stays in main.rs with the rest of the exit-code plumbing. The function bodies and the tests are relocated verbatim, and the dispatch() call sites are untouched; main.rs re-imports diagnose and fix for them. Edits other than relocated lines and module/import wiring: - diagnose and fix widen from private to pub(crate). - main.rs drops its re-import of assess_model_on_this_host (diagnose_cmd.rs imports it from model_fit.rs directly) and the rocm_core::browser::Opener import that only perform_delivery used. - the moved tests take their own use lines (RefCell, Opener, Delivery, perform_delivery) from the top of main.rs's test module. - the model_fit.rs module doc and the comment in rocm-dash-tui's examine_manager.rs that said show_prepared_report lives in main.rs now name diagnose_cmd.rs. - docs/architecture.md gains the diagnose_cmd.rs entry and updates the main.rs and model_fit.rs entries. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
…cmd.rs Moves install(), therock_install_version_selector and therock_install_version_selector_display out of main.rs, and sdk_install_request out of chat.rs, into a new install_cmd.rs, together with the two sdk_install_request tests from chat.rs's test module. Taking sdk_install_request along keeps install_cmd.rs from depending on chat.rs, which calls therock_install_version_selector. The function bodies and the tests are relocated verbatim, and the dispatch() call site is untouched. main.rs re-imports install and therock_install_version_selector, so chat.rs keeps reaching the latter as crate::therock_install_version_selector. Edits other than relocated lines and module/import wiring: - install and therock_install_version_selector widen from private to pub(crate). - sdk_install_request keeps the pub(crate) it had in chat.rs, although only install() and its tests call it now. - install()'s call to chat::sdk_install_request becomes a call to the function in the same module. - the doc comment of the first moved test said "the parse test above"; it now names the clap test it meant, install_sdk_devel_flag_defaults_off_and_wires_through_when_passed in main.rs. - main.rs drops the driver_install and runtime_install_finalize imports that only install() used, and the comment above its re-import block loses the sentence about install() and gains one for the new re-import. - doc references follow the code: the module docs of driver_install.rs and runtime_install_finalize.rs named main.rs's install(). - docs/architecture.md gains the install_cmd.rs entry and updates the main.rs, driver_install.rs and runtime_install_finalize.rs entries and the sentence about install() staying in main.rs. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
…to freeform_answer.rs Moves render_freeform_read_only_answer and render_freeform_examine_answer into a new freeform_answer.rs, verbatim. No unit test calls either function, so no test moves. main.rs re-imports render_freeform_read_only_answer for run_freeform, which stays where it is. Edits other than relocated lines and module/import wiring: - render_freeform_read_only_answer widens from private to pub(crate). - main.rs drops the recover_setup_runtime_registration, runtime_usability_status and DEFAULT_LOG_TAIL_LINES imports that only the moved code used, and the comment above its re-import block no longer names recover_setup_runtime_registration as re-imported there; the same comment also gets re-wrapped. - docs/architecture.md gains the freeform_answer.rs entry. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
Moves setup(), render_setup_status_text and reset_setup_prompt_state into a new setup_cmd.rs, together with the three tests that exercise only them. The function bodies and the tests are relocated verbatim, and the dispatch() call site is untouched. main.rs re-imports setup and render_setup_status_text, so chat.rs keeps reaching the latter as crate::render_setup_status_text. Edits other than relocated lines and module/import wiring: - setup and render_setup_status_text widen from private to pub(crate). - main.rs drops the validate_runtime_manifest_for_activation, std::fmt::Write and test-only write_test_pip_runtime imports that only the moved code used, and the comment above its re-import block no longer names validate_runtime_manifest_for_activation as re-imported there. - AGENTS.md names setup_reset_cli_output_is_plain_and_persists_first_time_prompt in setup_cmd.rs instead of main.rs (the citation is now a link). - docs/architecture.md gains the setup_cmd.rs entry and drops setup() from the main.rs paragraph. - the comment above main.rs's re-import block is re-wrapped, where earlier edits had left an orphaned short line. - the moved test's comment that names the dashboard test proving the onboarding behavior now points at crates/rocm-dash-tui/src/app/focus.rs, where that test lives after the dash-tui split on main. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
…s into bridge_snapshot.rs Moves build_codex_bridge_snapshot, build_codex_bridge_gpu_snapshot, builtin_codex_bridge_engine_inventory and builtin_engine_inventory into a new bridge_snapshot.rs, verbatim. No test exercises only them, so none moves. builtin_engine_inventory stays a table of its own and is not merged with main.rs's engine_inventory. main.rs re-imports the three builders, so chat.rs keeps reaching them as crate::<name>. Edits other than relocated lines and module/import wiring: - all four functions widen from private to pub(crate). - the main.rs test that checks --engine's help against builtin_engine_inventory now imports it from bridge_snapshot. - main.rs drops the managed_service_status and rocm_core imports that only the moved code used, and the comment above its re-import block gains a sentence for the new re-import. - doc references follow the code: managed_service_status.rs's module doc named main.rs as the caller of load_managed_services for the snapshot and for prune planning; it now names bridge_snapshot.rs and service_records.rs. - docs/architecture.md gains the bridge_snapshot.rs entry, drops the snapshot builder from the main.rs paragraph and updates the managed_service_status.rs entry. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
…cmd.rs Moves examine() and the ExamineJson and ExamineJsonSummary document types into a new examine_cmd.rs, verbatim. No test calls them, so none moves. The dispatch() call site is untouched; main.rs re-imports examine for it. Edits other than relocated lines and module/import wiring: - examine widens from private to pub(crate). - main.rs drops the examine_human_report, setup_runtime_paths and ExamineSummary imports that only the moved code used. - doc references follow the code: the module doc of examine_report_text.rs and its docs/architecture.md entry said main.rs's examine() calls examine_human_report through a re-import; they now name examine_cmd.rs, which imports it directly. - docs/architecture.md gains the examine_cmd.rs entry and drops examine() from the main.rs paragraph. - main.rs's re-import of examine sits above the comment that explains the cfg(test) re-import of append_examine_runtime_state, instead of between that comment and the import it describes. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
…d.rs Moves collect_serve_notes, whose only production caller is serve(), into serve_cmd.rs, together with its two tests and the vram and host_gpu fixtures only those tests use. The function and the tests are relocated verbatim and keep their private visibility; main.rs no longer imports or re-imports anything for it. Edits other than relocated lines and module/import wiring: - main.rs drops the GpuVramUsage, serve_gpu_low_memory_warning and GpuSelection imports that only the moved code used; serve_cmd.rs imports GpuVramUsage itself and no longer imports collect_serve_notes from the crate root. - doc references follow the code: serve_cmd.rs's module doc said collect_serve_notes stays in main.rs and gpu_policy.rs's module doc named main.rs as its reader of GpuVramUsage; both now name serve_cmd.rs. - docs/architecture.md updates the serve_cmd.rs entry and the gpu_policy.rs entry (which readers GpuVramUsage has, and where the duplicated fixture builders are needed). Signed-off-by: Jussi Elo <jussi.elo@amd.com>
…te_cmd.rs
Moves the body of the Command::Update arm of dispatch() into a new update()
function in update_cmd.rs, next to the helpers it calls. The arm now reads
Some(Command::Update { .. }) => update(apply, runtime, activate, dry_run, json,
timeout_secs); its destructuring pattern is unchanged, and the body is
relocated verbatim apart from its indentation and the parameter list, which
replaces the arm's bindings. This is the one step in the series that edits
dispatch() beyond a call-site re-import.
Edits other than relocated lines and module/import wiring:
- update is a new pub(crate) function whose signature takes the six values the
arm bound (apply, runtime, activate, dry_run, json, timeout_secs); the arm's
`return` statements are returns from update.
- update carries #[allow(clippy::fn_params_excessive_bools)]: its six
parameters include four bools, which the arm's bindings did not trip.
- rustfmt, run on the body at its new indentation, drops one trailing comma from
the apply_runtime_update call.
- main.rs replaces the apply_runtime_update, render_update_text and
update_should_preview_or_apply imports with the one for update, and
update_cmd.rs imports record_cli_audit_event.
- apply_runtime_update and update_should_preview_or_apply keep their pub(crate)
visibility although only update() calls them now.
- doc references follow the code: update_cmd.rs's module doc described
dispatch() calling three of its functions directly.
- docs/architecture.md updates the update_cmd.rs entry.
Signed-off-by: Jussi Elo <jussi.elo@amd.com>
…md.rs Moves the body of the Command::Chat arm of dispatch() into run_chat_command in a new chat_cmd.rs. The arm keeps its destructuring pattern and now calls run_chat_command with the eight bound values; the body is relocated verbatim apart from its indentation. It gets a module of its own rather than a place in chat.rs because the handler calls into both chat.rs and dash.rs, and dash.rs already calls into chat.rs: putting it in chat.rs would make the two depend on each other. Four source-text tests in main.rs read the handler's text to check its wiring. They keep their names and every assertion, and now read chat_cmd.rs instead of the arm in main.rs. After breaking the handler (a tui::run call, the provider note, the piped-prompt read and the chat_mock forward, one at a time) each of the four goes red. Edits other than relocated lines and module/import wiring: - run_chat_command is a new pub(crate) function that takes the eight values the arm bound, with #[allow(clippy::too_many_arguments)] for its eight parameters. - the main.rs test helper command_chat_handler_body now extracts the function's parameter list and body from chat_cmd.rs instead of the arm's destructure and block; a new chat_cmd_source helper reads the file, and slice_braced_to_arm_end, which only the old extraction used, is deleted. - docs/architecture.md gains the chat_cmd.rs entry and updates the chat.rs entry's sentence about the structural tests that stayed in main.rs. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
Move the four command_chat_* source-text tests next to the handler they read, in chat_cmd.rs's own test module, sharing slice_braced_block and strip_line_comments with main.rs's tests. Stop enumerating cli_audit.rs's callers in its module doc, which had already drifted from the code, and re-wrap an over-long doc line in examine_report_text.rs. architecture.md follows the test move. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
b7776c4 to
5f1694d
Compare
|
Thanks for the reviews. The branch is rebased onto the latest What changed, by finding:
Checked on this head: Not addressed here: the ticket text for the deferred |
nowycondro
left a comment
There was a problem hiding this comment.
🤖 Automated review (Claude Code) · 5f1694d
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.
Review — needs work
Full review of the whole change (merge-base c6ab82b54f685b01e6a3dacd87403c5fd16c9c4c to head 5f1694d5af91c20048e41ce559a12f8a5a4f931f, all 16 commits, fetched read-only via pull/840/head into a scratch clone, never checked out). Every file in the diff read completely by 7 independent fan-out workers grouped by cluster coupling, plus a dedicated full-main.rs/docs pass and a dedicated impact-analysis/ripple/history pass across the whole repository.
Implements all 15 "PR" steps of ROCMAI-759 (the ticket's own comments confirm "Steps 1 to 15 are covered by #840"); step 16 of that ticket (moving the comfyui dispatch function) is explicitly and separately tracked as ROCMAI-833, pending a maintainer decision on where the clap definition lives — consistent with this PR's own description.
Blocking
- The branch is not rebased onto the current tip of
main, and the description's "rebased onto the latest main" claim does not hold for this head — integration risk, not a defect in the reviewed code itself
git merge-base --is-ancestor 6b175eeeb1e881d4b293b9670894fb1811f61de1 pr/840fails: main's tip (6b175ee, "ROCMAI-829: report an unknown service id without the OS error", merged the same morning, before this PR's own last push) is not an ancestor of this PR's head; GitHub reports the PR as blocked/not mergeable. That main commit and this PR both touchapps/rocm/src/services_text.rsanddocs/testing.md, in adjacent-but-currently-disjoint hunks (confirmed by diffing both changesets against their shared base) — so a mechanical rebase looks likely to apply cleanly, but this is unverified by any actual rebase or build, since neither has happened yet.
Confidence 100 (directly confirmed bygit merge-base --is-ancestorand by diffing both changesets against the same base) · architectural · Fix: rebase onto currentmain, re-runcargo clippy/cargo test, specifically re-check theservices_text.rsarea (read_managed_service_manifest) after the rebase, and update the PR description's verification section once that's done.
Non-blocking
- Two functions stay
pub(crate)with no external caller, inconsistent with this stack's own visibility-tightening pattern —apps/rocm/src/update_cmd.rs:253,257(update_should_preview_or_apply,apply_runtime_update)
Both are called only fromupdate()and their own tests, all withinupdate_cmd.rsitself — every other hit of either name acrossapps/rocm/srcis a doc-comment mention, not a call.chat.rs's owndocs/architecture.mdentry states this stack's "visibility audit tightened every other function to module-private, so each function stillpub(crate)has a confirmed external caller"; these two do not.
Confidence 85 · mechanical · Fix: make both a privatefnrather thanpub(crate) fn. - Doubled word in a doc comment —
apps/rocm/src/service_launch.rs:24
Reads "pruning it dispatches to toservice_records.rs".
Confidence 85 · mechanical · Fix: drop the repeated "to".
Decisions for the author
- 13 new single-purpose files (plus 2 dispatch-arm extractions) for one ticket, several dispatch-only with no owned types (
chat_cmd.rs,bridge_snapshot.rs,service_hints.rs) — tradeoff
Every module boundary checked out as correct and cycle-free — e.g.chat_cmd.rsdepends on bothchat.rsanddash.rsprecisely because folding it into either would create the cycledash.rs's existing call intochat.rswould otherwise close — so nothing here is wrong, but it is a lot of small files for one ticket. Worth the author/maintainers confirming they're comfortable with the resulting module count versus, e.g., folding the smallest dispatch-only modules together. - Two e2e-cucumber feature-file comments went stale because of this PR's own moves — answered-by-intent
tests/e2e-cucumber/features/model_catalog.feature:15still says "seeengine_ruled_out_by_platformin main.rs" (moved tomodel_fit.rsby this PR), andtests/e2e-cucumber/features/service_stop.feature:3still says "the approval gate inmain.rs" (moved toservices_cmd.rs). ROCMAI-759's own "Out of scope" section says: "Pre-existing stale comments this ticket does not own: ... e2e-cucumber feature comments citingmain.rs(the suite stays unmodified)." That is a blanket, written decision to leave this whole class of comment stale rather than touch the e2e suite as part of these move PRs — these two would otherwise have been non-blocking findings. (Several other e2e-cucumber comments citingmain.rswere already stale before this PR, from unrelated earlier moves; the same policy covers those too.)
Positive signals
- Every one of the 15 move-commits was independently verified content-identical (whitespace/rustfmt-reflow aside) against its own immediate pre-move location by diffing, not by eye — including the two non-literal moves (
update()/run_chat_command, extracted from inline match-arm bodies with identical parameter order and narrowly-scoped#[allow(clippy::...)]matched to the exact lint their longer signatures trigger). - The correctness-critical
FixExitCodedowncast chain indiagnose_cmd.rs'sfix()is preserved exactly, and its regression test was deliberately left inmain.rsso it still exercises the realdispatch → fix → FixExitCode → exit_code_forpath rather than a stub. - A subprocess test that re-invokes itself by a hardcoded module-path string (
model_fit::tests::docker_unreachable_subprocess_helper) was correctly updated for the new location. - Module doc comments and
docs/architecture.mdentries are unusually rigorous and self-correcting across the stack: every caller-list,pub(crate)-rationale, and dependency-direction claim spot-checked (well over a dozen, across all seven review passes) verified true against the actual code viagit grep, including entries this PR didn't directly touch but whose text the moves made stale. - The newest commit (
5f1694d5, a post-review fixup) is itself clean, correctly-executed work: it relocates four tests to sit with the handler they assert on (with matchingpub(crate)widening of the sharedslice_braced_block/strip_line_commentstest helpers so the cross-module reference actually resolves), and replaces a stale hardcoded caller-list doc comment with a self-maintaining "git grep finds them" pointer. - No dead code, no orphaned modules (all 13 new files are declared and reachable), and no internal/proprietary names or secrets anywhere in the diff.
Deployment notes
- This PR cannot currently merge because it is one commit behind
main's tip (see Blocking, above). Whoever rebases should specifically re-diffapps/rocm/src/services_text.rsanddocs/testing.mdagainst the post-rebase result: main's6b175eechangedread_managed_service_manifest's body in the former and inserted a paragraph in the latter, in hunks adjacent to but not overlapping this PR's own edits to the same two files — a clean textual merge is likely but has not actually been attempted or built. - The PR description names five other open PRs (#817, #799, #709, #826, #837) that touch code relocated here and will need rebasing after this merges — a coordination point for whoever merges next.
- CI for the reviewed head (
5f1694d5) was green on every lane that had completed as of this review (clippy, build-and-test/affected-crates, Windows build/test/release, CodeQL, commit-signatures+sign-off, license headers, markdown-links, coverage). The four hardware-gated E2E lanes (Strix Halo Ubuntu nightly/release, W7900, MI300X) were still queued and the umbrella "E2E tests" job still in progress at the time of this check — not a failure, but not yet confirmed either way from CI alone.
What this covered
Every file in the diff (c6ab82b54f685b01e6a3dacd87403c5fd16c9c4c…5f1694d5af91c20048e41ce559a12f8a5a4f931f, all 16 commits), read completely by 7 independent fan-out workers split by cluster coupling (chat/update/cli_audit; services; config/install/setup; diagnose/model_fit/serve; examine/freeform/bridge; a dedicated full-main.rs-plus-docs pass; and a dedicated impact-analysis/ripple/history pass across the whole repository, not just the 30 changed files), each diffing every relevant commit against its own first parent rather than relying on a single merge-base-relative diff. ROCMAI-759 was retrieved directly by key (not via a link in the PR body) and read in full, including its PR-by-PR plan, risk notes, and out-of-scope section.
Did not run: cargo build/cargo test/cargo clippy locally (no Rust toolchain in this review environment) — relied on the PR's own CI for that, per the note above. No design-review question rose to "fundamental approach problem" — the one real structural question (module count) is recorded above as a tradeoff.
Exposure disclosure: this review's mandated claim-check step (checking for an existing "nowycondro" review before starting) necessarily returned the full body of three prior reviews on this PR, and the mandated head-sha check also returned the full PR description, both before code-reading began. Neither was used to derive any finding above — every finding was independently re-established from git (diffs, git grep, ancestry checks) by the fan-out workers or by direct verification in this driver context, and the fan-out workers themselves were never shown any of that text. The PR description was read again, deliberately, only after the findings list was otherwise settled, to check the change's own claims about itself, per this method's Step 9. The prior reviews' and comments' discussion was not reconciled against this one — this review was produced blind to it, by design.
🤖 Generated with Claude Code
Bring in main's native-Windows vLLM gate (GatedEngineAction and ensure_engine_allowed_on_platform) and its tests, which land in main.rs where main put them; serve_cmd.rs keeps collect_serve_notes in its own module and takes the two new imports. The examine_report_text.rs module doc combines main's added callers with the note that the platform-gate items now live in model_fit.rs. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
Bring in the AIM catalog change: the engine_ruled_out_by_platform split into a probe-injectable form moves with the platform-gate items into model_fit.rs and is re-imported in main.rs, the AIM engine description follows the engine-inventory builder into bridge_snapshot.rs, and the serve_cmd.rs architecture entry keeps both the AIM pre-flight and collect_serve_notes. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
|
Main moved twice more after the last push, so the branch now merges
On the merged head, |
Why
apps/rocm/src/main.rswas still about 9,500 lines because it held the command handlers themselves, not just the clap declarations and dispatch, so every change to any command touched the same file. This change moves the remaining handler clusters out into their own modules, as pure moves, untilmain.rsis mostly the CLI definition, dispatch and glue: it goes from 9,506 to 4,895 lines, with the production part ending at line 2,545 and the rest being its tests. Completes ROCMAI-759; moving thecomfyuidispatch function, which that ticket also listed, is tracked separately as ROCMAI-833 because it needs a maintainer decision first.What changes
Fifteen commits, one per step, so the branch can be reviewed commit by commit. Each moves one cluster out of
main.rsinto a module of its own, with its tests beside it and an entry indocs/architecture.md:cli_audit.rs(the CLI audit and lifecycle log),service_hints.rs(the service action label helpers),service_records.rs(service-record removal and pruning),services_cmd.rs,config_cmd.rs,model_fit.rs(the model-fit assessment),diagnose_cmd.rs(diagnose, report delivery and fix),install_cmd.rs(which also takessdk_install_requestand its two tests fromchat.rs),freeform_answer.rs,setup_cmd.rs,bridge_snapshot.rs(the Codex-bridge snapshot builders),examine_cmd.rs,collect_serve_notesintoserve_cmd.rs, and theupdateandchatcommand arms.The
dispatch()call sites are unchanged except for theUpdateandChatarms, whose bodies are now calls toupdate()inupdate_cmd.rsandrun_chat_commandin a newchat_cmd.rs; both are new functions that take the values the arm used to bind, so those two arms are not byte-identical moves.Deviations from a plain move, each also stated in the relevant commit message:
chat_cmd.rsrather than intochat.rs, becausechat.rsis already reached fromdash.rsand the handler callsdash::run_chat, so placing it inchat.rswould create achatanddashcycle.chat_cmd.rsdepends on both and neither depends on it. The fourcommand_chat_*source-text tests keep their names and assertions and now live inchat_cmd.rs's own test module, where they read the handler next to them (they shareslice_braced_blockandstrip_line_commentswithmain.rs's tests); each of the four was checked to go red when the handler is broken.main.rstests use are widened topub(crate), and a few are re-imported undercfg(test).prompt_text::any_substringdoes not exist, so the freeform answers usechat::any_substring.update()andrun_chat_commandcarry a#[allow]for the clippy lints their longer signatures trigger (fn_params_excessive_bools,too_many_arguments).main.rsfollow the moved code: theascii_output_contractexempt literals inxtask, theadvised_commandsassertions,docs/testing.md,AGENTS.md, and a doc comment inrocm-dash-tui.docs/architecture.mdstatements that the moves made false are corrected in the commit that made them false.Verification
cargo fmt --checkis clean, andcargo clippy -p rocm --all-targets -- -D warningsis clean on the current head, which is rebased onto the latestmain.cargo test -p rocm --bin rocmpasses: 1,379 passed and 7 ignored, none failed.model_fit::tests::docker_unreachable_subprocess_helper) was shown to run its helper by breaking the helper and seeing the parent test fail.cargo xtask manifest --checkandcargo xtask check-crate-edgespass, and a scan found no new two-module cycle. Theuse crate::edges each new module has in its production code (explicituse crate::imports andcrate::<module>::paths, test code excluded) are listed below; items that stay inmain.rsare named separately.cli_audit: none.service_hints: none, apart fromSandboxToolArgfrommain.rs.service_records:cli_progress,cli_report,endpoint_keys,managed_service_status,service_hints,services_text.services_cmd:cli_audit,service_hints,service_records,services_text;ServicesCommandfrommain.rs.config_cmd:cli_audit,provider_keys,providers,runtimes_cmd;ConfigCommandandprovider_namefrommain.rs.model_fit:gpu_policy,serve_cmd.diagnose_cmd:model_fit;FixExitCodefrommain.rs.install_cmd:cli_audit,driver_install,runtime_install_finalize,therock;InstallFormatandInstallTargetfrommain.rs.freeform_answer:chat,comfyui,freeform_planner,runtimes_cmd,therock.setup_cmd:runtimes_cmd,therock;SetupCommandfrommain.rs.bridge_snapshot:managed_service_status.examine_cmd:examine_report_text,runtimes_cmd,therock.serve_cmd(which gainedcollect_serve_notes):cli_progress,endpoint_keys,engine_ipc,engine_runtime_select,engines_cmd,gpu_policy,managed_service_status,serve_summary,service_launch;DevicePolicyArganddevice_policy_namefrommain.rs.update_cmd:cli_audit,runtime_services,runtimes_cmd,therock;ROLLBACK_RECOVERY_HINT,engine_inventoryandsanitize_log_valuefrommain.rs.chat_cmd:chat,dash;ChatInferenceParams,Providerandprovider_namefrommain.rs. Neitherchatnordashdepends on it.cargo test -p xtask(the editedascii_output_contractpin was only compiled), thetests/e2e-cucumbersuite (including the scenarios forrocm updateandrocm chatthat exercise the two moved arms) and the Windows lane. No Windows-only code moved.Scope
This is an internal refactor with no user-observable change, so no end-to-end scenario is added; the unmodified
tests/e2e-cucumbersuite covers the unchanged behaviour. The move of thecomfyuidispatch function is deliberately not included (it is ROCMAI-833: it contradicts the currentcomfyui.rsentry indocs/architecture.md, so the convention has to be decided first), and a few other open PRs (for example #817, #799, #709, #826 and #837) edit code that moved here and will need rebasing onto the new modules.Template checklist: not a bug fix, so there are no stale xfail rows to narrow; no new subcommand or subsystem; no user-facing message is added or changed.