Skip to content

fix(breakdown): record the GEAK candidate at close and kernel e2e gain from the rebench - #2048

Merged
haishuok0525 merged 11 commits into
mainfrom
fix/recorder-settled-semantics
Oct 21, 2026
Merged

haishuok0525 merged 11 commits into
mainfrom
fix/recorder-settled-semantics

Conversation

@lishuoshuo-amd

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

Copy link
Copy Markdown
Collaborator
  • Description:
    Two recorder facts were written from the wrong source or never written, so the breakdown and the report stated outcomes that did not happen. Enablement landed counting is left for a separate change: a revalidation window does not name its KEEP, and resume recovery can end a window without an outcome row.
    1. close.geak_candidate had no writer, so the Final section's GEAK candidate AWAITING / DROPPED warnings could never fire. CLOSE now records shared_state.geak_pending as its own geak_candidate close step (a failure in it, or in the baseline record, is attributed to and isolated from the other) (non-empty only when a candidate is still awaiting a rebench or was dropped without one) through a new close_out.record_geak_candidate, with revalidation_pending = (status == "awaiting_rebench"). An empty slot is written as null, which overwrites the block an earlier CLOSE of a resumed session left (the singleton merge replaces a key with a non-mapping value), so a candidate settled after resume no longer renders a stale warning. The dropped-status set read by the Final renderer and the mission summary named rebench_unavailable, which nothing writes, and missed rebench_declined / overlay_unloadable, which the GEAK-harness fallback writes when it reaches no verdict. It is now one constant, kernel_records.GEAK_DROPPED_STATUSES = {rebench_cancelled, rebench_declined, overlay_unloadable}, used by both readers. The Final section's provisional / cross-harness branches, unreachable before this writer and premised on a candidate counted in the headline, are removed: an awaiting candidate adds only its AWAITING line.
    2. Kernel e2e_gain_pct:
      • GEAK route: the attempt's e2e.e2e_gain_pct carried GEAK's self-reported figure (glm52 add_rmsnorm_quant: 40.80%) while Hyperloom's rebench measured 10.71%. GEAK's figure now goes to e2e.self_reported_e2e_gain_pct, and e2e_gain_pct is set from the rebench delta when the attempt settles (new recorder/kernel_gain.py), null until then. A revoked KEEP keeps its self-reported figure instead of overwriting it.
      • Forge route: _integrate_e2e took the best gain over all gates while decision was the last gate's. The gain now comes from the same (last) row as the decision, null when that row measured nothing; each gate's figure stays on its integrate row.
  • Linked issue(s): Refs Serving throughput is labelled tok/s/GPU but is the aggregate over all TP GPUs #1932. Based on main (fix(breakdown): rename throughput_tok_s_per_gpu to output_throughput (schema 6.1) and record per-GPU output on baseline and validation rows #2023 has merged).
  • Tests: new tests in test_close_phase_sequencer.py (CLOSE write -> collect_v6_close -> Final render shows AWAITING / DROPPED for each dropped status; empty slot clears; a two-leg real on_enter_close shows no stale warning), test_geak_decline_status.py (mission summary for each dropped status), test_geak_gain_alignment.py (test_report_shows_provisional_not_zero_validated removed: its scenario, a pending candidate already in the final action_path with a higher final throughput, cannot occur under rebench-first, where geak_e2e enters the stack only when the rebench promotes it; test_report_shows_pending_candidate_excluded_from_headline now asserts the exact facts and warnings), test_geak_revalidation_dispatch.py (an awaiting candidate with validated gain -1.5 / 0 / none / 3.0 yields exactly the validated-gain lines plus its AWAITING fact and warning), test_sbd_v6_kernel_timeline.py (full e2e block with measured 10.7132 vs self-reported 40.799, no measurement -> null, revoke keeps self-reported, forge takes the last gate, accepted GEAK candidate with no rebench verdict -> null gain, empty delivered gain and no_improvement); they fail on the base branch except four that pin behaviour base already had: test_a_revoked_geak_keep_keeps_the_claim_it_made, test_close_sequencer_records_no_geak_candidate_when_none_is_pending, test_mission_summary_flags_a_dropped_candidate[rebench_cancelled] and the positive-gain case of test_an_awaiting_geak_candidate_adds_only_its_own_lines. test_geak_promotion_retention.py now expects e2e_gain_pct is None with the self-reported 50.0. Ran these and the related close / geak / reporter test files individually; ruff, lint-imports and scripts/code_metrics.py pass. Replayed glm52 (e2e_gain_pct 10.7132, self_reported_e2e_gain_pct 40.799) through the recorders.
  • Size/complexity triggers crossed: 15 files (+470/-66): 8 source files (one new, kernel_gain.py, kept out of kernel_event.py because that module is at its line budget), 6 test files, and code_metrics_baseline.txt, which lowers four entries the change shortened.
  • If this simplifies or refactors: n/a.
  • Observable effect: the Final section's GEAK candidate warnings, and kernel e2e gains read as described above. Also, a GEAK candidate accepted by GEAK but never given a rebench verdict (rebench cancelled, declined or overlay_unloadable) now has attempts[].gain_pct = null and outcome.delivered[].gain_pct = null, and the visit outcome.verdict is no_improvement ("nothing measured a gain on the candidates kept") instead of improved with GEAK's own figure: nothing Hyperloom measured backs the gain.
  • Breaking changes: for a GEAK candidate with no rebench verdict, attempts[].gain_pct, outcome.delivered[].gain_pct and outcome.verdict change as described under Observable effect; kernel e2e.e2e_gain_pct changes value semantics; close.geak_candidate and e2e.self_reported_e2e_gain_pct are new or newly populated fields.
  • PR addresses single concern: yes, recorder facts (GEAK candidate at close, kernel e2e gain) written from the wrong source or not written.
  • Root cause is upstream: no.

