Repository navigation
ci: merge freezes as owned, expiring GitHub issues - #21706
Conversation
A freeze is an open merge-freeze issue naming paths, an owner and an expiry (at most 72 hours). merge_freeze.py checks a pull request against the open freezes through the GitHub API from any host; only the owner's freeze-ok label lets one through, and an unreadable state counts as frozen. merge-freeze.yml shows a 'merge freeze' check on pull requests into main and feat-cmux-next and closes lapsed freezes hourly. This replaces the FREEZE lines in cmux-lawrence's WINDOW file, whose tokens had all lapsed by 2026-10-10 while tools still refused on them. Switching gh-merge-green to this checker is a separate change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 23 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
All contributors have signed the CLA ✍️ ✅ |
…lizes paths From review: grade both ends of a rename, exit 2 when the files API lists fewer files than the pull request changed (its 3000-file cap), read './x/', '/x/' and 'x/,' as 'x/', and report globs as malformed instead of matching nothing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot needs on-demand usage enabledBugbot uses usage-based billing for this team and requires on-demand usage to be enabled. A team admin can enable on-demand usage in the Cursor dashboard. |
|
Passes: CI passes on CI passes on Written by |
|
|
From coord-2's review: any triager could label an issue merge-freeze, and its author could then widen paths: for 72 hours. A freeze is now active only when an admin or maintainer added the label, after the body's last edit; an edit afterwards turns it off until a maintainer labels it again. Also registers tests/test_merge_freeze.py in tests/test-execution.toml. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot needs on-demand usage enabledBugbot uses usage-based billing for this team and requires on-demand usage to be enabled. A team admin can enable on-demand usage in the Cursor dashboard. |
|
Merge receipt for |
…ive freezes (#21938) * test(merge-freeze): unexpected API shapes exit 2, and old inactive freezes close Fails on main: a null created_at escapes as exit 1, and lapsed_at doesn't exist yet (expire never closes unauthorised or malformed freezes). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(merge-freeze): unknown API shapes read as unknown; close old inactive freezes From coord-2's review of #21706: a TypeError or AttributeError from an unexpected GitHub answer now exits 2 (unknown), not 1, and expire closes a malformed or unauthorised freeze issue once 72 hours have passed since it opened instead of leaving it open forever. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(merge-freeze): list and expire report read errors as 2; clearer close comment From review of 694c4f6: the error message read args.pr, which list and expire don't have, so their read errors escaped as exit 1. And a freeze edited after its label may have been active before, so the close comment says it isn't active rather than that it never was. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Merge freezes become GitHub issues that anyone can see, that have an owner, and that expire on their own, instead of
FREEZE:lines in~/agent-mailbox/WINDOWon cmux-lawrence.That file broke in three ways. gh-merge-green read it over ssh, so a host without ssh to cmux-lawrence (Huge Blue) couldn't merge into feat-cmux-next at all. Every token in it had lapsed by 2026-10-10, but the tools kept refusing on it. And nobody but its readers could see it was stale.
How a freeze works now
Open an issue and have an admin or maintainer add the
merge-freezelabel. The title is the reason, and the body says:paths:say, turns it off until a maintainer labels it again.paths:orexpires:blocks nothing and is reported as malformed, so a typo can't freeze the repository.freeze-okto it. The checker reads who added the label from the timeline, so a label from anyone else doesn't count.scripts/ci/merge_freeze.py checkdecides, using only the GitHub API, so it works the same from any host. It exits 0 for clear, 1 for frozen, and 2 when GitHub can't be read, which counts as frozen..github/workflows/merge-freeze.ymlshows amerge freezecheck on pull requests into main.pull_request_targetreads the workflow from the base branch, so feat-cmux-next pull requests get the check once the same file lands there, in a one-file follow-up after this merges. Every hour it closes lapsed freezes with a comment, so the open issues are exactly the live freezes. It'spull_request_target, and it checks out only main's checker, never the pull request.docs/ci/merge-freeze.mdis the how-to.Should freezes exist at all?
Mostly no. Per-PR risk is now the job of the risk tiers (#21691), and the batch queue validates stacks. What's left is coordination: a release cut, or one lane reworking an area others would collide with. That justifies a small, visible, expiring freeze, not a standing one.
Not in this pull request: switching gh-merge-green
gh-merge-green still reads the WINDOW file. Replacing that block with
merge_freeze.py check, and dropping the RELEASE mail it sends to cmux-lawrence, is a separate change. It needs explicit approval, because it edits the merge gate's freeze logic.~/Projects/briefs/huge-blue-merge-ready.shhas its own hard-coded WINDOW path list and gets the same change. The old file on cmux-lawrence is left untouched.Testing
python3 tests/test_merge_freeze.py: 13 tests pass, including that labels from triage, write, outside users or nobody don't count, and that an edit after the label turns the freeze off. They cover prefix matching including siblings, expiry, the 72-hour cap, malformed freezes, owner-onlyfreeze-ok(including a later removal), theowner:andbranch:lines, closed or unlabeled issues, and an unreadable list returning 2. The test is wired intoci-guards.ymland registered intests/test-execution.toml.listshows no open freezes,check --pr 21690exits 0, andexpire --dry-runcloses nothing.bash scripts/ci/guards-local.sh: 108 pass and 3 fail. On main without this change, 105 pass and 5 fail, and no failure is new.Review: SHIP with nits at 5ff3070 (cmux-review subagent), and 2ef1e13 fixed those nits. coord-2's independent review at 2ef1e13 said fix first: the test registry entry was missing, and anyone could label a freeze. 21a1da5 fixes both. Left as-is: one
freeze-okcan't satisfy two freezes with different owners on the same PR, and approval isn't reset by a later push.Runtime test: at 21a1da5,
merge_freeze.py listandcheck --pr 21706against manaflow-ai/cmux (exit 0), plus the new helpers live:repo_role(admin for teamleaderleo, read for an outsider),last_editedon issue #21611, andlast_labeleron #21334's events.Changelog
none
Proof
Not UI: merge tooling and docs.
🤖 Generated with Claude Code