browser/experiments/docs/manifest.rst

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/browser/experiments/docs/manifest.rst	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,429 @@
     1.4 +.. _experiments_manifests:
     1.5 +
     1.6 +=====================
     1.7 +Experiments Manifests
     1.8 +=====================
     1.9 +
    1.10 +*Experiments Manifests* are documents that describe the set of active
    1.11 +experiments a client may run.
    1.12 +
    1.13 +*Experiments Manifests* are fetched periodically by clients. When
    1.14 +fetched, clients look at the experiments within the manifest and
    1.15 +determine which experiments are applicable. If an experiment is
    1.16 +applicable, the client may download and start the experiment.
    1.17 +
    1.18 +Manifest Format
    1.19 +===============
    1.20 +
    1.21 +Manifests are JSON documents where the main element is an object.
    1.22 +
    1.23 +The *schema* of the object is versioned and defined by the presence
    1.24 +of a top-level ``version`` property, whose integer value is the
    1.25 +schema version used by that manifest. Each version is documented
    1.26 +in the sections below.
    1.27 +
    1.28 +Version 1
    1.29 +---------
    1.30 +
    1.31 +Version 1 is the original manifest format.
    1.32 +
    1.33 +The following properties may exist in the root object:
    1.34 +
    1.35 +experiments
    1.36 +   An array of objects describing candidate experiments. The format of
    1.37 +   these objects is documented below.
    1.38 +
    1.39 +   An array is used to create an explicit priority of experiments.
    1.40 +   Experiments listed at the beginning of the array take priority over
    1.41 +   experiments that follow.
    1.42 +
    1.43 +Experiments Objects
    1.44 +^^^^^^^^^^^^^^^^^^^
    1.45 +
    1.46 +Each object in the ``experiments`` array may contain the following
    1.47 +properties:
    1.48 +
    1.49 +id
    1.50 +   (required) String identifier of this experiment. The identifier should
    1.51 +   be treated as opaque by clients. It is used to uniquely identify an
    1.52 +   experiment for all of time.
    1.53 +
    1.54 +xpiURL
    1.55 +   (required) String URL of the XPI that implements this experiment.
    1.56 +
    1.57 +   If the experiment is activated, the client will download and install this
    1.58 +   XPI.
    1.59 +
    1.60 +xpiHash
    1.61 +   (required) String hash of the XPI that implements this experiment.
    1.62 +
    1.63 +   The value is composed of a hash identifier followed by a colon
    1.64 +   followed by the hash value. e.g.
    1.65 +   `sha1:f677428b9172e22e9911039aef03f3736e7f78a7`. `sha1` and `sha256`
    1.66 +   are the two supported hashing mechanisms. The hash value is the hex
    1.67 +   encoding of the binary hash.
    1.68 +
    1.69 +   When the client downloads the XPI for the experiment, it should compare
    1.70 +   the hash of that XPI against this value. If the hashes don't match,
    1.71 +   the client should not install the XPI.
    1.72 +
    1.73 +   Clients may also use this hash as a means of determining when an
    1.74 +   experiment's XPI has changed and should be refreshed.
    1.75 +
    1.76 +startTime
    1.77 +   Integer seconds since UNIX epoch that this experiment should
    1.78 +   start. Clients should not start an experiment if *now()* is less than
    1.79 +   this value.
    1.80 +
    1.81 +maxStartTime
    1.82 +   (optional) Integer seconds since UNIX epoch after which this experiment
    1.83 +   should no longer start.
    1.84 +
    1.85 +   Some experiments may wish to impose hard deadlines after which no new
    1.86 +   clients should activate the experiment. This property may be used to
    1.87 +   facilitate that.
    1.88 +
    1.89 +endTime
    1.90 +   Integer seconds since UNIX epoch after which this experiment
    1.91 +   should no longer run. Clients should cease an experiment when the current
    1.92 +   time is beyond this value.
    1.93 +
    1.94 +maxActiveSeconds
    1.95 +   Integer seconds defining the max wall time this experiment should be
    1.96 +   active for.
    1.97 +
    1.98 +   The client should deactivate the experiment this many seconds after
    1.99 +   initial activation.
   1.100 +
   1.101 +   This value only involves wall time, not browser activity or session time.
   1.102 +
   1.103 +appName
   1.104 +   Array of application names this experiment should run on.
   1.105 +
   1.106 +   An application name comes from ``nsIXULAppInfo.name``. It is a value
   1.107 +   like ``Firefox``, ``Fennec``, or `B2G`.
   1.108 +
   1.109 +   The client should compare its application name against the members of
   1.110 +   this array. If a match is found, the experiment is applicable.
   1.111 +
   1.112 +minVersion
   1.113 +   (optional) String version number of the minimum application version this
   1.114 +   experiment should run on.
   1.115 +
   1.116 +   A version number is something like ``27.0.0`` or ``28``.
   1.117 +
   1.118 +   The client should compare its version number to this value. If the client's
   1.119 +   version is greater or equal to this version (using a version-aware comparison
   1.120 +   function), the experiment is applicable.
   1.121 +
   1.122 +   If this is not specified, there is no lower bound to versions this
   1.123 +   experiment should run on.
   1.124 +
   1.125 +maxVersion
   1.126 +   (optional) String version number of the maximum application version this
   1.127 +   experiment should run on.
   1.128 +
   1.129 +   This is similar to ``minVersion`` except it sets the upper bound for
   1.130 +   application versions.
   1.131 +
   1.132 +   If the client's version is less than or equal to this version, the
   1.133 +   experiment is applicable.
   1.134 +
   1.135 +   If this is not specified, there is no upper bound to versions this
   1.136 +   experiment should run on.
   1.137 +
   1.138 +version
   1.139 +   (optional) Array of application versions this experiment should run on.
   1.140 +
   1.141 +   This is similar to ``minVersion`` and ``maxVersion`` except only a
   1.142 +   whitelisted set of specific versions are allowed.
   1.143 +
   1.144 +   The client should compare its version to members of this array. If a match
   1.145 +   is found, the experiment is applicable.
   1.146 +
   1.147 +minBuildID
   1.148 +   (optional) String minimum Build ID this experiment should run on.
   1.149 +
   1.150 +   Build IDs are values like ``201402261424``.
   1.151 +
   1.152 +   The client should perform a string comparison of its Build ID against this
   1.153 +   value. If its value is greater than or equal to this value, the experiment
   1.154 +   is applicable.
   1.155 +
   1.156 +maxBuildID
   1.157 +   (optional) String maximum Build ID this experiment should run on.
   1.158 +
   1.159 +   This is similar to ``minBuildID`` except it sets the upper bound
   1.160 +   for Build IDs.
   1.161 +
   1.162 +   The client should perform a string comparison of its Build ID against
   1.163 +   this value. If its value is less than or equal to this value, the
   1.164 +   experiment is applicable.
   1.165 +
   1.166 +buildIDs
   1.167 +   (optional) Array of Build IDs this experiment should run on.
   1.168 +
   1.169 +   This is similar to ``minBuildID`` and ``maxBuildID`` except only a
   1.170 +   whitelisted set of Build IDs are considered.
   1.171 +
   1.172 +   The client should compare its Build ID to members of this array. If a
   1.173 +   match is found, the experiment is applicable.
   1.174 +
   1.175 +os
   1.176 +   (optional) Array of operating system identifiers this experiment should
   1.177 +   run on.
   1.178 +
   1.179 +   Values for this array come from ``nsIXULRuntime.OS``.
   1.180 +
   1.181 +   The client will compare its operating system identifier to members
   1.182 +   of this array. If a match is found, the experiment is applicable to the
   1.183 +   client.
   1.184 +
   1.185 +channel
   1.186 +   (optional) Array of release channel identifiers this experiment should run
   1.187 +   on.
   1.188 +
   1.189 +   The client will compare its channel to members of this array. If a match
   1.190 +   is found, the experiment is applicable.
   1.191 +
   1.192 +   If this property is not defined, the client should assume the experiment
   1.193 +   is to run on all channels.
   1.194 +
   1.195 +locale
   1.196 +   (optional) Array of locale identifiers this experiment should run on.
   1.197 +
   1.198 +   A locale identifier is a string like ``en-US`` or ``zh-CN`` and is
   1.199 +   obtained by looking at
   1.200 +   ``nsIXULChromeRegistry.getSelectedLocale("global")``.
   1.201 +
   1.202 +   The client should compare its locale identifier to members of this array.
   1.203 +   If a match is found, the experiment is applicable.
   1.204 +
   1.205 +   If this property is not defined, the client should assume the experiment
   1.206 +   is to run on all locales.
   1.207 +
   1.208 +sample
   1.209 +   (optional) Decimal number indicating the sampling rate for this experiment.
   1.210 +
   1.211 +   This will contain a value between ``0.0`` and ``1.0``. The client should
   1.212 +   generate a random decimal between ``0.0`` and ``1.0``. If the randomly
   1.213 +   generated number is less than or equal to the value of this field, the
   1.214 +   experiment is applicable.
   1.215 +
   1.216 +disabled
   1.217 +   (optional) Boolean value indicating whether an experiment is disabled.
   1.218 +
   1.219 +   Normally, experiments are deactivated after a certain time has passed or
   1.220 +   after the experiment itself determines it no longer needs to run (perhaps
   1.221 +   it collected sufficient data already).
   1.222 +
   1.223 +   This property serves as a backup mechanism to remotely disable an
   1.224 +   experiment before it was scheduled to be disabled. It can be used to
   1.225 +   kill experiments that are found to be doing wrong or bad things or that
   1.226 +   aren't useful.
   1.227 +
   1.228 +   If this property is not defined or is false, the client should assume
   1.229 +   the experiment is active and a candidate for activation.
   1.230 +
   1.231 +frozen
   1.232 +   (optional) Boolean value indicating this experiment is frozen and no
   1.233 +   longer accepting new enrollments.
   1.234 +
   1.235 +   If a client sees a true value in this field, it should not attempt to
   1.236 +   activate an experiment.
   1.237 +
   1.238 +jsfilter
   1.239 +    (optional) JavaScript code that will be evaluated to determine experiment
   1.240 +    applicability.
   1.241 +
   1.242 +    This property contains the string representation of JavaScript code that
   1.243 +    will be evaluated in a sandboxed environment using JavaScript's
   1.244 +    ``eval()``.
   1.245 +
   1.246 +    The string is expected to contain the definition of a JavaScript function
   1.247 +    ``filter(context)``. This function receives as its argument an object
   1.248 +    holding application state. See the section below for the definition of
   1.249 +    this object.
   1.250 +
   1.251 +    The purpose of this property is to allow experiments to define complex
   1.252 +    rules and logic for evaluating experiment applicability in a manner
   1.253 +    that is privacy conscious and doesn't require the transmission of
   1.254 +    excessive data.
   1.255 +
   1.256 +    The return value of this filter indicates whether the experiment is
   1.257 +    applicable. Functions should return true if the experiment is
   1.258 +    applicable.
   1.259 +
   1.260 +    If an experiment is not applicable, they should throw an Error whose
   1.261 +    message contains the reason the experiment is not applicable. This
   1.262 +    message may be logged and sent to remote servers, so it should not
   1.263 +    contain private or otherwise sensitive data that wouldn't normally
   1.264 +    be submitted.
   1.265 +
   1.266 +    If a falsey (or undefined) value is returned, the client should
   1.267 +    assume the experiment is not applicable.
   1.268 +
   1.269 +    If this property is not defined, the client does not consider a custom
   1.270 +    JavaScript filter function when determining whether an experiment is
   1.271 +    applicable.
   1.272 +
   1.273 +JavaScript Filter Context Objects
   1.274 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   1.275 +
   1.276 +The object passed to a ``jsfilter`` ``filter()`` function contains the
   1.277 +following properties:
   1.278 +
   1.279 +healthReportSubmissionEnabled
   1.280 +   This property contains a boolean indicating whether Firefox Health
   1.281 +   Report has its data submission flag enabled (whether Firefox Health
   1.282 +   Report is sending data to remote servers).
   1.283 +
   1.284 +healthReportPayload
   1.285 +   This property contains the current Firefox Health Report payload.
   1.286 +
   1.287 +   The payload format is documented at :ref:`healthreport_dataformat`.
   1.288 +
   1.289 +telemetryPayload
   1.290 +   This property contains the current Telemetry payload.
   1.291 +
   1.292 +The evaluation sandbox for the JavaScript filters may be destroyed
   1.293 +immediately after ``filter()`` returns. This function should not assume
   1.294 +async code will finish.
   1.295 +
   1.296 +Experiment Applicability and Client Behavior
   1.297 +============================================
   1.298 +
   1.299 +The point of an experiment manifest is to define which experiments are
   1.300 +available and where and how to run them. This section explains those
   1.301 +rules in more detail.
   1.302 +
   1.303 +Many of the properties in *Experiment Objects* are related to determining
   1.304 +whether an experiment should run on a given client. This evaluation is
   1.305 +performed client side.
   1.306 +
   1.307 +1. Multiple conditions in an experiment
   1.308 +---------------------------------------
   1.309 +
   1.310 +If multiple conditions are defined for an experiment, the client should
   1.311 +combine each condition with a logical *AND*: all conditions must be
   1.312 +satisfied for an experiment to run. If one condition fails, the experiment
   1.313 +is not applicable.
   1.314 +
   1.315 +2. Active experiment disappears from manifest
   1.316 +---------------------------------------------
   1.317 +
   1.318 +If a specific experiment disappears from the manifest, the client should
   1.319 +continue conducting an already-active experiment. Furthermore, the
   1.320 +client should remember what the expiration events were for an experiment
   1.321 +and honor them.
   1.322 +
   1.323 +The rationale here is that we want to prevent an accidental deletion
   1.324 +or temporary failure on the server to inadvertantly deactivate
   1.325 +supposed-to-be-active experiments. We also don't want premature deletion
   1.326 +of an experiment from the manifest to result in indefinite activation
   1.327 +periods.
   1.328 +
   1.329 +3. Inactive experiment disappears from manifest
   1.330 +-----------------------------------------------
   1.331 +
   1.332 +If an inactive but scheduled-to-be-active experiment disappears from the
   1.333 +manifest, the client should not activate the experiment.
   1.334 +
   1.335 +If that experiment reappears in the manifest, the client should not
   1.336 +treat that experiment any differently than any other new experiment. Put
   1.337 +another way, the fact an inactive experiment disappears and then
   1.338 +reappears should not be significant.
   1.339 +
   1.340 +The rationale here is that server operators should have complete
   1.341 +control of an inactive experiment up to it's go-live date.
   1.342 +
   1.343 +4. Re-evaluating applicability on manifest refresh
   1.344 +--------------------------------------------------
   1.345 +
   1.346 +When an experiment manifest is refreshed or updated, the client should
   1.347 +re-evaluate the applicability of each experiment therein.
   1.348 +
   1.349 +The rationale here is that the server may change the parameters of an
   1.350 +experiment and want clients to pick those up.
   1.351 +
   1.352 +5. Activating a previously non-applicable experiment
   1.353 +----------------------------------------------------
   1.354 +
   1.355 +If the conditions of an experiment change or the state of the client
   1.356 +changes to allow an experiment to transition from previously
   1.357 +non-applicable to applicable, the experiment should be activated.
   1.358 +
   1.359 +For example, if a client is running version 28 and the experiment
   1.360 +initially requires version 29 or above, the client will not mark the
   1.361 +experiment as applicable. But if the client upgrades to version 29 or if
   1.362 +the manifest is updated to require 28 or above, the experiment will
   1.363 +become applicable.
   1.364 +
   1.365 +6. Deactivating a previously active experiment
   1.366 +----------------------------------------------
   1.367 +
   1.368 +If the conditions of an experiment change or the state of the client
   1.369 +changes and an active experiment is no longer applicable, that
   1.370 +experiment should be deactivated.
   1.371 +
   1.372 +7. Calculation of sampling-based applicability
   1.373 +----------------------------------------------
   1.374 +
   1.375 +For calculating sampling-based applicability, the client will associate
   1.376 +a random value between ``0.0`` and ``1.0`` for each observed experiment
   1.377 +ID. This random value will be generated the first time sampling
   1.378 +applicability is evaluated. This random value will be persisted and used
   1.379 +in future applicability evaluations for this experiment.
   1.380 +
   1.381 +By saving and re-using the value, the client is able to reliably and
   1.382 +consistently evaluate applicability, even if the sampling threshold
   1.383 +in the manifest changes.
   1.384 +
   1.385 +Clients should retain the randomly-generated sampling value for
   1.386 +experiments that no longer appear in a manifest for a period of at least
   1.387 +30 days. The rationale is that if an experiment disappears and reappears
   1.388 +from a manifest, the client will not have multiple opportunities to
   1.389 +generate a random value that satisfies the sampling criteria.
   1.390 +
   1.391 +8. Incompatible version numbers
   1.392 +-------------------------------
   1.393 +
   1.394 +If a client receives a manifest with a version number that it doesn't
   1.395 +recognize, it should ignore the manifest.
   1.396 +
   1.397 +9. Usage of old manifests
   1.398 +-------------------------
   1.399 +
   1.400 +If a client experiences an error fetching a manifest (server not
   1.401 +available) or if the manifest is corrupt, not readable, or compatible,
   1.402 +the client may use a previously-fetched (cached) manifest.
   1.403 +
   1.404 +10. Updating XPIs
   1.405 +-----------------
   1.406 +
   1.407 +If the URL or hash of an active experiment's XPI changes, the client
   1.408 +should fetch the new XPI, uninstall the old XPI, and install the new
   1.409 +XPI.
   1.410 +
   1.411 +Examples
   1.412 +========
   1.413 +
   1.414 +Here is an example manifest::
   1.415 +
   1.416 +   {
   1.417 +     "version": 1,
   1.418 +     "experiments": [
   1.419 +       {
   1.420 +         "id": "da9d7f4f-f3f9-4f81-bacd-6f0626ffa360",
   1.421 +         "xpiURL": "https://experiments.mozilla.org/foo.xpi",
   1.422 +         "xpiHash": "sha1:cb1eb32b89d86d78b7326f416cf404548c5e0099",
   1.423 +         "startTime": 1393000000,
   1.424 +         "endTime": 1394000000,
   1.425 +         "appName": ["Firefox", "Fennec"],
   1.426 +         "minVersion": "28",
   1.427 +         "maxVersion": "30",
   1.428 +         "os": ["windows", "linux", "osx"],
   1.429 +         "jsfilter": "function filter(context) { return context.healthReportEnabled; }"
   1.430 +       }
   1.431 +     ]
   1.432 +   }

mercurial