Skip to content

refactor(orchestrator): pass actions, state and trace-analysis inputs as typed objects instead of parallel keywords - #1972

Merged
xiaofei-zheng merged 33 commits into
mainfrom
refactor/args-orch-actions
Oct 19, 2026
Merged

xiaofei-zheng merged 33 commits into
mainfrom
refactor/args-orch-actions

Conversation

@lishuoshuo-amd

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

Copy link
Copy Markdown
Collaborator

Rebased onto main after #1970 and #1971; the one conflict (actions/executors/roofline.py) keeps both refactors: _end_profile_run / _end_analysis_run take this PR's _RunEnd and build #1970's ProfileRunOutcome / AnalysisRunOutcome. #1973 shares 4 call-site files with this PR and rebases after it.

  • Description: what and why

    Brings orchestrator/actions, orchestrator/state and orchestrator/trace_analysis under the parameter-count limit (function-args > 5). Many of these functions were helpers extracted earlier from large executors and took long lists of the caller's locals, or took the fields of one row, request or command as separate keywords. Each now takes the object those values belong to:

    • State: AttemptRow (one function record_attempt_row writes both config and patch attempt rows, replacing _record / record_config_attempt / record_patch_attempt), RoundRequest, TaskSpec, KbInjection; record_tick_exception takes the exception; the roofline snapshot history reads the last_trace_analyze entry written just before it.
    • Trace analysis: TraceLensSkillRequest, SdkEntryPoints, RunStatus (update_status becomes RunStatus.write), TraceInputs, AuditSubject, OrchestratorOutcome, TraceSplitJob, AnalysisReport, BypassReportContext, KernelAggregate, TraceAnalysisOptions, GraphVariant, CaptureShard, ManifestOrigin, WorkloadTotals, TraceHealth, CoverageMeasures.
    • Executors: bypass ServerSpec / ClientRun / EvalRun / HealthPoll / LifecycleRecord, ReportSubject / RunOutcome, ScriptableBenchmark; session-kill SessionKillRound, _WatchedRound, ActorLaunch; integrate-patch _PatchBench, _PatchMeasurement, _KbLesson; roofline _RunEnd, _AnalysisAttempt; _TraceProbe, _AnalysisRun, _GeakPointReport, _SiteTiming, GapEvidence, _SourcePatch, _PatchMode, SetupLedger.
    • A boolean that switched populate_gpu_arch_json between two contracts is split into internal_extension_arch_json.

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

    Scope: 95 functions are over the limit in those three directories. 13 of them sit in four files that other open PRs are restructuring and that this PR does not touch (_grid_runner.py 4, _workload_envs.py 2, baseline.py 6, explore.py 1). Of the other 82, 66 are done, so 29 remain over the limit in these directories after this PR. The 16 in touched or callable files that keep their signatures:

    • 13 because a caller lives in an orchestrator file that other open PRs are restructuring (resolve_graded_comparison, SharedState.record_policy_denial, SharedState.record_action_attempt, TaskRegistry.create_or_return_existing and its twin TaskRegistry.create, sweep_via_geak, GridVariant.__init__, apply_compatibility_filter, effective_fingerprint, build_launch_evidence, run_with_session_kill, restart_server_for_round, ServingLease.run_session_kill); none of those files is touched here.
    • 3 because the change would break another gated limit: KvMetricsRecorder.__init__ (its module is already past the 1200-line ceiling), validate_session_shape (the type would have to be imported from a private module across packages, rule A1), GpuSpecialistLease.start_async (its only caller is exactly at its length and cognitive-complexity baseline; the layer below, ServingActor.start, now takes ActorLaunch).

    Gate count of functions over the parameter limit (function-args entries in scripts/code_metrics_baseline.txt): 397 on main -> 331 (-66); 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. In test_tracelens_csv.py a 9-field request block repeated 15 times is built by one helper.
    • Byte identity against the base branch for the shape manifest JSON, iter_details_from_name, the bypass server / client / eval argv, the report JSON and the pid / meta lifecycle files.
    • Locally, per test file with PYTHONPATH=src (never the full suite): all 44 changed test files and every other test file that calls or references a changed signature (118 files after the rebase onto main, 5505 passed). Every changed production module imports under python:3.10-slim and python:3.11-slim. TraceLens-dependent tests ran against TraceLens at the CI-pinned commit 647cbf27, unpacked outside the tree.
    • ruff check / ruff format --check on the changed files; python scripts/code_metrics.py --base-ref origin/main PASSED; baseline lowered with --update-baseline (1348 -> 1277 entries).
  • Size/complexity triggers crossed: split, or why the shape is right:
    Diff budget: 3540 production Python lines changed (+1748 / -1792 in 42 production .py files). One concern (parameter count of these three orchestrator directories 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 and the three attempt-row writers (one remains). Preserved: state.json and every persisted row and file, executor argv / env / paths, name-resolved entry points (Coordinator collaborators, ACTION_CATALOGUE, KERNEL_REQUEST_HANDLERS), shown by the tests and byte comparisons above.

    Deleted parameters (checked across src, scripts, .github, docs, examples and tests): build_shape_manifest(tracelens_revision=) (never passed) and analysis_route= (its only caller passes the default), populate_gpu_arch_json(device=), build_eval_command(batch_size=), build_apply_feedback(rejected_hunks=) (never passed), build_client_command(result_filename=) (every caller passes "inferencex_result" and the reader reads inferencex_result.json), _run_scriptable_benchmark(bench_envs=) (passed but never read), _build_analysis_meta(tool=) (derived one-to-one from route, as the handler already did).

  • Observable effect: what an operator will now see, and what the old behaviour cost them (if none, why the change is unobservable):
    None: no output file, state.json field, CLI flag, command line or log line changes.

  • 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 orchestrator/actions, state and trace_analysis).

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

@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 87 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 423 -5
Nested block depth fails > 5 0 0 0 26 +0
Parameter count fails > 5 0 0 0 331 -66
Module length (lines) warns > 800, fails > 1200 0 0 0 52 +0
Duplicated lines per file fails > 0 0 0 0 99 +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): 10

Module Lines Limit
src/hyperloom/orchestrator/actions/executors/_inferencex_patcher.py 1174 warns > 800
src/hyperloom/orchestrator/actions/executors/_ray_serving.py 1070 warns > 800
src/hyperloom/orchestrator/actions/executors/_server_patcher.py 1189 warns > 800
src/hyperloom/orchestrator/actions/executors/_subprocess_kill.py 1160 warns > 800
src/hyperloom/orchestrator/actions/executors/trace_analyze.py 806 warns > 800
src/hyperloom/orchestrator/enablement/lane.py 866 warns > 800
src/hyperloom/orchestrator/loop/conversation.py 952 warns > 800
src/hyperloom/orchestrator/specialists/dispatch.py 1052 warns > 800
src/hyperloom/orchestrator/trace_analysis/_bypass_trace_reader.py 1018 warns > 800
src/hyperloom/orchestrator/trace_analysis/bypass_trace_analysis.py 929 warns > 800

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

Unit Dimension Base Now
src/hyperloom/orchestrator/state/shared_state.py:98 resolve_graded_comparison Cognitive complexity 34 34
src/hyperloom/orchestrator/actions/executors/_geak_sweep.py:204 sweep_via_geak Cognitive complexity 70 70
src/hyperloom/orchestrator/actions/executors/_geak_sweep.py:204 sweep_via_geak Function length (lines) 235 235
src/hyperloom/orchestrator/enablement/lane.py:89 EnablementLane._maybe_enqueue_enablement_specialist Function length (lines) 94 94
src/hyperloom/orchestrator/knowledge/recipe_journal.py:142 _record_config_attempts Function length (lines) 142 142
src/hyperloom/orchestrator/phases/framework.py:478 _record_source_attempt Function length (lines) 156 156
src/hyperloom/orchestrator/actions/executors/roofline.py:1 Module length (lines) 1318 1315
src/hyperloom/orchestrator/knowledge/recipe_journal.py:1 Module length (lines) 1789 1787
src/hyperloom/orchestrator/phases/framework.py:1 Module length (lines) 3148 3144
87 findings in files this change does not touch

