Skip to content

refactor(breakdown): delete the dead and repeated code in two over-gate kernel-event and attribution-renderer functions - #2074

Merged
xiaofei-zheng merged 6 commits into
mainfrom
lean/shafeng/cc20-breakdown-2-pr
Oct 22, 2026
Merged

xiaofei-zheng merged 6 commits into
mainfrom
lean/shafeng/cc20-breakdown-2-pr

Conversation

@fengshaoyi-amd

Copy link
Copy Markdown
Contributor

What this does

Two session-breakdown functions were over the code-metrics gate: assemble_kernel_ext, which builds a kernel event's ext from its recorded rows, and the attribution renderer's render. This PR brings both under every limit they broke, mostly by deleting: eight hand-written read-and-sort blocks (now one table), a second pass that patched e2e results onto attempts after they were built, a helper whose tuple result was taken apart and rebuilt into the rebench block, nine guards on input every caller already fills, a fallback for a field its only writer always sets, and, in the renderer, a second read of the ledger state and three one-use accumulators.

Production code: +152 / −177 (net −25) across 2 files. No test is added or changed. The code-metrics baseline loses 3 entries, lowers 1 module-length entry and gains none.

This continues the complexity cleanup series that started with #2024; #2052, an earlier breakdown PR in it, shares no source file with this one. The 3 commits read one at a time; each commit message lists what it deleted and why that is safe.

Commit Module Production lines Baseline file
1fed096 read the attribution section's ledger state once reporters/_renderers/attribution.py +16 / −22
756dade assemble the kernel event from one ordered read of its sections recorder/kernel_event.py +136 / −155
a642b0f retire the code-metrics baseline entries the rework cleared baseline only 3 removed, 1 lowered

Both production files are under src/hyperloom/inference_optimizer/breakdown/.

Gate numbers per function

Measured with the gate's own collectors (ruff C901, complexipy, function lines), origin/main → this branch. Limits are 20, 30 and 80; bold values were over the limit at base.

Module Function Cyclomatic Cognitive Lines
recorder/kernel_event.py assemble_kernel_ext 11 → 3 50 → 11 206 → 77
reporters/_renderers/attribution.py render 11 → 8 28 → 24 85 → 79

Also changed, never over at base: _lane_attempt 1 → 1 / 0 → 1 / 35 → 39.

New functions in kernel_event.py, cyclomatic / cognitive / lines: _forge 3 / 6 / 29, _geak 3 / 12 / 35, _geak_rebench 2 / 8 / 25, _outcome 1 / 2 / 18.

Deleted function: _geak_settlement (3 / 7 / 20), replaced by _geak_rebench.

