Installing a KRL application
When picos were first conceived, about ten years ago, they were called “personal clouds,” or “personal event networks.” Each pico running on the Internet is like a personal computer running in the cloud. Like a personal computer, it needs applications. Such applications are written in KRL, as rulesets. Just as applications for a personal computer have to be installed before they can be used, so KRL applications need to be installed into a pico.
If the KRL application fits into a single ruleset, it can easily be installed through the developer UI (in the Rulesets tab) or by a program using the wrangler:install_ruleset_request
event. But when a KRL application is more involved, with multiple rulesets, it becomes more difficult to install manually, and more tedious to install programmatically.
The idea here is to write a ruleset (that, conceptually, is part of the KRL application) which installs the other rulesets. After a successful installation, it could even delete itself from the pico because its work is finished.
Instructions
This is how you could go about it:
Write the multiple rulesets that are to be installed in a single pico, and be sure that, working together, they allow the pico to perform as intended.
Consider which rulesets, or which combinations of rulesets will be needed in a pico.
Write an installation ruleset, such as the one shown in the example below.
Example
- 1 Instructions
- 2 Example
- 2.1 A real KRL application
- 2.2 A literate programming presentation
- 2.2.1 The ruleset name, and description
- 2.2.2 Lists of RIDs
- 2.2.3 For the Testing tab
- 2.2.4 Channel policies
- 2.2.5 A defined action to install a ruleset if needed
- 2.2.6 Creating the channel
- 2.2.7 Starting the installation process
- 2.2.8 Doing the installation
- 2.2.9 Installing base rulesets
- 2.2.10 Installing connections rulesets
- 2.2.11 Installing the trust_ping ruleset
- 2.2.12 Installing the basicmessage ruleset
- 2.2.13 Installing the discover-features ruleset
- 2.2.14 Cleaning up after the installation ruleset
- 2.3 Screenshots
- 2.4 Discussion
A real KRL application
Here we will consider a real KRL application, called the ACA-Pico, which when installed in a pico makes that pico an Aries cloud agent, which can perform self-sovereign identity operations, connecting with other agents to communicate securely (with signed and encrypted messages), as well as issue, hold, and verify credentials, etc. This application consists of a dozen or so rulesets, most of which need to be installed in the pico to give it the desired functionality.
Our point here is not to talk about Aries agents per se, but to show an example of a ruleset which installs other rulesets.
A literate programming presentation
The presentation of the installation ruleset will borrow concepts from the Literate Programming idea, interleaving English explanation with snippets of KRL code. If a reader were to simply concatenate all of the program snippets together, in order, she would have the entire source code of this ruleset (for convenience, available here as a single file).
The ruleset name, and description
ruleset io.picolabs.aca.installer {
meta {
description <<
Ruleset to install rulesets to make a pico
into an Aries cloud agent
>>
use module io.picolabs.wrangler alias wrangler
}
This part of the ruleset defines the RID and describes the ruleset’s purpose. Like most rulesets, this one will make use of the wrangler ruleset (which plays a role like that of an operating system in a personal computer).
Notice also that no functions are shared by this ruleset. It will operate only by reacting to a single event (which, spoiler alert, will be aca_installer:install_request
).
Lists of RIDs
global {
base_rids = [
"io.picolabs.did",
"io.picolabs.aca",
]
connections_rids = [
"html",
"io.picolabs.aca.connections.ui",
"io.picolabs.aca.connections",
]
Next comes the global
block, which will be the subject of this and several sections to follow.
Here we see two lists of ruleset identifiers. The first are the RIDs of rulesets which must always be part of any installation, bound to the name base_rids
. The second is the list of RIDS which will be required if our agent must make new connections, bound to the name connections_rids
.
Notice that the order is significant. The first one or two rulesets identified are used as modules by subsequent rulesets. Modules (themselves rulesets) must be installed in the pico before rulesets which use them as modules.
For the Testing tab
__testing = {
"events": [
{
"domain": "aca_installer",
"name": "install_request",
"attrs": [
"connections",
"basicmessage",
"trust_ping",
"discover-features",
]
}
]
}
Rather than use the __testing
map which the compiler would define (see the Developer UI -- Testing tab page), we wish to expose just one event, again the aca_installer:install_request
event. It will expect four attributes. The value of these attributes will determine which rulesets are installed.
Channel policies
Since we will want the installed ruleset to receive and handle the aca_installer:install_request
event, we will be creating a channel for that purpose. Its policy is laid out in this code, allowing just that one event. An alert reader will notice that the query policy would allow any function shared by this ruleset to be called. Since there are none, the policy could have been simpler.
A defined action to install a ruleset if needed
This is the final bit of the global
block, which ends in line 12 of this snippet.
The name install_request
is bound to a KRL programmer defined action (or defaction
for short) which will check to see whether the ruleset whose rid
is passed in is already installed in the pico (lines 2-3). If needed, this defaction
will send a wrangler:install_ruleset_request
to this same pico, using the current channel (lines 5-8). Notice that line 7 refers to meta:rulesetURI
which means that the KRL file for this installation ruleset is expected to be in the same folder as the rulesets it is installing.
Normally, we raise
such event, so that it happens in the same event evaluation cycle. Here we are deliberately choosing to queue up the event. It will be added to this pico’s event bus and will be taken up after everything in the queue already (including this the currently evaluating event) will have been handled.
Creating the channel
We are now in the rules portion of the installation ruleset. As soon as this ruleset is itself installed in the pico, it will automatically receive the wrangler:ruleset_installed
event. This rule selects because the rids
array, passed as an attribute with the event, will contain its own RID (lines 2-3).
When this rule is selected, it will take action (lines 4-5) by having wrangler create a channel with the tags aca installer
and the policies defined earlier in the global
block (see section “Channel policies” above). That action will return the newly created channel, which the rule will store in the ent:channel
entity variable (in line 7) of the pico (and which will be used later in the last rule of the installer ruleset).
Starting the installation process
With the installation ruleset installed, it will just be sitting in the pico waiting to be activated. The pico itself will just be waiting. It now has a channel, tagged aca installer
appropriate for the one event this ruleset expects, and the developer UI will have an entry in the Testing tab that could be used to send the aca_installer:install_request
event. Or that event could be send programmatically. Eventually the event will be sent to the pico.
When the pico receives the event, however it might be sent or raised, this rule will be selected (line 2). Its only action is to queue up an aca_installer:install_request_on_self
event to itself. The only purpose of this rule is to switch from the aca installer
channel to the system self
family channel. The ultimate reason for this will become clear in the very last rule of this ruleset, discussed later.
When this rule finishes, that is the end of the ruleset’s reaction to the aca_installer:install_request
event. The pico will then turn to its event bus for the next event. That will likely be the one we just queued up in lines 3-7.
Doing the installation
A rule that reacts to the aca_installer:install_request_on_self
event:
This is the heart of the installer. It defines an auxiliary function in the pre
block (the prelude) of the rule and binds it to the name needed
for use later on in the rule evaluation. This function simply returns true when there is an event attribute named name
and the attribute value begins with the letter Y (in either upper or lower case).
The rule will fire (because there is no conditional action given), and when it does, it will raise
two or more of the six events mentioned in the postlude. First, it will always raise the aca_installer:base_install_request
in order to install the rulesets that are always required. Then it will raise separate events for each of the possible attributes “connections”, “trust_ping”, “basicmessage”, and “discover-features” depending on whether these attribute are present in the event attributes and if so on their value.
Finally, the rule will always raise the aca_installer:cleanup
event.
Raised events are added to the end of the evaluation schedule, so they will be handled within the context of this same evaluation cycle. Evaluation of the do_an_installation
rule (for the aca_installer:install_request_on_self
event) will not conclude until the evaluation schedule is empty.
Installing base rulesets
This rule will select when the aca_installer:base_install_request
event is taken from the evaluation schedule. It will simply take the action defined by install_request
(see the “A defined action to install a ruleset if needed” section above) for each of the RIDs in the base_rids
array (defined in the global
block). See the Looping in rules page for discussion of the foreach
clause.
Installing connections rulesets
Similarly for the RIDS in the connections_rids
array.
Installing the trust_ping ruleset
There is only one ruleset for the “trust_ping” functionality, so its RID is hard-coded in this rule.
Installing the basicmessage ruleset
Similarly for the “basicmessage” functionality…
Installing the discover-features ruleset
and for the “discover-features” functionality.
Cleaning up after the installation ruleset
This is the final rule of the ruleset (which ends with the closing curly brace of line 8 here).
It takes one action, which is to delete the channel tagged aca installer
because it won’t be needed again. This is why, incidentally, that we switched to the family channel, because we couldn’t otherwise delete the channel we had been using up to that point (see the “Starting the installation process“ section above). We had saved the entire channel in the ent:channel
entity variable, but here use just the ECI (the Event Channel Identifier).
The rule also fires (because there is no condition on the action), and so we add to the schedule one final event, asking wrangler to uninstall this very ruleset. When that has been done, the schedule will be empty and the evaluation cycle begun with the do_an_installation
rule (see the “Doing the installation“ section above) will be complete.
The pico will then return to examine its event bus queue, which will contain the events to actually install the rulesets. The rulesets will be installed in the order those events were put on the queue by the event:send
in the install_request
defined action (see the “A defined action to install a ruleset if needed“ section above).
Once the event bus/queue is empty, the pico will return to its quiescent state, waiting for more events and queries to come in. But it has been changed in an important way by this burst of activity. The pico is now an Aries agent, along with whatever it was before and whatever it might become with future application installations.
Screenshots
This screenshot shows the rulesets and channels of the pico before installing the installer ruleset:
This screenshot shows the rulesets and channels after the installer ruleset has been installed:
This screenshot shows the Testing tab for the installer, ready to be used:
Finally, this screenshot shows the rulesets and channels after the Testing tab was used to send the aca_installer:install_request
event with connections=y
but the other boxes left blank:
Note that the installer ruleset is gone, as is the aca
installer
channel. In their place are five new rulesets and two new channels, which are part of the ACA-Pico application. The pico is now an Aries agent.
Discussion
This sample ruleset is pretty straightforward.
Much can be learned by reading through it, and understanding what it causes the pico to do. It includes example of functions, a defined action, sent events, raised events, and rules. It speaks of rules being “selected” and then possibly “firing.” It also shows the interplay between the rule evaluation schedule and the pico event bus/queue.
Copyright Picolabs | Licensed under Creative Commons.