Outside this change (informational): 87

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/inference_optimizer/cli/__init__.py _reexport_session_environment Function length (lines) absent 112
src/hyperloom/inference_optimizer/cli/__init__.py _resolve_agent_lineup Function length (lines) absent 89
src/hyperloom/inference_optimizer/cli/__init__.py _resolve_run_topology Function length (lines) absent 92
src/hyperloom/inference_optimizer/cli/__init__.py _resume_session Function length (lines) absent 171
src/hyperloom/inference_optimizer/cli/__init__.py _seed_fresh_session Function length (lines) absent 172
src/hyperloom/inference_optimizer/multi_node/cli.py _restart_multinode Function length (lines) absent 107
src/hyperloom/inference_optimizer/multi_node/scripts/launch_multinode.py _build_parser Function length (lines) absent 84
src/hyperloom/inference_optimizer/multi_node/scripts/launch_multinode.py _spawn_rank_actors Function length (lines) absent 90
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 151
src/kernelforge/loop/knowledge_integration.py _measure_warmstart_field Function length (lines) absent 83
src/kernelforge/loop/runner.py IterationLoop._close_iteration Function length (lines) absent 135
src/kernelforge/loop/runner.py IterationLoop._collect_session_candidate Function length (lines) absent 187
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 104
src/kernelforge/loop/runner.py IterationLoop._run_supervisor_review Function length (lines) absent 88

...and 62 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.

from ..bus.message_bus import Message
from hyperloom.inference_optimizer.trace.conversation_trace import ConversationRecord, append_conversation
from ..state.failure_evidence import UNMEASURED_OUTCOMES, render_failure_line
from ..state.shared_state import KbInjection

from ..collaborator import CoordinatorCollaborator
from ..measurement.runtime_findings import render_runtime_findings
from ..state.shared_state import KbInjection
@lishuoshuo-amd

Copy link
Copy Markdown
Collaborator Author

PR #1972 -- refactor(orchestrator): pass actions, state and trace-analysis inputs as typed objects instead of parallel keywords

What it does: Functions in orchestrator/actions, orchestrator/state and orchestrator/trace_analysis that took the fields of one row, request or command as parallel keywords now take one frozen dataclass per clump (AttemptRow through a single record_attempt_row, RoundRequest, TaskSpec, KbInjection, bypass ServerSpec/ClientRun/EvalRun, SessionKillRound/ActorLaunch across the Ray actor, _PatchBench, RunStatus, TraceLensSkillRequest, ...). Every caller, tests included, is updated, and a few never-passed parameters are deleted. Bypass argv, attempts-ledger rows, the roofline snapshot history and the tick-exception entry are unchanged against main, and every number in the description now matches the tree.

Blocking issues: none

