Skip to content

Add per-PR subsystem-size budget gate with PR-comment surface#15

Merged
jserv merged 1 commit intomainfrom
lto
May 1, 2026
Merged

Add per-PR subsystem-size budget gate with PR-comment surface#15
jserv merged 1 commit intomainfrom
lto

Conversation

@jserv
Copy link
Copy Markdown
Owner

@jserv jserv commented May 1, 2026

The existing total-bytes regression gate is too coarse: a 3% growth in mm/ that cancels out a 3% drop in drivers/ slips through unannounced. This wires a per-bucket gate on top, sourced from the diagnostic build's subsystem rollup, and surfaces the result as a PR comment so regressions are visible during code review rather than after merge.

configs/subsystem-budget.txt pins ceilings for the four big top-level buckets (kernel, fs, lib, mm, ) plus depth-2 rules for the buckets the recent fair-tiny + time-prune patches drove down (kernel/sched, kernel/printk) so any future regression is bucket-scoped rather than hidden by a total-bytes cancellation. lib/zstd / lib/lz4 / lib/xz are pinned at zero -- olddefconfig re-enabling a decompressor selector breaks the gate immediately.

scripts/check-subsystem-budget.py grows --deep-rollup support and merges depth-2 buckets after refusing any name present in both the top-level and deep tables (ambiguous input -> exit 2). The deep-rollup parser keys off " by 2nd-level subdirectory" and a regex-matched " top N source files" so file-row noise stays out of the budget namespace, decoupling the parser from the top_files default in subsystem-rollup.py.

scripts/kernel-size-report.sh wipes subsystem-budget.txt before the run and only swallows exit 1 (warn-only breach); exit 2 logs an error and ensures no stale status survives a cached-workspace replay. --deep-rollup is passed conditionally so a top-level-only run still produces a useful status file.

The CI flow splits along trust boundaries. The Build job stays at contents:read; a separate pr-rollup-comment.yml workflow triggers via workflow_run, downloads the artifact under its own scoped pull-requests:write token, and upserts a single bot comment per PR. The upsert filters strictly on the github-actions[bot] login, deletes older marker-bearing duplicates so a crashed prior run does not leave stale gate state visible, and reads the PR number through env (PR_NUMBER) instead of template interpolation. Fork PRs work via a head-SHA fallback because workflow_run.pull_requests is empty for forks.

scripts/rollup-to-markdown.py (new) renders subsystem-rollup.txt and the budget status into the comment body. Bucket names go through md_cell() which substitutes pipe and backtick -- the two characters that break a GFM table inside a backtick code span, where backslash escapes are not processed.

scripts/subsystem-rollup.py grows a styled Pareto-style HTML breakdown alongside the existing SVG bars; the left column ranks subsystems, the right column drills into the selected bucket.

The existing total-bytes regression gate is too coarse: a 3% growth
in mm/ that cancels out a 3% drop in drivers/ slips through
unannounced.  This wires a per-bucket gate on top, sourced from the
diagnostic build's subsystem rollup, and surfaces the result as a
PR comment so regressions are visible during code review rather
than after merge.

configs/subsystem-budget.txt pins ceilings for the four big
top-level buckets (kernel, fs, lib, mm, <icf-merged>) plus depth-2
rules for the buckets the recent fair-tiny + time-prune patches
drove down (kernel/sched, kernel/printk) so any future regression
is bucket-scoped rather than hidden by a total-bytes cancellation.
lib/zstd / lib/lz4 / lib/xz are pinned at zero -- olddefconfig
re-enabling a decompressor selector breaks the gate immediately.

scripts/check-subsystem-budget.py grows --deep-rollup support and
merges depth-2 buckets after refusing any name present in both the
top-level and deep tables (ambiguous input -> exit 2).  The
deep-rollup parser keys off " by 2nd-level subdirectory" and a
regex-matched " top N source files" so file-row noise stays out of
the budget namespace, decoupling the parser from the top_files
default in subsystem-rollup.py.

scripts/kernel-size-report.sh wipes subsystem-budget.txt before the
run and only swallows exit 1 (warn-only breach); exit 2 logs an
error and ensures no stale status survives a cached-workspace
replay.  --deep-rollup is passed conditionally so a top-level-only
run still produces a useful status file.

The CI flow splits along trust boundaries.  The Build job stays at
contents:read; a separate pr-rollup-comment.yml workflow triggers
via workflow_run, downloads the artifact under its own scoped
pull-requests:write token, and upserts a single bot comment per PR.
The upsert filters strictly on the github-actions[bot] login,
deletes older marker-bearing duplicates so a crashed prior run does
not leave stale gate state visible, and reads the PR number through
env (PR_NUMBER) instead of template interpolation.  Fork PRs work
via a head-SHA fallback because workflow_run.pull_requests is empty
for forks.

scripts/rollup-to-markdown.py (new) renders subsystem-rollup.txt and
the budget status into the comment body.  Bucket names go through
md_cell() which substitutes pipe and backtick -- the two characters
that break a GFM table inside a backtick code span, where backslash
escapes are not processed.

scripts/subsystem-rollup.py grows a styled Pareto-style HTML
breakdown alongside the existing SVG bars; the left column ranks
subsystems, the right column drills into the selected bucket.
@jserv jserv merged commit 1edb897 into main May 1, 2026
2 checks passed
@jserv jserv deleted the lto branch May 1, 2026 16:27
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.

1 participant