browser/experiments/docs/manifest.rst

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 .. _experiments_manifests:
michael@0 2
michael@0 3 =====================
michael@0 4 Experiments Manifests
michael@0 5 =====================
michael@0 6
michael@0 7 *Experiments Manifests* are documents that describe the set of active
michael@0 8 experiments a client may run.
michael@0 9
michael@0 10 *Experiments Manifests* are fetched periodically by clients. When
michael@0 11 fetched, clients look at the experiments within the manifest and
michael@0 12 determine which experiments are applicable. If an experiment is
michael@0 13 applicable, the client may download and start the experiment.
michael@0 14
michael@0 15 Manifest Format
michael@0 16 ===============
michael@0 17
michael@0 18 Manifests are JSON documents where the main element is an object.
michael@0 19
michael@0 20 The *schema* of the object is versioned and defined by the presence
michael@0 21 of a top-level ``version`` property, whose integer value is the
michael@0 22 schema version used by that manifest. Each version is documented
michael@0 23 in the sections below.
michael@0 24
michael@0 25 Version 1
michael@0 26 ---------
michael@0 27
michael@0 28 Version 1 is the original manifest format.
michael@0 29
michael@0 30 The following properties may exist in the root object:
michael@0 31
michael@0 32 experiments
michael@0 33 An array of objects describing candidate experiments. The format of
michael@0 34 these objects is documented below.
michael@0 35
michael@0 36 An array is used to create an explicit priority of experiments.
michael@0 37 Experiments listed at the beginning of the array take priority over
michael@0 38 experiments that follow.
michael@0 39
michael@0 40 Experiments Objects
michael@0 41 ^^^^^^^^^^^^^^^^^^^
michael@0 42
michael@0 43 Each object in the ``experiments`` array may contain the following
michael@0 44 properties:
michael@0 45
michael@0 46 id
michael@0 47 (required) String identifier of this experiment. The identifier should
michael@0 48 be treated as opaque by clients. It is used to uniquely identify an
michael@0 49 experiment for all of time.
michael@0 50
michael@0 51 xpiURL
michael@0 52 (required) String URL of the XPI that implements this experiment.
michael@0 53
michael@0 54 If the experiment is activated, the client will download and install this
michael@0 55 XPI.
michael@0 56
michael@0 57 xpiHash
michael@0 58 (required) String hash of the XPI that implements this experiment.
michael@0 59
michael@0 60 The value is composed of a hash identifier followed by a colon
michael@0 61 followed by the hash value. e.g.
michael@0 62 `sha1:f677428b9172e22e9911039aef03f3736e7f78a7`. `sha1` and `sha256`
michael@0 63 are the two supported hashing mechanisms. The hash value is the hex
michael@0 64 encoding of the binary hash.
michael@0 65
michael@0 66 When the client downloads the XPI for the experiment, it should compare
michael@0 67 the hash of that XPI against this value. If the hashes don't match,
michael@0 68 the client should not install the XPI.
michael@0 69
michael@0 70 Clients may also use this hash as a means of determining when an
michael@0 71 experiment's XPI has changed and should be refreshed.
michael@0 72
michael@0 73 startTime
michael@0 74 Integer seconds since UNIX epoch that this experiment should
michael@0 75 start. Clients should not start an experiment if *now()* is less than
michael@0 76 this value.
michael@0 77
michael@0 78 maxStartTime
michael@0 79 (optional) Integer seconds since UNIX epoch after which this experiment
michael@0 80 should no longer start.
michael@0 81
michael@0 82 Some experiments may wish to impose hard deadlines after which no new
michael@0 83 clients should activate the experiment. This property may be used to
michael@0 84 facilitate that.
michael@0 85
michael@0 86 endTime
michael@0 87 Integer seconds since UNIX epoch after which this experiment
michael@0 88 should no longer run. Clients should cease an experiment when the current
michael@0 89 time is beyond this value.
michael@0 90
michael@0 91 maxActiveSeconds
michael@0 92 Integer seconds defining the max wall time this experiment should be
michael@0 93 active for.
michael@0 94
michael@0 95 The client should deactivate the experiment this many seconds after
michael@0 96 initial activation.
michael@0 97
michael@0 98 This value only involves wall time, not browser activity or session time.
michael@0 99
michael@0 100 appName
michael@0 101 Array of application names this experiment should run on.
michael@0 102
michael@0 103 An application name comes from ``nsIXULAppInfo.name``. It is a value
michael@0 104 like ``Firefox``, ``Fennec``, or `B2G`.
michael@0 105
michael@0 106 The client should compare its application name against the members of
michael@0 107 this array. If a match is found, the experiment is applicable.
michael@0 108
michael@0 109 minVersion
michael@0 110 (optional) String version number of the minimum application version this
michael@0 111 experiment should run on.
michael@0 112
michael@0 113 A version number is something like ``27.0.0`` or ``28``.
michael@0 114
michael@0 115 The client should compare its version number to this value. If the client's
michael@0 116 version is greater or equal to this version (using a version-aware comparison
michael@0 117 function), the experiment is applicable.
michael@0 118
michael@0 119 If this is not specified, there is no lower bound to versions this
michael@0 120 experiment should run on.
michael@0 121
michael@0 122 maxVersion
michael@0 123 (optional) String version number of the maximum application version this
michael@0 124 experiment should run on.
michael@0 125
michael@0 126 This is similar to ``minVersion`` except it sets the upper bound for
michael@0 127 application versions.
michael@0 128
michael@0 129 If the client's version is less than or equal to this version, the
michael@0 130 experiment is applicable.
michael@0 131
michael@0 132 If this is not specified, there is no upper bound to versions this
michael@0 133 experiment should run on.
michael@0 134
michael@0 135 version
michael@0 136 (optional) Array of application versions this experiment should run on.
michael@0 137
michael@0 138 This is similar to ``minVersion`` and ``maxVersion`` except only a
michael@0 139 whitelisted set of specific versions are allowed.
michael@0 140
michael@0 141 The client should compare its version to members of this array. If a match
michael@0 142 is found, the experiment is applicable.
michael@0 143
michael@0 144 minBuildID
michael@0 145 (optional) String minimum Build ID this experiment should run on.
michael@0 146
michael@0 147 Build IDs are values like ``201402261424``.
michael@0 148
michael@0 149 The client should perform a string comparison of its Build ID against this
michael@0 150 value. If its value is greater than or equal to this value, the experiment
michael@0 151 is applicable.
michael@0 152
michael@0 153 maxBuildID
michael@0 154 (optional) String maximum Build ID this experiment should run on.
michael@0 155
michael@0 156 This is similar to ``minBuildID`` except it sets the upper bound
michael@0 157 for Build IDs.
michael@0 158
michael@0 159 The client should perform a string comparison of its Build ID against
michael@0 160 this value. If its value is less than or equal to this value, the
michael@0 161 experiment is applicable.
michael@0 162
michael@0 163 buildIDs
michael@0 164 (optional) Array of Build IDs this experiment should run on.
michael@0 165
michael@0 166 This is similar to ``minBuildID`` and ``maxBuildID`` except only a
michael@0 167 whitelisted set of Build IDs are considered.
michael@0 168
michael@0 169 The client should compare its Build ID to members of this array. If a
michael@0 170 match is found, the experiment is applicable.
michael@0 171
michael@0 172 os
michael@0 173 (optional) Array of operating system identifiers this experiment should
michael@0 174 run on.
michael@0 175
michael@0 176 Values for this array come from ``nsIXULRuntime.OS``.
michael@0 177
michael@0 178 The client will compare its operating system identifier to members
michael@0 179 of this array. If a match is found, the experiment is applicable to the
michael@0 180 client.
michael@0 181
michael@0 182 channel
michael@0 183 (optional) Array of release channel identifiers this experiment should run
michael@0 184 on.
michael@0 185
michael@0 186 The client will compare its channel to members of this array. If a match
michael@0 187 is found, the experiment is applicable.
michael@0 188
michael@0 189 If this property is not defined, the client should assume the experiment
michael@0 190 is to run on all channels.
michael@0 191
michael@0 192 locale
michael@0 193 (optional) Array of locale identifiers this experiment should run on.
michael@0 194
michael@0 195 A locale identifier is a string like ``en-US`` or ``zh-CN`` and is
michael@0 196 obtained by looking at
michael@0 197 ``nsIXULChromeRegistry.getSelectedLocale("global")``.
michael@0 198
michael@0 199 The client should compare its locale identifier to members of this array.
michael@0 200 If a match is found, the experiment is applicable.
michael@0 201
michael@0 202 If this property is not defined, the client should assume the experiment
michael@0 203 is to run on all locales.
michael@0 204
michael@0 205 sample
michael@0 206 (optional) Decimal number indicating the sampling rate for this experiment.
michael@0 207
michael@0 208 This will contain a value between ``0.0`` and ``1.0``. The client should
michael@0 209 generate a random decimal between ``0.0`` and ``1.0``. If the randomly
michael@0 210 generated number is less than or equal to the value of this field, the
michael@0 211 experiment is applicable.
michael@0 212
michael@0 213 disabled
michael@0 214 (optional) Boolean value indicating whether an experiment is disabled.
michael@0 215
michael@0 216 Normally, experiments are deactivated after a certain time has passed or
michael@0 217 after the experiment itself determines it no longer needs to run (perhaps
michael@0 218 it collected sufficient data already).
michael@0 219
michael@0 220 This property serves as a backup mechanism to remotely disable an
michael@0 221 experiment before it was scheduled to be disabled. It can be used to
michael@0 222 kill experiments that are found to be doing wrong or bad things or that
michael@0 223 aren't useful.
michael@0 224
michael@0 225 If this property is not defined or is false, the client should assume
michael@0 226 the experiment is active and a candidate for activation.
michael@0 227
michael@0 228 frozen
michael@0 229 (optional) Boolean value indicating this experiment is frozen and no
michael@0 230 longer accepting new enrollments.
michael@0 231
michael@0 232 If a client sees a true value in this field, it should not attempt to
michael@0 233 activate an experiment.
michael@0 234
michael@0 235 jsfilter
michael@0 236 (optional) JavaScript code that will be evaluated to determine experiment
michael@0 237 applicability.
michael@0 238
michael@0 239 This property contains the string representation of JavaScript code that
michael@0 240 will be evaluated in a sandboxed environment using JavaScript's
michael@0 241 ``eval()``.
michael@0 242
michael@0 243 The string is expected to contain the definition of a JavaScript function
michael@0 244 ``filter(context)``. This function receives as its argument an object
michael@0 245 holding application state. See the section below for the definition of
michael@0 246 this object.
michael@0 247
michael@0 248 The purpose of this property is to allow experiments to define complex
michael@0 249 rules and logic for evaluating experiment applicability in a manner
michael@0 250 that is privacy conscious and doesn't require the transmission of
michael@0 251 excessive data.
michael@0 252
michael@0 253 The return value of this filter indicates whether the experiment is
michael@0 254 applicable. Functions should return true if the experiment is
michael@0 255 applicable.
michael@0 256
michael@0 257 If an experiment is not applicable, they should throw an Error whose
michael@0 258 message contains the reason the experiment is not applicable. This
michael@0 259 message may be logged and sent to remote servers, so it should not
michael@0 260 contain private or otherwise sensitive data that wouldn't normally
michael@0 261 be submitted.
michael@0 262
michael@0 263 If a falsey (or undefined) value is returned, the client should
michael@0 264 assume the experiment is not applicable.
michael@0 265
michael@0 266 If this property is not defined, the client does not consider a custom
michael@0 267 JavaScript filter function when determining whether an experiment is
michael@0 268 applicable.
michael@0 269
michael@0 270 JavaScript Filter Context Objects
michael@0 271 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
michael@0 272
michael@0 273 The object passed to a ``jsfilter`` ``filter()`` function contains the
michael@0 274 following properties:
michael@0 275
michael@0 276 healthReportSubmissionEnabled
michael@0 277 This property contains a boolean indicating whether Firefox Health
michael@0 278 Report has its data submission flag enabled (whether Firefox Health
michael@0 279 Report is sending data to remote servers).
michael@0 280
michael@0 281 healthReportPayload
michael@0 282 This property contains the current Firefox Health Report payload.
michael@0 283
michael@0 284 The payload format is documented at :ref:`healthreport_dataformat`.
michael@0 285
michael@0 286 telemetryPayload
michael@0 287 This property contains the current Telemetry payload.
michael@0 288
michael@0 289 The evaluation sandbox for the JavaScript filters may be destroyed
michael@0 290 immediately after ``filter()`` returns. This function should not assume
michael@0 291 async code will finish.
michael@0 292
michael@0 293 Experiment Applicability and Client Behavior
michael@0 294 ============================================
michael@0 295
michael@0 296 The point of an experiment manifest is to define which experiments are
michael@0 297 available and where and how to run them. This section explains those
michael@0 298 rules in more detail.
michael@0 299
michael@0 300 Many of the properties in *Experiment Objects* are related to determining
michael@0 301 whether an experiment should run on a given client. This evaluation is
michael@0 302 performed client side.
michael@0 303
michael@0 304 1. Multiple conditions in an experiment
michael@0 305 ---------------------------------------
michael@0 306
michael@0 307 If multiple conditions are defined for an experiment, the client should
michael@0 308 combine each condition with a logical *AND*: all conditions must be
michael@0 309 satisfied for an experiment to run. If one condition fails, the experiment
michael@0 310 is not applicable.
michael@0 311
michael@0 312 2. Active experiment disappears from manifest
michael@0 313 ---------------------------------------------
michael@0 314
michael@0 315 If a specific experiment disappears from the manifest, the client should
michael@0 316 continue conducting an already-active experiment. Furthermore, the
michael@0 317 client should remember what the expiration events were for an experiment
michael@0 318 and honor them.
michael@0 319
michael@0 320 The rationale here is that we want to prevent an accidental deletion
michael@0 321 or temporary failure on the server to inadvertantly deactivate
michael@0 322 supposed-to-be-active experiments. We also don't want premature deletion
michael@0 323 of an experiment from the manifest to result in indefinite activation
michael@0 324 periods.
michael@0 325
michael@0 326 3. Inactive experiment disappears from manifest
michael@0 327 -----------------------------------------------
michael@0 328
michael@0 329 If an inactive but scheduled-to-be-active experiment disappears from the
michael@0 330 manifest, the client should not activate the experiment.
michael@0 331
michael@0 332 If that experiment reappears in the manifest, the client should not
michael@0 333 treat that experiment any differently than any other new experiment. Put
michael@0 334 another way, the fact an inactive experiment disappears and then
michael@0 335 reappears should not be significant.
michael@0 336
michael@0 337 The rationale here is that server operators should have complete
michael@0 338 control of an inactive experiment up to it's go-live date.
michael@0 339
michael@0 340 4. Re-evaluating applicability on manifest refresh
michael@0 341 --------------------------------------------------
michael@0 342
michael@0 343 When an experiment manifest is refreshed or updated, the client should
michael@0 344 re-evaluate the applicability of each experiment therein.
michael@0 345
michael@0 346 The rationale here is that the server may change the parameters of an
michael@0 347 experiment and want clients to pick those up.
michael@0 348
michael@0 349 5. Activating a previously non-applicable experiment
michael@0 350 ----------------------------------------------------
michael@0 351
michael@0 352 If the conditions of an experiment change or the state of the client
michael@0 353 changes to allow an experiment to transition from previously
michael@0 354 non-applicable to applicable, the experiment should be activated.
michael@0 355
michael@0 356 For example, if a client is running version 28 and the experiment
michael@0 357 initially requires version 29 or above, the client will not mark the
michael@0 358 experiment as applicable. But if the client upgrades to version 29 or if
michael@0 359 the manifest is updated to require 28 or above, the experiment will
michael@0 360 become applicable.
michael@0 361
michael@0 362 6. Deactivating a previously active experiment
michael@0 363 ----------------------------------------------
michael@0 364
michael@0 365 If the conditions of an experiment change or the state of the client
michael@0 366 changes and an active experiment is no longer applicable, that
michael@0 367 experiment should be deactivated.
michael@0 368
michael@0 369 7. Calculation of sampling-based applicability
michael@0 370 ----------------------------------------------
michael@0 371
michael@0 372 For calculating sampling-based applicability, the client will associate
michael@0 373 a random value between ``0.0`` and ``1.0`` for each observed experiment
michael@0 374 ID. This random value will be generated the first time sampling
michael@0 375 applicability is evaluated. This random value will be persisted and used
michael@0 376 in future applicability evaluations for this experiment.
michael@0 377
michael@0 378 By saving and re-using the value, the client is able to reliably and
michael@0 379 consistently evaluate applicability, even if the sampling threshold
michael@0 380 in the manifest changes.
michael@0 381
michael@0 382 Clients should retain the randomly-generated sampling value for
michael@0 383 experiments that no longer appear in a manifest for a period of at least
michael@0 384 30 days. The rationale is that if an experiment disappears and reappears
michael@0 385 from a manifest, the client will not have multiple opportunities to
michael@0 386 generate a random value that satisfies the sampling criteria.
michael@0 387
michael@0 388 8. Incompatible version numbers
michael@0 389 -------------------------------
michael@0 390
michael@0 391 If a client receives a manifest with a version number that it doesn't
michael@0 392 recognize, it should ignore the manifest.
michael@0 393
michael@0 394 9. Usage of old manifests
michael@0 395 -------------------------
michael@0 396
michael@0 397 If a client experiences an error fetching a manifest (server not
michael@0 398 available) or if the manifest is corrupt, not readable, or compatible,
michael@0 399 the client may use a previously-fetched (cached) manifest.
michael@0 400
michael@0 401 10. Updating XPIs
michael@0 402 -----------------
michael@0 403
michael@0 404 If the URL or hash of an active experiment's XPI changes, the client
michael@0 405 should fetch the new XPI, uninstall the old XPI, and install the new
michael@0 406 XPI.
michael@0 407
michael@0 408 Examples
michael@0 409 ========
michael@0 410
michael@0 411 Here is an example manifest::
michael@0 412
michael@0 413 {
michael@0 414 "version": 1,
michael@0 415 "experiments": [
michael@0 416 {
michael@0 417 "id": "da9d7f4f-f3f9-4f81-bacd-6f0626ffa360",
michael@0 418 "xpiURL": "https://experiments.mozilla.org/foo.xpi",
michael@0 419 "xpiHash": "sha1:cb1eb32b89d86d78b7326f416cf404548c5e0099",
michael@0 420 "startTime": 1393000000,
michael@0 421 "endTime": 1394000000,
michael@0 422 "appName": ["Firefox", "Fennec"],
michael@0 423 "minVersion": "28",
michael@0 424 "maxVersion": "30",
michael@0 425 "os": ["windows", "linux", "osx"],
michael@0 426 "jsfilter": "function filter(context) { return context.healthReportEnabled; }"
michael@0 427 }
michael@0 428 ]
michael@0 429 }

mercurial