V4 -- not reported: advisory (#1952 shares 9 files, #1762 shares 6, #1867 shares 5; the body names only #1970)

Step 7 independent reader: a second reader re-ran the Python 3.10/3.11 imports of round_store and the changed modules, test_framework_gap_composer.py, and the scope count (95 over in the three directories, 13 in untouched files, 66 done).
SKIPPED: V4 -- "# PARTIAL: #1032 changes 1075 files, only its first 100 were compared", overlap there unchecked
SKIPPED: V4 -- "# PARTIAL: #1154 changes 1232 files, only its first 100 were compared", overlap there unchecked
SKIPPED: V4 -- "# PARTIAL: #1276 changes 1311 files, only its first 100 were compared", overlap there unchecked
SKIPPED: V4 -- "# PARTIAL: #1869 changes 426 files, only its first 100 were compared", overlap there unchecked
SKIPPED: V4 -- "# PARTIAL: #1971 changes 106 files, only its first 100 were compared", overlap there unchecked

Checked: all 42 changed production files, including the Tier 1 state/shared_state.py and loop/coordinator.py and the Ray actor boundary; the four review-fix commits; a tree-wide AST sweep of every tracked *.py for calls to the reshaped signatures; and the whole description at this head, claim by claim:

LGTM

…objects, read the roofline snapshot from last_trace_analyze
…ts, orchestrator outcome and split job as objects
…ontext, size a roofline from one KernelAggregate
…s take a _KbLesson, keep paths read the attempt
…intReport and time a site with one _SiteTiming
… place and read launch geometry off the buffers
@lishuoshuo-amd
lishuoshuo-amd force-pushed the refactor/args-orch-actions branch from 03366d3 to 3e4596d Compare October 18, 2026 13:14
@lishuoshuo-amd

Copy link
Copy Markdown
Collaborator Author

PR #1972 -- refactor(orchestrator): pass actions, state and trace-analysis inputs as typed objects instead of parallel keywords

What it does: Functions in orchestrator/actions, orchestrator/state and orchestrator/trace_analysis that took the fields of one row, request or command as parallel keywords now take one frozen dataclass per clump (AttemptRow through a single record_attempt_row, RoundRequest, TaskSpec, KbInjection, bypass ServerSpec/ClientRun/EvalRun, SessionKillRound/ActorLaunch, _PatchBench, RunStatus, TraceLensSkillRequest, ...). After the rebase onto #1970/#1971, roofline's _end_profile_run / _end_analysis_run take this PR's _RunEnd and build #1970's ProfileRunOutcome / AnalysisRunOutcome from it. Every caller, tests included, is updated and a few never-passed parameters are deleted; persisted roofline rows, timeline events and state are unchanged against main, and every number in the updated description matches the tree.

Blocking issues: none

V4 -- not reported: advisory (#1952 shares 9 files, #1762 shares 6, #1867 shares 5; the body names #1970, #1971 and #1973 only)

Step 7 independent reader: a second reader re-checked the roofline.py conflict resolution against #1970's recorder API, the Python 3.10/3.11 imports and the gate totals (397 -> 331 function-args rows) at head.
SKIPPED: V4 -- "# PARTIAL: #1032 changes 1075 files, only its first 100 were compared", overlap there unchecked
SKIPPED: V4 -- "# PARTIAL: #1154 changes 1232 files, only its first 100 were compared", overlap there unchecked
SKIPPED: V4 -- "# PARTIAL: #1276 changes 1311 files, only its first 100 were compared", overlap there unchecked
SKIPPED: V4 -- "# PARTIAL: #1869 changes 426 files, only its first 100 were compared", overlap there unchecked
SKIPPED: V4 -- "# PARTIAL: #1974 changes 117 files, only its first 100 were compared", overlap there unchecked

Checked: the rebase delta against the clean r2 review (the +/- lines of the PR diff differ only in the roofline.py end.status / end.result / end.failure hunks and one baseline line; the same 87 files); roofline.py against #1970's RooflineRequest / ProfileRunOutcome / AnalysisRunOutcome / RooflineConclusion / begin_* / end_* / adopt_* / finish_* signatures in breakdown/recorder/roofline_event.py (every call matches, one path, no old signature left); the six auto-merged files (lane.py, recipe_journal.py, framework.py, dispatch.py, test_sbd_v6_enablement_wiring.py, test_sbd_v6_roofline_timeline.py) hunk by hunk against #1970's changes (distinct hunks, no interleaving); the tree-wide sweep of every tracked *.py for calls to the 69 changed or removed symbols (only name collisions remain: open, _record, _candidate, _finalize, kernelforge build_report, forge CI render_report, _write_report), a git grep of the removed names, all inspect.signature / .bind( contract tests (none touch a changed name), and all setattr / patch targets and fake defs of changed names in untouched files (only unrelated same-named symbols); the whole description claim by claim:

  • scope: 95 / 13 / 82 / 66 / 29 / 16 reproduced (ruff PLR0913 over actions + state + trace_analysis production files: 95 on main, 29 at head; the four named files hold 4 / 2 / 6 / 1 and are untouched; the 16 retained functions are exactly the 13 + 3 named; refactor(baseline): name how a run applies its patches, and the failures that end it #1961, refactor(workload): split materialize_config_with_envs into the phases it runs #1963, refactor(grid): drive the grid over named variant phases #1964/fix(grid): give the run_grid warmup round its own prompt seed #1968, refactor(explore): let the explore round own the stack it builds and the ledger it writes #1965 are open and touch those four files)
  • size: 3540 = +1748 / -1792 in 42 production .py files, 44 changed test files, at most 4 production files per commit
  • totals: 397 -> 331 matches the gate's function-args rows in the baseline file (ruff PLR0913 over production src gives 415 -> 349, the same -66), baseline 1348 -> 1277 entries, C901 > 20 71 -> 71, >= 100 1 -> 1, broad except unchanged (BLE001 1 -> 1, no except line added or removed in the diff)
  • deleted parameters have no remaining keyword caller; refactor(inference-optimizer): pass trace, roofline, multi-node and CLI inputs as typed objects instead of parallel keywords #1973 shares 4 call-site files
  • [unverified] the "118 files, 5505 passed" local figure (not contradicted; the 44 changed test files and the roofline / sbd_v6 files were re-run, below)
    | Ran (PYTHONPATH=src, one file at a time, no cache or bytecode writes in the checkout):
  • test_roofline_executor, _rows, _units, test_sbd_v6_roofline_timeline (36), test_sbd_v6_enablement_wiring (24), test_prelude_roofline, test_roofline_comparison_pipeline, test_trace_analysis_failures, all 23 test_sbd_v6_* files, test_lifecycle_wiring, test_specialist_integration, test_kernel_request_handlers_units, test_diffusion_roofline, test_bypass_roofline, test_roofline_snapshot_unit: all pass; all 44 changed test files pass (TraceLens-dependent ones with TraceLens at 647cbf27 plus openpyxl / pandas / numpy / matplotlib outside the tree; without those modules the same files fail on missing imports, the same on main)
  • persisted-output parity, main vs head, 25 scripted roofline scenarios (clean, recovered profile + N26 retry, ten unusable / terminal / capture-failure profiles, five analysis failures, seven compute-bound re-profile paths, cuda-graph off): result, timeline events, last_trace_analyze, roofline_snapshots and profile state identical (par_base.json vs par_head.json; only the environment's free_bytes disk probe differs)
  • ruff C901 / PLR0913 head vs base over the changed production files (no function new or worse; PLR0913 90 -> 24)
  • CI at head 3e4596d59: 33 success, 7 skipped by path filters, 4 cancelled duplicate runs superseded by green runs of the same workflows at the same sha; py3.10 and py3.11 shards 1-6 green; MERGEABLE
    | Base: dae423b | Head: 3e4596d

LGTM

@lishuoshuo-amd

Copy link
Copy Markdown
Collaborator Author

/review

@github-actions

Copy link
Copy Markdown

Automated review started for head 3e4596d. Progress: https://github.com/AMD-AGI/Hyperloom/actions/runs/39193259430

@xiaofei-zheng

Copy link
Copy Markdown
Collaborator

PR #1972 — refactor(orchestrator): pass actions, state and trace-analysis inputs as typed objects instead of parallel keywords

What it does: 95 functions under orchestrator/actions, orchestrator/state and orchestrator/trace_analysis were over the code-metrics function-args limit, mostly helpers extracted from large executors that took the caller's locals as parallel keywords. Each now takes the frozen dataclass those values belong to — AttemptRow, RoundRequest, TaskSpec, RunStatus, TraceAnalysisOptions, _RunEnd, _PatchBench and the rest — and every in-tree call site is updated. Nine parameters that no caller ever passed a non-default for are dropped. No **kwargs, shim or new fallback branch; 66 function-args entries leave the baseline.

Blocking issues: none

Checked:

  • Persisted shape. asdict(AttemptRow) reproduces the key set and key order of the old _record dict literal in state/attempt_ledger.py, for both the config arm (knowledge/recipe_journal.py:393) and the patch arm (phases/framework.py:2427), including the inlined patch_lever_kind(evidence) and candidate_id derivations and the {**res, **params} merge direction. RunStatus.write emits the same payload at the same 8 call sites as update_status.
  • Argv and artifacts. build_server_command / build_client_command / build_eval_command compared base-vs-head over 144 / 72 / 6 input grids including the falsy-but-not-None edges (max_model_len=0, num_prompts=0, limit="") — identical. build_report over 144 combinations, write_lifecycle_files byte-identical, wait_for_server_ready identical probe/sleep sequences over 6 scenarios.
  • Analysis output. analyze_trace run on a synthetic Kineto trace under 5 option sets (default, top_k=0, emit_launches, steady_state, steady_state+framework) — JSON identical, including the _TraceBuffers single-pass rewrite of _finalize. compute_roofline over 1921 parameter combinations, build_shape_manifest over eager / single / multi-variant — identical.
  • Removed parameters. tracelens_revision, analysis_route, device, batch_size, result_filename, bench_envs, rejected_hunks, tool, timeline each grepped across src, tests, scripts, docs, examples and .github on both trees: no caller passed a non-default, and no doc or prompt names them. _build_analysis_meta(tool=) is safe to derive because _VALID_ANALYSIS_ROUTES is a closed frozenset({"bypass", "agent"}) rejected before dispatch, and _analysis_tool reproduces the old "bypass" if is_bypass else "tracelens" exactly.
  • Defaults and ordering. Every new dataclass field default matched against the keyword default it replaced; no mutable default (RoundRequest.evidence uses default_factory onto the same read-only MappingProxyType({}) sentinel the base used); _RunEnd positional order verified at all 8 roofline.py call sites against the rebase with refactor(breakdown): pass each breakdown row as one typed record instead of parallel keywords #1970's ProfileRunOutcome/AnalysisRunOutcome; the three values that moved across a computation point (params in _adopt_profile, write_source_resolution_artifact, the roofline snapshot now read from last_trace_analyze) are provably unchanged between the old and new evaluation points.
  • Ray boundary. SessionKillRound, ActorLaunch and _WatchedRound pickle round-trip equal; the _subprocess_kill kill scope, signal order, pid set and timeout logic are outside the diff.
  • Description vs diff at head: 42 production files / +1748 / -1792, function-args 397 -> 331, 95 -> 29 remaining in the three directories, baseline 1348 -> 1277 entries — all four reproduced from the tree. 0 **kwargs added in production code.

Ran: git diff base-vs-head on all 42 production files; module-level base-vs-head equivalence harnesses for argv, lifecycle files, health polling, analyze_trace, compute_roofline, build_report, build_report_from_bypass and build_shape_manifest; head-tree orphan scan over all 95 added symbols. Base: dae423b | Head: 3e4596d

LGTM

@xiaofei-zheng xiaofei-zheng 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.

No blocking issues. Review details in the comment above.

@xiaofei-zheng
xiaofei-zheng merged commit 8f11b79 into main Oct 19, 2026
42 of 46 checks passed
@xiaofei-zheng
xiaofei-zheng deleted the refactor/args-orch-actions branch October 19, 2026 03:37
@github-actions

Copy link
Copy Markdown

Automated review: no verdict applied -- the PR is MERGED. Comment /review to retry. Run: https://github.com/AMD-AGI/Hyperloom/actions/runs/39193259430

PR #1972 -- refactor(orchestrator): pass actions, state and trace-analysis inputs as typed objects instead of parallel keywords

What it does: Functions in orchestrator/actions, orchestrator/state and orchestrator/trace_analysis that took the fields of one row, request or command as parallel keywords now take one frozen dataclass per clump (AttemptRow through a single record_attempt_row, RoundRequest, TaskSpec, KbInjection, bypass ServerSpec/ClientRun/EvalRun/LifecycleRecord, SessionKillRound/ActorLaunch across the Ray actor, _PatchBench/_KbLesson/_PatchMeasurement, RunStatus, TraceLensSkillRequest, TraceInputs, GraphVariant/CaptureShard, _RunEnd/_AnalysisAttempt). Every in-tree caller, tests included, is updated, and eight never-passed or never-read parameters are deleted; after the rebase onto #1970/#1971, roofline's _end_profile_run / _end_analysis_run take this PR's _RunEnd and build #1970's ProfileRunOutcome / AnalysisRunOutcome from it. Persisted rows, executor argv and the shape-manifest bytes are unchanged against main, and the code-metrics parameter-count baseline drops 397 -> 331.

Blocking issues: none

Step 7 independent reader: a second reader re-ran the whole adversarial pass against card.md, diff.txt and base.txt only -- tree-wide greps for surviving old-shape callers of every reshaped or removed symbol, the roofline merge into #1970's ProfileRunOutcome/AnalysisRunOutcome, the dataclass defaults, the Ray-boundary pickling and the baseline count (397 -> 331), plus head test runs (round_store, bypass backend/reader/report, selfcert, reconcile, setup replay, apply feedback, ray backend unit, enablement keep records, integrate-patch coverage unit -- all green); no blocking issue found, and the one candidate it raised (test_trace_shape_manifest collection error) reproduces identically on the base tree (missing TraceLens in the sandbox, not a regression).

SKIPPED: V4 -- "# PARTIAL: #1032 changes 1075 files, only its first 100 were compared", overlap there unchecked
SKIPPED: V4 -- "# PARTIAL: #1154 changes 1232 files, only its first 100 were compared", overlap there unchecked
SKIPPED: V4 -- "# PARTIAL: #1276 changes 1311 files, only its first 100 were compared", overlap there unchecked
SKIPPED: V4 -- "# PARTIAL: #1869 changes 426 files, only its first 100 were compared", overlap there unchecked
SKIPPED: V4 -- "# PARTIAL: #1974 changes 117 files, only its first 100 were compared", overlap there unchecked

Checked: all 42 changed production files, including the Tier 1 state/shared_state.py (KbInjection, record_tick_exception, roofline snapshot history) and loop/coordinator.py, and the Ray actor boundary (SessionKillRound, ActorLaunch); the roofline.py conflict resolution against #1970's ProfileRunOutcome/AnalysisRunOutcome signatures in breakdown/recorder/roofline_event.py (all six fields passed, instrumentation still drained per attempt); tree-wide greps for remaining callers of every reshaped or removed symbol (build_shape_manifest, update_status -> RunStatus.write, record_tick_exception, record_config_attempt/record_patch_attempt, run_tracelens_skill, analyze_trace, compute_roofline, render_report, _maybe_write_framework_kb_record), including readers outside the diff (kernelforge artifact_manifest.py:33, test_apply_feedback_unit.py); the behaviour-equivalence spots against the merge base (tool derived from route equals base's is_bypass derivation at trace_analyze.py:672; _enablement_keep_records locals were attempt.* aliases at base; _finalize's graph_launch_count; argv and manifest literals; _PatchMode flag tuples and labels); the description's numbers against the head tree (397 -> 331 gate rows, 87 files, 42 production + 44 test files, 111 -> 47 >5-arg functions by raw AST over the three directories) | Ran: PYTHONPATH=src python3 -m pytest src/hyperloom/orchestrator/state/tests/test_round_store.py (15 passed); test_shared_state_persistence.py + test_bypass_roofline.py + test_bypass_reader.py + test_trace_selfcert_observability.py (127 passed); CI at head: 35 success including py3.10/py3.11 shards (6+6), coverage both, code-metrics, ruff, pylint, mypy, import-linter, reuse, bandit; mergeable: MERGEABLE | Base: dae423b | Head: 3e4596d

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