Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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 has named where a feature is and after Stable as Trust Boundary 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, 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. 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 until the coordinated release, and a downstream vendor with advance access 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 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 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 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 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 and the security-labels documentation 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 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 is the source for the branch-heads checkout mechanics and the fix-on-trunk-first rule. The Chrome for Developers two-week-release announcement (March 3, 2026) is the source for the September 8, 2026 cadence shift that compresses every merge window.

Technical Drill-Down