--- slug: release-merge-gate type: pattern summary: "A fix that has landed on main reaches an already-cut milestone branch only through a release-manager-gated cherry-pick whose criteria tighten as the branch nears Stable." created: 2026-06-14 updated: 2026-06-14 last_link_verified: 2026-06-14 related: four-channel-pipeline: relation: complements note: "The branch's phase on the channel pipeline is what changes which fixes the merge gate will accept; a fix acceptable for a fresh Beta branch may be rejected on a branch days from Stable." stable-trust-boundary: relation: enforces note: "The merge gate is the mechanism that protects the Stable trust-boundary claim from risky late changes while still admitting fixes urgent enough to warrant the risk." commit-queue-gate: relation: extends note: "A release-branch cherry-pick still passes through Gerrit and the commit queue, but adds a release-manager approval the ordinary main landing does not require." tree-sheriff: relation: complements note: "A post-submit regression the Tree Sheriff finds after branch point may have to be merged into the release branch rather than fixed only on main, which routes it through this gate." embargoed-disclosure: relation: enables note: "A security fix held under embargo is delivered to the public through a release-branch merge timed to the disclosure, so the gate is the path embargoed fixes travel into a shipping milestone." downstream-advance-access: relation: enables note: "Downstream vendors consuming advance security access still depend on the upstream merge landing in a release branch before the fix reaches their users; the gate is what completes the upstream half." supply-chain-lag: relation: prevents note: "Downstream exposure depends on whether a fix actually reached the active release branch, not merely main; a missed or expired merge is exactly the lag this gate exists to close." --- # Release Branch Merge Gate > **Pattern** > > A named solution to a recurring problem. *A fix that has landed on main reaches an already-cut milestone branch only through a release-manager-gated cherry-pick whose criteria tighten as the branch approaches Stable.* A fix on main is not a fix in Beta, Stable, or Extended Stable. Chromium develops on a single main branch, but it ships from milestone branches that were cut weeks earlier and have moved on their own track ever since. When a bug surfaces on a shipping milestone, fixing it on main does nothing for the users running that milestone until someone deliberately carries the fix across, through a gate that exists precisely to keep late changes from undoing the stability the branch has earned. The gate is where "we fixed it" and "our users have the fix" stop being the same sentence. ## Context This pattern sits at the operational end of the release-discipline axis, after the [four-channel pipeline](four-channel-pipeline.md) has named where a feature is and after [Stable as Trust Boundary](stable-trust-boundary.md) has named what reaching Stable warrants. It applies the moment a milestone branch exists. Chromium cuts a branch at `refs/branch-heads/####` (the number is the milestone's branch identifier) several weeks before that milestone reaches Stable; from branch point onward the branch and main diverge. Beta stabilizes the branch, an Early Stable cut narrows it further, the Stable cut commits it to the general population, and Extended Stable keeps a subset of branches alive on a longer cadence for managed fleets. The reader who needs this pattern is reasoning about a fix that already exists. The fix has cleared code review, passed the [commit queue](commit-queue-gate.md), and landed on main. The open question is no longer whether the fix is correct but whether, when, and how it enters a branch that has already left main behind. ## Problem Development is main-first by doctrine: a bug should be fixed and tested on trunk before it is considered for any branch. But a milestone branch is a frozen, shipping artifact with users on it, and main keeps moving. The two facts pull against each other. Carrying every main fix into every live branch reintroduces churn into exactly the artifact that was frozen to remove churn, raising the odds that a late "fix" ships a fresh regression to the general population. Carrying nothing leaves a critical security patch or a launch-blocking crash on main, fixed for a future milestone, while the current Stable population stays exposed. The recurring difficulty is deciding, per fix and per branch phase, whether the value of getting this fix to this branch's users now outweighs the risk of changing a stabilizing branch. That decision cannot be made by the fix's author alone, because the author optimizes for their fix, not for the branch's overall risk budget. ## Forces - **Urgency versus stability.** A security fix or a crash regression wants to reach users immediately; a branch nearing Stable wants to absorb as few changes as possible. The same change is "obviously merge it" early in Beta and "are you certain" days before the Stable cut. - **Authorship versus stewardship.** The engineer who wrote the fix is the worst-placed person to weigh it against the branch's whole risk profile, yet the best-placed to describe what it does and what breaks without it. - **Speed versus review boundary.** Cherry-picks are usually mechanical, and waiting on a human reviewer for a clean backport wastes time; but the OWNERS review that authorized the change on main does not automatically carry to the branch. - **Promptness versus drift.** An approved merge that is not cherry-picked quickly goes stale: the branch moves, the patch stops applying cleanly, and an expired approval has to be re-sought. ## Solution **Request the merge through the labeled release process, and let the release manager for the branch's phase decide.** A developer who wants a main fix in a milestone branch files a merge request on the issue, which the project's automation and release managers triage. The request carries the fix's risk and the cost of not merging it; the release manager (or a delegated team for a specific component) weighs that against the branch's current phase and either approves or declines. The issue's labels carry the state machine: `Merge-Request-###` opens the request for milestone `###`, `Merge-Approved-###` authorizes the cherry-pick, and `Merge-Merged-###` records that it landed. Triage automation (the project's release-tooling bots) routes requests and chases missed merges so an approval does not silently expire. The approval criteria are not fixed; they tighten as the branch advances. Early in a branch's life, a wide range of fixes is acceptable. As the branch approaches its Stable cut, the bar rises to security fixes, severe stability regressions, and launch-blocking issues only. This phase-dependence is the point: the gate is not a uniform filter but a sliding one, calibrated to how much risk the branch can still absorb. Once approved, the fix is cherry-picked onto `refs/branch-heads/####` as a Gerrit change that still passes through the [commit queue](commit-queue-gate.md). The cherry-pick must land promptly, because the branch keeps moving and a stale approval has to be renewed. For a clean cherry-pick (one that applies without conflict and is identical to the already-reviewed main change), the Rubber Stamper bot can supply the code-review approval, since re-reviewing an unchanged patch adds no safety. Rubber Stamper does not, and cannot, supply OWNERS approval: a cherry-pick that is not clean, or that touches a path with its own ownership, still needs a human OWNERS reviewer. The boundary the gate relaxes is redundant re-review of identical code, not the ownership boundary itself. Security fixes travel a parallel, partly automated path. When a security bug is marked fixed, the project's security automation evaluates which shipping milestones are affected, requests or approves the backports, and updates the merge labels, so that the fix reaches every branch where the vulnerability is live and the public disclosure can be timed to a coordinated Stable release. ## How It Plays Out A developer fixes a renderer crash that reproduces on the current Beta milestone. The fix lands on main, and the developer files a merge request on the issue for that milestone. The branch is early in Beta, so the release manager approves within a day. The developer cherry-picks onto the branch head, the commit queue runs, the change lands, and the next Beta build carries the fix. The label progression `Merge-Request` to `Merge-Approved` to `Merge-Merged` is the audit trail of the whole transaction. A second developer has a fix for a non-security UI glitch and requests a merge two days before the Stable cut. By that phase the bar has risen: the release manager declines the merge for that milestone and tells the developer the fix will ride the next milestone, which is already on main. Nothing's lost, because the fix is on trunk; the gate simply judged the glitch not worth perturbing a branch on the eve of general release. > **⚠️ An approved merge is not a merged fix** > > Approval is permission, not delivery. A `Merge-Approved-###` label means the release manager said yes; it doesn't mean the fix reached users. The cherry-pick still has to be authored, pass the commit queue, and land on the branch head before the branch is built. An approval left un-acted-upon goes stale as the branch moves, and the original author has to renew it. Treat the cherry-pick as the deliverable and the approval as a perishable token. A security engineer marks a high-severity renderer-sandbox-escape bug fixed on main. The security automation evaluates affected milestones, requests backports to the live Beta and Stable branches, and the release managers approve them under the security exception. The cherry-picks land, the public bug is held under [embargo](embargoed-disclosure.md) until the coordinated release, and a [downstream vendor with advance access](downstream-advance-access.md) integrates the patch into its own branch ahead of public disclosure. The upstream merge landing in the release branch is what makes the fix real for upstream Stable users; everything downstream is timed against that landing. ## Consequences **Benefits.** The gate protects the trust-boundary claim that [reaching Stable](stable-trust-boundary.md) makes: uncontrolled late changes cannot erode it, yet fixes urgent enough to justify the risk still get through. The phase-dependent bar means a branch absorbs more risk when it can afford to and almost none when it cannot. The labeled state machine gives release managers, downstream vendors, and security teams a precise, queryable answer to the question that actually matters during an incident: did the fix reach this branch, or only main? The Rubber Stamper exception removes the busywork of re-reviewing identical cherry-picks without lowering the ownership bar for non-trivial backports. **Liabilities.** The gate adds latency and human judgment to every backport, which is friction exactly when a team feels most urgency. It introduces a failure mode the [supply-chain lag](supply-chain-lag.md) names directly: a fix that's on main but never merged, or merged late, leaves the branch's users exposed for longer than anyone intended, and a missed or expired merge can pass unnoticed if the triage automation doesn't catch it. The two-week Stable and Beta cadence the project has announced for Chrome 153 (September 8, 2026) shrinks every release window, which compresses the time available to request, approve, and land a merge before the branch is cut. A shorter window raises the value of knowing exactly which branch a fix reached and raises the cost of getting the merge timing wrong. ## Notes for Agent Context When reasoning about whether a Chromium fix is live for a given milestone, never treat a commit on main as delivered to that milestone's users; check whether a corresponding `Merge-Merged-###` state exists for the branch in question, because main and the release branch diverge at branch point. When generating release-tracking or vulnerability-exposure tooling, model the merge labels as a state machine (`Merge-Request` to `Merge-Approved` to `Merge-Merged`) and treat an approved-but-not-merged fix as not yet delivered, not as delivered. When proposing a cherry-pick onto `refs/branch-heads/####`, do not assume the main change's OWNERS approval carries to the branch; only a clean, identical cherry-pick qualifies for Rubber Stamper review, and any conflict or new path requires a human OWNERS reviewer. When advising on merge timing, account for the branch phase: a fix acceptable early in Beta may be correctly declined days before the Stable cut, and the correct response to a decline is to let the fix ride the next milestone from main, not to escalate. ## Sources The Chromium project's [release-cycle documentation](https://chromium.googlesource.com/chromium/src/+/HEAD/docs/process/release_cycle.md) defines branch point, the Beta and Stable phases, the Stable refresh, and Extended Stable, and is the source for the milestone-branch lifecycle this pattern operates inside. The [merge-request process documentation](https://chromium.googlesource.com/chromium/src/+/HEAD/docs/process/merge_request.md) is the central source for the gate itself: main-first doctrine, the release-manager review, the phase-dependent acceptance criteria, the `Merge-Request` and `Merge-Approved` and `Merge-Merged` issue labels, the triage automation, and the rule that approved merges must be cherry-picked promptly or they expire. The [life-of-a-security-issue documentation](https://chromium.googlesource.com/chromium/src.git/+/HEAD/docs/security/life-of-a-security-issue.md) and the [security-labels documentation](https://chromium.googlesource.com/chromium/src.git/+/HEAD/docs/security/security-labels.md) are the sources for the security variant, in which marking a bug fixed triggers automation that evaluates affected milestones and requests or approves backports. The [mandatory code-review and OWNERS documentation](https://chromium.googlesource.com/chromium/src/+/HEAD/docs/code_review_owners.md) is the source for the Rubber Stamper boundary: the bot can review a clean cherry-pick but never provides OWNERS approval. The Chromium [working-with-release-branches how-to](https://www.chromium.org/developers/how-tos/get-the-code/working-with-release-branches/) is the source for the `branch-heads` checkout mechanics and the fix-on-trunk-first rule. The [Chrome for Developers two-week-release announcement](https://developer.chrome.com/blog/chrome-two-week-release) (March 3, 2026) is the source for the September 8, 2026 cadence shift that compresses every merge window. ## Technical Drill-Down - [`docs/process/merge_request.md`](https://chromium.googlesource.com/chromium/src/+/HEAD/docs/process/merge_request.md) — the central gate description; the merge-label workflow, the phase-dependent criteria, and the prompt-cherry-pick-or-expire rule are documented here. - [`docs/process/release_cycle.md`](https://chromium.googlesource.com/chromium/src/+/HEAD/docs/process/release_cycle.md) — branch point, Beta, Early Stable cut, Stable cut, Stable refresh, and Extended Stable; the lifecycle the merge gate sits inside. - [`docs/security/life-of-a-security-issue.md`](https://chromium.googlesource.com/chromium/src.git/+/HEAD/docs/security/life-of-a-security-issue.md) — the security backport path from main landing through automation, merge approval, cherry-pick, and coordinated disclosure. - [`docs/security/security-labels.md`](https://chromium.googlesource.com/chromium/src.git/+/HEAD/docs/security/security-labels.md) — the merge and `ReleaseBlock` labels on vulnerabilities and how severity drives merge and release speed. - [`docs/code_review_owners.md`](https://chromium.googlesource.com/chromium/src/+/HEAD/docs/code_review_owners.md) — the Rubber Stamper behavior on clean cherry-picks and the rule that it never substitutes for OWNERS approval. - [Working with release branches — chromium.org](https://www.chromium.org/developers/how-tos/get-the-code/working-with-release-branches/) — the concrete `branch-heads/$BRANCH` checkout and build mechanics, and the fix-on-trunk-first guidance. - [Chrome moves to a two-week release cycle — Chrome for Developers, March 3, 2026](https://developer.chrome.com/blog/chrome-two-week-release) — the September 8, 2026 Chrome 153 cadence shift and the unchanged Extended Stable cycle. --- - [Next: Zombie Origin Trial](zombie-origin-trial.md) - [Previous: Stable as Trust Boundary](stable-trust-boundary.md)