Repository navigation
refactor(breakdown, kernelforge): delete what eleven over-gate functions re-checked - #2052
Merged
Merged
Conversation
… table FrameworkEventRecorder.record_attempt spelled out every field of an attempt row as its own statement: nineteen text fields, three tri-state booleans, three text lists and six blocks, each block a hand-written dict of the same few coercions. The row is now driven by two tables, _ATTEMPT_FIELDS for the flat fields and _ATTEMPT_BLOCKS for the blocks, and the measured-against stack shares its server-argument and environment fields with config_delta through _CONFIG_DELTA instead of repeating them in _stack. Every field keeps its coercion, and a field the caller did not pass is still absent from the row. Deleted, because no caller of record_attempt passes them: - accepted_kernels, which V6FrameworkAttempt drops as well; - the ts= override, so the row is always stamped with the record time. assemble_framework_ext groups attempts by proposal and proposals by run with group_rows, the package's grouping primitive, instead of two hand-rolled setdefault loops. Every proposal and run row has its own id, since each writer returns early on an empty key. conc_sweep_event's local text coercion moves to event_fields as text, beside text_or_none, so the two recorders share one copy. The code-metrics baseline drops record_attempt (cognitive complexity and function length) and assemble_framework_ext (function length). Co-authored-by: Cursor <cursoragent@cursor.com>
… reports them _mirror_backend_attempts_to_kernel_timeline normalised its input as if it could arrive in any shape the retired GEAK journey replay produced: alias keys for most fields (id, speedup, started_at/created_at/ts, ended_at, duration_sec/elapsed_sec/elapsed_s, error_message, optimized_path, optimized_file, compile_passed, correctness_passed, integration_id, candidate.task_group, verification.best_artifact_path), a pre-dispatch row for a result with no attempts, status, decision, run-id and speedup fallbacks, and _to_bool for spelled-out booleans. Its only producer, KernelPhase._record_kernel_rewrite_controller_timeline, sends one attempt per settled controller row with an attempt_id, the backend, a lower-cased non-empty status, an upper-case decision constant, the micro speedup, error and error_class, plus the kernel name and the adopted attempt's id. It sends none of the aliases, never an empty attempts list, and sets proposal.decision and verification.micro_speedup to the attempt's own values. The mirror now hands those fields to KernelRewriteRun and LaneRunFields, whose row() normalizes every field of a kernel_rewrites row, and keeps only what that producer relies on: no recorder or no kernel id records nothing, attempts must be a list of dicts, the adopted backend is the attempt verification names, and an unmeasured 0.0 speedup is still recorded as None. _to_bool and the to_float import go with it. The code-metrics baseline drops the function (cognitive complexity and function length). Co-authored-by: Cursor <cursoragent@cursor.com>
…rantees kernel_lifecycle.render re-checked fields kernel_rows always fills: every row it returns has a non-empty kernel_id, a string name and a final_decision from a closed set, and a kernel with a lane summary is one the rollup has already marked selected. The "—" fallbacks on kernel_id and final_decision, the "or ''" on name and the GEAK and Forge terms of the actionable test are gone; a kernel is actionable when it was selected or a gate verdict reached it. The three verdict decisions come from one table instead of three copies of the same Decision block, the verdict counts from one Counter instead of four filtered lists, and the bw% and compute% columns from one table instead of two flags checked in two places. The markdown tables move into _kernel_tables, which reads only the detected kernels. render's only input is the breakdown, and every row it reads comes out of kernel_rows, so the section is unchanged for any breakdown. The code-metrics baseline drops render (cognitive complexity and function length). Co-authored-by: Cursor <cursoragent@cursor.com>
…each collect_v6_metadata derived versions.framework and versions.framework_version from the workload a second time, with the same coercion task_config had just applied; they now read task_config. The session block moves into _session_block, where the recovery mapping is narrowed with _mapping rather than a hand-written copy of it, and image_id loses an "if image" branch that returned the None the split already gives an empty image. _validation_from_timeline read the ledger's adoptions block three times; it now reads it once. The per-source attribution split and its _bucket helper move into _attribution, beside _bucket_of. _validation_from_timeline and _baseline_from_timeline accepted source_ids=None and guarded every write to it, but their one caller, collect_v6_outcome, always passes a list, so the parameter is required. The metadata and outcome sections are unchanged. The code-metrics baseline drops collect_v6_metadata and _validation_from_timeline (cognitive complexity and function length). Co-authored-by: Cursor <cursoragent@cursor.com>
…eir inputs normalize_framework_reviews narrowed request, review and emit with _mapping, although its one caller, record_critic_iteration, passes review and emit through its own _dict and calls request.get() before the call, and request is only read through _safe_get, which accepts any value. Those three calls are gone. judge_bundle keeps its _mapping: it comes straight from read_json and nothing checks it first. Also deleted: the "or ''" on a proposal's msg_id, which the comprehension's own filter already rules out, and the trailing None and [] arguments to _first, which already returns None when nothing qualifies and whose result _string_list already turns into []. The fixed action-to-arm branches become one table, and the candidate a proposal names is resolved in one place: _candidate_id now takes the payload and params and checks the Framework Agent id before the candidate's own references, as the inline lookup around it did. The specialist's source-or-config rule and the critic's ruling fields move into _specialist_authors_source and _ruling. The rows are unchanged, key order included. The code-metrics baseline drops normalize_framework_reviews (cognitive complexity and function length). Co-authored-by: Cursor <cursoragent@cursor.com>
…lexity gate try_flydsl_kb_warmstart was over the gate on cognitive complexity (71), length (169 lines) and nesting depth (7). The candidate trials now run on one _Trials object whose reject, measure and settle methods own the state the loop used to thread through nested blocks: the survivors, the references and the search deadline. The function keeps the read, the admission checks and the deadline handling (cognitive 12, 61 lines). Deleted, and why each is safe: - The top_k keyword. Its only production caller (runner.py) never passes it, so the warm start always read warmstart_policy.top_k() candidates. - stop_at_unix=None (or <= 0) meaning "no deadline", with the matching None branch in _stage_timeout. The production caller always passes the run's search stop, a positive unix timestamp; the default is now infinity, which bounds nothing. - The (speedup, -index) tie-break. Survivors are appended in rank order and max() returns the first maximal item, so the winner is the same. - The plan.candidates check before turning "hit" into "candidates_rejected": _read_top_candidates reports "hit" only when it returns candidates. Kernel writes, validation and benchmark calls and attempt records happen in the same order: a differential run against the previous code over 8000 generated scenarios found no difference. Co-authored-by: Cursor <cursoragent@cursor.com>
…gate generate_applyback_patch (cognitive 33, 209 lines) and _validate_worktree_changes (cognitive 35) were over the gate. The clean-room attempt loop now runs on _CleanRoomAttempts: run owns each attempt's pristine worktree, its cleanup and the retry decision, and _integrate runs the agent, validates what it changed and publishes it. generate_applyback_patch keeps the request checks and the reference copy. Deleted, and why each is safe: - The placeholder result for a loop that never ran, and the separate out-of-time return on the first attempt: the result before any attempt is now the out-of-time one, which is what the first attempt returned when there was no time to start it. - The math.isfinite branch around the baseline import timeout: min() with the 60 s import ceiling already turns an unbounded remaining time into 60. - The "failed without diagnostics" fallback: both failure handlers always set a non-empty error text. - The retryable flag, replaced by one check of the error against the two failures a fresh attempt cannot fix, and the max(1, ...) clamps on attempts_left, which is at least 1 inside the loop. - _staged_paths and _reject_unpublishable_paths, folded into _publishable_staged_paths: both call sites listed the staged paths, refused an empty list and checked the same forbidden paths. - The attempt counter in the pre-commit loop, replaced by for/else. A max_attempts below 1 now runs no attempt and reports the out-of-time failure; the CLI (IntRange(min=1)) and the request default (2) never pass one. Worktree setup, validation, agent calls, failure snapshots and cleanup run in the same order: differential runs against the previous code (300 validation and 200 end-to-end scenarios on real git worktrees) found no difference. Co-authored-by: Cursor <cursoragent@cursor.com>
…plexity gate prepare_rewrite_driver was over the gate on cognitive complexity (37) and length (231 lines). Its authoring loop now runs on _DriverAuthoring, which holds the caller's original driver, the audit directory and the failure the next prompt reports; run, _seed_stage, _author and _failure are its phases. prepare_rewrite_driver keeps the independence checks, the invocation-spec read and the audit setup. Deleted, and why each is safe: - The prior_failure assignments in the agent timeout and error handlers: every path after an authoring turn overwrites prior_failure or returns before the next prompt is built, so those messages never reached the agent or the final error. - max(1, max_attempts): the runner never sets DriverPreparation's max_attempts, so it is always the default of 3. - The "not initial_preflight.ok" condition on seeding the first prompt with the preflight detail: the runner calls prepare_rewrite_driver only after that preflight failed. - _unexpected_stage_outputs and _clean_unexpected_outputs, folded into _restore_write_boundary: their one caller always ran them around _restore_evidence, so the three steps are now one call that returns what crossed the write boundary. Audit files, driver writes and restores, preflight calls and results are unchanged: a differential run against the previous code over 600 generated scenarios, including agent timeouts and errors, found no difference. Co-authored-by: Cursor <cursoragent@cursor.com>
Code metrics gate: PASSEDJudged: 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.
Module length warning: over 800 lines, within the 1200-line failure limit (not failing): 3
Already over at the base (backlog, not this change's): 1
107 findings in files this change does not touchOutside this change (informational): 107
...and 82 more; the job log lists every row.
Thresholds and sources: |
…akdown-flydsl Co-authored-by: Cursor <cursoragent@cursor.com> # Conflicts: # scripts/code_metrics_baseline.txt
This was referenced Oct 20, 2026
…akdown-flydsl Co-authored-by: Cursor <cursoragent@cursor.com> # Conflicts: # src/kernelforge/rewrite_by_flydsl/applyback.py # src/kernelforge/rewrite_by_flydsl/flydsl_rewrite_driver_preparation.py
This was referenced Oct 20, 2026
fengshaoyi-amd
marked this pull request as ready for review
October 20, 2026 11:11
Contributor
Author
|
/review |
|
Automated review started for head 1273401. Progress: https://github.com/AMD-AGI/Hyperloom/actions/runs/39413579400 |
|
Automated review: no verdict applied -- the review job ended with result 'failure'. Comment |
…akdown-flydsl Co-authored-by: Cursor <cursoragent@cursor.com>
This was referenced Oct 20, 2026
…akdown-flydsl Co-authored-by: Cursor <cursoragent@cursor.com> # Conflicts: # scripts/code_metrics_baseline.txt
This was referenced Oct 21, 2026
This was referenced Oct 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this does
Eleven functions in the session breakdown and in the FlyDSL rewrite pipeline were over the code-metrics gate. This PR brings each one under every limit it broke, mostly by deleting what it re-checked: alias keys and fallbacks for a producer that no longer exists, guards on inputs whose only caller already guarantees them, keyword arguments no caller passes, second reads of a value already read, and two pairs of helpers that always ran together. What is left of the three long FlyDSL retry loops moves onto one object per loop that owns that loop's state.
Production code: +727 / −1,070 (net −343) across 11 files. The code-metrics baseline loses 21 entries and gains none.
This continues the complexity cleanup of #2024 and #2026. The two areas share one PR to save a review round; the eight commits read one at a time, and each commit message lists what it deleted and why that is safe.
breakdown/recorder/framework_event.py(alsoevent_fields.py,conc_sweep_event.py,schema.py)breakdown/recorder/instrument.pybreakdown/reporters/_renderers/kernel_lifecycle.pybreakdown/collectors/v6.pybreakdown/critic_reviews.pyrewrite_by_flydsl/kb.pyrewrite_by_flydsl/applyback.pyrewrite_by_flydsl/flydsl_rewrite_driver_preparation.pybreakdown/is undersrc/hyperloom/inference_optimizer/,rewrite_by_flydsl/undersrc/kernelforge/.Gate numbers per function
Measured with the gate's own tools (ruff C901, complexipy, function lines), base → head. Limits are 20, 30 and 80; bold values were over the limit at base.
FrameworkEventRecorder.record_attemptassemble_framework_ext_mirror_backend_attempts_to_kernel_timelinekernel_lifecycle.rendercollect_v6_metadata_validation_from_timelinenormalize_framework_reviewstry_flydsl_kb_warmstart(nesting 7 → under 5)generate_applyback_patch_validate_worktree_changesprepare_rewrite_driverAcross the 11 touched production files: C901 total 563 → 528 and cognitive total 1,103 → 915. Functions over a gate limit: cognitive 10 → 0, length 12 → 2 (the two left are functions this PR does not change).
FrameworkEventRecorder.record_proposal_reviewstays in the baseline for its 12 keyword parameters. They are the recorder's call interface, and an object built only to pass them under the limit would be a parameter bag.New names
_ATTEMPT_FIELDS,_ATTEMPT_BLOCKSand_CONFIG_DELTAfor framework attempt rows;_VERDICT_DECISIONSand_UTIL_COLUMNSin the kernel-lifecycle renderer;_ACTION_ROUTESfor critic reviews.event_fields.text(replaces the private copy inconc_sweep_event),_textsand_text_rows,_session_block,_attribution,_kernel_tables,_specialist_authors_source,_ruling. Two pairs of helpers that always ran together became one each:_publishable_staged_pathsand_restore_write_boundary._Trials(KB warm start) owns the survivors, the references and the search deadline that the trial loop used to thread through nested blocks.reject,measureandsettleupdate them._DriverAuthoring(driver preparation) owns the failure the next prompt reports, the attempt count and the last preflight.run,_seed_stage,_authorand_failureread and update them._CleanRoomAttempts(apply-back) is frozen and holds the four inputs that both the retry loop (run) and one attempt's integration (_integrate) read. It is the closest of the three to a parameter carrier; without it,_integratetakes seven parameters.Observable effect
Nothing an operator sees changes. Breakdown JSON, reports, rewrite results, apply-back patches, audit trees and log lines are the same for every input the repo's own callers produce.
The differences below are reachable only by input that no caller in the repo produces:
KernelPhase._record_kernel_rewrite_controller_timeline, sends neither. An adopted attempt whose micro speedup is exactly 0.0 is now recorded with speedupNone, as every other attempt with a 0.0 speedup already was. That would be a KEEP at a −100% gain, which the controller does not produce.FrameworkEventRecorder.record_attempt. It no longer takests=oraccepted_kernels=; no caller passes either. A row is always stamped with the record time, andV6FrameworkAttemptdropsaccepted_kernels, which no writer ever filled.normalize_framework_reviewsexpectsreviewandemitto be dicts, which its one caller already ensures._validation_from_timelineand_baseline_from_timelinerequiresource_ids, which their one caller always passes.try_flydsl_kb_warmstart.top_k; no caller passes it.stop_at_unix=NoneraisesTypeErrorinstead of meaning "no deadline". The default, infinity, is what means no deadline now.stop_at_unixstops the search at once. The runner always passes the search stop, a positive timestamp derived from the run deadline.max_attemptsbelow 1 now runs no attempt instead of one.IntRange(min=1)and the request default is 2.max_attempts, so it is the default of 3.prepare_rewrite_drivergiven an initial preflight that passed would seed the first prompt with that preflight's detail. The runner calls it only after that preflight failed.Checklist
top_k=3it passed.size-exception. The reasons: two areas share one review round, the eight commits each change one module and read on their own, and the net is −343.kernel_lifecycle.render(79 lines),_DriverAuthoring.run(79) and_CleanRoomAttempts.run(78) sit close to the 80-line trigger; each is the one loop that owns its state.framework_event.py(1,044 → 986 lines),conc_sweep_event.py(1,038 → 1,034) andapplyback.py(933 → 860) stay over the 800-line module warning, and each gets shorter._to_bool.group_rows) and a duplicated text coercion.top_k,ts=,accepted_kernels=) belong to internal functions and had no caller.Known merge interactions
applyback.pyandflydsl_rewrite_driver_preparation.py, were resolved by keeping this PR's restructuring and putting fix: narrow, remove or log the remaining broad handlers outside the files under restructuring #2049's threelog.warningcalls, with their messages unchanged, into theexcept Exceptionhandlers where they now live:_CleanRoomAttempts.run,_DriverAuthoring.runand_DriverAuthoring._author.or 0.0in_validation_from_timelineand conflicts with this PR inbreakdown/collectors/v6.py, where this PR rewrites the lines around them. Whichever lands second reapplies the two edits.breakdown/schema.py.breakdown/schema.pybut conflicts only inscripts/code_metrics_baseline.txt, as do refactor: delete the dead and repeated code in fourteen over-gate functions #2024 and refactor(kernelforge): delete the dead and repeated code in twelve over-gate functions #2026. About forty other open PRs share only that file.Gate
scripts/code_metrics.py --base-ref origin/mainpasses: 0 new, 0 worse, 0 out-of-date entries. Baseline: −21 entries, +0.ruff checkandruff format --checkare clean on the touched files.