Skip to content

refactor(inference-optimizer): pass trace, roofline, multi-node and CLI inputs as typed objects instead of parallel keywords - #1973

Merged
chaojhou merged 27 commits into
mainfrom
refactor/args-optimizer
Oct 19, 2026
Merged

chaojhou merged 27 commits into
mainfrom
refactor/args-optimizer

Conversation

@lishuoshuo-amd

@lishuoshuo-amd lishuoshuo-amd commented Oct 18, 2026 •

Copy link
Copy Markdown
Collaborator

Rebased onto main after #1970, #1971, #1972 and #1974; the files it shares with #1970 (kernel/conc_sweep.py, knowledge/recipe_journal.py, roles/critic_agent.py) and #1972 (knowledge/recipe_journal.py, loop/coordinator.py, state/shared_state.py, test_resume_guard.py) merged without conflicts, and both sides' shapes stand.

  • Description: what and why

    Brings src/hyperloom/inference_optimizer outside breakdown/ under the parameter-count limit (function-args > 5). For each function the question was where the values come from and where they travel together; each now takes the object they belong to:

    • Trace: LLMCallSite (call identity for LLMCallRecord.from_metadata / for_failure), ToolCall, EventWindow.
    • Session: Journal.load_or_create takes the fresh Journal its caller describes; the resume guard chain carries _Confirmation and _ConfirmTarget.
    • Roofline: callers that unpacked ModelMeta and RooflineBreakdown pass them whole; DecodeShape, ComputeTarget, DitGeometry (a NamedTuple, so tuple unpacking keeps working), _MoeShape, _SdpaShape, RooflineReading.
    • Reference script and baseline comparison: LaunchSettings, ServingTarget, BaselineQuery (callers already built it), TargetAnalysisRequest, AcceptedMetrics.
    • Multi-node: SshTarget / RemoteScript for the SSH helpers (published from multi_node/__init__.py so the orchestrator's server-log sweep does not reach into a private module), KernelPatchApply, _MultinodeLaunch, _FanoutOptions, NodeLaunch (the kill-only mode of build_node_launch_args is split out as build_node_kill_args), KillWaits, _ServerGroup / _PdRole / _LaunchDirs / _GroupHeads for the pod launcher. _short_poll keeps the job-status predicates all 7 callers passed identically inside the function.
    • CLI: OrchestrationPromptContext, LaunchInfo (moved with _emit_launch_info into cli/bootstrap.py, which keeps cli/__init__.py from growing), PartitionRequest / PartitionModel, _OperatorLaunchShape, ModelRouting / CriticSetup, InstallStep, PreflightRuntime.
    • framework_deps.ensure had dry_run and check_only doing the same thing; they are one parameter now (both CLI flags still exist).
    • Parameters no caller passes are deleted (evidence below).

    No **kwargs, untyped dict, compatibility shim or new fallback branch is added; every call site is updated.

    Scope: 54 functions over the limit; 50 are done. 4 keep their signatures because a caller lives in an orchestrator file another open PR is restructuring: recipe_canonical_id and kb_hardware_slug (knowledge/recipe_kb_t0.py), inject_sglang_context_length (actions/executors/_workload_envs.py), and canonical_labels, which shares recipe_canonical_id's seven identity dimensions and moves with it.

    Gate count of functions over the parameter limit (function-args entries in scripts/code_metrics_baseline.txt): 256 on main -> 206 (-50); the cyclomatic-complexity entries and the broad-except count are unchanged.

  • Linked issue(s): none.

  • Tests: added/updated? commands run?

    • Tests changed only where a signature changed; assertions are kept. One test that asserted _sdpa_bytes ignores its causal argument is removed with that argument.
    • CLI contract: --help is byte-identical between main and this head for hyperloom, optimize, recover, check, multi-node and all 9 of its subcommands, and framework_deps. The pod kill / launch scripts need ray for --help; no argparse line changed in them.
    • Every changed production module imports under python:3.10-slim and python:3.11-slim (two need a third-party package absent from the slim image).
    • Locally, per test file with PYTHONPATH=src (never the full suite): the 31 changed test files (1591 passed) and 34 caller / related test files (1406 passed, 2 skipped).
    • ruff check / ruff format --check on the changed files; python scripts/code_metrics.py --base-ref origin/main PASSED (parameter count -50); baseline lowered with --update-baseline.
  • Size/complexity triggers crossed: split, or why the shape is right:
    Diff budget: 2503 production Python lines changed (+1166 / -1337 in 40 production .py files). One concern (parameter count of the inference_optimizer modules outside breakdown and their call sites). Each commit touches at most 5 production files and is grouped by module. The code-metrics gate passes without a waiver.

  • If this simplifies or refactors: which mechanism was removed, which contract was preserved, and the tests that show it:
    Removed: the parallel keyword lists, the duplicated job-status predicates at the 7 _short_poll call sites, and the dead dry_run duplicate of check_only. Preserved: every CLI flag, default and help text (above), launcher argv and env, persisted journals and confirmations.

    Deleted parameters (checked across src, scripts, docs and tests, including aliases): record_kb_span(phase=), ssh_*(user=), _infera_ssh_run_script(remote_path=), _short_poll(failure_diag=, quiet_fetch_error_grace_s=, is_quiet_fetch_error=), _submit_and_collect_pod_json(runtime_env=, success_statuses=), build_node_launch_args(dist_init_port=, pid_file=, log_file=, health_port=, health_wait_sec=) (now constants with the old defaults), _kill_remote(gpu_fallback_timeout_s=), _build_orchestration_prompt(action_registry=), workload_signature(benchmark_mode=): no caller passes them. _infera_ssh_bash_with_env(env=): its only caller passes None. _sdpa_bytes(causal=): never read.

  • Observable effect: what an operator will now see, and what the old behaviour cost them (if none, why the change is unobservable):
    None for valid inputs: no CLI flag, output file, command line or log line changes. Two edge cases: the multi-node kill-only path no longer parses state["nodes"], so a state file with a malformed node count no longer fails a kill; and WorkloadTerminalFailure can no longer be raised, which was already true in practice because no caller passed a failure diag (its exit-code handler is left in place).

  • Breaking changes: yes, for Python callers only: the refactored functions take their typed objects. Every in-tree caller is updated.

  • PR addresses single concern: yes (parameter count of inference_optimizer outside breakdown/).

  • Root cause is upstream (Magpie/TraceLens/GEAK/IntelliKit/AgentKernelArena), ticket filed: n/a.

@lishuoshuo-amd
lishuoshuo-amd requested a review from a team as a code owner October 18, 2026 12:17
@lishuoshuo-amd lishuoshuo-amd added the size-exception Waives the PR diff budget; added by a maintainer with a reason in the PR description label Oct 18, 2026
@github-actions

github-actions Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

Code metrics gate: PASSED

Judged: the 72 files this change touches. Files it does not touch never fail it; anything found there is listed under Outside this change for information.

Dimension Limit New Worse Baseline out of date Baseline entries vs base
Cyclomatic complexity fails > 20 0 0 0 69 +0
Cognitive complexity fails > 30 0 0 0 275 +0
Function length (lines) fails > 80 0 0 0 419 -3
Nested block depth fails > 5 0 0 0 26 +0
Parameter count fails > 5 0 0 0 206 -50
Module length (lines) warns > 800, fails > 1200 0 0 0 51 -1
Duplicated lines per file fails > 0 0 0 0 98 +0
Dead code (vulture) fails > 0 0 0 0 2 +0
Check Findings Effect
Comments 0
English only 0
Production code imports test code 0
Repeated literals 0
A1 Private name of another package 0
A8 Flag argument 0
A9 Tuple return 0
A10 Raw vocabulary comparison 0
A11 Hidden global write 0
A12 Pure forwarder 0
A12 Single-implementation abstraction 0

Module length warning: over 800 lines, within the 1200-line failure limit (not failing): 5

Module Lines Limit
src/hyperloom/inference_optimizer/cli/bootstrap.py 846 warns > 800
src/hyperloom/inference_optimizer/multi_node/commands/infera.py 841 warns > 800
src/hyperloom/inference_optimizer/multi_node/scripts/launch_multinode.py 1073 warns > 800
src/hyperloom/inference_optimizer/trace/langfuse_emitter.py 1195 warns > 800
src/hyperloom/orchestrator/actions/executors/_multi_node_server_lifecycle.py 1200 warns > 800

Already over at the base (backlog, not this change's): 17

Unit Dimension Base Now
src/hyperloom/orchestrator/state/shared_state.py:98 resolve_graded_comparison Cognitive complexity 34 34
src/hyperloom/inference_optimizer/cli/__init__.py:1810 _reexport_session_environment Function length (lines) 112 111
src/hyperloom/inference_optimizer/cli/__init__.py:2372 _resolve_agent_lineup Function length (lines) 89 89
src/hyperloom/inference_optimizer/cli/__init__.py:2267 _resolve_run_topology Function length (lines) 92 92
src/hyperloom/inference_optimizer/cli/__init__.py:1923 _resume_session Function length (lines) 171 170
src/hyperloom/inference_optimizer/cli/__init__.py:2095 _seed_fresh_session Function length (lines) 172 170
src/hyperloom/inference_optimizer/multi_node/cli.py:1314 _restart_multinode Function length (lines) 107 107
src/hyperloom/inference_optimizer/multi_node/scripts/launch_multinode.py:591 _build_parser Function length (lines) 84 84
src/hyperloom/inference_optimizer/multi_node/scripts/launch_multinode.py:738 _spawn_rank_actors Function length (lines) 90 84
src/hyperloom/inference_optimizer/cli/bootstrap.py:419 _seed_shared_state Function length (lines) 156 156
src/hyperloom/orchestrator/kernel/conc_sweep.py:1164 run_conc_sweep Function length (lines) 251 251
src/hyperloom/orchestrator/knowledge/recipe_journal.py:142 _record_config_attempts Function length (lines) 142 142
src/hyperloom/orchestrator/roles/critic_agent.py:530 CriticAgentBackend.run Function length (lines) 209 209
src/hyperloom/orchestrator/specialists/runner.py:542 SpecialistRunner._prepare Function length (lines) 199 199
src/hyperloom/inference_optimizer/cli/__init__.py:1 Module length (lines) 2814 2805
src/hyperloom/orchestrator/knowledge/recipe_journal.py:1 Module length (lines) 1787 1787
src/hyperloom/orchestrator/roles/critic_agent.py:1 Module length (lines) 1295 1294
75 findings in files this change does not touch

Outside this change (informational): 75

Unit Dimension Baseline Now
src/hyperloom/orchestrator/enablement/recipe/projections.py project_launch_evidence Cognitive complexity absent 36
src/hyperloom_kb/collect/mapping.py _experience Cognitive complexity absent 31
src/hyperloom_kb/schema.py FieldDeclaration.__post_init__ Cognitive complexity absent 32
src/kernelforge/cli/forge_loop_command.py _prepare_measurement_driver Cognitive complexity absent 36
src/kernelforge/cli/forge_loop_command.py _read_kb_warm_start Cognitive complexity absent 40
src/kernelforge/loop/runner.py IterationLoop._collect_session_candidate Cognitive complexity absent 44
src/kernelforge/loop/runner.py IterationLoop._rule_on_attempt Cognitive complexity absent 38
src/hyperloom_kb/sync.py GlobalSync.pull Function length (lines) absent 84
src/kernelforge/cli/forge_loop_command.py _RunReporter.build_result Function length (lines) absent 91
src/kernelforge/cli/forge_loop_command.py _prepare_measurement_driver Function length (lines) absent 136
src/kernelforge/cli/forge_loop_command.py _read_kb_warm_start Function length (lines) absent 149
src/kernelforge/loop/runner.py IterationLoop._close_iteration Function length (lines) absent 117
src/kernelforge/loop/runner.py IterationLoop._collect_session_candidate Function length (lines) absent 184
src/kernelforge/loop/runner.py IterationLoop._implementer_history Function length (lines) absent 112
src/kernelforge/loop/runner.py IterationLoop._rule_on_attempt Function length (lines) absent 102
src/kernelforge/loop/runner.py IterationLoop._run_supervisor_review Function length (lines) absent 88
src/kernelforge/loop/runner.py IterationLoop._source_attempt Function length (lines) absent 173
src/hyperloom_kb/http_service.py Module length (lines) absent 1525
src/kernelforge/cli/forge_loop_command.py Module length (lines) absent 2063
src/hyperloom/orchestrator/actions/executors/_geak_sweep.py sweep_via_geak Cognitive complexity 67 70
src/hyperloom/orchestrator/actions/executors/explore.py ExploreExecutor.__call__ Cognitive complexity 369 374
src/hyperloom/orchestrator/kernel/request_handlers.py _run_forge_gemm_tuning Cognitive complexity 124 125
src/hyperloom/orchestrator/loop/intent_router.py IntentRouter.handle_delegate Cognitive complexity 40 41
src/hyperloom/orchestrator/phases/kernel.py KernelPhase._run_geak_kernel_phase Cognitive complexity 122 130
src/hyperloom/orchestrator/phases/prelude.py PreludePhase.maybe_enqueue_warm_replay Cognitive complexity 190 191

...and 50 more; the job log lists every row.

Verdict computed by the gate scripts in /home/runner/work/_temp/code-metrics-gate, not by this tree's copy.

Thresholds and sources: [tool.hyperloom.code_metrics] in pyproject.toml. Tools: complexipy 8.0.1, jscpd 5.4.1, ruff 0.16.2, vulture 2.16.

@lishuoshuo-amd

Copy link
Copy Markdown
Collaborator Author

PR #1973 -- refactor(inference-optimizer): pass trace, roofline, multi-node and CLI inputs as typed objects instead of parallel keywords

What it does: In inference_optimizer outside breakdown/, 54 functions took more than five parameters because values that travel together were threaded as separate keywords. This PR cuts that to 4 by giving each group one frozen record built where its values are resolved (SSH target, node launch, kill wait budgets, server group, roofline shape and compute target, operator confirmation, LLM call site, event window, orchestration prompt context, model routing, install step, and so on). It also deletes parameters no caller passes and moves the job-status check that all 7 _short_poll callers repeated into _short_poll. Every call site is updated in place; there are no shims. Since the earlier clean review the branch was rebased onto main after #1970 and #1971; apart from the regenerated baseline, the 26 code commits are patch-identical to the ones reviewed before.

Blocking issues: none

Checked:

Ran:

  • pytest, one file at a time with PYTHONPATH=src: conc_sweep test_conc_sweep + test_conc_sweep_ceiling (131 passed, 2 skipped), test_conc_sweep_session_deadline (38), test_sbd_v6_conc_sweep_timeline (41), test_sbd_v6_conc_sweep_wiring (24), test_cli_conc_sweep_default (23); recipe_journal test_optimization_journal (30), test_trajectory_reviewer (16), test_coordinator_kb_writes (37), test_recipe_sedimentation (19), test_sbd_v6_framework_wiring (43); critic_agent test_critic_agent_backend (74). test_conc_sweep_ceiling.py run alone fails collection with a circular import at executors/__init__ -> kernel/conc_sweep, identically at base dae423b.
  • All 31 changed test files, each singly: 1591 passed, 0 failed.
  • scripts/code_metrics.py --base-ref origin/main: PASSED, parameter count -50; ruff check / ruff format --check on the 71 changed .py files: clean.
  • sigbind.py, imports_mon.py, bind3.py (AST bind passes), pcount*.py / ccount.py (ruff counts on base and head clones), help_dump.sh on both trees, cmp_roofline.py on both trees.
  • No real Ray cluster was run; the pod-script equivalence from the earlier review (cloudpickle emulation) is carried over because launch_multinode.py and kill_multinode.py are patch-identical.

Base: dae423b | Head: a371e4a

Step 7 independent reader: a second reader re-checked the rebase seam in the three shared files and the gate totals (397 -> 347 function-args rows) at head.
SKIPPED: V4 -- #1032 (1075 files), #1154 (1232), #1276 (1311), #1869 (427) and #1974 (117) were compared on their first 100 files only; overlap beyond those is unchecked.

LGTM

Every KB span nests under the unphased agent span.
…one tool call as ToolCall

record_event builds its row inline instead of forwarding every argument to _build_row.
…tGeometry to the ceiling formulas

The SDPA and fused-MoE helpers take one _SdpaShape / _MoeShape; _sdpa_bytes drops the causal flag it never read.
…caller passes

The digest always reads the mode from HYPERLOOM_AGENTX.
…k_only into check_only

The installer entry point still accepts both --check-only and --dry-run.
The ssh helpers drop the user nobody overrides; the Infera wrappers drop the remote_path and env their callers never pass.
… status predicates

Every caller passed the same terminal-status checks and none passed the failure diag or quiet-404 grace.
…rds to the RayJob patch and restart helpers

_submit_and_collect_pod_json drops the runtime_env and success_statuses no caller passes.
…he kill-only argv into build_node_kill_args

The pid/log paths, dist-init port and health settings no caller overrides become module constants.
The 45s per-card fallback no caller overrides becomes _GPU_FALLBACK_TIMEOUT_S.
…ts _PdRole and _LaunchDirs

The launch summary reads the group leaders from _GroupHeads.
…nPromptContext

The phase re-scope partial binds the context; the action_registry override no caller passes is dropped.
LaunchInfo and _emit_launch_info sit with the other session bootstrap printers in cli/bootstrap.py.
…atorLaunchShape

_reexport_session_environment takes the session id it reads instead of the whole manifest.
@lishuoshuo-amd
lishuoshuo-amd force-pushed the refactor/args-optimizer branch from a371e4a to 4c9d8b9 Compare October 19, 2026 03:46
@lishuoshuo-amd

Copy link
Copy Markdown
Collaborator Author

Rebased onto main after #1972 and #1974 (head 4c9d8b9). The code commits applied without conflicts; only the code-metrics baseline was regenerated. Re-verified at this head: code-metrics gate passes, the test files of the four files shared with #1972 pass (916 tests), every changed module imports on Python 3.10 and 3.11, and CI is green (33 pass, 7 skipped). The earlier LGTM stands.

@chaojhou chaojhou left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR #1973 -- refactor(inference-optimizer): pass trace, roofline, multi-node and CLI inputs as typed objects instead of parallel keywords

What it does: brings inference_optimizer outside breakdown/ under the parameter-count limit. 50 of 54 functions now take the record their values belong to (SshTarget / RemoteScript, NodeLaunch, KillWaits, the pod launcher's server group, ComputeTarget / DecodeShape / DitGeometry, LLMCallSite, EventWindow, OrchestrationPromptContext, ModelRouting, InstallStep and others). Parameters no caller passes are deleted, the job-status predicate all 7 _short_poll callers repeated moves inside it, and framework_deps.ensure's duplicate dry_run folds into check_only. No CLI flag, launcher argv, persisted journal or log line changes.

Blocking issues: none

Non-blocking (both are the PR's own "delete what no caller passes" left one step short; small to finish here):

  • WorkloadTerminalFailure (src/hyperloom/inference_optimizer/multi_node/cli.py:81) and its except branch in main() (:1844-1848) can no longer run: this PR deleted _short_poll(failure_diag=), which held the only raise. The EXIT_TERMINAL_FAILURE comment (:76) and the main() docstring (:1836, "2 terminal workload failure (do not retry)") describe a path nothing produces; a FAILED job raises RuntimeError and exits 1. Exit 2 and MULTI_NODE_FAILURE_SNAPSHOT still come from launch_multinode.py and the PD refusal at :1438, so deleting the class and branch and re-scoping the comment and docstring to those removes no live path.
  • _infera_ssh_bash_with_env lost env, and both its calls (cli.py:254, :263) now pass a literal None to ssh_run_bash_with_env, whose env parameter, export prologue and assert_env_key_shapes only a test still reaches. Dropping env there (ssh_run_bash) and renaming the wrapper finishes the deletion instead of moving the None down a layer.
  • Smaller: RemoteScript.remote_path and DitGeometry being a NamedTuple are kept only for tests (the test file also adds an adapter rebuilding the old 8-keyword signature); compute_compute_bound_ceiling_tok_per_sec still takes three ModelMeta fields unpacked by both callers while its sibling takes ModelMeta whole; multi_node/_internal/__init__.py:4 still says the CLI is the only public surface though multi_node/__init__.py now exports SshTarget.

Checked: every production hunk in the 40 files for field-to-keyword mapping and defaults; the constants that replace deleted parameters (build_node_launch_args ports, pid/log paths and health wait; _GPU_FALLBACK_TIMEOUT_S; KillWaits); build_node_kill_args; the 7 _short_poll callers; Journal.load_or_create merge; resume-guard confirmation rows; LLMCallRecord sites and record_event callers (no ts= / start_ts= left, including via **context); framework_deps flags; workload_signature digest; callers of every deleted parameter across src, scripts, docs and the Ray pod scripts; docs and both SKILL.md files for removed names | Ran: base vs head on build_node_launch_args / kill args, the SSH helpers' subprocess.run argv, input and timeout, an emulated Ray launch_multinode.py (sglang/vllm, aggregated and disaggregated), roofline ceilings over 2 models x 3 GPUs x 3 shapes x 3 precisions x 2 GPU counts, build_roofline_snapshot, tool_attributes, LLMCallRecord rows, render_reference_script and gap_analysis (all identical); CI green at head. Not run: pytest (not installed here), real Ray or SSH | Base: d914a83 | Head: 4c9d8b9

LGTM

@chaojhou
chaojhou merged commit 5f42336 into main Oct 19, 2026
40 of 42 checks passed
@chaojhou
chaojhou deleted the refactor/args-optimizer branch October 19, 2026 05:15
@xiaofei-zheng

Copy link
Copy Markdown
Collaborator

What it does

50 functions in src/hyperloom/inference_optimizer outside breakdown/ carried more than five parameters, holding scripts/code_metrics_baseline.txt at 256 function-args waivers. Each now takes the frozen record its values already travel as — LLMCallSite, ToolCall, EventWindow, DecodeShape/ComputeTarget/DitGeometry/RooflineReading, LaunchSettings/ServingTarget, SshTarget/RemoteScript/NodeLaunch/KillWaits/_ServerGroup, OrchestrationPromptContext/LaunchInfo/PartitionRequest/InstallStep/PreflightRuntime, _Confirmation/_ConfirmTarget — with every in-tree call site rewritten, no **kwargs bridge and no compatibility shim. Parameters no caller passed are deleted, and the gate baseline drops to 206.

Blocking issues: none.

What was checked

  • The full 7038-line diff, then every changed signature traced to every call site in the head tree including tests/, scripts/ and docs/: record_event, record_kb_span, workload_signature, ssh_run/ssh_run_script/ssh_run_bash_with_env, build_node_launch_args, _submit_and_collect_pod_json, all eleven _record_install_step sites, framework_deps.ensure, _build_orchestration_prompt and the functools.partial reached from phases/machine.py:491, LLMCallRecord.from_metadata/for_failure, analyze, render_reference_script, build_roofline_snapshot, Journal.load_or_create, and the four roofline formulas. No consumer is left on an old shape.
  • Each deleted parameter checked against the merge base rather than taken on trust: record_kb_span(phase=), ssh_*(user=), _infera_ssh_bash_with_env(env=), _short_poll(failure_diag=, quiet_fetch_error_grace_s=, is_quiet_fetch_error=), _submit_and_collect_pod_json(runtime_env=, success_statuses=), the five build_node_launch_args knobs, _kill_remote(gpu_fallback_timeout_s=), _build_orchestration_prompt(action_registry=), workload_signature(benchmark_mode=), _sdpa_bytes(causal=) — no production or test caller supplies any of them, and _forward_runtime_env keeps its reader at multi_node/cli.py:1326.
  • Every new dataclass field default compared against the parameter default it replaced (_PdRole(), PartitionModel(), ServingTarget(), KillWaits(), RooflineReading(), _GPU_FALLBACK_TIMEOUT_S, _INFERA_DIST_INIT_PORT/_INFERA_PID_FILE/_INFERA_LOG_FILE), and every positional construction compared against field order (KillWaits, PreflightRuntime, DitGeometry, SshTarget, _GroupHeads, InstallStep, RooflineReading).
  • Three spots where a dropped guard could have bitten: RooflineBreakdown's seven construction sites, to show the removed float(... or 0.0) guarded an unreachable None; trajectory_trace.py:252-292, where the inlined row's ctx.session_dir.name sits below the is None early return that already made the old else "" dead; resume_guard.py:457-470, where target.history is the same list object the confirmation entry was appended to.
  • WorkloadTerminalFailure is now unraisable, but git show <base>:src/hyperloom/inference_optimizer/multi_node/cli.py lines 299/337 show failure_diag already defaulted to None with no caller passing it, so its handler was dead before this PR.
  • The body's numbers reproduce exactly: function-args 256 → 206 (grep -c on the baseline at base and head), 50 removed / 0 added entries in the diff, and 40 production .py files at +1166/−1337 = 2503 lines from numstat.
  • py_compile on both Ray-shipped scripts (launch_multinode.py, kill_multinode.py), which now carry dataclasses across the actor boundary. No local test suite was run; CI is green at head across both Python versions, all twelve shards, ruff, pylint, mypy, bandit, CodeQL, import-linter and code-metrics.

Not checked: the --help byte-identity claim — consistent with cli/parser.py and multi_node/cli.py::build_parser being untouched, but not independently reproduced. The open-PR overlap scan is partial for #1032, #1154, #1276, #1869, #1962 and #1977 (only each one's first 100 files were compared).

Base d914a83dcc606930a55ffcd15cf741d7e8b301c7 · Head 4c9d8b95dcbed9d14d9261b0e0e246f0dc6b4d6a

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size-exception Waives the PR diff budget; added by a maintainer with a reason in the PR description

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants