-
Notifications
You must be signed in to change notification settings - Fork 0
The Jarvis Specification
This serves as a complete specification of the structure, organization, and functionality of Jarvis:
The goal of Jarvis is to create a "modular open-source platform for reactive and predictive data analysis and presentation". We want users to be able to "install" 3rd party modules that give them access to specific data analytics into our platform without having to trust the modules completely with their data.
In essence, the platform is separated into the Core (Jarvis itself) and Modules (3rd party code to analyze data).
-------------------------------------
| Core Application |
| |
| -------------- ------------- |
| | Module #1 | | Module #2 | |
| -------------- ------------- |
| |
-------------------------------------`
While the Core has direct access to hardware, it is up to the untrusted 3rd-party modules to create useful data for the user. All communication for the modules must first go through the core (to ensure that permissions are being enforced) - they may not communicate directly. We have an extensive permissions system to ensure that users know exactly where their data is going.
Each module functions as a node in a flow graph of the user's data through the Jarvis system. Some modules function as "producers" and are the starting point for events. These modules will read data from a source - sensor, network, etc. - and send the data out for other modules to consume. Consumer modules are able to do either take data sources as input and display them to the user or do further data processing and output that data for other modules to use. Notably, this means that a module can act as both a producer and a consumer.
--------------
| Module #1 |
--------------
|
| (typed output)
|
| Core |
|
| (typed input)
v
--------------
| Module #2 |
--------------
All input and output of the modules is "typed" to ensure that
- modules have permission to access that type of data
- new modules may output data that is compatible with older modules (see superset rule in Data Communications below)
- we can make strong guarantees about each sensor's data and the modules that use it
|- Module Directory
|--- Manifest File (package.json)
|--- Main File (index.html)
|--- Supporting JS/CSS Files
Jarvis modules are structured much like a regular online website with the addition of a manifest file.
Each module has an index.html
file that gets loaded first when the module is installed. Each module is loaded into an iFrame that exists within the core application on a unique origin. Therefore, modules may access their resources with relative paths in the HTML (e.g. <link href="/styles.css"></link>
).
The manifest file contains both general information about the module for Jarvis (title, description, author, website) and information about what the module wishes to accomplish (permissions, subscribed_events, dependencies).
package.json
example:
{
"title": "GPS Module",
"permissions": {
"sensor": ["gps"]
},
"subscribed_events": [],
"dependencies": [],
"provided_events": [
{
"name": "GPS Data",
"type_name": "gps",
"fields": {
"latitude": "float",
"longitude": "float"
}
}
]},
"description": "Produces GPS Data for other modules to consume.",
}
-
permissions
- Network, system, and hardware permissions the modules needed. -
dependencies
- Modules which must be installed for this module to operate correctly. -
subscribed_events
- subscribed_events. -
outputs
- A type of data that the module will output to the system.
Where outputs
and subscribed_events
are in the form of a data type. Data types in JSON are specified as:
{
"name": "GPS Data", // The human readable name shown to users when they want to assign a module to this data type.
"type_name": "gps", // The unique name given to this type, used internally throughout Jarvis.
"fields": { // An object of fields where the key is the field name and the value is the type of data stored in the field.
"latitude": "float",
"longitude": "float",
}
}
A field is analogous to the idea of "tuple matching-rules" in section on Data Communications.
Events signify the availability of data from a provider module or a notification of a real-world event. They could signal the completion of data processing on a server, the arrival of an email, the device's entrance into a geofenced area, etc. Modules register to receive specific event types in their manifest. When an event is created, the core checks permissions, then distributes events to modules that have subscribed to that type of event.
An event's data is accessible via a URI which describes the type of data produced and the timestamp at which it was made available. The user is able to select which modules' data are provided by default for each data type. For example, GPS events use the URI format: jarvis://gps/2014-09-22T05:29:33+00:00
. If two modules are installed which create GPS events, the user selects his preferred GPS module and all GPS URIs route to the selected module.
{
"id": “event-id”, // Unique id corresponding to the event type and name.
"timestamp": “iso”, // Time at which the data was made available.
"description": "Human-readable description of the event",
"URI": "jarvis://[datatype]/[timestamp]", // URI from which other modules can request data.
"type": "data " // Data type registered with the core. Must be in the module's provided types.
}
All data in Jarvis is considered to be structured and typed. Since we are using JSON as the intermediary language between the Modules and the Core, typing becomes a matter of defining (key, value type) tuples that a module is interested in.
For example, in this snippet of data, a tuple of ("times_eaten", int)
would match:
{ "times_eaten": 5 }
Our data type system allows for for data to conform to rules that only match a subset of its features. For example, the following data would match the rules ("latitude", float)
("longitude", float)
despite the fact that it contains an extra field (altitude
).
{
"latitude": 64.3,
"longitude": -37.5,
"altitude": -100,
}
If a module requested data matching the rules above, the fields not explicitly requested (altitude
) would be stripped out.
Outside of the type system, all module-to-core and inter-module communications is handled by a Javascript API that allows information to flow into (and out of) the sandboxed iFrames that modules live in.
The following is a cursory list of expected API functions:
getData
publishData
-
sensor
- Access to a specific hardware sensor (possible values:gps
,gyro
,accelerometer
). -
network
- Access to a specific network resources (e.g.https://*.google.com
). -
system
- Access to resources which the OS can access. (possible values:sms
,email
,airdispatch
)
Permissions may include other metadata in order to determine the quality of the data accessed.
For example, gps resolution:low frequency:4h
can be used to show that the module only needs low resolution GPS data at a frequency of once every 4 hours.
Each module produces an html fragment, which is hosted in an iframe provided by the core interface for each module. All of the iframes are enumerated over in one of two list views, a la Google Now. Eventually, there will be a style guide for module’s views. However, modules are free to define their own layout entirely. If a tile is swiped to the side, it will be dismissed. If it is long-pressed, a configuration dialogue will be invoked.
The first list view, named “On Demand,” will show contextual and real-time information pertinant to the user’s activities. This list will primarily be dedicated to spontaneous information display, such as weather and social media summaries. The second list view, named “Utility,” will give access to more permanent and functionality / interaction-based items, such as the schedule optimizer and friendship assistant.
Swiping the entire screen to the right will display a list of currently visible modules, which will allow users to select/deselect modules for display. The user will also have the option to install additional modules on this screen.
Modules are expected to have their own elements for user interaction, if necessary, and listen for/catch UI events as triggered.
Modules can be pinned to the top of either the on-demand or the utility list view.