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:

  1. 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.

  2. Consider which rulesets, or which combinations of rulesets will be needed in a pico.

  3. Write an installation ruleset, such as the one shown in the example below.

Example

 

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.