Skip to content

fix(breakdown): drop never-populated 6.1 keys and report unmeasured figures as null - #2047

Merged
haishuok0525 merged 7 commits into
mainfrom
fix/breakdown-v7-dead-fields
Oct 21, 2026
Merged

haishuok0525 merged 7 commits into
mainfrom
fix/breakdown-v7-dead-fields

Conversation

@lishuoshuo-amd

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

Copy link
Copy Markdown
Collaborator
  • Description:
    Ships with the schema 6.1 declaration in 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: removes breakdown keys that no producer ever populated and reports unmeasured figures as null instead of a fabricated default.
    Removed (each verified to have no producer and to be null in every audited session; the documented disposition is "removed in 6.1, never populated"):
    • framework_agent policy.force_exit_budget_pct, policy.variant_timeout_sec, policy.overtime_kill_ratio (_framework_policy_fields never passes them)
    • kernel_agent trace_analyze_runs[].trace_validate_ref (a constant None)
    • critic_review.iteration on framework proposals (no caller passes it)
    • kernel_agent geak.product.cfg_hash and geak.product.final_overlay_digest (never passed by the orchestrator; the other product fields stay)
    • kernel_agent entry.budget_remaining_sec (conc_sweep points[].budget_remaining_sec is live and unchanged)
    • the V6RowScope event_id / ordinal declarations (stripped by wire_row before export, never on the wire)
    • warm_start fragment duration_sec (recorded, never exported)
    • session_terminal.json / session_terminal.pre.json from the session package allowlist (no producer)
      Null instead of a default:
    • outcome.validation.attributed_gain_pct / unattributed_gain_pct (and the stack ledger's attributed_gain_pct, attributed_gain_pct_excluding_fixes) are null when no adoption could be measured, instead of 0.0. A session with no adoptions no longer reports "Their contributions sum to 0.00%".
    • framework_agent run empty is null when the producer did not report it, instead of false; config runs that report it are unchanged.
    • entry.snapshot_staleness is typed as the string it is ("absent" / "fresh"); the producer is unchanged.
      docs/reference/session-breakdown.md and docs/reference/upgrade.md list the removals and the null semantics in the 6.1 section; the opening 6.1 sentence and the two compatibility-rule exceptions (Compatibility rules, Stability guarantee) now cover all three changes (the rename, the removed keys, the null defaults).
  • Linked issue(s): Refs Serving throughput is labelled tok/s/GPU but is the aggregate over all TP GPUs #1932. Builds on 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, which is merged; the base branch is main.
  • Tests: 7 new tests plus updates in 6 test files, with exact key-set / dict assertions for every removed key and is None for the null cases; all failed on the base branch. Ran the related test_sbd_v6_*, test_session_package.py, test_breakdown_renderers.py, test_reporters_smoke.py files individually; ruff, lint-imports and scripts/code_metrics.py pass (code_metrics_baseline.txt lowers entries the removals shortened). Real sessions: attributed/unattributed are unchanged where measured (ds-v4-pro 1.58 / -94.04, glm52 13.18 / -69.84) and become null for sglang-glm52 (no adoptions) and vllm-dsv4pro (an unmeasurable adoption).
  • Size/complexity triggers crossed: 18 files (+232/-120 against main), but each source change is a deletion or a one-line null fix; 6 are test files and 3 are docs (the two reference docs and the breakdown SKILL.md versioning policy, kept consistent with them).
  • If this simplifies or refactors: removes dead keys and the code that wrote them; no live key changes meaning except the null cases above.
  • Observable effect: the listed keys disappear from session_breakdown.json; attributed/unattributed gain and run empty read null when unmeasured; the session package no longer reserves session_terminal*.json.
  • Breaking changes: yes, as a declared exception inside the 6.x minor version (6.1, together with the 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 rename): schema keys no producer populated are removed and two defaults become null. The exception is stated in the Compatibility rules and Stability guarantee of the reference doc, and each change is listed in its 6.1 section.
  • PR addresses single concern: yes, breakdown fields that claimed a value no producer measured.
  • Root cause is upstream: no.

…s as null

Drop keys no producer ever wrote (framework policy budget and timeout keys,
trace_validate_ref, critic_review.iteration, geak product cfg_hash and
final_overlay_digest, kernel entry budget_remaining_sec, the RowScope
declarations, warm_start duration_sec, the session_terminal package entries),
report attributed/unattributed gain and run empty as null when unmeasured or
not provided, and type snapshot_staleness as the string it is.
@lishuoshuo-amd
lishuoshuo-amd requested a review from a team as a code owner October 20, 2026 05:07
@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Code metrics gate: PASSED

Judged: the 18 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 89 -1
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/inference_optimizer/breakdown/recorder/framework_event.py 981 warns > 800

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

Unit Dimension Base Now
src/hyperloom/orchestrator/phases/framework.py:1246 FrameworkPhase._maybe_rearm_authored_lane Function length (lines) 104 104
src/hyperloom/orchestrator/phases/framework.py:1946 FrameworkPhase._submit_framework_agent_candidate_for_review Function length (lines) 98 98
src/hyperloom/orchestrator/phases/framework.py:2190 FrameworkPhase.maybe_reauthor_from_critic_feedback Function length (lines) 133 133
src/hyperloom/orchestrator/phases/framework.py:514 _record_source_attempt Function length (lines) 151 151
src/hyperloom/inference_optimizer/breakdown/schema.py:1 Module length (lines) 2704 2690
src/hyperloom/orchestrator/phases/framework.py:1 Module length (lines) 3153 3148
102 findings in files this change does not touch

Outside this change (informational): 102

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 77 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.

@lishuoshuo-amd

Copy link
Copy Markdown
Collaborator Author

PR #2047 -- fix(breakdown): drop never-populated V7 keys and report unmeasured figures as null

What it does: Within the V7 cutover of #2023, deletes breakdown keys no producer ever set (framework policy caps, trace_validate_ref, critic_review.iteration, geak.product.cfg_hash/final_overlay_digest, entry.budget_remaining_sec, warm_start duration_sec, the V6RowScope declarations, and the session_terminal*.json package entries) at their recorder and TypedDict. It also stops the stack ledger, the outcome collector and record_run from turning an unmeasured attribution or an unreported run empty into 0.0/false, so those values now read null. The V7 sections of the reference and upgrade docs list all three kinds of break.

Blocking issues: none

Checked: diff.txt and body.txt at 3940e27. bcc987d..3940e27 changes only the opening V7 sentence in docs/reference/session-breakdown.md:40 and docs/reference/upgrade.md:262-264, which now name the rename, the removed keys and the null figures, and removes the renderer test that passed on base; production src/ is unchanged. Producers and readers of every removed or changed key were re-swept tree-wide with git grep over src/hyperloom, src/hyperloom_kb, src/kernelforge, docs, .claude/skills, scripts and breakdown/contracts/*.json. No removed key has a reader. attributed/unattributed are read only at optimizations.py:69 and attribution.py:43, both isinstance-guarded. The workflow-evaluation action.empty: boolean belongs to phase_records.py:231, which omits None. Of the empty callers, dispatch.py:822 always passes None and recipe_journal.py:138 passes a bool, unchanged. The removed-kwarg callers kernel.py:493, kernel.py:1977, intent_router.py:290 and framework.py:422 pass none of the removed kwargs. session_terminal has no producer at head or base. | Ran: the 6 changed test files plus test_breakdown_renderers.py and test_reporters_smoke.py individually at head (296 passed); the head tests on a git archive c565c19 tree (14 fail, including all 7 added tests); 9 real sessions (key renamed to output_throughput) replayed through assemble_stack_ext, _validation_from_timeline and the optimizations/attribution renderers, with output identical to the previous round (ds-v4-pro 1.58/-94.04 and glm52 13.18/-69.84 unchanged, sglang-glm52 and vllm-dsv4pro null); PYTHONPATH=src lint-imports (7 kept); ruff check. CI at 3940e27 is green: the cancelled code-metrics and pr-hygiene runs were superseded by successful runs at the same head. | SKIPPED: V4 -- #1154, #1276, #1869, #1907, #2004 and #2049 were compared on their first 100 files only, and only the newest 100 of 101 open PRs were compared; overlap beyond that is unchecked | Base: c565c19 | Head: 3940e27

LGTM

@lishuoshuo-amd lishuoshuo-amd changed the title fix(breakdown): drop never-populated V7 keys and report unmeasured figures as null fix(breakdown): drop never-populated 6.1 keys and report unmeasured figures as null Oct 20, 2026
@lishuoshuo-amd
lishuoshuo-amd force-pushed the fix/breakdown-v7-dead-fields branch from 1e09f4c to 9a0d168 Compare October 20, 2026 09:45
Base automatically changed from refactor/breakdown-output-throughput-key to main October 21, 2026 03:47
@lishuoshuo-amd

Copy link
Copy Markdown
Collaborator Author

PR #2047 -- fix(breakdown): drop never-populated 6.1 keys and report unmeasured figures as null

What it does: As part of schema 6.1 (the #2023 rename, now on main), the PR deletes breakdown keys no producer ever set, at their recorder and TypedDict. These are the framework policy caps, trace_validate_ref, critic_review.iteration, geak.product.cfg_hash/final_overlay_digest, entry.budget_remaining_sec, warm_start duration_sec, the V6RowScope declarations and the session_terminal*.json package entries. It also stops the stack ledger, the outcome collector and record_run from turning an unmeasured attribution or an unreported run empty into 0.0/false; those now read null. The reference doc, the upgrade doc and the breakdown skill's versioning policy all restate 6.1 as three changes inside the 6 major, declared as an exception to the major-bump rule.

Blocking issues: none

Checked: diff.txt, body.txt and title.txt at 8fe31a0. bd072f8..8fe31a0 changes only src/hyperloom/inference_optimizer/breakdown/SKILL.md:156-163 (+8/-5). It now describes the 6.1 exception as the rename, the removal of never-populated keys and null attributed_gain_pct/unattributed_gain_pct/run empty, in the same terms as docs/reference/session-breakdown.md:40-42, :107-115, :650-657 and docs/reference/upgrade.md:262-278. git grep over docs, src and .claude for rename-only wording ("6.1 rename", "renames one key", "one key inside", "declared 6.1", "for one rename") finds no remaining copy. The body now says 18 files +233/-121 with 3 docs, which matches numstat. Production src and tests are unchanged since bd072f8, where they were reviewed against main 958874f. At that review no removed key had a reader in src/hyperloom, src/hyperloom_kb, src/kernelforge, docs, .claude/skills, scripts or contracts/*.json, and attributed/unattributed are read only at optimizations.py:69 and attribution.py:43, both isinstance-guarded. scripts/code_metrics_baseline.txt touches only entries for files this PR edits. | Ran: at bd072f8, the 6 changed test files plus test_breakdown_renderers.py and test_reporters_smoke.py (296 passed), the head tests on a git archive 958874f tree (14 fail, including all 7 added tests), and 4 real sessions replayed under main and head (ds-v4-pro 1.58/-94.04 and glm52 13.18/-69.84 identical; sglang-glm52 and vllm-dsv4pro go from 0.0 to null); at 8fe31a0, test_sbd_v6_stack_ledger.py (32 passed). Polled gh pr checks 2047 at 8fe31a0 from 12:16 to 12:23: 33 pass (12 test shards, coverage 3.10/3.11, code-metrics, pr-hygiene, ruff, pylint, import-linter, sphinx, readthedocs, CodeQL), 7 skipping, 0 fail. | SKIPPED: V4 -- #1869 and #2055 were compared on their first 100 files only, and only the newest 100 of 104 open PRs were compared; overlap beyond that is unchecked | Base: 958874f | Head: 8fe31a0

LGTM

@lishuoshuo-amd

Copy link
Copy Markdown
Collaborator Author

Merged the latest main (9f7030a, with #2043 and #2045) at 47b729bcb. Two textual conflicts: scripts/code_metrics_baseline.txt (took main's file and re-applied only the three entries this PR lowers, from the code-metrics report) and one line in collectors/v6.py (kept main's by_keep_reason read and this PR's unattributed_gain_pct without or 0.0). The removed keys still have no reader on main, the diff against main is still only this PR's 18 files, and all checks are green at the new head.

@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: Completes the schema 6.1 exception from #2023. It removes breakdown keys that no producer ever populated (framework policy.force_exit_budget_pct / variant_timeout_sec / overtime_kill_ratio, kernel trace_validate_ref, critic_review.iteration, geak.product.cfg_hash / final_overlay_digest, kernel entry.budget_remaining_sec, the V6RowScope declarations, warm-start duration_sec, and the session_terminal*.json package entries). Unmeasured attributed_gain_pct / unattributed_gain_pct (outcome and stack ledger, plus attributed_gain_pct_excluding_fixes) and an unreported run empty now read null instead of 0.0 / false. The reference docs, upgrade notes and breakdown SKILL.md state the extended 6.1 exception.

Blocking issues: none.

Checked:

  • Removed keyword parameters: no remaining caller passes them. kernel.py calls begin(...) and record_geak_product(...) without the removed arguments; both record_proposal_review callers (framework.py, intent_router.py) never pass iteration; the phase_event.record_proposal_review signature is separate and unchanged. record_policy takes **fields, and _framework_policy_fields never supplied the removed keys.
  • Removed keys have no reader. conc_sweep budget_remaining_sec and variant_timeout_sec are separate fields and remain unchanged. session_terminal*.json has no producer.
  • Null gain consumers: the optimizations and attribution renderers already guard with isinstance(..., (int, float)). stack_event guards excluding_fixes and unattributed on attributed is not None.
  • empty=None: the only producer (recipe_journal, empty=not measured) always passes a bool, so the workflow-evaluation contract's "empty": {"type": "boolean"} is not violated in practice. The contract references none of the removed keys.
  • The description matches the diff, and CI is green.

LGTM

@haishuok0525
haishuok0525 merged commit 110ff0d into main Oct 21, 2026
40 checks passed
@haishuok0525
haishuok0525 deleted the fix/breakdown-v7-dead-fields branch October 21, 2026 09:14
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.

2 participants