Across the 2 touched production files: C901 total 141 → 136, cognitive total 287 → 266, functions 51 → 54. Functions over a gate limit: cognitive 3 → 2, length 4 → 2. What is left is outside this work, all in kernel_event.py: _merge_acceptances (cognitive 31), record_geak_attempts (cognitive 31, 102 lines; #2048 changes it) and record_integrate_verdict (89 lines).

Module lengths: kernel_event.py 2,168 → 2,149, attribution.py 102 → 96.

What changes in each module

Kernel event assembly (recorder/kernel_event.py)

New names:

  • _ROW_ORDER: the fields each of the eight row sections is ordered by. One comprehension reads and orders all of them.
  • _geak_rebench: builds GEAK's wire rebench block (V6KernelGeakRebench), including the attempt GEAK's acceptances settle against and any conflicting decisions.
  • _forge: builds the forge block (V6KernelForge), or None when forge did not run.
  • _geak: builds the geak block (V6KernelGeak), or None when GEAK did not run.
  • _outcome: builds the outcome block (V6KernelOutcome).
  • _lane_attempt now takes the integrate rows by id. A lane that states no e2e result takes its gate's result while the lane is built.

The ext literal and its field comments stay in assemble_kernel_ext, because test_sbd_v6_ext_schema_contract.py reads the wire keys from that function's body (:31, :40-62).

Removed:

  • Eight read-and-sort blocks, one per row section.
  • The second pass over the attempts that patched an e2e block onto lanes after they were built.
  • _geak_settlement and its (ref, conflicts) tuple, and the second derivation of "a GEAK ledger exists or a rebench was stated" in the GEAK engagement test, which now reads rebench["required"].
  • Nine parts.get(section) or [] guards.
  • The entry.route fallback for outcome.route.

Attribution renderer (reporters/_renderers/attribution.py)

Removed from render: the second read of attribution.available (the "no per-source split" fact is now the elif of the "no ledger" fact), the notes list built up front, the loop that accumulated decisions (now a comprehension over the same rows and filter), and the one-use md local.

Why the deletions are safe

Line numbers are on this branch unless marked "on main".

  • Row order table. Each row of _ROW_ORDER (kernel_event.py:2037-2046) holds the sort fields of the block it replaces (kernel_event.py:1948-1989 on main). The sections main passed through wire_rows still go through it where they are read: trace runs and discovered kernels in _forge (:1966-1967), discovery runs in _geak (:2009), GEAK kernel rows before _geak_attempt (:2065). wire_rows drops only rows that are not mappings (event_rows.py:88), and rows_for_event already kept only mappings (event_rows.py:35), so the GEAK engagement test, which now reads the unwired kernel rows (:1995), sees the same rows.

  • E2E join in _lane_attempt. On main, the second pass (kernel_event.py:1999-2003 on main) filled e2e only for an attempt whose e2e was empty and whose integrate_ref was set. Only a lane sets integrate_ref: _geak_attempt (:833-872) and _acceptance_attempt (:875-895) keep the template's "" (:705), and acceptance attempts were appended after the pass anyway (:2004 on main). _lane_attempt now does the same join while it builds the lane (:802-803, :828). A lane without a reference calls _integrate_e2e([]), which returns None (:659-660), as before.

  • GEAK rebench block. _geak_rebench (:1921-1945) derives the settled attempt and the conflicting decisions from the same settled rows _geak_settlement read, and keeps the block's key order. assemble_kernel_ext reads rebench["settled_against"] for _merge_acceptances (:2066) and "conflicting_decisions" in rebench for _settle (:2073); that key is present exactly when the old tuple's conflict list was non-empty (:1943-1944). rebench["required"] is bool(ledger) or bool(stated) (:1935), the two facts the old engagement test read separately (kernel_event.py:2044-2046 on main).

  • Sections read without a guard. Every production caller builds parts with event_parts, which puts a list under every section it is asked for (assembler.py:297-300), and all three ask for EVENT_SECTIONS (sections.py:141-152). That includes KERNEL_EVENT_SECTIONS (sections.py:58-68), which is exactly the event section read at kernel_event.py:2055 plus the eight _ROW_ORDER keys. The callers:

    • the recorder's close (kernel_event.py:1601-1604);
    • _republish_closed_event (kernel_event.py:641-642);
    • the finalize spec (event_finalize.py:62-63, with parts from event_parts(spec.sections) at :147, called at :162).

    Tests call it with kernel_event_parts() (assembler.py:333-335), which is event_parts over KERNEL_EVENT_SECTIONS: test_sbd_v6_kernel_timeline.py:112, :984, :1076 and test_coordinator_gemm_promote_units.py:1578. Nothing in scripts/ calls it.

  • outcome.route. The only code that writes route or entry.route into the kernel event section is KernelEventRecorder.__init__ (kernel_event.py:1098-1110), which writes both from self._route in the same record; every version of the file since it was created (5085b93) does the same. The entry fragment begin writes later (:1131-1149) carries no route, and the route that begin hands to open_event (:1154) goes into the timeline envelope, not into the section's rows (event_timeline.py:122-135). The recorder is built only by make_kernel_recorder (kernel_event.py:2128, constructor call at :2144), called from orchestrator/phases/kernel.py:480.

  • Attribution facts. attribution is a plain dict (attribution.py:35), so reading available once and branching with elif (:62-64) adds the same facts as main's two separate tests. The breakdown's validation.notes is written by _validation_notes (collectors/v6.py:560, defined at :588), which returns strings; for a string, and for any JSON value read back from disk, f"{note}" and str(note) give the same text.

Observable effect

Nothing an operator sees changes. For every input the repo's own callers produce, kernel event ext blocks (contents and key order), the breakdown JSON and the attribution section stay the same. A seeded differential of assemble_kernel_ext before and after this change, over 6,000 generated events, matched byte for byte apart from the 292 events that hit the first case below.

The differences below are reachable only by input that no caller in the repo produces:

  • A kernel event header with a blank route but a non-blank entry.route. outcome.route used to fall back to entry.route; it is now "". Only KernelEventRecorder.__init__ writes either field, both from the same value in one record (see Why the deletions are safe).
  • assemble_kernel_ext given a parts mapping that lacks one of the nine kernel sections, or holds None for one. Such a section used to read as empty; now a missing section raises KeyError and None raises TypeError. Every caller passes event_parts output, which holds a list for each of them.
  • attribution.render: no difference. The facts, their order, the decisions and the table are unchanged. Notes are formatted by an f-string instead of str(), which gives the same text for every JSON value.

Checklist

  • Description: above.
  • Linked issue(s): none.
  • Tests:
    • No test was added or changed, so no contract or failure-mode assertion moved. The existing tests keep pinning what these functions export: test_sbd_v6_kernel_timeline.py and test_coordinator_gemm_promote_units.py call assemble_kernel_ext directly, test_sbd_v6_ext_schema_contract.py pins its top-level wire keys, and test_reporters_smoke.py covers the attribution section's table, shares, notes and decisions.
    • Locally on Windows, before the rebase onto main, the affected tests gave the same result on the base (b4e296a) and on these commits: 715 passed on both sides, with the same two pre-existing problems. One failure is in the framework recorder, which this change does not touch (test_sbd_v6_framework_wiring.py::test_source_attempt_records_its_pair_gate_and_lifecycle_step, a CRLF mismatch in the patch content on Windows); one collection error is in test_tracelens_csv.py, because TraceLens is not installed. None of the test files that reach these two modules changed on main since. Linux CI on this PR is the authority.
  • Size/complexity triggers crossed:
    • 329 changed production lines, under the 400-line review trigger.
    • No added or changed function crosses a gate limit, and none is over the cyclomatic-10 trigger.
    • Two functions sit over the ~60-line trigger and under the 80-line gate. render (79), 15 lines of which are its docstring, is one pass that builds the section's facts, decisions and table. assemble_kernel_ext (77) has 28 comment lines, 15 of them on the ext literal, which stays in this function because the schema contract test reads its keys there.
    • kernel_event.py (2,149) stays over the 1,200-line module limit it was already over, and stays in the module-length baseline, 19 lines shorter.
  • If this simplifies or refactors:
    • Mechanisms removed: listed under What changes in each module.
    • Contract preserved: every in-repo caller and all persisted data.
    • Tests: as above.
  • Observable effect: none; see the section above for why, and for the out-of-contract inputs that now behave differently.
  • Breaking changes: no. assemble_kernel_ext keeps its signature and now needs every kernel section in parts, which every caller already passes; _lane_attempt and _geak_settlement are private.
  • PR addresses single concern: yes, bringing the two over-gate session-breakdown functions under the gate.
  • Root cause is upstream: no.

Known merge interactions

Trial merges used git merge-tree --write-tree against the current head of every open PR that shares a file with this branch, plus the five whose file list GitHub cuts off at 100 files. A conflict counts as this branch's only when the same merge onto main (931af8a) does not have it.

Gate

The code-metrics gate (scripts/code_metrics.py --base-ref origin/main, run locally) passes on the 3 touched files: 0 new, 0 worse and 0 out-of-date entries in every dimension, and 0 findings from the comment, English-only, test-import, repeated-literal and A1–A12 checks. Baseline changes:

  • removed cognitive-complexity …/kernel_event.py::assemble_kernel_ext 50;
  • removed function-lines …/kernel_event.py::assemble_kernel_ext 206;
  • removed function-lines …/_renderers/attribution.py::render 85;
  • lowered module-lines …/kernel_event.py from 2168 to 2149.

ruff check and ruff format --check are clean on the touched files.

fengshaoyi-amd and others added 3 commits October 21, 2026 10:47
Delete the second read of attribution.available: the "no per-source split"
fact is now the elif of the "no ledger" fact, which is what the old
`not has_any_split and available` test spelled out. Delete the `notes` list
that was built up front only to be looped at the end; the notes are appended
where they always landed, as the last facts. The kept decisions become a
comprehension over the same rows and filter, and the markdown table is passed
straight into the section instead of through a one-use local.

Behaviour is identical: the facts, their order, the decisions and the table
are unchanged, nothing between the old and new position of the notes read can
raise, and an f-string formats every JSON value exactly as str() did.

render: cyclomatic 11 -> 8, cognitive 28 -> 24, lines 85 -> 79.

Co-authored-by: Cursor <cursoragent@cursor.com>
…of its sections

Delete the eight hand-written read-and-sort blocks in assemble_kernel_ext:
each section's sort fields are now one row of _ROW_ORDER, read by a single
comprehension. Delete the second pass that patched an e2e block onto
attempts after they were built: _lane_attempt now joins its integrate gate
rows while it builds the row, which is the only place the join could fire
(a GEAK or acceptance attempt never carries an integrate_ref). Delete
_geak_settlement and its (ref, conflicts) tuple: _geak_rebench builds the
wire rebench block directly, the attempts read settled_against and
conflicting_decisions off it, and the GEAK engagement test reads its
`required` field instead of re-deriving the same ledger-or-stated test.

Two guards go as dead. `parts.get(section) or []`: every caller builds
parts with event_parts(), which fills every requested section with a list
(the recorder's own close, _republish_closed_event, event_finalize's kernel
spec over EVENT_SECTIONS, and assembler.kernel_event_parts). The
entry.route fallback for outcome.route: the header's only writer,
KernelEventRecorder.__init__, has put `route` and `entry.route` in the same
record with the same value since kernel_event.py was created (5085b93).

What stays per wire block moves into _forge, _geak and _outcome, each
returning its schema block, so the ext literal the schema contract test
pins stays in assemble_kernel_ext. Block contents, key order and the order
of the roofline and baseline sub-assemblies are unchanged; a seeded
differential over 6000 random events is byte-identical except for a header
whose route is blank while entry.route is set, which no writer produces.

assemble_kernel_ext: cyclomatic 11 -> 3, cognitive 50 -> 11, lines 206 -> 77.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ork cleared

Delete the three entries for functions now under the gate:
kernel_event.py::assemble_kernel_ext (cognitive 50, lines 206) and
attribution.py::render (lines 85). Lower kernel_event.py's module-lines
entry from 2168 to its new length, 2149. No entry is raised or added.

Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Code metrics gate: PASSED

Judged: the 3 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 14 +0
Cognitive complexity fails > 30 0 0 0 89 -1
Function length (lines) fails > 80 0 0 0 221 -2
Nested block depth fails > 5 0 0 0 8 +0
Parameter count fails > 5 0 0 0 87 +0
Module length (lines) warns > 800, fails > 1200 0 0 0 47 +0
Duplicated lines per file fails > 0 0 0 0 95 +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
61 findings in files this change does not touch

Outside this change (informational): 61

Unit Dimension Baseline Now
src/hyperloom/orchestrator/state/shared_state.py resolve_graded_comparison Cognitive complexity absent 34
src/hyperloom_kb/collect/mapping.py _experience Cognitive complexity absent 31
src/kernelforge/cli/forge_loop_command.py forge_loop Cognitive complexity absent 31
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 107
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/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 84
src/hyperloom_kb/sync.py GlobalSync.pull Function length (lines) absent 84
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 185
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._source_attempt Function length (lines) absent 175
src/hyperloom_kb/http_service.py Module length (lines) absent 1525
src/kernelforge/cli/forge_loop_command.py Module length (lines) absent 2003
src/hyperloom/orchestrator/actions/executors/_kv_metrics.py port_from_server_log Nested block depth absent 6
src/hyperloom/orchestrator/specialists/dispatch.py SpecialistDispatchCollaborator.warm_specialist_params Cognitive complexity 93 94
src/hyperloom/agents/quantization/driver/retry.py quantize_via_prompt Function length (lines) 102 103
src/hyperloom/inference_optimizer/breakdown/exporter.py build Function length (lines) 132 136
src/hyperloom/inference_optimizer/cli/__init__.py _run_optimize Function length (lines) 273 279
src/hyperloom/inference_optimizer/cli/preflight.py _preflight Function length (lines) 203 208
src/hyperloom/inference_optimizer/multi_node/scripts/kernel_patch_multinode.py _do_apply Function length (lines) 98 99

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

…akdown-2-pr

Co-authored-by: Cursor <cursoragent@cursor.com>
@fengshaoyi-amd
fengshaoyi-amd marked this pull request as ready for review October 21, 2026 06:46
@fengshaoyi-amd
fengshaoyi-amd requested a review from a team as a code owner October 21, 2026 06:46

@ZhengGong-amd ZhengGong-amd 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.

Reviewed: gate numbers re-measured (ruff C901, complexipy, function lines) and match the description; each removed guard / "producer always sets it" claim checked against its producers and call sites; base vs head differential runs show no undisclosed behaviour change; tests covering the touched modules pass.

LGTM.

fengshaoyi-amd and others added 2 commits October 21, 2026 17:54
…akdown-2-pr

Co-authored-by: Cursor <cursoragent@cursor.com>
…akdown-2-pr

Co-authored-by: Cursor <cursoragent@cursor.com>
@xiaofei-zheng
xiaofei-zheng merged commit c76424b into main Oct 22, 2026
40 checks passed
@xiaofei-zheng
xiaofei-zheng deleted the lean/shafeng/cc20-breakdown-2-pr branch October 22, 2026 08:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants