You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Part of the #860 runaway remediation (tracker: #926). A contributing factor: PR #860's branch carried a stale April base and was repeatedly merge main-d rather than rebased, inflating it to 378 commits for a net 18-file diff and generating recurring merge-conflict resolution work that itself triggered more fixup cycles (related to the #655 stale-base hazard).
Problem
Agent branches accumulate Merge branch 'main' into … commits instead of staying rebased, so commit count diverges from real change, conflict churn compounds, and a long-lived PR drifts further from a clean, reviewable state.
Fix (choose/scope during planning)
Prefer rebase/squash over repeated merge main for agent branches — ideally via the existing auto-rebase path rather than merge commits.
Optionally add a lint/health smell: flag PRs whose commit count vastly exceeds their changed-file count (e.g. >50 commits with <20 files) as a candidate for rebase/squash — complements the detection in the runaway-health issue.
Respect AGENTS.md: auto-rebase.yml stays pinned to @auto-rebase/stable (do not repoint), and the #655 guards (test-deletion-guard + "require branches up to date before merging") must remain intact.
Acceptance criteria
Agent branches are kept current via rebase/squash rather than repeated merge main (or a clear rationale + smell-detector if full automation is out of scope).
Thanks for the thorough write-up and for linking this back to the #860/#926 runaway remediation — the commit-inflation root cause is clearly documented here. Before planning the implementation: the issue presents two approaches (full rebase/squash automation via the existing auto-rebase path, vs. a smell-detector lint flag), and notes the choice should be scoped during planning — do you have a preference between the two, or is the deciding factor whether the auto-rebase path can handle agent branches without touching the auto-rebase/stable pin constraint?
Full rebase-vs-merge automation lives in the central auto-rebase reusable workflow (this repo only carries a thin caller stub pinned to auto-rebase/stable, which AGENTS.md forbids repointing), so per the acceptance-criteria fallback I implement the smell-detector path: flag PRs whose commit count vastly exceeds their changed-file count (the #860 merge-stacking signature — 378 commits for an 18-file net diff) as a rebase/squash candidate, complementing the #948 runaway detection net. No touch to the #655 guards or the auto-rebase/stable pin.
Implementation Checklist
scripts/lib/pr-runaway-detect.sh — add pr_rebase_smell <commits> <changed_files> pure function + env-overridable thresholds REBASE_SMELL_MIN_COMMITS (50) / REBASE_SMELL_MAX_FILES (20); extend generate_runaway_report header to document the new criterion.
scripts/pr_runaway_scan.sh — extract changed_files from the PR detail, call pr_rebase_smell, and fold its reason into the existing candidate reasons (detection-only, no PR mutation).
Full rebase-vs-merge main automation lives in the centralauto-rebase reusable workflow — this repo carries only the thin caller stub, which AGENTS.md forbids repointing off the auto-rebase/stable channel. So per the acceptance-criteria fallback ("a clear rationale + smell-detector if full automation is out of scope") I implemented the merge-stacked smell-detector, complementing the #948 runaway net. No #655 guard or auto-rebase/stable pin was touched.
Plan Execution
Added pr_rebase_smell <commits> <changed_files> pure function + env-overridable thresholds REBASE_SMELL_MIN_COMMITS (50) / REBASE_SMELL_MAX_FILES (20) to scripts/lib/pr-runaway-detect.sh
Wired changed_files extraction + the smell into scripts/pr_runaway_scan.sh (detection-only, no PR mutation)
Added 9 unit tests to tests/test_pr_runaway_detect.bats (already in the lint bats list)
Behaviour
Flags any open PR whose commit count vastly exceeds its changed-file count — the #860 signature (378 commits for an 18-file net diff) — as a rebase/squash candidate, surfaced in the existing daily runaway report. Fires only when commits > 50AND0 < changed_files < 20, so a genuinely broad PR (60 commits / 60 files) does not flag, and a 0-file API glitch does not false-positive. Thresholds are independently env-overridable, so an operator can catch merge-stacking below the runaway commit floor.
Detection-only, consistent with #948 — no PR is mutated, labeled, or commented. is_pr_runaway (the 4-metric boolean wrapper) is intentionally unchanged; the scan consumes the combined reasons string directly. Possible follow-up: an automated rebase-intent nudge on flagged PRs, which belongs in the central reusable workflow, not this thin-caller repo.
Activity
github-actions commentedon Jun 26, 2026
Thanks for the thorough write-up and for linking this back to the #860/#926 runaway remediation — the commit-inflation root cause is clearly documented here. Before planning the implementation: the issue presents two approaches (full rebase/squash automation via the existing
auto-rebasepath, vs. a smell-detector lint flag), and notes the choice should be scoped during planning — do you have a preference between the two, or is the deciding factor whether theauto-rebasepath can handle agent branches without touching theauto-rebase/stablepin constraint?don-petry commentedon Jul 3, 2026
Dev-Lead Implementation Plan
Issue: #949 — P2 (#860 follow-up): keep agent branches rebased/squashed instead of merge-stacked
Scope
Full rebase-vs-merge automation lives in the central
auto-rebasereusable workflow (this repo only carries a thin caller stub pinned toauto-rebase/stable, which AGENTS.md forbids repointing), so per the acceptance-criteria fallback I implement the smell-detector path: flag PRs whose commit count vastly exceeds their changed-file count (the #860 merge-stacking signature — 378 commits for an 18-file net diff) as a rebase/squash candidate, complementing the #948 runaway detection net. No touch to the#655guards or theauto-rebase/stablepin.Implementation Checklist
scripts/lib/pr-runaway-detect.sh— addpr_rebase_smell <commits> <changed_files>pure function + env-overridable thresholdsREBASE_SMELL_MIN_COMMITS(50) /REBASE_SMELL_MAX_FILES(20); extendgenerate_runaway_reportheader to document the new criterion.scripts/pr_runaway_scan.sh— extractchanged_filesfrom the PR detail, callpr_rebase_smell, and fold its reason into the existing candidate reasons (detection-only, no PR mutation).Tests to Write
tests/test_pr_runaway_detect.bats— boundary (strict>/<), the feat: implement issue #846 — [Phase 2] Cache the LSP index and enforce the 30s cold-start SLA with auto-skip #860 378/18 case fires, a normal 60-file/60-commit PR does not, 0-file glitch does not, env-override respected, defensive non-numeric input.Test Command
bash scripts/run-bats.sh tests/test_pr_runaway_detect.batsandbash .dev-lead/scripts/dev-lead-lint.shdon-petry commentedon Jul 3, 2026
Dev-Lead: Implementation Complete
Scope decision
Full rebase-vs-
merge mainautomation lives in the centralauto-rebasereusable workflow — this repo carries only the thin caller stub, whichAGENTS.mdforbids repointing off theauto-rebase/stablechannel. So per the acceptance-criteria fallback ("a clear rationale + smell-detector if full automation is out of scope") I implemented the merge-stacked smell-detector, complementing the #948 runaway net. No#655guard orauto-rebase/stablepin was touched.Plan Execution
pr_rebase_smell <commits> <changed_files>pure function + env-overridable thresholdsREBASE_SMELL_MIN_COMMITS(50) /REBASE_SMELL_MAX_FILES(20) toscripts/lib/pr-runaway-detect.shgenerate_runaway_reportheader to document the merge-stacked criterion (P2 (#860 follow-up): runaway-PR detection in daily health check (commits/comments/cycles/age thresholds) #948 / P2 (#860 follow-up): keep agent branches rebased/squashed instead of merge-stacked #949)changed_filesextraction + the smell intoscripts/pr_runaway_scan.sh(detection-only, no PR mutation)tests/test_pr_runaway_detect.bats(already in the lint bats list)Behaviour
Flags any open PR whose commit count vastly exceeds its changed-file count — the #860 signature (378 commits for an 18-file net diff) — as a rebase/squash candidate, surfaced in the existing daily runaway report. Fires only when
commits > 50AND0 < changed_files < 20, so a genuinely broad PR (60 commits / 60 files) does not flag, and a 0-file API glitch does not false-positive. Thresholds are independently env-overridable, so an operator can catch merge-stacking below the runaway commit floor.Test Results
Files Changed
scripts/lib/pr-runaway-detect.sh:pr_rebase_smellfn +REBASE_SMELL_*thresholds + report-header docsscripts/pr_runaway_scan.sh: extractchanged_files, fold the smell into per-PR reasons, threshold log linetests/test_pr_runaway_detect.bats: 9 new cases (boundary, feat: implement issue #846 — [Phase 2] Cache the LSP index and enforce the 30s cold-start SLA with auto-skip #860 case, broad-PR/0-file false-positive guards, env overrides, defensive input, report docs)Notes
Detection-only, consistent with #948 — no PR is mutated, labeled, or commented.
is_pr_runaway(the 4-metric boolean wrapper) is intentionally unchanged; the scan consumes the combinedreasonsstring directly. Possible follow-up: an automatedrebase-intent nudge on flagged PRs, which belongs in the central reusable workflow, not this thin-caller repo.feat: implement issue #949 — P2 (#860 follow-up): keep agent branches…