Repository navigation
refactor(forge-loop): delete the dead and repeated code in nine over-gate stop, warm-start, config, KEEP and locked-loop functions - #2082
Conversation
…e patterns _python_command_payloads walked every character of a payload through a hand-written three-way state machine (single-quoted, double-quoted with backslash escapes, bare word), after a second loop that skipped the whitespace between `-c` and the payload. Both loops are gone: - `_PYTHON_COMMAND_PREFIX` now consumes the whitespace after `-c` itself (`-c\s+` instead of `-c(?=\s)`), so the match ends where the payload starts. Python's `\s` is the same class as `str.isspace()`, checked over every code point. - `_PAYLOAD_WORD_BODY` maps the opening quote to the anchored pattern that finds the word's end, so the scan is one `match()` call. - the unbalanced-quote test is one `startswith` at that end, and the single-use `raw` alias is inlined. The scan stays linear: a 400,000-character unterminated payload takes about 0.1 s, as before. A differential run of base against this code on 200,014 generated and edge commands (80,926 of them with payloads) gives identical results. Cognitive complexity 42 -> 16, cyclomatic 14 -> 6, 48 -> 27 lines. Co-authored-by: Cursor <cursoragent@cursor.com>
…caller
_inspect_pending_keep re-checked and re-normalized fields that its only
caller, _plan_resume_recovery, already pins down from _load_pending_keep:
- the iteration <= 0 guard: _plan_resume_recovery (runner.py:2310-2312)
raises the same "pending KEEP metadata is incomplete" when
int(pending.get("iteration", 0) or 0) is not positive, before this
function is reached.
- int(pending.get("iteration", 0) or 0) and the two
str(pending.get(...) or "") coercions of base_head and patch_sha256:
PENDING_KEEP_FIELDS plus _load_pending_keep's exact key-set check mean
those keys are present, and the caller has already required a positive
iteration and a non-empty base_head.
Cognitive complexity 33 -> 30 (at the limit), 58 lines unchanged in count.
Co-authored-by: Cursor <cursoragent@cursor.com>
…ding fields _reconcile_best_publication built two pending keys that _publish_best_result never reads, and restated why describes_current_best short-circuits: - pending["changed_files"] and pending["patch"], including the published-patch file read that only fed the latter: _publish_best_result (runner.py:1637-1644) takes publication_changed_files / publication_patch and otherwise calls _publication_changed_files / _publication_patch on the KEEP commit, so the assembled values were discarded. The git lookups that filled those keys therefore ran a second time inside publish. - the three-line comment above describes_current_best: it narrated the resume session_index / experiment_id divergence the call itself encodes. 89 -> 68 lines, cyclomatic 10 -> 8, cognitive 20 -> 14. Co-authored-by: Cursor <cursoragent@cursor.com>
_resolve_keep_sigma inlined a re-measure loop whose only job is to buy extra benches until the dominant case's sigma settles, then fold that into the KEEP resolution. That loop is now _remeasure_keep_sigma, which returns the finished SigmaResolution so the caller does not unpack a 3-tuple. Also deleted: - the isinstance(extra, dict) guards around measure_wallclock's result: measure_wallclock is annotated and always returns a dict (evaluation/benchmark/runner.py:256). - the three-line comment on variance share, which narrated a property of the attribution math rather than a local invariant. 96 -> 50 lines (helper 50). Cyclomatic 12 -> 6, cognitive 23 -> 9. Co-authored-by: Cursor <cursoragent@cursor.com>
InSessionGate._on_stop mixed harness protection, the block-budget hand-off, correctness, and the KEEP-bar bench into one 186-line method. Those are now three complete jobs plus a short recorder: - _stop_for_protected_harness: the harness-tamper allow-or-block - _stop_candidate_verdict: JIT rebuild, correctness, and the correctness-only allow; delegates the KEEP-bar bench to _stop_performance_verdict - _stop_performance_verdict: three-measurement bench and the allow/block on the mean-case score - _record_insession_bench: the bench fields the outer loop reuses on allow Also deleted the pre-clear of last_bench_result before measure_wallclock: every path already sets last_bench_result (to the bench or to None) before returning. 186 -> 27 lines. The helpers are each under the gate. Co-authored-by: Cursor <cursoragent@cursor.com>
…h steps run_one_iteration inlined build, validate printing, bench obtain, score printing, registers, the KEEP bar and canonical acceptance. After deleting what it rewrote for no reader, those jobs are named helpers: - pmc_diagnosis / pmc_full local "" constants: IterationResult defaults are "". - vgpr = None before the only assignment that sets it. - isinstance(bench_result, dict) on both IterationResult paths: every producer here returns a dict (reuse copies one; measure_wallclock returns one). - the duration alias of time.time() - iter_start. - the Step N / profiling / variance-bar narrating comments. - the nested validate status ternary: one table lookup, _VALIDATE_FAIL_STATUS. Helpers: _emit_validation_stages, _iteration_bench_result, _emit_bench_scores, _decide_iteration_keep. Side-effect order on the success path is unchanged (observe after bench; score print before registers; canonical observe before the failure return). 206 -> 66 lines, cognitive 39 -> 6. Co-authored-by: Cursor <cursoragent@cursor.com>
run_one_iteration mixed build, validation printing, bench reuse, scoring prints, registers, the KEEP bar and the assembly canonical suite. Those are now named jobs, and three mechanisms are gone: - the nested PASS/TIMEOUT/ERROR/FAIL ternary: one _VALIDATE_FAIL_STATUS table plus _emit_validation_stages - the empty pmc_diagnosis / pmc_full locals: IterationResult already defaults both to "" - the isinstance(bench_result, dict) guards on bench_detail: both the reused in-session path and measure_wallclock return a dict _decide_iteration_keep still captures the bench-failure tail before _apply_mean_case_speedup_metric, which may rewrite success and message. 206 -> 57 lines (cognitive 39 -> 5). Helpers each under the gate. Co-authored-by: Cursor <cursoragent@cursor.com>
kb_warmstart inlined reading the ranked field, the dirty-workspace reference-only return, pristine measurement, adoption, and the success envelope. Those jobs now live on _WarmStartAttempt: - load_solutions: read_top_solutions plus the claimed-speedup floor filter - dirty_result / empty_result: the two early returns that clear or reject the reference ledger - measure_and_adopt: pristine bench, field measurement, and winner adopt - final_result: the success envelope the loop persists Also deleted the isinstance(pristine_bench, (int, float)) branch when reading median_ms: aggregate_benchmark_measurements always returns a dict (evaluation/benchmark/runner.py:157). Cognitive 54 -> 6, 234 -> 44 lines. Co-authored-by: Cursor <cursoragent@cursor.com>
_WarmStartAttempt.workspace_dir / applied / applied_rank were one-line properties counted as cyclomatic 1 each. empty_result and dirty_result were straight-line returns. Inlining them (and the pristine_ms ternary into the existing None branch) brings the three-file C901 total back to the base 1198 while cognitive stays lower. run_one_iteration also takes back the validate-print and bench-obtain steps that were pure relocation. Co-authored-by: Cursor <cursoragent@cursor.com>
The seven over-gate functions in kf-loop-b are within every limit they broke. Removes their cognitive-complexity and function-lines baseline entries, and lowers knowledge_integration.py module-lines 1457 -> 1455. Co-authored-by: Cursor <cursoragent@cursor.com>
Delete the kernel/driver/program_md aliases, the redundant list() copy of parsed targets and the str() wrap around gpu_type. The clean-branch gate and the program.md digest each name one job, so create_campaign_config stays under the line limit without re-checking inputs its callers already hold, and its validation errors are raised in the same order as before. Co-authored-by: Cursor <cursoragent@cursor.com>
… aliases Delete the getattr guard on archive (always set by _initialize_campaign_runtime), the unused actor unpacking in session setup, the best_before locals that only fed replace(), and the narrating comments that restated what the call sequence already says. Session open and attempt settlement each name one job so _run_locked stays under every gate limit. Co-authored-by: Cursor <cursoragent@cursor.com>
…elpers Test the workspace branch against one set, drop the state_exists gate on stale-session reconcile (a fresh RunState is never SESSION_RUNNING), build the benchmark_measurement keyword inline so a None measurement still leaves it off the run_one_iteration call, and always record planning state the way _abandon_iteration already does. Co-authored-by: Cursor <cursoragent@cursor.com>
…e gate create_campaign_config and IterationLoop._run_locked are within every gate limit after the deletion-first cleanup. Co-authored-by: Cursor <cursoragent@cursor.com>
Put back the comments that state ordering, rebuild, scoring, noise and budget rules the code cannot show; step numbers, section banners and comments that only restate the next line stay deleted. The KEEP bar and the round pricing move into _clears_keep_bar and _price_round, whose docstrings carry their rules, _settle_locked_attempt reads the session sink from its frame, and the in-session gate's verdict strings are rewrapped unchanged, so every changed function stays within 80 lines and no module ends longer than it was. Co-authored-by: Cursor <cursoragent@cursor.com>
Code metrics gate: PASSEDJudged: the 10 files this change touches. Files it does not touch never fail it; anything found there is listed under Outside this change for information.
Already over at the base (backlog, not this change's): 10
72 findings in files this change does not touchOutside this change (informational): 72
...and 47 more; the job log lists every row.
Thresholds and sources: |
…loop-bd-pr Correction to 2430053 (reconcile a best publication without unused pending fields): the three-line comment above describes_current_best is not narration. It states why that short-circuit exists - a resumed session recomputes session_index and experiment_id, so republishing an already-current best would trip the same-iteration conflict guard and report persistence_degraded over a correct bundle - and 15c40c0 restored it unchanged. Co-authored-by: Cursor <cursoragent@cursor.com>
ZhengGong-amd
left a comment
There was a problem hiding this comment.
Please reconsider these points before merge.
src/kernelforge/loop/insession_gate.py:1103-1145: the reset oflast_bench_resultwas removed on the claim that every path sets it, but on case-coverage failure (:1127) or a bench exception it keeps the previous stop's value (base: None, head: stale result). KEEP is unaffected today only becauserunner.py:5964also requiresgate_passed.
Action: reset thelast_*attributes once at the start of the verdict and drop the per-branch resets; fix the claim in the commit/description.src/kernelforge/loop/runner.py:2517-2523_reconcile_best_publication: a failed publication diff on resume used to abort (CalledProcessError); it is now caught, markedpersistence_degradedwith a warning, and resume continues. The direction is fine, but the description says exception behaviour is unchanged. AGENTS.md Every change states its observable effect.
Action: list this change in the description and add a test that pins it.src/kernelforge/loop/runner.py:316-320_VALIDATE_FAIL_STATUSduplicates_status_labelinsrc/kernelforge/evaluation/correctness/pipeline.py:103-110. AGENTS.md Clean design.
Action: makestatus_labelpublic and call it; delete the new table.
Also: this PR conflicts with #2083 in runner.py (6 large hunks); please agree on merge order.
Reuse correctness status labels and pin degraded best-publication reconciliation on resume. Co-authored-by: Cursor <cursoragent@cursor.com>
…loop-bd-pr Co-authored-by: Cursor <cursoragent@cursor.com>
The standalone status_label(outcome, passed) branched on a flag; the result owns both fields, so the pipeline and the runner now ask it. Co-authored-by: Cursor <cursoragent@cursor.com>
…loop-bd-pr Co-authored-by: Cursor <cursoragent@cursor.com>
|
Addressed the review.
Merge order vs #2083: prefer landing this PR first (reviewed, behaviour fixes), then re-splitting #2083 on the new main — it is move-only / AST-equivalent and already conflicts in |
Resolve scripts/code_metrics_baseline.txt by key: keep main's removals and this branch's removals; no entry was changed on both sides. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
chaojhou
left a comment
There was a problem hiding this comment.
Verified at f64dd4a: last_* are reset at the start of the stop verdict, the resume publication-diff degradation is pinned by a real-git test, and the duplicated status table is replaced by ValidationResult.status_label. I merged origin/main into the branch (the conflict was only scripts/code_metrics_baseline.txt, resolved by key: both sides' removals kept, no entry changed on both sides); code-metrics and every other check are green on the merge.
Please refresh the PR description against this head (counts, commit table and the statements the reviewers listed): the release notes are built from it.
LGTM
What this does
Nine functions in
src/kernelforge/loop/were over the code-metrics gate: the in-session gate's stop hook (InSessionGate._on_stop) and itspython -cpayload scanner (_python_command_payloads), the KB warm-start (kb_warmstart), the campaign-config factory (create_campaign_config), and fiveIterationLoopmethods on the path from a pending KEEP to a measured iteration (_inspect_pending_keep,_reconcile_best_publication,_resolve_keep_sigma,run_one_iteration,_run_locked). This PR brings each one under every limit it broke, mostly by deleting what no caller needs, and changes two failure paths, described under Observable effect.Production code: +700 / -767 lines (net -67) in 5 files. Tests: +123 / -4 in 4 files. Code-metrics baseline: 12 entries retired, none added.
What changes in each module
insession_gate.py:_on_stopkeeps only the order of its checks;_stop_for_protected_harness,_stop_candidate_verdictand_stop_performance_verdictdecide the stop, and_record_insession_benchpublishes the bench the outer loop may reuse._stop_performance_verdictclears the previous stop's measurements before it benches._python_command_payloadsends a payload word through a table of three patterns (_PAYLOAD_WORD_BODY) instead of a hand-written quote state machine.knowledge_integration.py:_WarmStartAttemptruns the stageskb_warmstartran inline (load_solutions,measure_and_adopt,final_result), and the branch that took a numeric pristine aggregate as the median is deleted.campaign_config.py:_require_dev_branchand_program_md_sha256take the branch check and theprogram.mddigest out ofcreate_campaign_config; thekernel,driverandprogram_md_filealiases, a copy of the parsed targets and thestr()aroundgpu_typeare deleted.runner.py:_remeasure_keep_sigmabuys the extra benches_resolve_keep_sigmadecides on;_emit_bench_scores,_clears_keep_barand_decide_iteration_keeptake the scoring and the KEEP decision out ofrun_one_iteration;_begin_locked_run,_price_roundand_settle_locked_attempttake the session opening, the round pricing and each attempt's settlement out of_run_locked. Deleted: thechanged_filesandpatchfields_reconcile_best_publicationput in its pending record, which the publisher never read, with the published-patch read and the git calls that computed them; theiteration <= 0guard and coercions in_inspect_pending_keep;isinstance(..., dict)checks on bench results that are always adict; and in_run_locked, thegetattr(self, "archive", None)guard, alias locals and thestate_existsgate in front ofreconcile_stale_running_session.evaluation/correctness/pipeline.py:ValidationResult.status_labelnames a result's status (PASS, TIMEOUT, ERROR or FAIL), and the pipeline and the runner both ask the result, replacing the pipeline's_status_labelfunction and the runner's own copy of the same ladder.Functions brought under the gate
Baseline entries this PR retires, with their values at base:
campaign_config.py:create_campaign_config(lines 119)insession_gate.py:_python_command_payloads(cognitive 42);InSessionGate._on_stop(lines 186)knowledge_integration.py:kb_warmstart(cognitive 54, lines 234)runner.py:IterationLoop._inspect_pending_keep(cognitive 33);IterationLoop._run_locked(cognitive 39, lines 256);IterationLoop.run_one_iteration(cognitive 39, lines 206);IterationLoop._reconcile_best_publication(lines 89);IterationLoop._resolve_keep_sigma(lines 96)Observable effect
Two failure paths change:
mean_case_speedup=,raw_mean=) and the session record, which no longer report a measurement this stop did not make. KEEP decisions are unaffected: the loop reuses the in-session bench only when the gate passed.For every input the repo's own callers produce, campaign configs, session events, in-session allow and block decisions, warm-start envelopes, iteration measurements, KEEP decisions, rulings, persisted KEEP publications, archive digests, log lines and file formats are otherwise the same. Inputs that no in-repo caller produces now behave differently:
_remeasure_keep_sigmagiven a non-dict frommeasure_wallclockraisesAttributeError, recorded as a crashed iteration, instead of treating the bench as failed.read_reason: "warm_start_error") instead of being taken as a median or as an unavailable baseline.base_head,iterationorpatch_sha256raisesKeyError;_load_pending_keeprefuses such a record first.reconcile_stale_running_sessionis now also called when there was no priorrun_state.json; on the fresh state it is a no-op._apply_iteration_planning_statenow also runs whenagent_fnisNoneafter a sourced attempt, as it does in_abandon_iteration.gpu_typeraisesAttributeErrorinstead of being converted withstr();Nonestill becomes"mi355x".Checklist
test_insession_gate_logic.pyaddstest_performance_verdict_clears_stale_bench_state_on_coverage_failure,test_stop_clears_stale_bench_state_when_benchmark_raisesandtest_performance_verdict_keeps_current_wall_when_scoring_is_unavailable.test_loop_runner.pyaddstest_resume_publication_diff_failure_degrades_persistence_without_propagating, which runs_reconcile_best_publicationover a real git workspace whose publication diff raisesGitErrorand asserts the degraded persistence, the recorded error and the warning; two fakes gainstatus_label.test_pipeline.pyaddstest_validation_result_status_label_contract, one case per label.test_pr_kb_cli_wiring.py:test_loop_appends_the_event_only_after_the_campaign_guardreadsIterationLoop._begin_locked_run, where the campaign guard and the PR-knowledge append now live; its assertion is unchanged.f64dd4aa2.size-exception: most of it reworksIterationLoopinrunner.py, the validate, bench and KEEP path and the locked loop that drives it, against one baseline file. No function this PR adds or changes crosses a gate limit. Over a review trigger and within the gate, each one ordered sequence:create_campaign_config(80 lines),_decide_iteration_keep(79),_begin_locked_run(77),_run_locked(77),_WarmStartAttempt.measure_and_adopt(77),run_one_iteration(72),_reconcile_best_publication(71),kb_warmstart(69) and_stop_performance_verdict(66)._inspect_pending_keepstays at cyclomatic 19, as at base: it is the one classifier of a pending KEEP against the commit graph.runner.py,knowledge_integration.pyandinsession_gate.pystay over the 1,200-line module limit they were already over, each shorter than at base.create_campaign_config,kb_warmstartandIterationLoop.run_one_iterationkeep their signatures. The one added public name is theValidationResult.status_labelproperty; the_status_labelfunction it replaces had no caller outsidepipeline.py.Commits
Squash-merged as
270158c2efrom headf64dd4aa2.18a704786refactor(forge-loop): end a python -c payload word by a table of three patterns52309831drefactor(forge-loop): inspect a pending KEEP without re-checking its caller243005300refactor(forge-loop): reconcile a best publication without unused pending fieldseb6117f56refactor(forge-loop): remeasure KEEP sigma as one settled resolutionc42d444b3refactor(forge-loop): decide an in-session stop as three named verdicts474e6b3b8refactor(forge-loop): finish a validated iteration through named bench steps86e95a10arefactor(forge-loop): decide one iteration as validate, bench, then KEEPe6a8eedf8refactor(forge-loop): run KB warm-start as one attempt object7976e6dc8refactor(forge-loop): drop warm-start properties that only added C901d205c8542chore(metrics): drop forge-loop baseline entries now under the gate806b4c269refactor(forge-loop): create a campaign config without input aliasesf917b5d1frefactor(forge-loop): drive the locked loop without archive guards or aliases518143dd3refactor(forge-loop): drop leftover cyclomatic from the locked-loop helpers2f9d723b0chore(code-metrics): drop the kf-loop-d baseline entries now under the gate15c40c031refactor(forge-loop): restore the comments that state constraintsb0fe5d455fix(forge-loop): clear stale stop measurements3b3b7abdarefactor(correctness): let a validation result name its statusorigin/main, the last by chaojhou