…ppened

Enablement counted a KEEP awaiting revalidation as landed, close never wrote
the GEAK candidate it later rendered warnings from, the dropped-status set
named a status nothing writes, a GEAK attempt's e2e gain carried GEAK's own
figure instead of the rebench measurement, and a forge kernel's e2e gain was
the best of all gates while its decision was the last one.
@lishuoshuo-amd
lishuoshuo-amd requested a review from a team as a code owner October 20, 2026 05:16
@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Code metrics gate: PASSED

Judged: the 15 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 51 +0
Cognitive complexity fails > 30 0 0 0 195 +0
Function length (lines) fails > 80 0 0 0 340 +0
Nested block depth fails > 5 0 0 0 20 +0
Parameter count fails > 5 0 0 0 90 +0
Module length (lines) warns > 800, fails > 1200 0 0 0 48 +0
Duplicated lines per file fails > 0 0 0 0 96 +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): 1

Module Lines Limit
src/hyperloom/orchestrator/phases/close.py 1008 warns > 800

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

Unit Dimension Base Now
src/hyperloom/inference_optimizer/breakdown/schema.py:1 Module length (lines) 2705 2704
107 findings in files this change does not touch

Outside this change (informational): 107

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/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/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 111
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 170
src/hyperloom/inference_optimizer/cli/__init__.py _seed_fresh_session Function length (lines) absent 164
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 84
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 92
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 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

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

…a stale GEAK candidate on resume

Landed and validation-pending counts are assembled from the revalidation
windows instead of the KEEP row flags, which are written once. An empty GEAK
slot is recorded as null so a resumed close replaces the earlier block.
@lishuoshuo-amd
lishuoshuo-amd force-pushed the fix/recorder-settled-semantics branch from 44695c8 to dff890f Compare October 20, 2026 05:55
Restore the enablement attempt counts and their rendering to the base
behavior; a revalidation window does not name its KEEP, so the counts
need an orchestrator-side record instead of an assembly-time pairing.
@lishuoshuo-amd lishuoshuo-amd changed the title fix(breakdown): record enablement, GEAK candidate and kernel gain facts from the settled source fix(breakdown): record the GEAK candidate at close and kernel e2e gain from the rebench Oct 20, 2026
…iting GEAK candidate

Under rebench-first an awaiting candidate is never part of the validated
gain, so it adds only its own AWAITING fact and warning and the validated
gain renders as recorded.
…n branch

