Skip to content

feat(kernelforge): export-runs reads AgentKernelArena driver.log sessions - #1950

Open
amd-ama10002-2 wants to merge 3 commits into
feat/kernelforge-run-experiencesfrom
feat/kernelforge-export-runs-arena-session
Open

amd-ama10002-2 wants to merge 3 commits into
feat/kernelforge-run-experiencesfrom
feat/kernelforge-export-runs-arena-session

Conversation

@amd-ama10002-2

@amd-ama10002-2 amd-ama10002-2 commented Oct 16, 2026 •

Copy link
Copy Markdown
Collaborator

Motivation

We are building knowledge-base support for KernelForge runs (kernel writing): turning KernelForge's raw logs into structured Experiences in Hyperloom's Experience KB. We are also changing the logs KernelForge writes so they carry what the KB extracts: planner plans open with a Summary: line, and implementers keep a <plan>.reasoning.md work log that opens the same way. This PR teaches kernelforge export-runs the AgentKernelArena driver.log session.

Stack: merge in this order, one at a time. Each PR targets the branch of the PR above it in this list.

  1. feat(kernelforge): plans open with a Summary line; implementers keep <plan>.reasoning.md #1949 — Summary line in plans; implementer reasoning logs
  2. feat(kernelforge): collect plain forge-loop runs as Experiences with export-runs and kernelforge-v1 #1944 — export-runs and the kernelforge-v1 mapping, for plain forge-loop runs
  3. feat(kernelforge): export-runs reads AgentKernelArena driver.log sessions #1950 — export-runs reads AgentKernelArena driver.log sessions (this PR)
  4. feat(kernelforge): export-runs reads AgentKernelArena campaign logs #1951 — export-runs reads AgentKernelArena campaign logs

Don't collect AgentKernelArena logs into a KB until #1951 lands: until then a campaign's artifacts are still read as a plain forge-loop run.

