John Abd-El-Malek | da0e8cd | 2022-09-16 23:42:05 | [diff] [blame] | 1 | # Chromium Flag Guarding Guidelines |
| 2 | |
| 3 | This document describes using [`base::Feature`](/base/feature_list.h) flags which |
Alan Cutter | a2d83dd | 2022-10-26 15:46:31 | [diff] [blame] | 4 | can be remotely set via a server. This applies to both A/B experiments |
John Abd-El-Malek | da0e8cd | 2022-09-16 23:42:05 | [diff] [blame] | 5 | ([internal link](http://go/finch101)) (disabled by default) and to kill switches |
| 6 | ([internal link](http://go/finch-killswitch)) (enabled by default). |
| 7 | |
| 8 | Google maintains its own server which you'll see referenced by its internal name |
| 9 | Finch. Other embedders can and do run their own server for their products. |
| 10 | |
| 11 | [TOC] |
| 12 | |
| 13 | ## Goals |
| 14 | * Prevent large scale outages and reduce the response time latency of outages of |
| 15 | Chromium and Android WebView |
| 16 | * Reduce the need for a binary respin to address problems in the field |
| 17 | * Catch regressions in core product vitals |
| 18 | |
| 19 | ## Non-Goals |
| 20 | * Require a flag per CL/bug without consideration. This is not scalable. See the |
| 21 | next section for guidance of when flags should be used. |
| 22 | * Flag-guarding of ChromeOS-specific features. |
| 23 | * Add a lot of long-lived server-configurable flags across the code base. New |
| 24 | flags generated by this proposal should be removed 1-2 milestones after launch. |
| 25 | * Mandate that all changes be rolled out via server side configurations. |
| 26 | |
| 27 | ## When is a flag required? |
| 28 | * Every project/feature launch shall use a flag unless it’s not [feasible](#feasible) |
| 29 | * Every feature going through Launch Process (Note, you do not need a launch bug |
| 30 | to use a flag) |
| 31 | * Every feature using origin trials, per existing [guidelines](https://www.chromium.org/blink/origin-trials/running-an-origin-trial/#is-your-feature-ready-to-be-an-origin-trial:~:text=Have%20a%20way%20to%20remotely%20disable%20the%20feature) |
| 32 | * Every deprecation/addition of web platform APIs |
| 33 | * Very large structural changes that have very different paths (e.g. navigation |
| 34 | rewrite in PlzNavigate, networking rewrite in Network Service, Out-of-process |
| 35 | Rasterization etc.). |
| 36 | * Refactorings in code paths that have historically been risky or prone to |
| 37 | accidental breakages should also be treated the same as a new feature. |
| 38 | * Regardless of whether it is a new feature, refactoring, or bug fix, there is |
| 39 | no minimum size that dictates whether a flag is required (either for isolated |
| 40 | CLs or for many CLs that form a project/feature). A one line change with |
| 41 | potential to impact stability, performance, usability is just as required to use |
| 42 | a flag as a multi-thousand line feature. |
| 43 | * {#feasible}If, as a CL author, you are uncertain whether a flag can/should be |
| 44 | used, talk to the relevant TL/Uber-TL and if still unsure, just use a flag. |
| 45 | |
| 46 | ## When is a flag not required? |
| 47 | * Targeted/micro performance optimizations: projects like V8/Skia/decoders etc. |
| 48 | that have their own large correctness and performance test suites to not have to |
| 49 | use server rollouts since they have large confidence based on their tests |
| 50 | * Changes to core data structures where it would almost be impossible to |
| 51 | maintain both worlds (e.g. V8 pointer compression where adding a branch in each |
| 52 | dereference would not be practical). |
| 53 | * Features shipped via component updater: if we ship a bad component we can |
| 54 | update to a fixed one |
| 55 | * Chrome A/B binary experiments: we can use Omaha/AppStore/Play to update users |
| 56 | from bad builds |
| 57 | * Non-chromium-repo binary drops: e.g. SwiftShader |
| 58 | * Rolling/Updating third party dependencies (e.g. libvpx, libwebp etc.) |
| 59 | * Mechanical/automated refactorings |
| 60 | * Changes to internal API naming |
| 61 | * Simple parameter changes (adding params, changing the type etc.) |
| 62 | * Isolated refactorings where test coverage with high test coverage / confidence |
| 63 | |
| 64 | |
| 65 | ## What type of flag rollout to use? |
| 66 | * If a change has the potential to affect performance or memory |
| 67 | ([internal link](http://go/chrome-browser-guiding-metrics)), or you want to |
| 68 | analyze the impact of the launch on feature-specific metrics, use a |
| 69 | disabled-by-default base::Feature flag and run an A/B experiment. |
| 70 | Non-Googler committers will need to work with owners of the code that work at |
| 71 | Google to launch and monitor the experiment. |
| 72 | * Otherwise it should be guarded minimally by an enabled-by-default |
| 73 | base::Feature flag, which can be remotely disabled by a server configuration. |
Rick Byers | e64b12a | 2023-03-24 19:06:38 | [diff] [blame] | 74 | * For code in blink, this can be as simple as using a |
| 75 | [Runtime Enabled Feature](/third_party/blink/renderer/platform/RuntimeEnabledFeatures.md), |
| 76 | which has long been common-practice for new or changed APIs. |