A pending candidate is never in the final stack under rebench-first, so the
unreachable provisional scenario is dropped and the awaiting case asserts the
exact facts and warnings.
Comment on lines +985 to +986
"GEAK candidate (self-reported +13.79%) is AWAITING a main-flow rebench — excluded from the headline gain "
"and final stack until a measured rebench validates it.",
@lishuoshuo-amd

Copy link
Copy Markdown
Collaborator Author

PR #2048 -- fix(breakdown): record the GEAK candidate at close and kernel e2e gain from the rebench

What it does: This PR fixes two places where the breakdown recorded the wrong value or no value. CLOSE now writes the unsettled GEAK candidate slot to close.geak_candidate, so the Final section's AWAITING and DROPPED warnings can fire. An empty slot is written as null, so a resumed close clears the block an earlier close left. One GEAK_DROPPED_STATUSES constant now drives both the Final warning and the mission-summary warning. The Final section's provisional / cross-harness branches, which could never be reached, are removed. A GEAK attempt's e2e_gain_pct is now the rebench delta, GEAK's own figure moves to self_reported_e2e_gain_pct, and the forge e2e gain comes from the gate that made the standing decision. The enablement landed-count change was withdrawn, and those files are identical to base.

Blocking issues: none

SKIPPED: V4 -- the "# PARTIAL:" lines in openprs.txt mean overlap with those open PRs (each was compared on its first 100 changed files only, and only the newest 100 open PRs were compared) is unchecked.

Checked:

  • CLOSE writer: close.py (_record_close_progress, now a direct call; on_enter_close order; _record_close_final_recipe), close_out.py, recorder.py (record_upsert_singleton, recorder_for), recorder_warnings.py, collectors/v6_close.py, exporter.py (patch_breakdown_close), machine.py (resume reopen).
  • Final renderer: final.py (remaining reads of the candidate and revalidation_pending, the markdown key-value table, decisions, warnings) and collectors/v6.py outcome.final.gain_pct.
  • Headline exclusion chain: kernel.py _record_geak_candidate and promote_geak_from_candidate, plus writeback.py 2666-2670, 2686 and 4672.
  • Kernel gain: kernel_event.py, kernel_gain.py, kernel_records.py, _shared_state/render.py, schema.py, _kernels.py, capability_summary.py.
  • Searches: tree-wide non-test rg over src/hyperloom and src/hyperloom_kb for geak_candidate, geak_pending clears, the GEAK statuses, e2e_gain_pct and revalidation_pending readers.
  • Earlier rounds: every round 1-4 finding is fixed or withdrawn.

Ran:

  • The six changed test files individually on head: 64, 8, 33, 83, 91 and 81 passed.
  • Representative new tests on the base tree: the regression cases fail, and the four declared base-passing cases pass.
  • The real on_enter_close with OSError and ValueError injected inside the recorder's guarded write: the failure was logged as a recorder warning and CLOSE completed.
  • lint-imports (7 kept), ruff on the changed files, and a broad-handler count in close.py (13 at base and at head).

Independent reader: second agent (see independent.txt) | Base: c565c19 | Head: d54ce67

LGTM

The roofline, baseline and GEAK candidate records each run as a separate
close step, so a failure is attributed to the record that failed and one
failing record no longer skips another.
Comment on lines +985 to +986
"GEAK candidate (self-reported +13.79%) is AWAITING a main-flow rebench — excluded from the headline gain "
"and final stack until a measured rebench validates it.",
@lishuoshuo-amd

lishuoshuo-amd commented Oct 21, 2026 •

Copy link
Copy Markdown
Collaborator Author

PR #2048 -- fix(breakdown): record the GEAK candidate at close and kernel e2e gain from the rebench

What it does: CLOSE now records the unsettled GEAK candidate slot as its own geak_candidate close step. It runs through main's _run_close_step after the roofline and baseline records, so a failure is recorded under its own name and does not skip the other records. An empty slot is written as null, so a resumed close clears an earlier block. The Final section's AWAITING/DROPPED warnings can therefore fire, and an awaiting candidate adds only its own lines. One GEAK_DROPPED_STATUSES constant now drives the Final and mission-summary drop checks. A GEAK attempt's e2e_gain_pct is now the rebench delta (GEAK's own figure moves to self_reported_e2e_gain_pct), and the forge e2e gain comes from the gate that made the standing decision.

Blocking issues: none

SKIPPED: V4 -- the "# PARTIAL:" lines in openprs.txt mean overlap with those open PRs (each was compared on its first 100 changed files only, and only the newest 100 open PRs were compared) is unchecked.

Checked: close.py under main's async structure: on_enter_close order, the new _record_close_progress and _record_close_geak_candidate, and _run_close_step failure semantics. The geak_candidate step runs after stack_revalidation and post_opt_roofline, the only CLOSE steps that can settle geak_pending. It runs before stack_ledger, final_recipe, fact_finalize, report and session_breakdown. Also read machine.py (resume reopen), close_out.py, recorder.py record_upsert_singleton, v6_close.py, the merged render.py import, and every geak_pending writer in kernel.py, writeback.py and geak_native_revalidation.py. Confirmed promote_geak_from_candidate still lifts the candidate and clears geak_pending in one synchronous step. All non-close source hunks are byte-identical to the version reviewed at d54ce67 (diff-hash compare). Ran a tree-wide non-test rg over src/hyperloom and src/hyperloom_kb for geak_candidate, the GEAK statuses, e2e_gain_pct readers and close step names. Re-fetched the description at the same head: it now says the baseline file lowers four entries, matching the diff. The rest of the description matches git diff --numstat (15 files, +470/-66; 8 source, 6 test, 1 baseline). | Ran: the six changed test files individually on head (82, 8, 33, 83, 91 and 81 passed). Ran the head test files on base main 958874f: 27 new or changed tests fail there, including both new close-step tests; the four cases the description names as already passing on base pass. Also ran lint-imports (10 kept) and ruff check / format --check on the changed files. pr-hygiene and code-metrics were re-run after the description edit and pass. Independent reader: second agent (see independent.txt) | Base: 958874f | Head: 933058f

LGTM

@lishuoshuo-amd

Copy link
Copy Markdown
Collaborator Author

PR #2048 -- fix(breakdown): record the GEAK candidate at close and kernel e2e gain from the rebench

What it does: CLOSE now records the unsettled GEAK candidate slot as its own geak_candidate close step. The step runs through _run_close_step after the roofline and baseline records. An empty slot is written as null, so a resumed close clears an earlier block. With that, the Final section's AWAITING/DROPPED warnings can fire, and an awaiting candidate adds only its own lines. One GEAK_DROPPED_STATUSES constant now drives both the Final and the mission-summary drop checks. A GEAK attempt's e2e_gain_pct is now the rebench delta, and GEAK's own figure moves to self_reported_e2e_gain_pct. The forge e2e gain comes from the gate that made the standing decision.

Blocking issues: none

SKIPPED: V4 -- the "# PARTIAL:" lines in openprs.txt mean overlap with those open PRs (each was compared on its first 100 changed files only, and only the newest 100 open PRs were compared) is unchecked.

Checked:

  • final.py merge with fix(report): render fields on the axis and scope they were recorded on #2043: relative to main, the only changes are the shared constant, the removed is_provisional/headline_unvalidated branches and the gain_missing term. _gain_axis_note, _validation_gap_warnings and measured_ms are kept.
  • fix(report): count dispatches, kernel outcomes and critic passes once each #2045 counters vs the e2e backfill: _kernels.py::source_counters counts REVERT before adopted, and capability_summary reads its maximum e2e_gain_pct. REVERT rows carrying the rebench delta add only to reverts. Adopted GEAK rows report the measured delta, or null when there is no rebench verdict.
  • Baseline file: the four entries are lowered on top of main's values: final.py::render 37 to 31 and 175 to 163, on_enter_close 112 to 111, kernel_event.py 2168 to 2167.
  • Diff scope and description: git diff origin/main HEAD touches only the PR's 15 files (+470/-66). The description is unchanged and matches.
  • Unchanged hunks since 933058f: close.py, close_out.py, kernel_event.py, kernel_gain.py, kernel_records.py, render.py and schema.py.

Ran:

  • Final render matrix: final.render with gain -1.5, 0, None and 3.0, against no candidate, an awaiting candidate, and each dropped status. Facts, decisions and warnings are identical to the 933058f LGTM output.
  • Head vs main: identical output wherever the removed branches cannot fire: interactivity axis note, stack-changed warning, measured_ms.
  • Counter probe: a GEAK candidate that is rebench-validated, rejected, or has no verdict, run through the counters and the capability summary on head and on main.
  • Tests: the six changed test files plus test_breakdown_renderers, test_reporters_smoke and test_sbd_v6_kernel_integrate_wiring, each run individually on head; all pass.
  • Base check: the head test files run on base main 9f7030a. The 27 new or changed regression tests fail there, and the four declared cases pass.
  • Lint and CI: lint-imports (10 kept); ruff check and format --check. gh pr checks was polled to completion: 33 pass, 7 skipping, 0 fail.

Independent reader: second agent (see independent.txt) | Base: 9f7030a | Head: 5df30c0

LGTM

@haishuok0525 haishuok0525 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.

What it does:

  1. CLOSE now records shared_state.geak_pending as its own geak_candidate close step via close_out.record_geak_candidate, writing null for an empty slot so a resumed session's stale block is replaced. The dropped-status set becomes one constant, kernel_records.GEAK_DROPPED_STATUSES = {rebench_cancelled, rebench_declined, overlay_unloadable}, used by both the Final renderer and the mission summary. The unreachable provisional / cross-harness branches in final.render are removed.
  2. A GEAK attempt's e2e.e2e_gain_pct is now Hyperloom-measured: null at record time and stamped from the rebench delta_pct in _settle. GEAK's own figure moves to self_reported_e2e_gain_pct. On the forge route, _integrate_e2e takes the gain from the same (last) row as the decision instead of the maximum across all gates.

Blocking issues: none.

Checked:

  • Status vocabulary: rebench_unavailable has no writer anywhere in src/. rebench_cancelled (kernel.py, cancelled explore rebench) and rebench_declined / overlay_unloadable (_geak_decline_status in _revalidate_on_geak_harness) are exactly the statuses written when no verdict is reached.
  • Field names: the geak_pending keys read by record_geak_candidate (self_reported_gain_pct / _tput / _basis, revalidation_error) match _record_geak_candidate and the decline/cancel writers.
  • Close ordering: the snapshot runs after stack_revalidation and post_opt_roofline, and it runs inside _run_close_step. The failure isolation from baseline_progress is covered by a test.
  • Settlement: _settle runs at assembly, so stamping is idempotent across exports. reject_geak_attempts no longer copies the (now null) e2e_gain_pct over the claim. The KB / remote-recipe e2e_gain_pct values come from integrate records and stack entries, not from this block. The _kernels / capability counters accept null.
  • Final renderer: dropping headline_unvalidated cannot surface a fabricated 0.00%, because outcome.final.gain_pct is validated_total_gain_pct and stays null without a validation.
  • The description matches the diff, and CI is green.

LGTM

@haishuok0525
haishuok0525 merged commit 8ccbd73 into main Oct 21, 2026
40 checks passed
@haishuok0525
haishuok0525 deleted the fix/recorder-settled-semantics branch October 21, 2026 08:58
siliangchen-amd added a commit that referenced this pull request Oct 26, 2026
.claude/skills/review-pr/evals/cases.yaml holds 11 cases, each a PR at a head a reviewer once saw and what a review of
that head must report:

- 6 rules.md source PRs, at the head the finding was raised against and with the place it was raised at: D7 #1567,
  S1 #1564, P1 #1526, R4 #1563, X6 #1497 and M3 #1444. Each finding was fixed afterwards.
- #2045 at ab239fd, where two cards were clean and a third found the C2 the author then reproduced and fixed.
- 4 clean cases, #2048, #2044, #2039 and #2059: every card on them was clean, the head they reviewed is the head that
  merged, and no later commit on main names them.

A finding about the description is left out, since a replay reads today's description, which the author may have
corrected since; so is #2094, whose blocking card came after the merge and was never settled.

scripts/review_pr_eval.py score reads one eval-<case>-r<repeat> directory per replay and reports how many expected
findings were found (by key, or by a cited place within ten lines), how many clean replays blocked, whether the
replays of one case agree, and the time, turns and tokens from the run log. Replayed through fetch.sh, #1567 at
a143f8f and #1444 at 6767a77 cut their comments before the finding was raised and carry the expected file in their
diff.

Co-authored-by: Cursor <cursoragent@cursor.com>
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