What changes

  • kernelforge export-runs reads an AgentKernelArena session directory (driver.log and arena_logs/ beside the task's directory, as the forge template writes for forge-rewrite-by-flydsl): one entry for the PORT step and one per forge-loop iteration, under the launcher's run name. Before, such a session yielded no entry. Collection makes an Experience of each iteration but skips the PORT step's entry, with a reason saying so: forge-rewrite logs no reasoning for the port, and every Experience requires reasoning.
  • Its identity comes from the task's own files and the session's config.yaml, its provenance from the session header: the KernelForge and arena checkouts, the model, and the KB mode.
  • rationale.reasoning taken from KernelForge's Rationale line leaves out the in-session gate's [gate edits=...] prefix, and provenance.kb_record is set only when forge-rewrite's KB publication names a written record, never its failure reason.
  • Refactor-only parts: the gate-prefix rule moves from forge_loop.py into archive.py (rationale_text), so the plain-run and arena readers share it.

Known limitations

  • Decision labels are read from the line shapes KernelForge's runner prints (as of 1c14e79e1); a change to those messages needs a matching change here.
  • A session directory must hold exactly one arena log, one arena run directory and one task directory; otherwise it is one entry saying why.
  • Arena log times are naive local times too, read as UTC.

  • Tests: new test_run_export_arena.py, session layout.
  • Size/complexity triggers crossed: session_log._line (cyclomatic 11) and _label (12); each is one flat dispatch over the line shapes KernelForge prints.
  • Observable effect: see What changes.
  • Breaking changes: no
  • PR addresses single concern: yes

@github-actions

github-actions Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

Code metrics gate: PASSED

Judged: the 11 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 68 +0
Cognitive complexity fails > 30 0 0 0 274 +0
Function length (lines) fails > 80 0 0 0 412 +0
Nested block depth fails > 5 0 0 0 25 +0
Parameter count fails > 5 0 0 0 95 +0
Module length (lines) warns > 800, fails > 1200 0 0 0 51 +0
Duplicated lines per file fails > 0 0 0 0 97 +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
105 findings in files this change does not touch

Outside this change (informational): 105

Unit Dimension Baseline Now
src/hyperloom/orchestrator/enablement/recipe/projections.py project_launch_evidence Cognitive complexity absent 36
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/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 170
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 91
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 184
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 169

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

@amd-ama10002-2 amd-ama10002-2 added the run-forge-e2e Run the single-GPU Forge e2e smoke on this PR (again on every new commit while set) label Oct 16, 2026
@amd-ama10002-2
amd-ama10002-2 requested a balanced review from Copilot October 16, 2026 23:04

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved parsing errors can omit decisions and measurements or export incorrect reasoning and KB record references.

4 open issues
What changed in this PR

Extends kernelforge export-runs to read AgentKernelArena driver-log sessions for Experience KB collection. Campaign-log support remains deferred to #1951.

Changes:

  • Exports PORT steps and forge-loop iterations from session logs.
  • Reads task identity and session provenance.
  • Adds session tests and updates export documentation.
File Description
src/​kernelforge/​tests/​test_run_export_arena.py Tests session layouts, decisions, and failures.
src/​kernelforge/​run_export/​session_log.py Parses session timelines and exports steps.
src/​kernelforge/​run_export/​forge_loop.py Documents the shared timezone limitation.
src/​kernelforge/​run_export/​document.py Integrates arena session discovery.
src/​kernelforge/​run_export/​command.py Updates CLI help for session support.
src/​kernelforge/​run_export/​arena.py Reads session layout, identity, and provenance.
docs/​reference/​experience-kb-collect.md Documents arena collection inputs.
docs/​kernelforge/​reference/​cli.md Describes expanded export support.

Review effort: Balanced

Comment thread src/kernelforge/run_export/session_log.py
Comment thread src/kernelforge/run_export/session_log.py
Comment thread src/kernelforge/run_export/session_log.py Outdated
Comment thread src/kernelforge/run_export/session_log.py Outdated
@amd-ama10002-2

Copy link
Copy Markdown
Collaborator Author

/review

@github-actions

Copy link
Copy Markdown

Automated review started for head 0ea198d. Progress: https://github.com/AMD-AGI/Hyperloom/actions/runs/38980848102

@github-actions

Copy link
Copy Markdown

Automated review: no verdict applied -- the review job ended with result 'failure'. Comment /review to retry. Run: https://github.com/AMD-AGI/Hyperloom/actions/runs/38980848102

@amd-ama10002-2
amd-ama10002-2 force-pushed the feat/kernelforge-run-experiences branch from 05be3a7 to 924313c Compare October 16, 2026 23:34
@amd-ama10002-2
amd-ama10002-2 force-pushed the feat/kernelforge-export-runs-arena-session branch 2 times, most recently from 811b1c0 to 7e4cf6b Compare October 17, 2026 00:53
@amd-ama10002-2

amd-ama10002-2 commented Oct 17, 2026 •

Copy link
Copy Markdown
Collaborator Author

This is the result of running the agent review-pr skill locally (the /review skill I think)

PR #1950 -- feat(kernelforge): export-runs reads AgentKernelArena driver.log sessions

What it does: kernelforge export-runs had no reader for an AgentKernelArena driver.log session, so a forge-rewrite session's PORT step and forge-loop iterations never reached hyperloom-kb-collect. This PR adds that reader (run_export/arena.py, run_export/session_log.py) beside the plain forge-loop one, and keeps the in-session gate's [gate edits=...] prefix out of reasoning and forge-rewrite's failure reasons out of kb_record.

Blocking issues: 2

  1. [X3] The reference doc promises one Experience per PORT step; collection skips every PORT step [verified]
    Problem: docs/reference/experience-kb-collect.md:219-220 now says the kernelforge-v1 mapping gives "one Experience per forge-rewrite PORT step", but port_unit never writes reasoning, transcripts are linked only to plain runs (forge_loop_runs, document.py:33), and the mapping requires reasoning (kernelforge-v1.yaml:53). Running test_run_export_arena.py's own session (SETUP, KEPT, MERGED, UNFINISHED) through normalize() and hyperloom-kb-collect --mapping kernelforge-v1 --dry-run collects iteration 1 and skips sess-gemm/port with "No reasoning, which every Experience requires". The skip sentence at :256-258 names only a merge as the case that never has reasoning, and the one test that collects a PORT unit (test_collect_kernelforge.py:127-150) hand-builds a reasoning field the exporter never writes. src/kernelforge/run_export/session_log.py:251
    Impact: no driver.log session ever yields a PORT Experience although the reference doc says it does, and the skip reason's advice to provide logs that record the agent's reasoning cannot be followed, since nothing the export reads gives a PORT step reasoning.
    Action: Either give port_unit a reasoning source the export reads, or state in experience-kb-collect.md:219-220 and :256-258, and in the description, that a PORT step is exported but never collected, correcting the same sentence in kernelforge-v1.yaml:3 and kernelforge-run-v1.yaml:1.
  2. [C3] stop_line is written for every undecided iteration and read by nothing [verified]
    Problem: _stop adds stop_line to each iteration that has no decision line, and nothing under src/ reads it: it is the only key the session layout writes that kernelforge-v1.yaml never names, collect's skip report carries only unit_id and reason, no doc mentions it, and only test_run_export_arena.py:201,306 assert it. The description does not declare it record-only. src/kernelforge/run_export/session_log.py:413
    Impact: runs.json gains a field that never reaches an Experience or the collect report and is kept in step with _stop only for its own tests.
    Action: Delete stop_line and its two assertions, or list it in docs/kernelforge/reference/cli.md as a record-only field and say what an operator reads it for.

SKIPPED: Step 7 independent reader -- no second reader was available (two attempts to start one were aborted), so both findings above were refuted by this reviewer only.
SKIPPED: T1 real-artifact check -- no AgentKernelArena session from an actual run is in the tree or was available to this review, and no in-tree doc describes its layout, so the directory shape (arena_ws_*/run_*/Aiter-task_*, .task-sessions/) and the arena log line prefix the fixtures assume are unchecked; KernelForge's own line shapes were checked against the print statements that produce them.
SKIPPED: V4 -- "# PARTIAL: #1032 changes 1075 files, only its first 100 were compared", overlap there unchecked
SKIPPED: V4 -- "# PARTIAL: #1154 changes 1232 files, only its first 100 were compared", overlap there unchecked
SKIPPED: V4 -- "# PARTIAL: #1276 changes 1311 files, only its first 100 were compared", overlap there unchecked
SKIPPED: V4 -- "# PARTIAL: #1675 changes 161 files, only its first 100 were compared", overlap there unchecked
SKIPPED: V4 -- "# PARTIAL: #1869 changes 331 files, only its first 100 were compared", overlap there unchecked
SKIPPED: V4 -- "# PARTIAL: #1922 changes 118 files, only its first 100 were compared", overlap there unchecked

Checked: src/kernelforge/run_export/{arena,session_log,archive,forge_loop,document,command}.py, test_run_export_arena.py, test_run_export.py, hyperloom_kb test_collect_kernelforge.py, mappings/kernelforge-v1.yaml, declarations/kernelforge-run-v1.yaml, docs/reference/experience-kb-collect.md, docs/kernelforge/reference/cli.md, rewrite_by_flydsl/{runner,kb,report,optimize}.py, loop/runner.py, knowledge/kb_store/identity/kernel_recipe.py, .importlinter | Ran: normalize() then hyperloom-kb-collect --mapping kernelforge-v1 --dry-run on the test's session at head; a sweep of every key that session writes against the mapping's $run. names; ruff check --select C901; git grep sweeps at head and base; CI at head re-read before posting (33 success, 2 skipped main-only jobs) | Base: 7a1171a | Head: 3acafc2

@amd-ama10002-2

amd-ama10002-2 commented Oct 17, 2026 •

Copy link
Copy Markdown
Collaborator Author

This is the result of running the agent review-pr skill locally (the /review skill I think)

PR #1950 -- feat(kernelforge): export-runs reads AgentKernelArena driver.log sessions

What it does: kernelforge export-runs gains a reader for the AgentKernelArena driver.log session (driver.log and arena_logs/ beside the task's directory, as forge-rewrite-by-flydsl writes it), so a session yields one runs.json entry for its PORT step and one per forge-loop iteration for hyperloom-kb-collect --mapping kernelforge-v1; before, it yielded none. The head commit also keeps the in-session gate's [gate edits=...] prefix out of exported reasoning and sets provenance.kb_record only when forge-rewrite's publication names a written record.

Blocking issues: 1

  1. [X3] The reference doc promises an Experience per PORT step, but kernelforge-v1 skips every PORT step this layout exports [verified]
    Problem: docs/reference/experience-kb-collect.md:219-220 now says the mapping gives "one Experience per forge-rewrite PORT step", but port_unit (src/kernelforge/run_export/session_log.py:251) writes no reasoning, the session layout links no transcript, and src/hyperloom_kb/mappings/kernelforge-v1.yaml:53 requires $run.reasoning; the skip sentence at experience-kb-collect.md:256-258 names only a merge as the case that never has reasoning. Reproduced at 3acafc2 with test_run_export_arena.py's own PORT OK session: normalize() writes sess-gemm/port, and hyperloom-kb-collect --mapping kernelforge-v1 --dry-run skips it with "No reasoning, which every Experience requires ..." while collecting sess-gemm/iteration-1. The one test that collects a PORT unit (src/hyperloom_kb/tests/test_collect_kernelforge.py:127, from feat(kernelforge): collect plain forge-loop runs as Experiences with export-runs and kernelforge-v1 #1944) hand-adds a reasoning value the exporter never writes.
    Impact: no forge-rewrite PORT step reaches the KB, so the declaration's PORT OK / PORT FAILED outcomes never occur, while the reference doc says they do; the skip reason's remedy ("Provide logs that record the agent's reasoning") cannot be followed, since forge-rewrite logs no rationale for its port and the export reads no transcript for a session.
    Action: Decide whether a PORT step should be collected. If it should, give the PORT unit a reasoning source the export reads, or exempt kind: port from the reasoning requirement in kernelforge-v1.yaml:53. If it should not, say at experience-kb-collect.md:219-220 and :256-258, and in the description's first What-changes bullet, that a PORT step is exported but never collected, and correct the same sentence in kernelforge-v1.yaml:3 and kernelforge-run-v1.yaml:1 (feat(kernelforge): collect plain forge-loop runs as Experiences with export-runs and kernelforge-v1 #1944).

Checked: src/kernelforge/run_export/{arena,session_log,archive,forge_loop,document,command}.py; docs/kernelforge/reference/cli.md; docs/reference/experience-kb-collect.md; src/hyperloom_kb/mappings/kernelforge-v1.yaml; src/hyperloom_kb/declarations/kernelforge-run-v1.yaml; src/hyperloom_kb/tests/test_collect_kernelforge.py; the producers' prints in src/kernelforge/rewrite_by_flydsl/{runner,optimize,kb,report}.py and src/kernelforge/loop/runner.py; src/kernelforge/knowledge/kb_store/identity/kernel_recipe.py; src/kernelforge/orchestrator/agent.py _gate_outcome_tag; the full file lists of every open PR | Ran: radon cc on the added functions; git grep sweeps of each new and changed name over src/ and scripts/; normalize() plus hyperloom-kb-collect --mapping kernelforge-v1 --dry-run on the arena test's session; the head commit's new tests on 7e4cf6b (3 fail) and 3acafc2 (pass); CI at head (all green) | Base: 7a1171a | Head: 3acafc2

@amd-ama10002-2
amd-ama10002-2 force-pushed the feat/kernelforge-export-runs-arena-session branch 2 times, most recently from 25e84cc to 78558a9 Compare October 17, 2026 02:07
@amd-ama10002-2
amd-ama10002-2 marked this pull request as ready for review October 17, 2026 02:31
@amd-ama10002-2
amd-ama10002-2 requested a review from a team as a code owner October 17, 2026 02:31
amd-ama10002-2 and others added 3 commits October 19, 2026 17:28
AgentKernelArena's forge template runs KernelForge's
forge-rewrite-by-flydsl pipeline in a session directory holding
driver.log and arena_logs/, beside the task's directory. export-runs
read none of it, so those runs gave the KB nothing.

Such a session is now one run: a unit for forge-rewrite's PORT step
(seq 0) and one per forge-loop iteration, under the launcher's run name
as run_id. session_log reads the arena's timestamped log and driver.log
as that timeline: an iteration's fields come from its own lines (header,
merge text, the agent's rationale, what it measured, and the decision
line KernelForge printed). The task's conditions come from the task's
own files, and the session header gives the KernelForge and arena
checkouts, the model and the KB mode. The files a session holds are not
read again as a plain forge-loop run.

Observable effect: `kernelforge export-runs` on a directory holding
AgentKernelArena driver.log sessions writes their PORT step and
iterations, which kernelforge-v1 collects as Experiences; before, those
sessions yielded no unit.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ications out of arena Experiences

Two things the AgentKernelArena session reader took from KernelForge's log
were not what they looked like.

A gate-enabled implementer's Rationale line opens with the in-session
gate's outcome, "[gate edits=... pass=... end=...]", which became the first
words of rationale.reasoning. The plain-run reader already removed it; the
rule now lives once in run_export.archive (rationale_text), and both readers
use it.

forge-rewrite prints "KB publish: <reason or solution>", so a failed write
logs its reason where a successful one logs the record: "not_configured"
became provenance.kb_record, and a multi-word error its first word. A
payload now counts as a record only when it has the KB store's record
shape, <canonical id>/<session id>, built from the store's own scheme name
and dimension count, so logs already written are read correctly too.

The merge fixture now carries the [bench] line a real merge prints before
its decision line, and the test asserts its score.

Observable effect: an arena Experience's rationale.reasoning no longer
starts with the gate's telemetry, and provenance.kb_record is set only for
a publication that wrote a record.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ich logs no reasoning

export-runs writes an entry for a session's PORT step, but forge-rewrite logs no
reasoning for the port and kernelforge-v1 requires reasoning, so collection
always skips that entry. The collection reference, the mapping's description and
the declaration's header said there is one Experience per PORT step; they now
say there is one per forge-loop iteration and name the PORT step among the units
that never have reasoning, as the mapping's no-reasoning skip reason now does.
@amd-ama10002-2
amd-ama10002-2 force-pushed the feat/kernelforge-run-experiences branch from e5ea4c9 to 225058e Compare October 19, 2026 17:35
@amd-ama10002-2
amd-ama10002-2 force-pushed the feat/kernelforge-export-runs-arena-session branch from 78558a9 to 132dc38 Compare October 19, 2026 17:36

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

run-forge-e2e Run the single-GPU Forge e2e smoke on this PR (again on every new commit while set)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants