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
{{ message }}
Repository navigation
pr-merge: require a verifying run's head to be in main's history #8320
lane_dispatched (plugins/source-control/skills/babysit-prs/scripts/babysit_postmerge.py:631-670, with _lane_run at :782-788) trusts a run whose head_branch is main, and the run filter at :465 checks only head_branch == branch. The ancestry check at :817-818 (contains(merge_commit, head_sha)) accepts any descendant of the merge, not only main's own history.
Risk: an actor who already has write access, if no ruleset blocks tag creation (none of this repo's rulesets target tags today), could push a commit on top of main with a gutted pr-require-checks.yml, tag it main, and dispatch on the tag. If GitHub reports that run's head_branch as main (UNVERIFIED, not probed), a lane merge could be marked verified without its real CI. The impact is a false "verified" that frees an in-flight slot and suppresses post-merge demotion. The attacker must already hold repo write access.
Fix: also require that the run's head_sha is reachable from main's current tip (an ancestor of it, or equal), or add a ruleset that blocks tags named like branches. Check the cheaper one first.
Done when: a test with a dispatched run whose head_sha is not in main's history is not treated as verified, or a tag ruleset refusing main is live and referenced here.
Found by the reviews of #8311 and #8318 on 2026-10-18.
Closing: done. The done-when asked for a test showing that a dispatched run whose head_sha is not in main's history is not treated as verified. That is met on main.
on_branch in plugins/source-control/skills/babysit-prs/scripts/babysit_postmerge.py (lines 1433-1440) requires the run's head commit to be an ancestor of the refs/heads/ tip, not just to carry head_branch: main. The lane-dispatch record check (around line 1847) does the same, which also refuses a tag named like the branch.
Two tests in tests/test_babysit_postmerge.py assert that such a run does not verify: test_a_green_dispatch_off_the_branch_does_not_verify (line 1238) and test_a_tag_named_like_the_branch_does_not_verify (line 1646).
Activity
github-actions commentedon Oct 18, 2026
Thanks for the report. Automated triage handed this issue to a maintainer.
Proposed work class: work-class: scoped
Basis: automated intake triage; a maintainer confirms or changes it.
Automated triage. A maintainer reviews it.
kyle-sexton commentedon Oct 29, 2026
Closing: done. The done-when asked for a test showing that a dispatched run whose
head_shais not in main's history is not treated as verified. That is met on main.on_branchinplugins/source-control/skills/babysit-prs/scripts/babysit_postmerge.py(lines 1433-1440) requires the run's head commit to be an ancestor of therefs/heads/tip, not just to carryhead_branch: main. The lane-dispatch record check (around line 1847) does the same, which also refuses a tag named like the branch.Two tests in
tests/test_babysit_postmerge.pyassert that such a run does not verify:test_a_green_dispatch_off_the_branch_does_not_verify(line 1238) andtest_a_tag_named_like_the_branch_does_not_verify(line 1646).The work landed through #8403 and #9459.