summaryrefslogtreecommitdiffstats
path: root/toolkit/components/normandy/docs/execution-model.rst
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/normandy/docs/execution-model.rst')
-rw-r--r--toolkit/components/normandy/docs/execution-model.rst95
1 files changed, 95 insertions, 0 deletions
diff --git a/toolkit/components/normandy/docs/execution-model.rst b/toolkit/components/normandy/docs/execution-model.rst
new file mode 100644
index 0000000000..6d5b16870c
--- /dev/null
+++ b/toolkit/components/normandy/docs/execution-model.rst
@@ -0,0 +1,95 @@
+Execution Model
+===============
+This document describes the execution model of the Normandy Client.
+
+The basic unit of instruction from the server is a *recipe*, which contains
+instructions for filtering, and arguments for a given action. See below for
+details.
+
+One iteration through all of these steps is called a *Normandy session*. This
+happens at least once every 6 hours, and possibly more often if Remote
+Settings syncs new changes.
+
+1. Fetching
+-----------
+A list of all active recipes is retrieved from Remote Settings, which has
+likely been syncing them in the background.
+
+2. Suitability
+--------------
+
+Once recipes have been retrieved, they go through several checks to determine
+their suitability for this client. Recipes contain information about which
+clients should execute the recipe. All recipes are processed by all clients,
+and all filtering happens in the client.
+
+For more information, see `the suitabilities docs <./suitabilities.html>`_.
+
+Signature
+~~~~~~~~~
+
+First, recipes are validated using a signature generated by Autograph_ that
+is included with the recipe. This signature validates both the contents of
+the recipe as well as its source.
+
+This signature is separate and distinct from the signing that happens on the
+Remote Settings collection. This provides additional assurance that this
+recipe is legitimate and intended to run on this client.
+
+.. _Autograph: https://github.com/mozilla-services/autograph
+
+Capabilities
+~~~~~~~~~~~~
+Next a recipe is checked for compatibility using *capabilities*.
+Capabilities are simple strings, such as ``"action:show-heartbeat"``. A
+recipe contains a list of required capabilities, and the Normandy Client has
+a list of capabilities that it supports. If any of the capabilities required
+by the recipe are not compatible with the client, then the recipe does not
+execute.
+
+Capabilities are used to avoid running recipes on a client that are so
+incompatible as to be harmful. For example, some changes to filter expression
+handling cannot be detected by filter expressions, and so older clients that
+receive filters using these new features would break.
+
+.. note::
+
+ Capabilities were first introduced in Firefox 70. Clients prior to this
+ do not check capabilities, and run all recipes provided. To accommodate
+ this, the server splits recipes into two Remote Settings collections,
+ ``normandy-recipes``, and ``normandy-recipes-capabilities``. Clients
+ prior to Firefox 70 use the former, whereas Firefox 70 and above use the
+ latter. Recipes that only require "baseline" capabilities are published
+ to both, and those that require advanced capabilities are only published
+ to the capabilities aware collection.
+
+Filter Expressions
+~~~~~~~~~~~~~~~~~~
+Finally the recipe's filter expression is checked. Filter expressions are
+written in an expression language named JEXL_ that is similar to JavaScript,
+but far simpler. It is intended to be as safe to evaluate as possible.
+
+.. _JEXL: https://github.com/mozilla/mozjexl
+
+Filters are evaluated in a context that contains details about the client
+including browser versions, installed add-ons, and Telemetry data. Filters
+have access to "transforms" which are simple functions that can do things like
+check preference values or parse strings into ``Date`` objects. Filters don't
+have access to change any state in the browser, and are generally
+idempotent. However, filters are *not* considered to be "pure functions",
+because they have access to state that may change, such as time and location.
+
+3. Execution
+------------
+After a recipe's suitability is determined, that recipe is executed. The
+recipe specifies an *action* by name, as well as arguments to pass to that
+action. The arguments are validated against an expected schema.
+
+All action have a pre- and post-step that runs once each Normandy session.
+The pre-step is run before any recipes are executed, and once the post-step
+is executed, no more recipes will be executed on that action in this session.
+
+Each recipe is passed to the action, along with its suitability. Individual
+actions have their own semantics about what to do with recipes. Many actions
+maintain their own life cycle of events for new recipes, existing recipes,
+and recipes that stop applying to this client.