Skip to content

feat(kernelforge): spend the first round on a knowledge base batch with --wiki-guided - #2036

Closed
zili-amd wants to merge 4 commits into
feat/kernelforge-knowledge-toolsfrom
feat/kernelforge-wiki-guided-mode
Closed

zili-amd wants to merge 4 commits into
feat/kernelforge-knowledge-toolsfrom
feat/kernelforge-wiki-guided-mode

Conversation

@zili-amd

@zili-amd zili-amd commented Oct 19, 2026 •

Copy link
Copy Markdown
Collaborator
  • Description: what and why

    Stacked on feat(kernelforge): offer a configured knowledge base to every forge role and record why each step was taken #2034 (the knowledge base as read-only tools for every forge role); review that first. This PR adds --wiki-guided, which spends the campaign's first round on the knowledge base (GUIDED) and then plans exactly as KernelForge does without the flag (FREE).

    Without it, a campaign's first rounds spend whole sessions rediscovering directions the knowledge base already documents for this kind of kernel. With it, the first round:

    1. asks a read-only batch builder (role playbook, with the knowledge base tools and the round's measured evidence) for every direction both support: at most 12 items in at most six groups, one group per piece of code, each item citing the pages behind it, or marked support: profiling when only the evidence ranks it among the largest levers left; an outage of the builder's backend is retried once at once;
    2. skips the dispatch planner, the angle specialists and the plan critic: one playbook_group analyst per group, one planned part per group, and the parts composed into one plan;
    3. implements the whole batch in one Implementer session (each part checked and timed, a part that breaks or slows the kernel reverted, a part left out only when its precondition proves false or it measured worse) and measures it once. The session works through every part until a wrap-up time, 10 minutes or a sixth of the session before its end, whichever is more: its stopping rule replaces KernelForge's "submit the first candidate that beats the best", its deadline section names the UTC time the session ends and the wrap-up time, and the in-session gate sends a correct and faster stop back to the first part it left neither in the kernel nor dropped with evidence before the wrap-up time (at most once per part, outside the gate's block budget);
    4. credits a per-item ledger from the session's closing [playbook:...], [playbook-skip:...] and [playbook-untried:...] lines (its latest report only).

    When the batch is kept and the session did not get to some items, one more round plans only the groups holding them, from the same playbook; a session whose outcome says nothing about the batch (an agent or API error, a contended measurement) has it run once more. After that, after any other outcome of the batch (slower, failed validation or build, crash, no change), or when no batch can be built (NO_USEFUL_DIRECTION, PLAYBOOK_UNAVAILABLE) or planned (NO_BATCH_PLAN, in which case the same round is planned as without the flag), the knowledge base round is over. From then on every role plans and implements as without the flag: no batch, no Implementer note, the ledger frozen, and the knowledge base tools withdrawn from every session. The planners see only a short summary of what the round settled (context.wiki_guidance.knowledge_base_round: what is in the incumbent, what was dropped and why, what a failed batch held and its failure, what was not reached). Whether a task may change its arithmetic is left to the task's request and objective. Off by default; refused without a knowledge base.

    Evidence: on MI300X through AgentKernelArena, 8 Triton and HIP tasks, 3 replicas each, against earlier runs of the same tasks without the flag, the first iteration's mean case speedup was 11% higher (geometric mean; higher on 7 of 8 tasks), reached in 11% less time at about the same cost. That run used an experiment branch whose first round is this PR's; its later rounds kept building batches, which this PR replaces with plain KernelForge, so the runs after the first round are not yet measured in this form.

    Why the batch session has its own stopping rule: the first e2e of this PR on MI300X (six aiter GEMM campaigns) stopped every batch session at its first improvement, after 9 to 21 of its 60 minutes, landing 3 to 6 of 5 to 10 items and marking the rest untried "for lack of time"; one skipped a part to do the next. The Implementer's system prompt tells every self-correcting session to submit the first candidate that beats the best, its deadline section told it to stop well before an end it could not see, and the gate let any correct and faster stop through.

    Four commits: a refactor with no behaviour change (dispatch evidence binding in one function, which the group dispatch reuses), the feature, the batch session's stopping rule, clock and gate check, and one budget-free block response shared by the gate's harness and batch checks. The playbook and ledger live in loop/wiki_playbook.py and loop/wiki_guidance.py, the loop's side in loop/wiki_guided_rounds.py, the planning side in orchestrator/wiki_batch.py; runner.py, orchestration.py, agent.py and the in-session gate keep only the hooks, and KernelForge's own planning and Implementer prompts are unchanged outside a batch session.

  • Linked issue(s): none

  • Tests: added/updated? commands run?

    test_wiki_guided.py, 62 tests. Units: playbook parsing and renumbering, citation reading (leading ids only, a claim wins, the strict comma rule for skips, untried reasons, latest report only), the ledger, which groups stay open, the summary the planners see after the round (including a failed batch's failure), the state round trip, a batch session's wrap-up reserve, its stopping rule and clock, and when it may stop (every item in the kernel or dropped, or the wrap-up time reached; an untried item, a skipped earlier part or a missing report sends it back to the first part left). Through IterationLoop.run with a scripted orchestration service and Implementer: the first round implemented in one session and the next planned as without the flag (no Implementer note, the tools withdrawn, only the summary, the ledger frozen); each batch session given its parts and their open items, and a KernelForge session none; one completion round after a kept batch with untried items, and no second; a batch that is not kept ending the round; a batch session that measured nothing run once more, and a second one ending the round; an outage retried within the round, and a second giving the round to KernelForge; a batch none of whose parts could be planned giving the same round to KernelForge; a KEEP the process died before crediting credited on resume; a round interrupted before its measurement planned again from the saved batch without the builder; a resumed campaign continuing its phase; nothing changing without the flag. Through OrchestrationAgent and OrchestrationService: the builder's role, tools and prompt, one part per group, group dispatch skipping the planner and the critic, FREE keeping both, the factory adding the group analyst only with a knowledge base. Through the forge-loop command: the flag reaches the loop config, is off by default and is refused without a knowledge base. test_knowledge_wiki_tool.py: the factory test expects the group analyst in the pool, and a withdrawn knowledge base is offered to no later session. test_insession_gate_logic.py: a batch session stopping correct and faster with parts left is sent back without spending the block budget and let go once every item is in or dropped, at most once per part, with its last word read from the transcript when the hook is not given it, and let go at its wrap-up time or when its last word cannot be read. test_session_timeout_wiring.py: a batch session's system prompt differs from a plain one only in the stopping rule, and its deadline section names the wrap-up time.

    Run locally: pytest src/kernelforge -n 16 (6166 passed, 19 skipped), ruff check, ruff format --check, lint-imports (10 contracts kept), python scripts/code_metrics.py --base-ref <#2034 head>, python scripts/pr_hygiene.py size.

  • Size/complexity triggers crossed: split, or why the shape is right:

    2070 production lines, so requesting size-exception. 1606 of them are five new modules, each under every limit: wiki_guidance.py 540, wiki_guided_rounds.py 354, wiki_batch.py 316, wiki_playbook.py 298, dispatch_binding.py 98. The rest are hooks: orchestration.py +124/-77 (the refactor alone is +5/-66), runner.py +71/-19, the in-session gate's batch check +67/-8, the CLI +36, agent.py +21/-9, the knowledge base tool's withdrawal +19/-3, contracts and specialists +10. Splitting further would land the playbook and ledger without the loop that uses them, or the planning side without anything that ever triggers it: one flag, one behaviour. The refactor is its own commit.

    Requesting baseline-raise: a hook of one or two lines in units and modules already over their limits at the base, each kept free of new branches by small helpers (cognitive complexity unchanged everywhere):

    Unit Base Now
    IterationLoop._collect_session_candidate (function lines) 185 186
    IterationLoop._implementer_history (function lines) 112 113
    IterationLoop._record_iteration_outcome (function lines) 107 108
    IterationLoop.__init__ (function lines) 100 102
    InSessionGate.__init__ (function lines) 84 87
    make_agent_fn.agent_fn (function lines) 193 198
    make_agent_fn.agent_fn (parameters) 5 6
    forge_loop (function lines) 515 517
    loop/runner.py (module lines) 6553 6605
    loop/insession_gate.py (module lines) 1260 1313
    orchestrator/orchestration.py (module lines) 1843 1890
    cli/forge_loop_command.py (module lines) 2026 2048

    The Implementer's sixth parameter is the batch session, passed by name only to an Implementer that declares it, as baseline_case_times and best_mean_case_speedup are. OrchestrationService.run gets shorter (149 to 146), IterationLoop._source_attempt 13 lines shorter (its optional-argument introspection moved to a helper that also passes the batch), make_agent_fn one line shorter, and _bind_dispatch leaves the baseline; the OrchestrationService.run, make_agent_fn and _bind_dispatch entries are tightened in this PR. Every other check (comments, English only, repeated literals, A1 and A8 to A12, duplication, dead code) reports nothing.

  • If this simplifies or refactors: which mechanism was removed, which contract was preserved, and the tests that show it:

    The first commit moves the binding half of OrchestrationAgent._bind_dispatch (assignment ids and each assignment's evidence references) to dispatch_binding.bind_dispatch, which takes resolved intents in order; _bind_dispatch keeps the merging of the planner's intents. The same references in the same order and the same ids come out: the dispatch tests in test_forge_orchestration.py pass unchanged at that commit.

  • Observable effect: what an operator will now see, and what the old behaviour cost them:

    With --wiki-guided and FORGE_KNOWLEDGE_WIKI_ROOT set, the run banner prints Wiki-guided planning: on (...); the first round logs its batch ([wiki-guided] batch: N item(s) in M group(s)), the parts of its one session and what the session landed, dropped and did not try, then [wiki-guided] knowledge base round over (<reason>); the batch session's prompt says Keep working through the batch's parts until HH:MM UTC, and a stop the gate sends back for parts left logs [in-session-gate] BLOCK n/N (batch unfinished); forge_experiments/wiki_guidance/ holds state.json, playbook.json and the builder's answer; the event log gains wiki_playbook_built, wiki_playbook_declined, wiki_playbook_unavailable, wiki_batch_planned, wiki_batch_report, wiki_playbook_ledger and wiki_guidance_phase, and every iteration_result carries guidance_phase (and wiki_batch for a GUIDED iteration); a GUIDED round's orchestration diagnostics show dispatch.mode: playbook_groups and plan_critic.status: skipped_guided_batch. After the round, the sessions' tool lists no longer include the knowledge base tools. Before, the knowledge base could only be consulted ad hoc by each role, and the first rounds of a campaign were spent finding what it already documents. Without the flag nothing an operator sees changes.

  • Breaking changes: no

  • PR addresses single concern: yes (one flag), with a preparatory refactor commit

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

@zili-amd zili-amd added run-forge-e2e Run the single-GPU Forge e2e smoke on this PR (again on every new commit while set) size-exception Waives the PR diff budget; added by a maintainer with a reason in the PR description baseline-raise Waives new, worse and baseline-growth code-metrics findings; reason required in the PR description labels Oct 19, 2026
@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Code metrics gate: PASSED with waived findings (baseline-raise)

Judged: the 22 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 6 +0
Cognitive complexity fails > 30 0 0 0 53 -1
Function length (lines) fails > 50 0 9 0 543 -1
Nested block depth fails > 4 0 0 0 44 +0
Parameter count fails > 5 1 0 0 80 +0
Module length (lines) warns > 800, fails > 1200 1 3 0 44 +0
Duplicated lines per file fails > 0 0 0 0 95 +0
Dead code (vulture) fails > 0 0 0 0 2 +0
Directory size (entries) fails > 50 0 0 0 2 +0
Check Findings Effect
Comments 0
Broad catch without a reason 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

New violations (not in the baseline) (waived by the baseline-raise label): 2

Unit Dimension Value Limit
src/kernelforge/orchestrator/agent.py:714 make_agent_fn.agent_fn Parameter count 6 fails > 5
src/kernelforge/cli/forge_loop_command.py:1 Module length (lines) 2048 fails > 1200

Worse than the baseline (waived by the baseline-raise label): 12

Unit Dimension Baseline Now
src/kernelforge/cli/forge_loop_command.py:1532 forge_loop Function length (lines) 421 425
src/kernelforge/loop/insession_gate.py:1152 InSessionGate._stop_performance_verdict Function length (lines) 62 65
src/kernelforge/loop/runner.py:772 IterationLoop.__init__ Function length (lines) 53 54
src/kernelforge/loop/runner.py:5880 IterationLoop._collect_session_candidate Function length (lines) 154 155
src/kernelforge/loop/runner.py:6109 IterationLoop._implementer_history Function length (lines) 83 84
src/kernelforge/loop/runner.py:3743 IterationLoop._record_iteration_outcome Function length (lines) 89 90
src/kernelforge/orchestrator/agent.py:714 make_agent_fn.agent_fn Function length (lines) 140 144
src/kernelforge/orchestrator/contracts.py:256 OrchestrationContext.__post_init__ Function length (lines) 75 77
src/kernelforge/orchestrator/orchestration.py:1811 make_orchestration_service Function length (lines) 63 69
src/kernelforge/loop/insession_gate.py:1 Module length (lines) 1218 1312
src/kernelforge/loop/runner.py:1 Module length (lines) 6051 6606
src/kernelforge/orchestrator/orchestration.py:1 Module length (lines) 1831 1890

How to fix

  • New or worse: split the unit (extract a function, a class, a module) until it is back under the limit, or no worse than its recorded value. The baseline cannot absorb a new violation: CI refuses any baseline entry added or raised relative to the base branch.
  • Baseline out of date: something improved. Run python scripts/code_metrics.py --update-baseline and commit scripts/code_metrics_baseline.txt; the command only lowers or removes entries.
  • Override: the baseline-raise PR label waives new, worse and baseline-growth findings and the failing design checks (they stay listed here). Use it only with the reason in the PR description; it waives nothing else.
  • Tools for a local run: pip install ruff==0.16.2 complexipy==8.0.1 vulture==2.16 and npm install -g jscpd@5.4.1 (or point CODE_METRICS_JSCPD at another jscpd command, such as npx --yes jscpd@<version>).

Module length warning: over 800 lines, within the 1200-line failure limit (not failing): 1

Module Lines Limit
src/kernelforge/orchestrator/agent.py 976 warns > 800

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

Unit Dimension Base Now
src/kernelforge/cli/forge_loop_command.py:1532 forge_loop Cognitive complexity 31 31
src/kernelforge/loop/runner.py:5880 IterationLoop._collect_session_candidate Cognitive complexity 44 44
src/kernelforge/loop/runner.py:5502 IterationLoop._rule_on_attempt Cognitive complexity 38 38
src/kernelforge/orchestrator/specialists.py:475 SpecialistAgent.run Function length (lines) 98 98
27 findings in files this change does not touch

Outside this change (informational): 27

Unit Dimension Baseline Now
src/hyperloom/orchestrator/actions/executors/_integrate_apply.py ApplyStageMixin._stage_apply Cognitive complexity absent 32
src/hyperloom_kb/collect/mapping.py _experience Cognitive complexity absent 31
src/hyperloom/orchestrator/loop/_keep_patch_column.py AgentKeepStagingMixin._stage_agent_keep Parameter count absent 6
src/hyperloom/orchestrator/phases/kernel.py KernelPhase._record_geak_delegation_timeline Parameter count absent 7
src/hyperloom/orchestrator/loop/_baseline_failures.py BaselineFailureMixin.handle_unpromotable_result Function length (lines) absent 55
src/hyperloom/orchestrator/loop/_resume_recovery.py ResumeRecoveryMixin._resume_recover_pending_warm_replay Function length (lines) absent 75
src/hyperloom_kb/http_service.py Module length (lines) absent 1525
src/hyperloom/orchestrator/specialists/dispatch.py SpecialistDispatchCollaborator.warm_specialist_params Cognitive complexity 93 94
src/hyperloom/inference_optimizer/cli/preflight.py _probe_rocm_build Function length (lines) 54 57
src/kernelforge/config.py Config.from_env Function length (lines) 67 69
src/kernelforge/orchestrator/analysis.py AnalysisAgentService._run_analysis_session Function length (lines) 81 83
src/kernelforge/orchestrator/plan_critic.py PlanCriticAgent.review Function length (lines) 66 68
src/hyperloom/inference_optimizer/breakdown/schema.py Module length (lines) 2681 2686
src/hyperloom/inference_optimizer/cli/__init__.py Module length (lines) 2569 2739
src/hyperloom/orchestrator/actions/executors/_kv_metrics.py Module length (lines) 1578 1579
src/hyperloom/orchestrator/actions/executors/roofline.py Module length (lines) 1303 1305
src/hyperloom/orchestrator/kernel/conc_sweep.py Module length (lines) 1429 1449
src/hyperloom/orchestrator/phases/kernel.py Module length (lines) 4102 4199
src/hyperloom/orchestrator/phases/prelude.py Module length (lines) 2504 2506
src/hyperloom/orchestrator/prompts/prompt_builder.py Module length (lines) 1205 1212
src/hyperloom/orchestrator/prompts/specialist_prompt_builder.py Module length (lines) 2556 2567
src/kernelforge/fusion/command.py Module length (lines) 1584 1708
src/kernelforge/fusion/validate.py Module length (lines) 1513 1514
src/kernelforge/gemm_tune/tuners/_aiter_dense_common.py Module length (lines) 1399 1463
src/kernelforge/loop/knowledge_integration.py Module length (lines) 1457 1459

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

@zili-amd
zili-amd force-pushed the feat/kernelforge-wiki-guided-mode branch from 7aff902 to 0f9ae8a Compare October 20, 2026 01:18
@zili-amd
zili-amd force-pushed the feat/kernelforge-knowledge-tools branch from 727921f to 5821319 Compare October 21, 2026 18:26
@zili-amd
zili-amd force-pushed the feat/kernelforge-wiki-guided-mode branch from 0f9ae8a to e9c1614 Compare October 21, 2026 20:17
@zili-amd zili-amd changed the title feat(kernelforge): plan each round from a knowledge base playbook first with --wiki-guided feat(kernelforge): spend the first round on a knowledge base batch with --wiki-guided Oct 21, 2026
@zili-amd
zili-amd force-pushed the feat/kernelforge-knowledge-tools branch from 6961049 to d62aa93 Compare October 22, 2026 18:18
@zili-amd
zili-amd force-pushed the feat/kernelforge-wiki-guided-mode branch from d68424a to 3aff99b Compare October 22, 2026 23:06
@zili-amd
zili-amd force-pushed the feat/kernelforge-knowledge-tools branch 2 times, most recently from d183e78 to 6a154d0 Compare October 23, 2026 18:21
zili-amd and others added 4 commits October 23, 2026 12:09
_bind_dispatch both merged the dispatch planner's role/case intents and
bound each merged intent to an assignment id and the exact evidence it
reads. The binding half moves to dispatch_binding.bind_dispatch, which
takes resolved intents in order, so a dispatch that does not come from
the planner can be bound the same way. The same references in the same
order and the same ids come out; the baseline loses the two entries the
long method held.

Co-authored-by: Cursor <cursoragent@cursor.com>
With a knowledge base configured, --wiki-guided gives the campaign's
first round to the knowledge base (GUIDED). A read-only builder (role
playbook) turns the knowledge base and the round's measured evidence
into one batch: at most 12 items in at most six groups, one group per
piece of code, each item citing the pages behind it or, for a lever only
the evidence ranks, marked as supported by profiling alone. An outage of
the builder's backend is retried once at once. The round skips the
dispatch planner, the angle specialists and the plan critic: one
playbook_group analyst per group, one planned part per group, and the
parts composed into one plan that one Implementer session implements and
the loop measures once. The session's closing [playbook:...],
[playbook-skip:...] and [playbook-untried:...] lines (its latest report
only) credit a per-item ledger.

A kept batch that left items untried gets one more round for just those
groups, from the same playbook, and a session whose outcome says nothing
about the batch (an agent or API error, a contended measurement) has it
run once more. After that, after any other outcome of
the batch, or when no batch can be built or planned, every round plans
exactly as without the flag: no batch, no Implementer note, the ledger
frozen, and the knowledge base tools withdrawn from every session. The
planners see only a short summary of what the round settled
(context.wiki_guidance.knowledge_base_round). A round interrupted before
its measurement is planned again from the saved batch on resume,
without asking the builder again. State and events live under
forge_experiments/wiki_guidance; off by default, refused without a
knowledge base.

The playbook and ledger live in loop.wiki_playbook and
loop.wiki_guidance, the loop's side in loop.wiki_guided_rounds, and the
planning side in orchestrator.wiki_batch; the runner and orchestration
keep only the hooks.

Co-authored-by: Cursor <cursoragent@cursor.com>
A batch session stopped after its first improvement: on MI300X the
first-round sessions of six aiter campaigns landed 3 to 6 of 5 to 10
items and marked the rest untried "for lack of time" after 9 to 21 of
their 60 minutes, and one skipped a part to do the next. The
Implementer's system prompt told every self-correcting session to submit
the first candidate that beats the best, its deadline section told it to
stop well before an end it could not see, and the in-session gate let
any correct and faster stop through.

A batch session now gets its own stopping rule in place of submitting
the first improvement, and a deadline section that names the UTC time it
ends and the wrap-up time until which it keeps starting parts (10
minutes or a sixth of the session before the end, whichever is more).
The in-session gate reads the session's last message at a correct and
faster stop and, before the wrap-up time, sends it back to the first
part whose items are neither in the kernel nor dropped with evidence, at
most once per part and without spending its block budget. Every other
session's prompt and gate are unchanged.

Co-authored-by: Cursor <cursoragent@cursor.com>
The batch check wrote its own block response beside the harness
check's, a literal the code-metrics gate counts as repeated. Both now
go through one block that spends none of the perf loop's budget.

Co-authored-by: Cursor <cursoragent@cursor.com>
@zili-amd
zili-amd force-pushed the feat/kernelforge-wiki-guided-mode branch from 3aff99b to 3393204 Compare October 23, 2026 19:45
@zili-amd zili-amd closed this Oct 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

baseline-raise Waives new, worse and baseline-growth code-metrics findings; reason required in the PR description run-forge-e2e Run the single-GPU Forge e2e smoke on this PR (again on every new commit while set) 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.

1 participant