browser/experiments/docs/manifest.rst

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

mercurial